diff --git a/android/eatvio_app_android.iml b/android/eatvio_app_android.iml
index 1899969..3e44773 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 f0aafe9..c40516b 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 0000000..b77fb3f
--- /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 0000000..4d753a1
--- /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 0000000..93cc70f
--- /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 0000000..6a52223
--- /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 0000000..70e8c3b
--- /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 0000000..ab3385f
--- /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 f6cf07a..dca0eef 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 0000000..fb87104
--- /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 0000000..80deb91
--- /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 0000000..6184cfb
--- /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 8759775..9780f41 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 2919130..2f81b9f 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 1eda1fe..0000000
--- 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 cbb510f..0000000
--- 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