From 060fb512a0e60485f6b547425defb155b515869b Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 28 Jun 2024 12:55:57 +0300 Subject: [PATCH] refactor(feed): refactor feed screen --- android/eatvio_app_android.iml | 2 +- lib/app_router.dart | 2 +- .../feed/models/feed_blog_post_model.dart | 20 + .../models/feed_blog_post_model.freezed.dart | 310 +++++++++ .../feed/models/feed_blog_post_model.g.dart | 33 + .../bloc/feed_cubit/feed_cubit.dart | 19 + .../bloc/feed_cubit/feed_state.dart | 19 + .../bloc/feed_cubit/feed_state.freezed.dart | 620 ++++++++++++++++++ .../feed/presentation/pages}/feed_screen.dart | 90 ++- .../feed/repositories/feed_repository.dart | 16 + lib/features/feed/services/feed_service.dart | 13 + .../feed/services/feed_service.g.dart | 80 +++ lib/locator_service.dart | 6 + lib/main.dart | 5 +- .../feed/feed_screen/bloc/feed_bloc.dart | 73 --- .../feed/feed_screen/bloc/feed_event.dart | 23 - .../feed/feed_screen/bloc/feed_state.dart | 49 -- 17 files changed, 1183 insertions(+), 197 deletions(-) create mode 100644 lib/features/feed/models/feed_blog_post_model.dart create mode 100644 lib/features/feed/models/feed_blog_post_model.freezed.dart create mode 100644 lib/features/feed/models/feed_blog_post_model.g.dart create mode 100644 lib/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart create mode 100644 lib/features/feed/presentation/bloc/feed_cubit/feed_state.dart create mode 100644 lib/features/feed/presentation/bloc/feed_cubit/feed_state.freezed.dart rename lib/{presentation/feed/feed_screen => features/feed/presentation/pages}/feed_screen.dart (79%) create mode 100644 lib/features/feed/repositories/feed_repository.dart create mode 100644 lib/features/feed/services/feed_service.dart create mode 100644 lib/features/feed/services/feed_service.g.dart delete mode 100644 lib/presentation/feed/feed_screen/bloc/feed_bloc.dart delete mode 100644 lib/presentation/feed/feed_screen/bloc/feed_event.dart delete mode 100644 lib/presentation/feed/feed_screen/bloc/feed_state.dart diff --git a/android/eatvio_app_android.iml b/android/eatvio_app_android.iml index 18999696..3e44773e 100644 --- a/android/eatvio_app_android.iml +++ b/android/eatvio_app_android.iml @@ -26,4 +26,4 @@ - + \ No newline at end of file diff --git a/lib/app_router.dart b/lib/app_router.dart index f0aafe9f..c40516b9 100644 --- a/lib/app_router.dart +++ b/lib/app_router.dart @@ -8,7 +8,7 @@ import 'package:eatvio_app/presentation/diets/diet_select_screen/diet_select_scr import 'package:eatvio_app/presentation/feed/blog_post_create_screen/blog_post_create_screen.dart'; import 'package:eatvio_app/presentation/feed/blog_post_edit_screen/blog_post_edit_screen.dart'; import 'package:eatvio_app/presentation/feed/blog_post_screen/blog_post_screen.dart'; -import 'package:eatvio_app/presentation/feed/feed_screen/feed_screen.dart'; +import 'package:eatvio_app/features/feed/presentation/pages/feed_screen.dart'; import 'package:eatvio_app/presentation/glossary/glossary_screen/glossary_screen.dart'; import 'package:eatvio_app/presentation/plans/plan_select_screen/plan_select_screen.dart'; import 'package:eatvio_app/presentation/profile/my_profile_screen/my_profile_screen.dart'; diff --git a/lib/features/feed/models/feed_blog_post_model.dart b/lib/features/feed/models/feed_blog_post_model.dart new file mode 100644 index 00000000..b77fb3f0 --- /dev/null +++ b/lib/features/feed/models/feed_blog_post_model.dart @@ -0,0 +1,20 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'feed_blog_post_model.freezed.dart'; +part 'feed_blog_post_model.g.dart'; + +@freezed +class FeedBlogPostModel with _$FeedBlogPostModel { + const factory FeedBlogPostModel({ + required int id, + required String state, + required String image, + required String description, + @JsonKey(name: "youtube_url") required String youtubeUrl, + @JsonKey(name: "created_at") required DateTime createdAt, + @JsonKey(name: "updated_at") required DateTime updatedAt, + required String title, + }) = _FeedBlogPostModel; + + factory FeedBlogPostModel.fromJson(Map json) => _$FeedBlogPostModelFromJson(json); +} diff --git a/lib/features/feed/models/feed_blog_post_model.freezed.dart b/lib/features/feed/models/feed_blog_post_model.freezed.dart new file mode 100644 index 00000000..4d753a10 --- /dev/null +++ b/lib/features/feed/models/feed_blog_post_model.freezed.dart @@ -0,0 +1,310 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'feed_blog_post_model.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); + +FeedBlogPostModel _$FeedBlogPostModelFromJson(Map json) { + return _FeedBlogPostModel.fromJson(json); +} + +/// @nodoc +mixin _$FeedBlogPostModel { + int get id => throw _privateConstructorUsedError; + String get state => throw _privateConstructorUsedError; + String get image => throw _privateConstructorUsedError; + String get description => throw _privateConstructorUsedError; + @JsonKey(name: "youtube_url") + String get youtubeUrl => throw _privateConstructorUsedError; + @JsonKey(name: "created_at") + DateTime get createdAt => throw _privateConstructorUsedError; + @JsonKey(name: "updated_at") + DateTime get updatedAt => throw _privateConstructorUsedError; + String get title => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $FeedBlogPostModelCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $FeedBlogPostModelCopyWith<$Res> { + factory $FeedBlogPostModelCopyWith( + FeedBlogPostModel value, $Res Function(FeedBlogPostModel) then) = + _$FeedBlogPostModelCopyWithImpl<$Res, FeedBlogPostModel>; + @useResult + $Res call( + {int id, + String state, + String image, + String description, + @JsonKey(name: "youtube_url") String youtubeUrl, + @JsonKey(name: "created_at") DateTime createdAt, + @JsonKey(name: "updated_at") DateTime updatedAt, + String title}); +} + +/// @nodoc +class _$FeedBlogPostModelCopyWithImpl<$Res, $Val extends FeedBlogPostModel> + implements $FeedBlogPostModelCopyWith<$Res> { + _$FeedBlogPostModelCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? state = null, + Object? image = null, + Object? description = null, + Object? youtubeUrl = null, + Object? createdAt = null, + Object? updatedAt = null, + Object? title = null, + }) { + return _then(_value.copyWith( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as int, + state: null == state + ? _value.state + : state // ignore: cast_nullable_to_non_nullable + as String, + image: null == image + ? _value.image + : image // ignore: cast_nullable_to_non_nullable + as String, + description: null == description + ? _value.description + : description // ignore: cast_nullable_to_non_nullable + as String, + youtubeUrl: null == youtubeUrl + ? _value.youtubeUrl + : youtubeUrl // ignore: cast_nullable_to_non_nullable + as String, + createdAt: null == createdAt + ? _value.createdAt + : createdAt // ignore: cast_nullable_to_non_nullable + as DateTime, + updatedAt: null == updatedAt + ? _value.updatedAt + : updatedAt // ignore: cast_nullable_to_non_nullable + as DateTime, + title: null == title + ? _value.title + : title // ignore: cast_nullable_to_non_nullable + as String, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$FeedBlogPostModelImplCopyWith<$Res> + implements $FeedBlogPostModelCopyWith<$Res> { + factory _$$FeedBlogPostModelImplCopyWith(_$FeedBlogPostModelImpl value, + $Res Function(_$FeedBlogPostModelImpl) then) = + __$$FeedBlogPostModelImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {int id, + String state, + String image, + String description, + @JsonKey(name: "youtube_url") String youtubeUrl, + @JsonKey(name: "created_at") DateTime createdAt, + @JsonKey(name: "updated_at") DateTime updatedAt, + String title}); +} + +/// @nodoc +class __$$FeedBlogPostModelImplCopyWithImpl<$Res> + extends _$FeedBlogPostModelCopyWithImpl<$Res, _$FeedBlogPostModelImpl> + implements _$$FeedBlogPostModelImplCopyWith<$Res> { + __$$FeedBlogPostModelImplCopyWithImpl(_$FeedBlogPostModelImpl _value, + $Res Function(_$FeedBlogPostModelImpl) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? state = null, + Object? image = null, + Object? description = null, + Object? youtubeUrl = null, + Object? createdAt = null, + Object? updatedAt = null, + Object? title = null, + }) { + return _then(_$FeedBlogPostModelImpl( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as int, + state: null == state + ? _value.state + : state // ignore: cast_nullable_to_non_nullable + as String, + image: null == image + ? _value.image + : image // ignore: cast_nullable_to_non_nullable + as String, + description: null == description + ? _value.description + : description // ignore: cast_nullable_to_non_nullable + as String, + youtubeUrl: null == youtubeUrl + ? _value.youtubeUrl + : youtubeUrl // ignore: cast_nullable_to_non_nullable + as String, + createdAt: null == createdAt + ? _value.createdAt + : createdAt // ignore: cast_nullable_to_non_nullable + as DateTime, + updatedAt: null == updatedAt + ? _value.updatedAt + : updatedAt // ignore: cast_nullable_to_non_nullable + as DateTime, + title: null == title + ? _value.title + : title // ignore: cast_nullable_to_non_nullable + as String, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$FeedBlogPostModelImpl implements _FeedBlogPostModel { + const _$FeedBlogPostModelImpl( + {required this.id, + required this.state, + required this.image, + required this.description, + @JsonKey(name: "youtube_url") required this.youtubeUrl, + @JsonKey(name: "created_at") required this.createdAt, + @JsonKey(name: "updated_at") required this.updatedAt, + required this.title}); + + factory _$FeedBlogPostModelImpl.fromJson(Map json) => + _$$FeedBlogPostModelImplFromJson(json); + + @override + final int id; + @override + final String state; + @override + final String image; + @override + final String description; + @override + @JsonKey(name: "youtube_url") + final String youtubeUrl; + @override + @JsonKey(name: "created_at") + final DateTime createdAt; + @override + @JsonKey(name: "updated_at") + final DateTime updatedAt; + @override + final String title; + + @override + String toString() { + return 'FeedBlogPostModel(id: $id, state: $state, image: $image, description: $description, youtubeUrl: $youtubeUrl, createdAt: $createdAt, updatedAt: $updatedAt, title: $title)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$FeedBlogPostModelImpl && + (identical(other.id, id) || other.id == id) && + (identical(other.state, state) || other.state == state) && + (identical(other.image, image) || other.image == image) && + (identical(other.description, description) || + other.description == description) && + (identical(other.youtubeUrl, youtubeUrl) || + other.youtubeUrl == youtubeUrl) && + (identical(other.createdAt, createdAt) || + other.createdAt == createdAt) && + (identical(other.updatedAt, updatedAt) || + other.updatedAt == updatedAt) && + (identical(other.title, title) || other.title == title)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => Object.hash(runtimeType, id, state, image, description, + youtubeUrl, createdAt, updatedAt, title); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$FeedBlogPostModelImplCopyWith<_$FeedBlogPostModelImpl> get copyWith => + __$$FeedBlogPostModelImplCopyWithImpl<_$FeedBlogPostModelImpl>( + this, _$identity); + + @override + Map toJson() { + return _$$FeedBlogPostModelImplToJson( + this, + ); + } +} + +abstract class _FeedBlogPostModel implements FeedBlogPostModel { + const factory _FeedBlogPostModel( + {required final int id, + required final String state, + required final String image, + required final String description, + @JsonKey(name: "youtube_url") required final String youtubeUrl, + @JsonKey(name: "created_at") required final DateTime createdAt, + @JsonKey(name: "updated_at") required final DateTime updatedAt, + required final String title}) = _$FeedBlogPostModelImpl; + + factory _FeedBlogPostModel.fromJson(Map json) = + _$FeedBlogPostModelImpl.fromJson; + + @override + int get id; + @override + String get state; + @override + String get image; + @override + String get description; + @override + @JsonKey(name: "youtube_url") + String get youtubeUrl; + @override + @JsonKey(name: "created_at") + DateTime get createdAt; + @override + @JsonKey(name: "updated_at") + DateTime get updatedAt; + @override + String get title; + @override + @JsonKey(ignore: true) + _$$FeedBlogPostModelImplCopyWith<_$FeedBlogPostModelImpl> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/lib/features/feed/models/feed_blog_post_model.g.dart b/lib/features/feed/models/feed_blog_post_model.g.dart new file mode 100644 index 00000000..93cc70fc --- /dev/null +++ b/lib/features/feed/models/feed_blog_post_model.g.dart @@ -0,0 +1,33 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'feed_blog_post_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$FeedBlogPostModelImpl _$$FeedBlogPostModelImplFromJson( + Map json) => + _$FeedBlogPostModelImpl( + id: (json['id'] as num).toInt(), + state: json['state'] as String, + image: json['image'] as String, + description: json['description'] as String, + youtubeUrl: json['youtube_url'] as String, + createdAt: DateTime.parse(json['created_at'] as String), + updatedAt: DateTime.parse(json['updated_at'] as String), + title: json['title'] as String, + ); + +Map _$$FeedBlogPostModelImplToJson( + _$FeedBlogPostModelImpl instance) => + { + 'id': instance.id, + 'state': instance.state, + 'image': instance.image, + 'description': instance.description, + 'youtube_url': instance.youtubeUrl, + 'created_at': instance.createdAt.toIso8601String(), + 'updated_at': instance.updatedAt.toIso8601String(), + 'title': instance.title, + }; diff --git a/lib/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart b/lib/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart new file mode 100644 index 00000000..6a522235 --- /dev/null +++ b/lib/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart @@ -0,0 +1,19 @@ +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_state.dart'; +import 'package:eatvio_app/features/feed/repositories/feed_repository.dart'; + +class FeedCubit extends Cubit { + final FeedRepository feedRepository; + + FeedCubit({required this.feedRepository}) : super(const FeedState.loading()); + + loadFeedBlogPostList() async { + emit(const FeedStateLoading()); + try { + final feedBlogPostList = await feedRepository.getFeedBlogPostList(); + emit(FeedState.loaded(feedBlogPostList: feedBlogPostList)); + } catch (e) { + emit(FeedState.error(errorMessage: e.toString())); + } + } +} diff --git a/lib/features/feed/presentation/bloc/feed_cubit/feed_state.dart b/lib/features/feed/presentation/bloc/feed_cubit/feed_state.dart new file mode 100644 index 00000000..70e8c3b7 --- /dev/null +++ b/lib/features/feed/presentation/bloc/feed_cubit/feed_state.dart @@ -0,0 +1,19 @@ +import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'feed_state.freezed.dart'; + +@freezed +abstract class FeedState with _$FeedState { + const factory FeedState() = _FeedState; + + const factory FeedState.loading() = FeedStateLoading; + + const factory FeedState.loaded({ + required List feedBlogPostList, + }) = FeedStateLoaded; + + const factory FeedState.error({ + required String errorMessage, + }) = FeedStateError; +} diff --git a/lib/features/feed/presentation/bloc/feed_cubit/feed_state.freezed.dart b/lib/features/feed/presentation/bloc/feed_cubit/feed_state.freezed.dart new file mode 100644 index 00000000..ab3385f3 --- /dev/null +++ b/lib/features/feed/presentation/bloc/feed_cubit/feed_state.freezed.dart @@ -0,0 +1,620 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'feed_state.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); + +/// @nodoc +mixin _$FeedState { + @optionalTypeArgs + TResult when( + TResult Function() $default, { + required TResult Function() loading, + required TResult Function(List feedBlogPostList) loaded, + required TResult Function(String errorMessage) error, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function()? $default, { + TResult? Function()? loading, + TResult? Function(List feedBlogPostList)? loaded, + TResult? Function(String errorMessage)? error, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeWhen( + TResult Function()? $default, { + TResult Function()? loading, + TResult Function(List feedBlogPostList)? loaded, + TResult Function(String errorMessage)? error, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult map( + TResult Function(_FeedState value) $default, { + required TResult Function(FeedStateLoading value) loading, + required TResult Function(FeedStateLoaded value) loaded, + required TResult Function(FeedStateError value) error, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_FeedState value)? $default, { + TResult? Function(FeedStateLoading value)? loading, + TResult? Function(FeedStateLoaded value)? loaded, + TResult? Function(FeedStateError value)? error, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeMap( + TResult Function(_FeedState value)? $default, { + TResult Function(FeedStateLoading value)? loading, + TResult Function(FeedStateLoaded value)? loaded, + TResult Function(FeedStateError value)? error, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $FeedStateCopyWith<$Res> { + factory $FeedStateCopyWith(FeedState value, $Res Function(FeedState) then) = + _$FeedStateCopyWithImpl<$Res, FeedState>; +} + +/// @nodoc +class _$FeedStateCopyWithImpl<$Res, $Val extends FeedState> + implements $FeedStateCopyWith<$Res> { + _$FeedStateCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; +} + +/// @nodoc +abstract class _$$FeedStateImplCopyWith<$Res> { + factory _$$FeedStateImplCopyWith( + _$FeedStateImpl value, $Res Function(_$FeedStateImpl) then) = + __$$FeedStateImplCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$FeedStateImplCopyWithImpl<$Res> + extends _$FeedStateCopyWithImpl<$Res, _$FeedStateImpl> + implements _$$FeedStateImplCopyWith<$Res> { + __$$FeedStateImplCopyWithImpl( + _$FeedStateImpl _value, $Res Function(_$FeedStateImpl) _then) + : super(_value, _then); +} + +/// @nodoc + +class _$FeedStateImpl implements _FeedState { + const _$FeedStateImpl(); + + @override + String toString() { + return 'FeedState()'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$FeedStateImpl); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when( + TResult Function() $default, { + required TResult Function() loading, + required TResult Function(List feedBlogPostList) loaded, + required TResult Function(String errorMessage) error, + }) { + return $default(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function()? $default, { + TResult? Function()? loading, + TResult? Function(List feedBlogPostList)? loaded, + TResult? Function(String errorMessage)? error, + }) { + return $default?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function()? $default, { + TResult Function()? loading, + TResult Function(List feedBlogPostList)? loaded, + TResult Function(String errorMessage)? error, + required TResult orElse(), + }) { + if ($default != null) { + return $default(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_FeedState value) $default, { + required TResult Function(FeedStateLoading value) loading, + required TResult Function(FeedStateLoaded value) loaded, + required TResult Function(FeedStateError value) error, + }) { + return $default(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_FeedState value)? $default, { + TResult? Function(FeedStateLoading value)? loading, + TResult? Function(FeedStateLoaded value)? loaded, + TResult? Function(FeedStateError value)? error, + }) { + return $default?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_FeedState value)? $default, { + TResult Function(FeedStateLoading value)? loading, + TResult Function(FeedStateLoaded value)? loaded, + TResult Function(FeedStateError value)? error, + required TResult orElse(), + }) { + if ($default != null) { + return $default(this); + } + return orElse(); + } +} + +abstract class _FeedState implements FeedState { + const factory _FeedState() = _$FeedStateImpl; +} + +/// @nodoc +abstract class _$$FeedStateLoadingImplCopyWith<$Res> { + factory _$$FeedStateLoadingImplCopyWith(_$FeedStateLoadingImpl value, + $Res Function(_$FeedStateLoadingImpl) then) = + __$$FeedStateLoadingImplCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$FeedStateLoadingImplCopyWithImpl<$Res> + extends _$FeedStateCopyWithImpl<$Res, _$FeedStateLoadingImpl> + implements _$$FeedStateLoadingImplCopyWith<$Res> { + __$$FeedStateLoadingImplCopyWithImpl(_$FeedStateLoadingImpl _value, + $Res Function(_$FeedStateLoadingImpl) _then) + : super(_value, _then); +} + +/// @nodoc + +class _$FeedStateLoadingImpl implements FeedStateLoading { + const _$FeedStateLoadingImpl(); + + @override + String toString() { + return 'FeedState.loading()'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$FeedStateLoadingImpl); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when( + TResult Function() $default, { + required TResult Function() loading, + required TResult Function(List feedBlogPostList) loaded, + required TResult Function(String errorMessage) error, + }) { + return loading(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function()? $default, { + TResult? Function()? loading, + TResult? Function(List feedBlogPostList)? loaded, + TResult? Function(String errorMessage)? error, + }) { + return loading?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function()? $default, { + TResult Function()? loading, + TResult Function(List feedBlogPostList)? loaded, + TResult Function(String errorMessage)? error, + required TResult orElse(), + }) { + if (loading != null) { + return loading(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_FeedState value) $default, { + required TResult Function(FeedStateLoading value) loading, + required TResult Function(FeedStateLoaded value) loaded, + required TResult Function(FeedStateError value) error, + }) { + return loading(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_FeedState value)? $default, { + TResult? Function(FeedStateLoading value)? loading, + TResult? Function(FeedStateLoaded value)? loaded, + TResult? Function(FeedStateError value)? error, + }) { + return loading?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_FeedState value)? $default, { + TResult Function(FeedStateLoading value)? loading, + TResult Function(FeedStateLoaded value)? loaded, + TResult Function(FeedStateError value)? error, + required TResult orElse(), + }) { + if (loading != null) { + return loading(this); + } + return orElse(); + } +} + +abstract class FeedStateLoading implements FeedState { + const factory FeedStateLoading() = _$FeedStateLoadingImpl; +} + +/// @nodoc +abstract class _$$FeedStateLoadedImplCopyWith<$Res> { + factory _$$FeedStateLoadedImplCopyWith(_$FeedStateLoadedImpl value, + $Res Function(_$FeedStateLoadedImpl) then) = + __$$FeedStateLoadedImplCopyWithImpl<$Res>; + @useResult + $Res call({List feedBlogPostList}); +} + +/// @nodoc +class __$$FeedStateLoadedImplCopyWithImpl<$Res> + extends _$FeedStateCopyWithImpl<$Res, _$FeedStateLoadedImpl> + implements _$$FeedStateLoadedImplCopyWith<$Res> { + __$$FeedStateLoadedImplCopyWithImpl( + _$FeedStateLoadedImpl _value, $Res Function(_$FeedStateLoadedImpl) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? feedBlogPostList = null, + }) { + return _then(_$FeedStateLoadedImpl( + feedBlogPostList: null == feedBlogPostList + ? _value._feedBlogPostList + : feedBlogPostList // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc + +class _$FeedStateLoadedImpl implements FeedStateLoaded { + const _$FeedStateLoadedImpl( + {required final List feedBlogPostList}) + : _feedBlogPostList = feedBlogPostList; + + final List _feedBlogPostList; + @override + List get feedBlogPostList { + if (_feedBlogPostList is EqualUnmodifiableListView) + return _feedBlogPostList; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_feedBlogPostList); + } + + @override + String toString() { + return 'FeedState.loaded(feedBlogPostList: $feedBlogPostList)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$FeedStateLoadedImpl && + const DeepCollectionEquality() + .equals(other._feedBlogPostList, _feedBlogPostList)); + } + + @override + int get hashCode => Object.hash( + runtimeType, const DeepCollectionEquality().hash(_feedBlogPostList)); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$FeedStateLoadedImplCopyWith<_$FeedStateLoadedImpl> get copyWith => + __$$FeedStateLoadedImplCopyWithImpl<_$FeedStateLoadedImpl>( + this, _$identity); + + @override + @optionalTypeArgs + TResult when( + TResult Function() $default, { + required TResult Function() loading, + required TResult Function(List feedBlogPostList) loaded, + required TResult Function(String errorMessage) error, + }) { + return loaded(feedBlogPostList); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function()? $default, { + TResult? Function()? loading, + TResult? Function(List feedBlogPostList)? loaded, + TResult? Function(String errorMessage)? error, + }) { + return loaded?.call(feedBlogPostList); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function()? $default, { + TResult Function()? loading, + TResult Function(List feedBlogPostList)? loaded, + TResult Function(String errorMessage)? error, + required TResult orElse(), + }) { + if (loaded != null) { + return loaded(feedBlogPostList); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_FeedState value) $default, { + required TResult Function(FeedStateLoading value) loading, + required TResult Function(FeedStateLoaded value) loaded, + required TResult Function(FeedStateError value) error, + }) { + return loaded(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_FeedState value)? $default, { + TResult? Function(FeedStateLoading value)? loading, + TResult? Function(FeedStateLoaded value)? loaded, + TResult? Function(FeedStateError value)? error, + }) { + return loaded?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_FeedState value)? $default, { + TResult Function(FeedStateLoading value)? loading, + TResult Function(FeedStateLoaded value)? loaded, + TResult Function(FeedStateError value)? error, + required TResult orElse(), + }) { + if (loaded != null) { + return loaded(this); + } + return orElse(); + } +} + +abstract class FeedStateLoaded implements FeedState { + const factory FeedStateLoaded( + {required final List feedBlogPostList}) = + _$FeedStateLoadedImpl; + + List get feedBlogPostList; + @JsonKey(ignore: true) + _$$FeedStateLoadedImplCopyWith<_$FeedStateLoadedImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$$FeedStateErrorImplCopyWith<$Res> { + factory _$$FeedStateErrorImplCopyWith(_$FeedStateErrorImpl value, + $Res Function(_$FeedStateErrorImpl) then) = + __$$FeedStateErrorImplCopyWithImpl<$Res>; + @useResult + $Res call({String errorMessage}); +} + +/// @nodoc +class __$$FeedStateErrorImplCopyWithImpl<$Res> + extends _$FeedStateCopyWithImpl<$Res, _$FeedStateErrorImpl> + implements _$$FeedStateErrorImplCopyWith<$Res> { + __$$FeedStateErrorImplCopyWithImpl( + _$FeedStateErrorImpl _value, $Res Function(_$FeedStateErrorImpl) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? errorMessage = null, + }) { + return _then(_$FeedStateErrorImpl( + errorMessage: null == errorMessage + ? _value.errorMessage + : errorMessage // ignore: cast_nullable_to_non_nullable + as String, + )); + } +} + +/// @nodoc + +class _$FeedStateErrorImpl implements FeedStateError { + const _$FeedStateErrorImpl({required this.errorMessage}); + + @override + final String errorMessage; + + @override + String toString() { + return 'FeedState.error(errorMessage: $errorMessage)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$FeedStateErrorImpl && + (identical(other.errorMessage, errorMessage) || + other.errorMessage == errorMessage)); + } + + @override + int get hashCode => Object.hash(runtimeType, errorMessage); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$FeedStateErrorImplCopyWith<_$FeedStateErrorImpl> get copyWith => + __$$FeedStateErrorImplCopyWithImpl<_$FeedStateErrorImpl>( + this, _$identity); + + @override + @optionalTypeArgs + TResult when( + TResult Function() $default, { + required TResult Function() loading, + required TResult Function(List feedBlogPostList) loaded, + required TResult Function(String errorMessage) error, + }) { + return error(errorMessage); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function()? $default, { + TResult? Function()? loading, + TResult? Function(List feedBlogPostList)? loaded, + TResult? Function(String errorMessage)? error, + }) { + return error?.call(errorMessage); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function()? $default, { + TResult Function()? loading, + TResult Function(List feedBlogPostList)? loaded, + TResult Function(String errorMessage)? error, + required TResult orElse(), + }) { + if (error != null) { + return error(errorMessage); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_FeedState value) $default, { + required TResult Function(FeedStateLoading value) loading, + required TResult Function(FeedStateLoaded value) loaded, + required TResult Function(FeedStateError value) error, + }) { + return error(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_FeedState value)? $default, { + TResult? Function(FeedStateLoading value)? loading, + TResult? Function(FeedStateLoaded value)? loaded, + TResult? Function(FeedStateError value)? error, + }) { + return error?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_FeedState value)? $default, { + TResult Function(FeedStateLoading value)? loading, + TResult Function(FeedStateLoaded value)? loaded, + TResult Function(FeedStateError value)? error, + required TResult orElse(), + }) { + if (error != null) { + return error(this); + } + return orElse(); + } +} + +abstract class FeedStateError implements FeedState { + const factory FeedStateError({required final String errorMessage}) = + _$FeedStateErrorImpl; + + String get errorMessage; + @JsonKey(ignore: true) + _$$FeedStateErrorImplCopyWith<_$FeedStateErrorImpl> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/lib/presentation/feed/feed_screen/feed_screen.dart b/lib/features/feed/presentation/pages/feed_screen.dart similarity index 79% rename from lib/presentation/feed/feed_screen/feed_screen.dart rename to lib/features/feed/presentation/pages/feed_screen.dart index f6cf07a8..dca0eef8 100644 --- a/lib/presentation/feed/feed_screen/feed_screen.dart +++ b/lib/features/feed/presentation/pages/feed_screen.dart @@ -1,7 +1,8 @@ +import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart'; +import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart'; +import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_state.dart'; +import 'package:flutter/cupertino.dart'; import 'package:go_router/go_router.dart'; - -import 'bloc/feed_bloc.dart'; -import 'models/feed_model.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:eatvio_app/presentation/feed/feed_screen/widgets/feed_search_view.dart'; import 'package:eatvio_app/presentation/feed/feed_screen/widgets/feed_scroll_item.dart'; @@ -12,37 +13,30 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; class FeedScreen extends StatelessWidget { - static Widget builder(BuildContext context) { - return BlocProvider( - create: (context) => FeedBloc(FeedState(myProfileModelObj: FeedModel())) - ..add(FeedInitialEvent()), - child: FeedScreen()); - } - Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - if (state is FeedInitialState) { - // Это начальное состояние, данные ещё не загружены. - return CircularProgressIndicator( - color: Colors.white, - backgroundColor: Colors.white, - ); - } else if (state is FeedLoadedState) { - // Данные загружены, можно строить экран. + return BlocBuilder( + builder: (BuildContext context, FeedState state) { + if (state is FeedStateLoaded) { return _buildFeedScreen(context, state); } else { - // Другие состояния, если они есть. - return Container(); // Пустой контейнер для необработанных состояний. + return Scaffold( + body: Center( + child: CupertinoActivityIndicator(), + ), + ); } }, ); } - _buildFeedScreen(BuildContext context, FeedLoadedState state) { + _buildFeedScreen(BuildContext context, FeedStateLoaded state) { mediaQueryData = MediaQuery.of(context); - return SafeArea( + return RefreshIndicator( + onRefresh: () => context.read().loadFeedBlogPostList(), child: Scaffold( + appBar: AppBar( + toolbarHeight: 0, + ), backgroundColor: Colors.grey[200], resizeToAvoidBottomInset: true, body: SingleChildScrollView( @@ -106,8 +100,7 @@ class FeedScreen extends StatelessWidget { flex: 1, child: CustomOutlinedButton( text: "+", - onPressed: () => - GoRouter.of(context).goNamed('blogPostCreateScreen'), + onPressed: () => GoRouter.of(context).goNamed('blogPostCreateScreen'), buttonStyle: CustomButtonStyles.outlinePrimaryTL15, ), ), @@ -119,13 +112,11 @@ class FeedScreen extends StatelessWidget { ); } - _buildBlogPostList(BuildContext context, FeedLoadedState state) { + _buildBlogPostList(BuildContext context, FeedStateLoaded state) { List postWidgets = []; - if (state.posts != null) { - for (var post in state.posts!) { - postWidgets.add(_buildFeedEntry(post, context)); - } + for (var post in state.feedBlogPostList) { + postWidgets.add(_buildFeedEntry(post, context)); } return Column( @@ -134,7 +125,7 @@ class FeedScreen extends StatelessWidget { ); } - _buildFeedEntry(post, BuildContext context) { + _buildFeedEntry(FeedBlogPostModel post, BuildContext context) { return Container( margin: EdgeInsets.only(bottom: 10), decoration: BoxDecoration( @@ -153,31 +144,37 @@ class FeedScreen extends StatelessWidget { children: [ ListTile( leading: CachedNetworkImage( - imageUrl: dotenv.env['STORAGE_URL']! + - (post['profile_photo_path'] ?? ''), + imageUrl: dotenv.env['STORAGE_URL']! + ('' ?? ''), + + /// todo profile photo path imageBuilder: (context, imageProvider) => CircleAvatar( backgroundImage: imageProvider, - radius: 25, + radius: 24, + ), + placeholder: (context, url) => CircleAvatar( + child: Icon(Icons.person), + backgroundColor: Colors.white, + radius: 24, ), - placeholder: (context, url) => CircularProgressIndicator(), errorWidget: (context, url, error) => CircleAvatar( child: Icon(Icons.person), backgroundColor: Colors.white, - radius: 25, + radius: 24, ), ), title: Text( - post?['author_name'] ?? 'Authorae', + 'Authorae', + + /// todo author name style: CustomTextStyles.titleMediumSemiBold, ), subtitle: Text( - DateFormat('dd.MM.yyyy') - .format(DateTime.parse(post?['updated_at'])), + DateFormat('dd.MM.yyyy').format(post.updatedAt), style: theme.textTheme.bodyMedium, ), onTap: () => GoRouter.of(context).goNamed( 'blogPostScreen', - extra: post?['id'].toString(), + extra: post.id.toString(), ), trailing: PopupMenuButton( onSelected: (value) => print("tap"), @@ -204,7 +201,7 @@ class FeedScreen extends StatelessWidget { Align( alignment: Alignment.center, child: Text( - post?['title'], + post.title, style: CustomTextStyles.titleMediumBlack, ), ), @@ -213,17 +210,16 @@ class FeedScreen extends StatelessWidget { ), SizedBox(height: 8.0), Text( - post?['description'], + post.description, style: CustomTextStyles.bodyMediumBluegray800, ), SizedBox(height: 16.0), CachedNetworkImage( - imageUrl: dotenv.env['STORAGE_URL']! + (post?['image'] ?? ''), + imageUrl: dotenv.env['STORAGE_URL']! + (post.image ?? ''), imageBuilder: (context, imageProvider) => Stack( children: [ ClipRRect( - borderRadius: - const BorderRadius.all(Radius.circular(8.0)), + borderRadius: const BorderRadius.all(Radius.circular(8.0)), child: Image( image: imageProvider, ), @@ -286,7 +282,7 @@ class FeedScreen extends StatelessWidget { GoRouter.of(context).pop(); } - _buildMenu(BuildContext context, FeedLoadedState state) { + _buildMenu(BuildContext context, FeedStateLoaded state) { return Container( padding: EdgeInsets.all(12), margin: EdgeInsets.only(bottom: 10), diff --git a/lib/features/feed/repositories/feed_repository.dart b/lib/features/feed/repositories/feed_repository.dart new file mode 100644 index 00000000..fb871041 --- /dev/null +++ b/lib/features/feed/repositories/feed_repository.dart @@ -0,0 +1,16 @@ +import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart'; +import 'package:eatvio_app/features/feed/services/feed_service.dart'; + +class FeedRepository { + final FeedService feedService; + + FeedRepository({required this.feedService}); + + Future> getFeedBlogPostList() async { + try { + return await feedService.getBlocPostList(); + } catch (e) { + rethrow; + } + } +} diff --git a/lib/features/feed/services/feed_service.dart b/lib/features/feed/services/feed_service.dart new file mode 100644 index 00000000..80deb91e --- /dev/null +++ b/lib/features/feed/services/feed_service.dart @@ -0,0 +1,13 @@ +import 'package:dio/dio.dart'; +import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart'; +import 'package:retrofit/retrofit.dart'; + +part 'feed_service.g.dart'; + +@RestApi() +abstract class FeedService { + factory FeedService(Dio dio, {String baseUrl}) = _FeedService; + + @GET('/feed/index') + Future> getBlocPostList(); +} diff --git a/lib/features/feed/services/feed_service.g.dart b/lib/features/feed/services/feed_service.g.dart new file mode 100644 index 00000000..6184cfbf --- /dev/null +++ b/lib/features/feed/services/feed_service.g.dart @@ -0,0 +1,80 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'feed_service.dart'; + +// ************************************************************************** +// RetrofitGenerator +// ************************************************************************** + +// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers + +class _FeedService implements FeedService { + _FeedService( + this._dio, { + this.baseUrl, + }); + + final Dio _dio; + + String? baseUrl; + + @override + Future> getBlocPostList() async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _result = await _dio + .fetch>(_setStreamType>(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/feed/index', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + )))); + var value = _result.data! + .map((dynamic i) => + FeedBlogPostModel.fromJson(i as Map)) + .toList(); + return value; + } + + RequestOptions _setStreamType(RequestOptions requestOptions) { + if (T != dynamic && + !(requestOptions.responseType == ResponseType.bytes || + requestOptions.responseType == ResponseType.stream)) { + if (T == String) { + requestOptions.responseType = ResponseType.plain; + } else { + requestOptions.responseType = ResponseType.json; + } + } + return requestOptions; + } + + String _combineBaseUrls( + String dioBaseUrl, + String? baseUrl, + ) { + if (baseUrl == null || baseUrl.trim().isEmpty) { + return dioBaseUrl; + } + + final url = Uri.parse(baseUrl); + + if (url.isAbsolute) { + return url.toString(); + } + + return Uri.parse(dioBaseUrl).resolveUri(url).toString(); + } +} diff --git a/lib/locator_service.dart b/lib/locator_service.dart index 8759775c..9780f414 100644 --- a/lib/locator_service.dart +++ b/lib/locator_service.dart @@ -3,6 +3,9 @@ import 'package:eatvio_app/core/initialization_cubit/initialization_cubit.dart'; import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart'; import 'package:eatvio_app/features/chat/repositories/chat_repository.dart'; import 'package:eatvio_app/features/chat/services/chat_service.dart'; +import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart'; +import 'package:eatvio_app/features/feed/repositories/feed_repository.dart'; +import 'package:eatvio_app/features/feed/services/feed_service.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:get_it/get_it.dart'; @@ -12,12 +15,15 @@ Future init() async { // BLoC sl.registerFactory(() => ChatRoomCubit(chatRepository: sl())); sl.registerFactory(() => InitializationCubit(chatRepository: sl())); + sl.registerFactory(() => FeedCubit(feedRepository: sl())); // Repository sl.registerLazySingleton(() => ChatRepository(chatService: sl())); + sl.registerLazySingleton(() => FeedRepository(feedService: sl())); // Services sl.registerLazySingleton(() => ChatService(sl())); + sl.registerLazySingleton(() => FeedService(sl())); // External sl.registerLazySingleton( diff --git a/lib/main.dart b/lib/main.dart index 29191300..2f81b9fe 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,11 +3,10 @@ import 'package:eatvio_app/core/initialization_cubit/initialization_cubit.dart'; import 'package:eatvio_app/core/initialization_cubit/initialization_state.dart'; import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/bloc/chat_select_bloc.dart'; import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/models/chat_select_model.dart'; +import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart'; import 'package:eatvio_app/locator_service.dart'; import 'package:eatvio_app/presentation/diary/diary_edit_screen/bloc/diary_edit_bloc.dart'; import 'package:eatvio_app/presentation/diary/diary_edit_screen/models/diary_edit_model.dart'; -import 'package:eatvio_app/presentation/feed/feed_screen/bloc/feed_bloc.dart'; -import 'package:eatvio_app/presentation/feed/feed_screen/models/feed_model.dart'; import 'package:eatvio_app/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart'; import 'package:eatvio_app/presentation/profile/my_profile_screen/models/my_profile_model.dart'; import 'package:flutter/material.dart'; @@ -45,8 +44,8 @@ class MyApp extends StatelessWidget { providers: [ BlocProvider(create: (context) => InitializationCubit(chatRepository: sl())..runInitialization()), BlocProvider(create: (context) => ThemeBloc(ThemeState(themeType: PrefUtils().getThemeData()))), + BlocProvider(create: (context) => sl()..loadFeedBlogPostList()), BlocProvider(create: (context) => MyProfileBloc(MyProfileState(myProfileModelObj: MyProfileModel()))..add(MyProfileInitialEvent())), - BlocProvider(create: (context) => FeedBloc(FeedState(myProfileModelObj: FeedModel()))..add(FeedInitialEvent())), BlocProvider(create: (context) => DiaryEditBloc(DiaryEditState(diaryEditModelObj: DiaryEditModel()))..add(DiaryEditInitialEvent())), BlocProvider( create: (context) => ChatSelectBloc(ChatSelectState(chatSelectModelObj: ChatSelectModel()))..add(ChatSelectInitialEvent()), diff --git a/lib/presentation/feed/feed_screen/bloc/feed_bloc.dart b/lib/presentation/feed/feed_screen/bloc/feed_bloc.dart deleted file mode 100644 index 1eda1feb..00000000 --- a/lib/presentation/feed/feed_screen/bloc/feed_bloc.dart +++ /dev/null @@ -1,73 +0,0 @@ -//import 'package:eatvio_app/presentation/auth/auth_screen/auth_screen.dart'; -import 'dart:async'; - -import 'package:eatvio_app/app_router.dart'; -import 'package:equatable/equatable.dart'; -import 'package:flutter/material.dart'; -import '/core/app_export.dart'; -import 'package:eatvio_app/presentation/feed/feed_screen/models/feed_model.dart'; -import 'package:http/http.dart' as http; -import 'dart:convert'; -import 'package:hive/hive.dart'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; -import 'package:image_picker/image_picker.dart'; -import 'package:go_router/go_router.dart'; - -part 'feed_event.dart'; -part 'feed_state.dart'; - -/// A bloc that manages the state of a Feed according to the event that is dispatched to it. -class FeedBloc extends Bloc { - FeedBloc(FeedState initialState) : super(initialState) { - on(_onInitialize); - } - - Future _onInitialize( - FeedInitialEvent event, - Emitter emit, - ) async { - try { - final box = await Hive.openBox('token'); - final token = box.get('token'); - if (token == null) { - AppRouter.navigatorKey.currentContext?.goNamed('authScreen'); - } - final response = await http.get( - Uri.parse(dotenv.env['SERVER_ROOT']! + '/feed/index'), - headers: { - 'Authorization': 'Bearer $token', - }, - ); - print('Got response'); - if (response.statusCode == 200) { - print('Got 200'); - final data = jsonDecode(response.body); - if (data is List) { - print('Got List'); - if (state is FeedLoadedState) { - print('Got loaded'); - var currentState = state as FeedLoadedState; - emit((currentState).copyWith( - posts: data, - myProfileModelObj: currentState.myProfileModelObj, - )); - } else { - print('Got unloaded'); - emit(FeedLoadedState( - posts: data, - )); - } - } else { - // Один или несколько ключевых полей отсутствуют, обрабатываем ошибку - emit(FeedErrorState('Неверный формат ответа API.')); - } - } else { - // Статус ответа не равен 200, обрабатываем ошибку - emit(FeedErrorState('Ошибка сервера: ${response.statusCode}')); - } - } catch (e) { - // Ошибка при декодировании JSON или другая ошибка выполнения - emit(FeedErrorState('Ошибка при получении данных ленты: $e')); - } - } -} diff --git a/lib/presentation/feed/feed_screen/bloc/feed_event.dart b/lib/presentation/feed/feed_screen/bloc/feed_event.dart deleted file mode 100644 index cbb510f5..00000000 --- a/lib/presentation/feed/feed_screen/bloc/feed_event.dart +++ /dev/null @@ -1,23 +0,0 @@ -// ignore_for_file: must_be_immutable - -part of 'feed_bloc.dart'; - -/// Abstract class for all events that can be dispatched from the -///Feed widget. -/// -/// Events must be immutable and implement the [Equatable] interface. -@immutable -abstract class FeedEvent extends Equatable {} - -/// Event that is dispatched when the Feed widget is first created. -class FeedInitialEvent extends FeedEvent { - @override - List get props => []; -} - -class UploadAvatar extends FeedEvent { - UploadAvatar(this.image); - final XFile image; - @override - List get props => [image]; -} diff --git a/lib/presentation/feed/feed_screen/bloc/feed_state.dart b/lib/presentation/feed/feed_screen/bloc/feed_state.dart deleted file mode 100644 index dbc57ac5..00000000 --- a/lib/presentation/feed/feed_screen/bloc/feed_state.dart +++ /dev/null @@ -1,49 +0,0 @@ -// ignore_for_file: must_be_immutable - -part of 'feed_bloc.dart'; - -class FeedState extends Equatable { - const FeedState({this.myProfileModelObj}); - - final FeedModel? myProfileModelObj; - - @override - List get props => [myProfileModelObj]; -} - -class FeedInitialState extends FeedState { - FeedInitialState({required FeedModel myProfileModelObj}) - : super(myProfileModelObj: myProfileModelObj); -} - -/// Represents the state of Feed in the application. -class FeedLoadedState extends FeedState { - FeedLoadedState({this.myProfileModelObj, this.posts}) - : super(myProfileModelObj: null); - - FeedModel? myProfileModelObj; - List? posts; - @override - List get props => [ - myProfileModelObj, - posts, - ]; - FeedLoadedState copyWith({ - FeedModel? myProfileModelObj, - List? posts, - }) { - return FeedLoadedState( - myProfileModelObj: myProfileModelObj ?? this.myProfileModelObj, - posts: posts ?? this.posts, - ); - } -} - -class FeedErrorState extends FeedState { - final String errorMessage; - - const FeedErrorState(this.errorMessage); - - @override - List get props => [errorMessage]; -}