refactor(blog_post): Dio, retrfit and freezed implemented for blog post show screen
This commit is contained in:
@@ -7,7 +7,7 @@ import 'package:eatvio_app/presentation/diets/diet_create_screen/diet_create_scr
|
||||
import 'package:eatvio_app/presentation/diets/diet_select_screen/diet_select_screen.dart';
|
||||
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/features/blog_post/presentation/pages/blog_post_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';
|
||||
@@ -45,7 +45,8 @@ class AppRouter {
|
||||
path: '/auth-screen',
|
||||
name: 'authScreen',
|
||||
redirect: (context, state) async {
|
||||
if (await TokenStorage.haveTokenInStorage()) return '/my-profile-screen';
|
||||
if (await TokenStorage.haveTokenInStorage())
|
||||
return '/my-profile-screen';
|
||||
return null;
|
||||
},
|
||||
builder: (context, state) => AuthScreen.builder(context),
|
||||
@@ -58,72 +59,120 @@ class AppRouter {
|
||||
GoRoute(
|
||||
path: 'credentials-screen',
|
||||
name: 'credentialsScreen',
|
||||
builder: (context, state) => CredentialsScreen.builder(context, state.extra),
|
||||
builder: (context, state) =>
|
||||
CredentialsScreen.builder(context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'name-screen',
|
||||
name: 'nameScreen',
|
||||
builder: (context, state) => NameScreen.builder(context, state.extra),
|
||||
builder: (context, state) =>
|
||||
NameScreen.builder(context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'gender-screen',
|
||||
name: 'genderScreen',
|
||||
builder: (context, state) => GenderScreen.builder(context, state.extra),
|
||||
builder: (context, state) =>
|
||||
GenderScreen.builder(context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'date-of-birth-screen',
|
||||
name: 'dateOfBirthScreen',
|
||||
builder: (context, state) => DateOfBirthScreen.builder(context, state.extra),
|
||||
builder: (context, state) =>
|
||||
DateOfBirthScreen.builder(context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'city-of-living-screen',
|
||||
name: 'cityOfLivingScreen',
|
||||
builder: (context, state) => CityOfLivingScreen.builder(context, state.extra),
|
||||
builder: (context, state) =>
|
||||
CityOfLivingScreen.builder(
|
||||
context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'body-circumferences-screen',
|
||||
name: 'bodyCircumferencesScreen',
|
||||
builder: (context, state) => BodyCircumferencesScreen.builder(context, state.extra),
|
||||
builder: (context, state) =>
|
||||
BodyCircumferencesScreen.builder(
|
||||
context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'weight-screen',
|
||||
name: 'weightScreen',
|
||||
builder: (context, state) => WeightScreen.builder(context, state.extra),
|
||||
builder: (context, state) =>
|
||||
WeightScreen.builder(
|
||||
context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'height-screen',
|
||||
name: 'heightScreen',
|
||||
builder: (context, state) => HeightScreen.builder(context, state.extra),
|
||||
builder: (context, state) =>
|
||||
HeightScreen.builder(
|
||||
context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'blood-pressure-screen',
|
||||
name: 'bloodPressureScreen',
|
||||
builder: (context, state) => BloodPressureScreen.builder(context, state.extra),
|
||||
builder: (context, state) =>
|
||||
BloodPressureScreen.builder(
|
||||
context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'favorite-sports-screen',
|
||||
name: 'favoriteSportsScreen',
|
||||
builder: (context, state) => FavoriteSportsScreen.builder(context, state.extra),
|
||||
path:
|
||||
'favorite-sports-screen',
|
||||
name:
|
||||
'favoriteSportsScreen',
|
||||
builder: (context, state) =>
|
||||
FavoriteSportsScreen
|
||||
.builder(context,
|
||||
state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
name: 'allergiesScreen',
|
||||
path: 'allergiesScreen',
|
||||
builder: (context, state) => AllergiesScreen.builder(context, state.extra),
|
||||
builder: (context,
|
||||
state) =>
|
||||
AllergiesScreen
|
||||
.builder(
|
||||
context,
|
||||
state
|
||||
.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
name: 'medicineIntakeScreen',
|
||||
path: 'medicine-intake-screen',
|
||||
builder: (context, state) => MedicineIntakeScreen.builder(context, state.extra),
|
||||
name:
|
||||
'medicineIntakeScreen',
|
||||
path:
|
||||
'medicine-intake-screen',
|
||||
builder: (context,
|
||||
state) =>
|
||||
MedicineIntakeScreen
|
||||
.builder(
|
||||
context,
|
||||
state
|
||||
.extra),
|
||||
),
|
||||
GoRoute(
|
||||
name: 'favoriteFoodsScreen',
|
||||
path: 'favorite-foods-screen',
|
||||
builder: (context, state) => FavoriteFoodsScreen.builder(context, state.extra),
|
||||
name:
|
||||
'favoriteFoodsScreen',
|
||||
path:
|
||||
'favorite-foods-screen',
|
||||
builder: (context,
|
||||
state) =>
|
||||
FavoriteFoodsScreen
|
||||
.builder(
|
||||
context,
|
||||
state
|
||||
.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'additional-information-screen',
|
||||
name: 'additionalInformationScreen',
|
||||
builder: (context, state) => AdditionalInformationScreen.builder(context, state.extra),
|
||||
path:
|
||||
'additional-information-screen',
|
||||
name:
|
||||
'additionalInformationScreen',
|
||||
builder: (context,
|
||||
state) =>
|
||||
AdditionalInformationScreen.builder(
|
||||
context,
|
||||
state
|
||||
.extra),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -171,15 +220,14 @@ class AppRouter {
|
||||
GoRoute(
|
||||
path: 'blog-post-create-screen',
|
||||
name: 'blogPostCreateScreen',
|
||||
builder: (context, state) => BlogPostCreateScreen.builder(context),
|
||||
builder: (context, state) =>
|
||||
BlogPostCreateScreen.builder(context),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'blog-post-screen',
|
||||
name: 'blogPostScreen',
|
||||
builder: (context, state) => BlogPostScreen.builder(
|
||||
context,
|
||||
state.extra.toString(),
|
||||
),
|
||||
builder: (context, state) =>
|
||||
BlogPostScreen(blogPostID: state.extra as String),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'blog-post-edit-screen',
|
||||
|
||||
23
lib/features/blog_post/models/blog_post_model.dart
Normal file
23
lib/features/blog_post/models/blog_post_model.dart
Normal file
@@ -0,0 +1,23 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'blog_post_model.freezed.dart';
|
||||
part 'blog_post_model.g.dart';
|
||||
|
||||
@freezed
|
||||
class BlogPostModel with _$BlogPostModel {
|
||||
const factory BlogPostModel({
|
||||
required int id,
|
||||
required String state,
|
||||
String? image,
|
||||
required String description,
|
||||
String? author_name,
|
||||
String? author_avatar_path,
|
||||
@JsonKey(name: "youtube_url") required String youtubeUrl,
|
||||
@JsonKey(name: "created_at") required DateTime createdAt,
|
||||
@JsonKey(name: "updated_at") required DateTime updatedAt,
|
||||
required String title,
|
||||
}) = _BlogPostModel;
|
||||
|
||||
factory BlogPostModel.fromJson(Map<String, Object?> json) =>
|
||||
_$BlogPostModelFromJson(json);
|
||||
}
|
||||
351
lib/features/blog_post/models/blog_post_model.freezed.dart
Normal file
351
lib/features/blog_post/models/blog_post_model.freezed.dart
Normal file
@@ -0,0 +1,351 @@
|
||||
// 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 'blog_post_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(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');
|
||||
|
||||
BlogPostModel _$BlogPostModelFromJson(Map<String, dynamic> json) {
|
||||
return _BlogPostModel.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$BlogPostModel {
|
||||
int get id => throw _privateConstructorUsedError;
|
||||
String get state => throw _privateConstructorUsedError;
|
||||
String? get image => throw _privateConstructorUsedError;
|
||||
String get description => throw _privateConstructorUsedError;
|
||||
String? get author_name => throw _privateConstructorUsedError;
|
||||
String? get author_avatar_path => 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<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$BlogPostModelCopyWith<BlogPostModel> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $BlogPostModelCopyWith<$Res> {
|
||||
factory $BlogPostModelCopyWith(
|
||||
BlogPostModel value, $Res Function(BlogPostModel) then) =
|
||||
_$BlogPostModelCopyWithImpl<$Res, BlogPostModel>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
String state,
|
||||
String? image,
|
||||
String description,
|
||||
String? author_name,
|
||||
String? author_avatar_path,
|
||||
@JsonKey(name: "youtube_url") String youtubeUrl,
|
||||
@JsonKey(name: "created_at") DateTime createdAt,
|
||||
@JsonKey(name: "updated_at") DateTime updatedAt,
|
||||
String title});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$BlogPostModelCopyWithImpl<$Res, $Val extends BlogPostModel>
|
||||
implements $BlogPostModelCopyWith<$Res> {
|
||||
_$BlogPostModelCopyWithImpl(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 = freezed,
|
||||
Object? description = null,
|
||||
Object? author_name = freezed,
|
||||
Object? author_avatar_path = freezed,
|
||||
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: freezed == 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,
|
||||
author_name: freezed == author_name
|
||||
? _value.author_name
|
||||
: author_name // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
author_avatar_path: freezed == author_avatar_path
|
||||
? _value.author_avatar_path
|
||||
: author_avatar_path // 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 _$$BlogPostModelImplCopyWith<$Res>
|
||||
implements $BlogPostModelCopyWith<$Res> {
|
||||
factory _$$BlogPostModelImplCopyWith(
|
||||
_$BlogPostModelImpl value, $Res Function(_$BlogPostModelImpl) then) =
|
||||
__$$BlogPostModelImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
String state,
|
||||
String? image,
|
||||
String description,
|
||||
String? author_name,
|
||||
String? author_avatar_path,
|
||||
@JsonKey(name: "youtube_url") String youtubeUrl,
|
||||
@JsonKey(name: "created_at") DateTime createdAt,
|
||||
@JsonKey(name: "updated_at") DateTime updatedAt,
|
||||
String title});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$BlogPostModelImplCopyWithImpl<$Res>
|
||||
extends _$BlogPostModelCopyWithImpl<$Res, _$BlogPostModelImpl>
|
||||
implements _$$BlogPostModelImplCopyWith<$Res> {
|
||||
__$$BlogPostModelImplCopyWithImpl(
|
||||
_$BlogPostModelImpl _value, $Res Function(_$BlogPostModelImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? id = null,
|
||||
Object? state = null,
|
||||
Object? image = freezed,
|
||||
Object? description = null,
|
||||
Object? author_name = freezed,
|
||||
Object? author_avatar_path = freezed,
|
||||
Object? youtubeUrl = null,
|
||||
Object? createdAt = null,
|
||||
Object? updatedAt = null,
|
||||
Object? title = null,
|
||||
}) {
|
||||
return _then(_$BlogPostModelImpl(
|
||||
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: freezed == 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,
|
||||
author_name: freezed == author_name
|
||||
? _value.author_name
|
||||
: author_name // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
author_avatar_path: freezed == author_avatar_path
|
||||
? _value.author_avatar_path
|
||||
: author_avatar_path // 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 _$BlogPostModelImpl implements _BlogPostModel {
|
||||
const _$BlogPostModelImpl(
|
||||
{required this.id,
|
||||
required this.state,
|
||||
this.image,
|
||||
required this.description,
|
||||
this.author_name,
|
||||
this.author_avatar_path,
|
||||
@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 _$BlogPostModelImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$BlogPostModelImplFromJson(json);
|
||||
|
||||
@override
|
||||
final int id;
|
||||
@override
|
||||
final String state;
|
||||
@override
|
||||
final String? image;
|
||||
@override
|
||||
final String description;
|
||||
@override
|
||||
final String? author_name;
|
||||
@override
|
||||
final String? author_avatar_path;
|
||||
@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 'BlogPostModel(id: $id, state: $state, image: $image, description: $description, author_name: $author_name, author_avatar_path: $author_avatar_path, youtubeUrl: $youtubeUrl, createdAt: $createdAt, updatedAt: $updatedAt, title: $title)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$BlogPostModelImpl &&
|
||||
(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.author_name, author_name) ||
|
||||
other.author_name == author_name) &&
|
||||
(identical(other.author_avatar_path, author_avatar_path) ||
|
||||
other.author_avatar_path == author_avatar_path) &&
|
||||
(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,
|
||||
author_name, author_avatar_path, youtubeUrl, createdAt, updatedAt, title);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$BlogPostModelImplCopyWith<_$BlogPostModelImpl> get copyWith =>
|
||||
__$$BlogPostModelImplCopyWithImpl<_$BlogPostModelImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$BlogPostModelImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _BlogPostModel implements BlogPostModel {
|
||||
const factory _BlogPostModel(
|
||||
{required final int id,
|
||||
required final String state,
|
||||
final String? image,
|
||||
required final String description,
|
||||
final String? author_name,
|
||||
final String? author_avatar_path,
|
||||
@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}) = _$BlogPostModelImpl;
|
||||
|
||||
factory _BlogPostModel.fromJson(Map<String, dynamic> json) =
|
||||
_$BlogPostModelImpl.fromJson;
|
||||
|
||||
@override
|
||||
int get id;
|
||||
@override
|
||||
String get state;
|
||||
@override
|
||||
String? get image;
|
||||
@override
|
||||
String get description;
|
||||
@override
|
||||
String? get author_name;
|
||||
@override
|
||||
String? get author_avatar_path;
|
||||
@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)
|
||||
_$$BlogPostModelImplCopyWith<_$BlogPostModelImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
35
lib/features/blog_post/models/blog_post_model.g.dart
Normal file
35
lib/features/blog_post/models/blog_post_model.g.dart
Normal file
@@ -0,0 +1,35 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'blog_post_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$BlogPostModelImpl _$$BlogPostModelImplFromJson(Map<String, dynamic> json) =>
|
||||
_$BlogPostModelImpl(
|
||||
id: (json['id'] as num).toInt(),
|
||||
state: json['state'] as String,
|
||||
image: json['image'] as String?,
|
||||
description: json['description'] as String,
|
||||
author_name: json['author_name'] as String?,
|
||||
author_avatar_path: json['author_avatar_path'] 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<String, dynamic> _$$BlogPostModelImplToJson(_$BlogPostModelImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'state': instance.state,
|
||||
'image': instance.image,
|
||||
'description': instance.description,
|
||||
'author_name': instance.author_name,
|
||||
'author_avatar_path': instance.author_avatar_path,
|
||||
'youtube_url': instance.youtubeUrl,
|
||||
'created_at': instance.createdAt.toIso8601String(),
|
||||
'updated_at': instance.updatedAt.toIso8601String(),
|
||||
'title': instance.title,
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:eatvio_app/features/blog_post/presentation/bloc/blog_post_state.dart';
|
||||
import 'package:eatvio_app/features/blog_post/repositories/blog_post_repository.dart';
|
||||
|
||||
class BlogPostCubit extends Cubit<BlogPostState> {
|
||||
final BlogPostRepository blogPostRepository;
|
||||
|
||||
BlogPostCubit({required this.blogPostRepository})
|
||||
: super(const BlogPostState.loading());
|
||||
|
||||
loadBlogPost(String blogPostID) async {
|
||||
emit(const BlogPostState.loading());
|
||||
try {
|
||||
final blogPost = await blogPostRepository.getBlogPost(blogPostID);
|
||||
emit(BlogPostState.loaded(blogPost: blogPost));
|
||||
} catch (e) {
|
||||
emit(BlogPostState.error(errorMessage: e.toString()));
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import 'package:eatvio_app/features/blog_post/models/blog_post_model.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'blog_post_state.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class BlogPostState with _$BlogPostState {
|
||||
const factory BlogPostState() = _BlogPostState;
|
||||
|
||||
const factory BlogPostState.loading() = BlogPostStateLoading;
|
||||
|
||||
const factory BlogPostState.loaded({
|
||||
required BlogPostModel blogPost,
|
||||
}) = BlogPostStateLoaded;
|
||||
|
||||
const factory BlogPostState.error({
|
||||
required String errorMessage,
|
||||
}) = BlogPostStateError;
|
||||
}
|
||||
@@ -0,0 +1,622 @@
|
||||
// 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 'blog_post_state.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(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 _$BlogPostState {
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(BlogPostModel blogPost) loaded,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(BlogPostModel blogPost)? loaded,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(BlogPostModel blogPost)? loaded,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>(
|
||||
TResult Function(_BlogPostState value) $default, {
|
||||
required TResult Function(BlogPostStateLoading value) loading,
|
||||
required TResult Function(BlogPostStateLoaded value) loaded,
|
||||
required TResult Function(BlogPostStateError value) error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>(
|
||||
TResult? Function(_BlogPostState value)? $default, {
|
||||
TResult? Function(BlogPostStateLoading value)? loading,
|
||||
TResult? Function(BlogPostStateLoaded value)? loaded,
|
||||
TResult? Function(BlogPostStateError value)? error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>(
|
||||
TResult Function(_BlogPostState value)? $default, {
|
||||
TResult Function(BlogPostStateLoading value)? loading,
|
||||
TResult Function(BlogPostStateLoaded value)? loaded,
|
||||
TResult Function(BlogPostStateError value)? error,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $BlogPostStateCopyWith<$Res> {
|
||||
factory $BlogPostStateCopyWith(
|
||||
BlogPostState value, $Res Function(BlogPostState) then) =
|
||||
_$BlogPostStateCopyWithImpl<$Res, BlogPostState>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$BlogPostStateCopyWithImpl<$Res, $Val extends BlogPostState>
|
||||
implements $BlogPostStateCopyWith<$Res> {
|
||||
_$BlogPostStateCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$BlogPostStateImplCopyWith<$Res> {
|
||||
factory _$$BlogPostStateImplCopyWith(
|
||||
_$BlogPostStateImpl value, $Res Function(_$BlogPostStateImpl) then) =
|
||||
__$$BlogPostStateImplCopyWithImpl<$Res>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$BlogPostStateImplCopyWithImpl<$Res>
|
||||
extends _$BlogPostStateCopyWithImpl<$Res, _$BlogPostStateImpl>
|
||||
implements _$$BlogPostStateImplCopyWith<$Res> {
|
||||
__$$BlogPostStateImplCopyWithImpl(
|
||||
_$BlogPostStateImpl _value, $Res Function(_$BlogPostStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$BlogPostStateImpl implements _BlogPostState {
|
||||
const _$BlogPostStateImpl();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'BlogPostState()';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType && other is _$BlogPostStateImpl);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(BlogPostModel blogPost) loaded,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) {
|
||||
return $default();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(BlogPostModel blogPost)? loaded,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) {
|
||||
return $default?.call();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(BlogPostModel blogPost)? loaded,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if ($default != null) {
|
||||
return $default();
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>(
|
||||
TResult Function(_BlogPostState value) $default, {
|
||||
required TResult Function(BlogPostStateLoading value) loading,
|
||||
required TResult Function(BlogPostStateLoaded value) loaded,
|
||||
required TResult Function(BlogPostStateError value) error,
|
||||
}) {
|
||||
return $default(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>(
|
||||
TResult? Function(_BlogPostState value)? $default, {
|
||||
TResult? Function(BlogPostStateLoading value)? loading,
|
||||
TResult? Function(BlogPostStateLoaded value)? loaded,
|
||||
TResult? Function(BlogPostStateError value)? error,
|
||||
}) {
|
||||
return $default?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>(
|
||||
TResult Function(_BlogPostState value)? $default, {
|
||||
TResult Function(BlogPostStateLoading value)? loading,
|
||||
TResult Function(BlogPostStateLoaded value)? loaded,
|
||||
TResult Function(BlogPostStateError value)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if ($default != null) {
|
||||
return $default(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _BlogPostState implements BlogPostState {
|
||||
const factory _BlogPostState() = _$BlogPostStateImpl;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$BlogPostStateLoadingImplCopyWith<$Res> {
|
||||
factory _$$BlogPostStateLoadingImplCopyWith(_$BlogPostStateLoadingImpl value,
|
||||
$Res Function(_$BlogPostStateLoadingImpl) then) =
|
||||
__$$BlogPostStateLoadingImplCopyWithImpl<$Res>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$BlogPostStateLoadingImplCopyWithImpl<$Res>
|
||||
extends _$BlogPostStateCopyWithImpl<$Res, _$BlogPostStateLoadingImpl>
|
||||
implements _$$BlogPostStateLoadingImplCopyWith<$Res> {
|
||||
__$$BlogPostStateLoadingImplCopyWithImpl(_$BlogPostStateLoadingImpl _value,
|
||||
$Res Function(_$BlogPostStateLoadingImpl) _then)
|
||||
: super(_value, _then);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$BlogPostStateLoadingImpl implements BlogPostStateLoading {
|
||||
const _$BlogPostStateLoadingImpl();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'BlogPostState.loading()';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$BlogPostStateLoadingImpl);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(BlogPostModel blogPost) loaded,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) {
|
||||
return loading();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(BlogPostModel blogPost)? loaded,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) {
|
||||
return loading?.call();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(BlogPostModel blogPost)? loaded,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (loading != null) {
|
||||
return loading();
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>(
|
||||
TResult Function(_BlogPostState value) $default, {
|
||||
required TResult Function(BlogPostStateLoading value) loading,
|
||||
required TResult Function(BlogPostStateLoaded value) loaded,
|
||||
required TResult Function(BlogPostStateError value) error,
|
||||
}) {
|
||||
return loading(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>(
|
||||
TResult? Function(_BlogPostState value)? $default, {
|
||||
TResult? Function(BlogPostStateLoading value)? loading,
|
||||
TResult? Function(BlogPostStateLoaded value)? loaded,
|
||||
TResult? Function(BlogPostStateError value)? error,
|
||||
}) {
|
||||
return loading?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>(
|
||||
TResult Function(_BlogPostState value)? $default, {
|
||||
TResult Function(BlogPostStateLoading value)? loading,
|
||||
TResult Function(BlogPostStateLoaded value)? loaded,
|
||||
TResult Function(BlogPostStateError value)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (loading != null) {
|
||||
return loading(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class BlogPostStateLoading implements BlogPostState {
|
||||
const factory BlogPostStateLoading() = _$BlogPostStateLoadingImpl;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$BlogPostStateLoadedImplCopyWith<$Res> {
|
||||
factory _$$BlogPostStateLoadedImplCopyWith(_$BlogPostStateLoadedImpl value,
|
||||
$Res Function(_$BlogPostStateLoadedImpl) then) =
|
||||
__$$BlogPostStateLoadedImplCopyWithImpl<$Res>;
|
||||
@useResult
|
||||
$Res call({BlogPostModel blogPost});
|
||||
|
||||
$BlogPostModelCopyWith<$Res> get blogPost;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$BlogPostStateLoadedImplCopyWithImpl<$Res>
|
||||
extends _$BlogPostStateCopyWithImpl<$Res, _$BlogPostStateLoadedImpl>
|
||||
implements _$$BlogPostStateLoadedImplCopyWith<$Res> {
|
||||
__$$BlogPostStateLoadedImplCopyWithImpl(_$BlogPostStateLoadedImpl _value,
|
||||
$Res Function(_$BlogPostStateLoadedImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? blogPost = null,
|
||||
}) {
|
||||
return _then(_$BlogPostStateLoadedImpl(
|
||||
blogPost: null == blogPost
|
||||
? _value.blogPost
|
||||
: blogPost // ignore: cast_nullable_to_non_nullable
|
||||
as BlogPostModel,
|
||||
));
|
||||
}
|
||||
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$BlogPostModelCopyWith<$Res> get blogPost {
|
||||
return $BlogPostModelCopyWith<$Res>(_value.blogPost, (value) {
|
||||
return _then(_value.copyWith(blogPost: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$BlogPostStateLoadedImpl implements BlogPostStateLoaded {
|
||||
const _$BlogPostStateLoadedImpl({required this.blogPost});
|
||||
|
||||
@override
|
||||
final BlogPostModel blogPost;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'BlogPostState.loaded(blogPost: $blogPost)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$BlogPostStateLoadedImpl &&
|
||||
(identical(other.blogPost, blogPost) ||
|
||||
other.blogPost == blogPost));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, blogPost);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$BlogPostStateLoadedImplCopyWith<_$BlogPostStateLoadedImpl> get copyWith =>
|
||||
__$$BlogPostStateLoadedImplCopyWithImpl<_$BlogPostStateLoadedImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(BlogPostModel blogPost) loaded,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) {
|
||||
return loaded(blogPost);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(BlogPostModel blogPost)? loaded,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) {
|
||||
return loaded?.call(blogPost);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(BlogPostModel blogPost)? loaded,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (loaded != null) {
|
||||
return loaded(blogPost);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>(
|
||||
TResult Function(_BlogPostState value) $default, {
|
||||
required TResult Function(BlogPostStateLoading value) loading,
|
||||
required TResult Function(BlogPostStateLoaded value) loaded,
|
||||
required TResult Function(BlogPostStateError value) error,
|
||||
}) {
|
||||
return loaded(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>(
|
||||
TResult? Function(_BlogPostState value)? $default, {
|
||||
TResult? Function(BlogPostStateLoading value)? loading,
|
||||
TResult? Function(BlogPostStateLoaded value)? loaded,
|
||||
TResult? Function(BlogPostStateError value)? error,
|
||||
}) {
|
||||
return loaded?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>(
|
||||
TResult Function(_BlogPostState value)? $default, {
|
||||
TResult Function(BlogPostStateLoading value)? loading,
|
||||
TResult Function(BlogPostStateLoaded value)? loaded,
|
||||
TResult Function(BlogPostStateError value)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (loaded != null) {
|
||||
return loaded(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class BlogPostStateLoaded implements BlogPostState {
|
||||
const factory BlogPostStateLoaded({required final BlogPostModel blogPost}) =
|
||||
_$BlogPostStateLoadedImpl;
|
||||
|
||||
BlogPostModel get blogPost;
|
||||
@JsonKey(ignore: true)
|
||||
_$$BlogPostStateLoadedImplCopyWith<_$BlogPostStateLoadedImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$BlogPostStateErrorImplCopyWith<$Res> {
|
||||
factory _$$BlogPostStateErrorImplCopyWith(_$BlogPostStateErrorImpl value,
|
||||
$Res Function(_$BlogPostStateErrorImpl) then) =
|
||||
__$$BlogPostStateErrorImplCopyWithImpl<$Res>;
|
||||
@useResult
|
||||
$Res call({String errorMessage});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$BlogPostStateErrorImplCopyWithImpl<$Res>
|
||||
extends _$BlogPostStateCopyWithImpl<$Res, _$BlogPostStateErrorImpl>
|
||||
implements _$$BlogPostStateErrorImplCopyWith<$Res> {
|
||||
__$$BlogPostStateErrorImplCopyWithImpl(_$BlogPostStateErrorImpl _value,
|
||||
$Res Function(_$BlogPostStateErrorImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? errorMessage = null,
|
||||
}) {
|
||||
return _then(_$BlogPostStateErrorImpl(
|
||||
errorMessage: null == errorMessage
|
||||
? _value.errorMessage
|
||||
: errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$BlogPostStateErrorImpl implements BlogPostStateError {
|
||||
const _$BlogPostStateErrorImpl({required this.errorMessage});
|
||||
|
||||
@override
|
||||
final String errorMessage;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'BlogPostState.error(errorMessage: $errorMessage)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$BlogPostStateErrorImpl &&
|
||||
(identical(other.errorMessage, errorMessage) ||
|
||||
other.errorMessage == errorMessage));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, errorMessage);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$BlogPostStateErrorImplCopyWith<_$BlogPostStateErrorImpl> get copyWith =>
|
||||
__$$BlogPostStateErrorImplCopyWithImpl<_$BlogPostStateErrorImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(BlogPostModel blogPost) loaded,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) {
|
||||
return error(errorMessage);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(BlogPostModel blogPost)? loaded,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) {
|
||||
return error?.call(errorMessage);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(BlogPostModel blogPost)? loaded,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (error != null) {
|
||||
return error(errorMessage);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>(
|
||||
TResult Function(_BlogPostState value) $default, {
|
||||
required TResult Function(BlogPostStateLoading value) loading,
|
||||
required TResult Function(BlogPostStateLoaded value) loaded,
|
||||
required TResult Function(BlogPostStateError value) error,
|
||||
}) {
|
||||
return error(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>(
|
||||
TResult? Function(_BlogPostState value)? $default, {
|
||||
TResult? Function(BlogPostStateLoading value)? loading,
|
||||
TResult? Function(BlogPostStateLoaded value)? loaded,
|
||||
TResult? Function(BlogPostStateError value)? error,
|
||||
}) {
|
||||
return error?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>(
|
||||
TResult Function(_BlogPostState value)? $default, {
|
||||
TResult Function(BlogPostStateLoading value)? loading,
|
||||
TResult Function(BlogPostStateLoaded value)? loaded,
|
||||
TResult Function(BlogPostStateError value)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (error != null) {
|
||||
return error(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class BlogPostStateError implements BlogPostState {
|
||||
const factory BlogPostStateError({required final String errorMessage}) =
|
||||
_$BlogPostStateErrorImpl;
|
||||
|
||||
String get errorMessage;
|
||||
@JsonKey(ignore: true)
|
||||
_$$BlogPostStateErrorImplCopyWith<_$BlogPostStateErrorImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import 'package:eatvio_app/features/blog_post/presentation/bloc/blog_post_cubit.dart';
|
||||
import 'package:eatvio_app/features/blog_post/presentation/bloc/blog_post_state.dart';
|
||||
import 'package:eatvio_app/locator_service.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/blog_post_bloc.dart';
|
||||
import 'models/blog_post_model.dart';
|
||||
import 'widgets/comment_widget.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
@@ -12,53 +12,29 @@ import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
|
||||
class BlogPostScreen extends StatelessWidget {
|
||||
const BlogPostScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context, String blog_postID) {
|
||||
return BlocProvider<BlogPostBloc>(
|
||||
create: (context) => BlogPostBloc(
|
||||
BlogPostState(
|
||||
blog_postModelObj: BlogPostModel(
|
||||
blog_postID: blog_postID.toString(),
|
||||
),
|
||||
),
|
||||
)..add(
|
||||
BlogPostInitialEvent(),
|
||||
),
|
||||
child: BlogPostScreen(),
|
||||
);
|
||||
}
|
||||
final String blogPostID;
|
||||
|
||||
const BlogPostScreen({super.key, required this.blogPostID});
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<BlogPostBloc, BlogPostState>(
|
||||
builder: (context, state) {
|
||||
if (state is BlogPostInitialState) {
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
} else if (state is BlogPostLoadedState) {
|
||||
// Данные загружены, можно строить экран.
|
||||
return _buildBlogPost(context, state);
|
||||
} else if (state is BlogPostErrorState) {
|
||||
// Произошла ошибка при загрузке данных.
|
||||
return Center(
|
||||
child: Text(state.errorMessage),
|
||||
);
|
||||
} else {
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
// Другие состояния, если они есть.
|
||||
}
|
||||
},
|
||||
return BlocProvider<BlogPostCubit>(
|
||||
create: (context) => sl<BlogPostCubit>()..loadBlogPost(blogPostID),
|
||||
child: BlocBuilder<BlogPostCubit, BlogPostState>(
|
||||
builder: (context, state) {
|
||||
if (state is BlogPostStateLoaded) {
|
||||
return _buildBlogPost(context, state);
|
||||
} else {
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: CupertinoActivityIndicator(),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_buildBlogPost(BuildContext context, BlogPostLoadedState state) {
|
||||
_buildBlogPost(BuildContext context, BlogPostStateLoaded state) {
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
@@ -82,8 +58,8 @@ class BlogPostScreen extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
_buildHeaderRow(BuildContext context, BlogPostLoadedState state) {
|
||||
final String name = state.author?['name'];
|
||||
_buildHeaderRow(BuildContext context, BlogPostStateLoaded state) {
|
||||
final String name = state.blogPost.title;
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 16.h, vertical: 16.h),
|
||||
padding: EdgeInsets.symmetric(
|
||||
@@ -121,7 +97,8 @@ class BlogPostScreen extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
CachedNetworkImage(
|
||||
imageUrl: dotenv.env['STORAGE_URL']! + (state.author?['profile_photo_path'] ?? ''),
|
||||
imageUrl: dotenv.env['STORAGE_URL']! +
|
||||
(state.blogPost.author_avatar_path ?? ''),
|
||||
imageBuilder: (context, imageProvider) => CircleAvatar(
|
||||
backgroundImage: imageProvider,
|
||||
radius: 25,
|
||||
@@ -141,7 +118,7 @@ class BlogPostScreen extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
_buildBlogPostData(BuildContext context, BlogPostLoadedState state) {
|
||||
_buildBlogPostData(BuildContext context, BlogPostStateLoaded state) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: 16.h,
|
||||
@@ -161,79 +138,90 @@ class BlogPostScreen extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
state.blog_post?['title'],
|
||||
style: CustomTextStyles.titleMediumBlack,
|
||||
),
|
||||
Spacer(),
|
||||
PopupMenuButton<String>(
|
||||
onSelected: (value) => tapMenu(value, context, state),
|
||||
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
|
||||
PopupMenuItem<String>(
|
||||
value: 'edit',
|
||||
child: Text('Редактировать'),
|
||||
),
|
||||
PopupMenuItem<String>(
|
||||
value: 'delete',
|
||||
child: Text('Удалить'),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 8.0),
|
||||
_buildImage(state),
|
||||
SizedBox(height: 16.0),
|
||||
Text(
|
||||
state.blog_post?['description'],
|
||||
style: CustomTextStyles.bodyMediumBluegray800,
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
Align(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
state.blogPost.title,
|
||||
style: CustomTextStyles.titleMediumBlack,
|
||||
),
|
||||
Spacer(),
|
||||
PopupMenuButton<String>(
|
||||
onSelected: (value) => tapMenu(value, context, state),
|
||||
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
|
||||
PopupMenuItem<String>(
|
||||
value: 'edit',
|
||||
child: Text('Редактировать'),
|
||||
),
|
||||
PopupMenuItem<String>(
|
||||
value: 'delete',
|
||||
child: Text('Удалить'),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 8.0),
|
||||
_buildImage(state),
|
||||
SizedBox(height: 16.0),
|
||||
Text(
|
||||
state.blogPost.description,
|
||||
style: CustomTextStyles.bodyMediumBluegray800,
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Text(
|
||||
DateFormat('dd.MM.yyyy').format(DateTime.parse(state.blog_post?['updated_at'])),
|
||||
DateFormat('dd.MM.yyyy').format(state.blogPost.updatedAt),
|
||||
style: theme.textTheme.bodyMedium,
|
||||
),),
|
||||
SizedBox(height: 16.0),
|
||||
Row(children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 24),
|
||||
child: Row(children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(right: 8),
|
||||
child: Icon(Icons.favorite_outline),
|
||||
),
|
||||
Text(
|
||||
"Нравится",
|
||||
style: CustomTextStyles.titleMediumSemiBold,
|
||||
),
|
||||
],),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(right: 24),
|
||||
child: Row(children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 8),
|
||||
child: Icon(Icons.share_outlined),
|
||||
SizedBox(height: 16.0),
|
||||
Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 24),
|
||||
child: Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(right: 8),
|
||||
child: Icon(Icons.favorite_outline),
|
||||
),
|
||||
Text(
|
||||
"Нравится",
|
||||
style: CustomTextStyles.titleMediumSemiBold,
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
"Поделиться",
|
||||
style: CustomTextStyles.titleMediumSemiBold,
|
||||
),
|
||||
Spacer(),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(right: 24),
|
||||
child: Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 8),
|
||||
child: Icon(Icons.share_outlined),
|
||||
),
|
||||
Text(
|
||||
"Поделиться",
|
||||
style: CustomTextStyles.titleMediumSemiBold,
|
||||
),
|
||||
],
|
||||
),
|
||||
],),),
|
||||
],),
|
||||
],),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_buildImage(BlogPostLoadedState state) {
|
||||
_buildImage(BlogPostStateLoaded state) {
|
||||
return CachedNetworkImage(
|
||||
imageUrl: dotenv.env['STORAGE_URL']! + (state.blog_post?['image'] ?? ''),
|
||||
imageUrl: dotenv.env['STORAGE_URL']! + (state.blogPost.image ?? ""),
|
||||
imageBuilder: (context, imageProvider) => Stack(
|
||||
children: [
|
||||
ClipRRect(
|
||||
@@ -290,7 +278,7 @@ class BlogPostScreen extends StatelessWidget {
|
||||
),
|
||||
SizedBox(width: 4.0),
|
||||
Text(
|
||||
'${state.comments?.length}',
|
||||
'42',
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
],
|
||||
@@ -306,18 +294,18 @@ class BlogPostScreen extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
void tapMenu(String value, BuildContext context, BlogPostLoadedState state) {
|
||||
void tapMenu(String value, BuildContext context, BlogPostStateLoaded state) {
|
||||
if (value == 'edit') {
|
||||
GoRouter.of(context).goNamed(
|
||||
'blogPostEditScreen',
|
||||
extra: state.blog_post?['id'].toString(),
|
||||
extra: state.blogPost.id.toString(),
|
||||
);
|
||||
} else if (value == 'delete') {
|
||||
context.read<BlogPostBloc>().add(DeleteEntry(state.blog_post?['id']));
|
||||
// context.read<BlogPostB>().add(DeleteEntry(state.blog_post?['id']));
|
||||
}
|
||||
}
|
||||
|
||||
_buildTextField(BuildContext context, BlogPostLoadedState state) {
|
||||
_buildTextField(BuildContext context, BlogPostStateLoaded state) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: 16.h,
|
||||
@@ -343,7 +331,7 @@ class BlogPostScreen extends StatelessWidget {
|
||||
Column(
|
||||
children: [
|
||||
CustomTextFormField(
|
||||
controller: state.commentController,
|
||||
// controller: state.commentController,
|
||||
maxLines: 4,
|
||||
),
|
||||
SizedBox(height: 15.h),
|
||||
@@ -354,7 +342,9 @@ class BlogPostScreen extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
onPressed: () => context.read<BlogPostBloc>().add(CreateComment(state.commentController!.text)),
|
||||
/* onPressed: () => context
|
||||
.read<BlogPostBloc>()
|
||||
.add(CreateComment(state.commentController!.text)),*/
|
||||
// Установите прозрачный фон
|
||||
),
|
||||
],
|
||||
@@ -364,9 +354,9 @@ class BlogPostScreen extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
_buildCommentSection(BuildContext context, BlogPostLoadedState state) {
|
||||
if (state.comments != null && state.comments!.isNotEmpty) {
|
||||
return Column(
|
||||
_buildCommentSection(BuildContext context, BlogPostStateLoaded state) {
|
||||
/* if (state.comments != null && state.comments!.isNotEmpty) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
for (int i = 0; i < state.comments!.length; i++)
|
||||
@@ -380,15 +370,14 @@ class BlogPostScreen extends StatelessWidget {
|
||||
],
|
||||
);
|
||||
} else {
|
||||
// Return a message or placeholder widget when there are no comments
|
||||
return Center(
|
||||
child: Text('No comments available'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowleftone(BuildContext context) {
|
||||
GoRouter.of(context).pop();
|
||||
// Return a message or placeholder widget when there are no comments*/
|
||||
return Center(
|
||||
child: Text('No comments available'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowleftone(BuildContext context) {
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import 'package:eatvio_app/features/blog_post/models/blog_post_model.dart';
|
||||
import 'package:eatvio_app/features/blog_post/services/blog_post_service.dart';
|
||||
|
||||
class BlogPostRepository {
|
||||
final BlogPostService blogPostService;
|
||||
|
||||
BlogPostRepository({required this.blogPostService});
|
||||
|
||||
Future<BlogPostModel> getBlogPost(String blogPostID) async {
|
||||
try {
|
||||
return await blogPostService.getBlogPost(blogPostID);
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
lib/features/blog_post/services/blog_post_service.dart
Normal file
13
lib/features/blog_post/services/blog_post_service.dart
Normal file
@@ -0,0 +1,13 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/features/blog_post/models/blog_post_model.dart';
|
||||
import 'package:retrofit/retrofit.dart';
|
||||
|
||||
part 'blog_post_service.g.dart';
|
||||
|
||||
@RestApi()
|
||||
abstract class BlogPostService {
|
||||
factory BlogPostService(Dio dio, {String baseUrl}) = _BlogPostService;
|
||||
|
||||
@GET('/feed/show/{id}')
|
||||
Future<BlogPostModel> getBlogPost(@Path() String id);
|
||||
}
|
||||
77
lib/features/blog_post/services/blog_post_service.g.dart
Normal file
77
lib/features/blog_post/services/blog_post_service.g.dart
Normal file
@@ -0,0 +1,77 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'blog_post_service.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RetrofitGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers
|
||||
|
||||
class _BlogPostService implements BlogPostService {
|
||||
_BlogPostService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
String? baseUrl;
|
||||
|
||||
@override
|
||||
Future<BlogPostModel> getBlogPost(String id) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _result = await _dio
|
||||
.fetch<Map<String, dynamic>>(_setStreamType<BlogPostModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/feed/show/${id}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
))));
|
||||
final value = BlogPostModel.fromJson(_result.data!);
|
||||
return value;
|
||||
}
|
||||
|
||||
RequestOptions _setStreamType<T>(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();
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ class FeedCubit extends Cubit<FeedState> {
|
||||
FeedCubit({required this.feedRepository}) : super(const FeedState.loading());
|
||||
|
||||
loadFeedBlogPostList() async {
|
||||
emit(const FeedStateLoading());
|
||||
emit(const FeedState.loading());
|
||||
try {
|
||||
final feedBlogPostList = await feedRepository.getFeedBlogPostList();
|
||||
emit(FeedState.loaded(feedBlogPostList: feedBlogPostList));
|
||||
|
||||
@@ -100,7 +100,8 @@ class FeedScreen extends StatelessWidget {
|
||||
flex: 1,
|
||||
child: CustomOutlinedButton(
|
||||
text: "+",
|
||||
onPressed: () => GoRouter.of(context).goNamed('blogPostCreateScreen'),
|
||||
onPressed: () =>
|
||||
GoRouter.of(context).goNamed('blogPostCreateScreen'),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
),
|
||||
),
|
||||
@@ -144,7 +145,7 @@ class FeedScreen extends StatelessWidget {
|
||||
children: [
|
||||
ListTile(
|
||||
leading: CachedNetworkImage(
|
||||
imageUrl: dotenv.env['STORAGE_URL']! + ('' ?? ''),
|
||||
imageUrl: dotenv.env['STORAGE_URL']! + (''),
|
||||
|
||||
/// todo profile photo path
|
||||
imageBuilder: (context, imageProvider) => CircleAvatar(
|
||||
@@ -215,11 +216,12 @@ class FeedScreen extends StatelessWidget {
|
||||
),
|
||||
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,
|
||||
),
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/core/initialization_cubit/initialization_cubit.dart';
|
||||
import 'package:eatvio_app/features/blog_post/presentation/bloc/blog_post_cubit.dart';
|
||||
import 'package:eatvio_app/features/blog_post/repositories/blog_post_repository.dart';
|
||||
import 'package:eatvio_app/features/blog_post/services/blog_post_service.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';
|
||||
@@ -14,16 +17,24 @@ final sl = GetIt.instance;
|
||||
Future<void> init() async {
|
||||
// BLoC
|
||||
sl.registerFactory<ChatRoomCubit>(() => ChatRoomCubit(chatRepository: sl()));
|
||||
sl.registerFactory<InitializationCubit>(() => InitializationCubit(chatRepository: sl()));
|
||||
sl.registerFactory<InitializationCubit>(
|
||||
() => InitializationCubit(chatRepository: sl()));
|
||||
sl.registerFactory<FeedCubit>(() => FeedCubit(feedRepository: sl()));
|
||||
sl.registerFactory<BlogPostCubit>(
|
||||
() => BlogPostCubit(blogPostRepository: sl()));
|
||||
|
||||
// Repository
|
||||
sl.registerLazySingleton<ChatRepository>(() => ChatRepository(chatService: sl()));
|
||||
sl.registerLazySingleton<FeedRepository>(() => FeedRepository(feedService: sl()));
|
||||
sl.registerLazySingleton<ChatRepository>(
|
||||
() => ChatRepository(chatService: sl()));
|
||||
sl.registerLazySingleton<FeedRepository>(
|
||||
() => FeedRepository(feedService: sl()));
|
||||
sl.registerLazySingleton<BlogPostRepository>(
|
||||
() => BlogPostRepository(blogPostService: sl()));
|
||||
|
||||
// Services
|
||||
sl.registerLazySingleton<ChatService>(() => ChatService(sl()));
|
||||
sl.registerLazySingleton<FeedService>(() => FeedService(sl()));
|
||||
sl.registerLazySingleton<BlogPostService>(() => BlogPostService(sl()));
|
||||
|
||||
// External
|
||||
sl.registerLazySingleton(
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:eatvio_app/presentation/feed/blog_post_screen/models/comment_model.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:intl/intl.dart';
|
||||
import 'dart:convert';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/feed/blog_post_screen/models/blog_post_model.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
part 'blog_post_event.dart';
|
||||
part 'blog_post_state.dart';
|
||||
|
||||
/// A bloc that manages the state of a BlogPost according to the event that is dispatched to it.
|
||||
class BlogPostBloc extends Bloc<BlogPostEvent, BlogPostState> {
|
||||
BlogPostBloc(BlogPostState initialState) : super(initialState) {
|
||||
on<BlogPostInitialEvent>(_onInitialize);
|
||||
on<DeleteEntry>(_deleteEntry);
|
||||
on<CreateComment>(_createComment);
|
||||
}
|
||||
|
||||
_onInitialize(
|
||||
BlogPostInitialEvent event,
|
||||
Emitter<BlogPostState> emit,
|
||||
) async {
|
||||
try {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final String? blog_postID = state.blog_postModelObj?.blog_postID;
|
||||
final response = await http.get(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/feed/show/$blog_postID'),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body);
|
||||
if (data is Map<String, dynamic>) {
|
||||
if (state is BlogPostLoadedState) {
|
||||
var currentState = state as BlogPostLoadedState;
|
||||
emit(currentState.copyWith(
|
||||
blog_postModelObj: currentState.blog_postModelObj,
|
||||
blog_post: currentState.blog_post,
|
||||
author: currentState.author,
|
||||
comments: currentState.comments,
|
||||
token: currentState.token,),);
|
||||
} else {
|
||||
emit(BlogPostLoadedState(
|
||||
blog_post: data,
|
||||
token: token,
|
||||
commentController: TextEditingController(),
|
||||
author: await _fetchAuthor(data['id']),
|
||||
comments: fillCommentList(await _fetchComments(data['id'])),),);
|
||||
}
|
||||
} else {
|
||||
// Один или несколько ключевых полей отсутствуют, обрабатываем ошибку
|
||||
emit(BlogPostErrorState('Некоторые необходимые данные отсутствуют.'));
|
||||
}
|
||||
} else {
|
||||
// Статус ответа не равен 200, обрабатываем ошибку
|
||||
emit(BlogPostErrorState('Ошибка сервера: ${response.statusCode}'));
|
||||
}
|
||||
} catch (e) {
|
||||
// Ошибка при декодировании JSON или другая ошибка выполнения
|
||||
emit(BlogPostErrorState('Ошибка при получении данных о чатах: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _createComment(
|
||||
CreateComment event, Emitter<BlogPostState> emit,) async {
|
||||
if (state is BlogPostLoadedState) {
|
||||
var currentState = state as BlogPostLoadedState;
|
||||
// Отправляем данные по HTTP маршруту и ждем ответ
|
||||
var response = await _sendCommentData(
|
||||
currentState.token, event.body, currentState.blog_post?['id'],);
|
||||
if (response.statusCode == 200) {
|
||||
var updatedComments = fillCommentList(
|
||||
await _fetchComments(currentState.blog_post?['id']),);
|
||||
var updatedState = currentState.copyWith(
|
||||
comments: updatedComments,
|
||||
commentController:
|
||||
TextEditingController(), // Clear the comment input field
|
||||
);
|
||||
emit(updatedState); // Emit the updated state to trigger a screen update
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _deleteEntry(
|
||||
DeleteEntry event, Emitter<BlogPostState> emit,) async {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final int id = event.id;
|
||||
final response = await http.post(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/feed/delete/$id'),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('feedScreen');
|
||||
} else {
|
||||
// Статус ответа не равен 200, обрабатываем ошибку
|
||||
emit(BlogPostErrorState('Ошибка: ${response.statusCode}'));
|
||||
}
|
||||
}
|
||||
|
||||
_fetchAuthor(int id) async {
|
||||
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/getAuthor/$id'),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
);
|
||||
final data = jsonDecode(response.body);
|
||||
return data;
|
||||
}
|
||||
|
||||
Future<List> _fetchComments(int id) async {
|
||||
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/getComments/$id'),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
);
|
||||
final data = jsonDecode(response.body);
|
||||
return data;
|
||||
}
|
||||
|
||||
List<CommentModel> fillCommentList(List<dynamic> comments) {
|
||||
List<CommentModel> list = [];
|
||||
for (int i = 0; i < comments.length; i++) {
|
||||
list.add(CommentModel(
|
||||
id: comments[i]['id'].toString(),
|
||||
userImage: comments[i]['profile_photo_path'],
|
||||
username: comments[i]['name'],
|
||||
dateText: DateFormat('dd.MM')
|
||||
.format(DateTime.parse(comments[i]['updated_at'])),
|
||||
greetingText: comments[i]['body'],),);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
Future<http.Response> _sendCommentData(
|
||||
String? token, String body, int id,) async {
|
||||
String url = dotenv.env['SERVER_ROOT']! + '/feed/createComment/$id';
|
||||
final Map<String, dynamic> credentials = {
|
||||
'id': id,
|
||||
'body': body,
|
||||
};
|
||||
|
||||
var response = await http.post(Uri.parse(url),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
body: json.encode(credentials),
|
||||
encoding: utf8,);
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
part of 'blog_post_bloc.dart';
|
||||
|
||||
/// Abstract class for all events that can be dispatched from the
|
||||
///BlogPost widget.
|
||||
///
|
||||
/// Events must be immutable and implement the [Equatable] interface.
|
||||
@immutable
|
||||
abstract class BlogPostEvent extends Equatable {}
|
||||
|
||||
/// Event that is dispatched when the BlogPost widget is first created.
|
||||
class BlogPostInitialEvent extends BlogPostEvent {
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class DeleteEntry extends BlogPostEvent {
|
||||
DeleteEntry(this.id);
|
||||
final int id;
|
||||
@override
|
||||
List<Object?> get props => [id];
|
||||
}
|
||||
|
||||
class FetchAuthor extends BlogPostEvent {
|
||||
FetchAuthor(this.id);
|
||||
final int id;
|
||||
@override
|
||||
List<Object?> get props => [id];
|
||||
}
|
||||
|
||||
class FetchComments extends BlogPostEvent {
|
||||
FetchComments(this.id);
|
||||
final int id;
|
||||
@override
|
||||
List<Object?> get props => [id];
|
||||
}
|
||||
|
||||
class CreateComment extends BlogPostEvent {
|
||||
CreateComment(this.body);
|
||||
final String body;
|
||||
@override
|
||||
List<Object?> get props => [body];
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
part of 'blog_post_bloc.dart';
|
||||
|
||||
/// Represents the state of BlogPost in the application.
|
||||
///
|
||||
|
||||
class BlogPostState extends Equatable {
|
||||
BlogPostState({
|
||||
this.blog_postModelObj,
|
||||
});
|
||||
|
||||
BlogPostModel? blog_postModelObj;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [blog_postModelObj];
|
||||
BlogPostState copyWith({BlogPostModel? blog_postModelObj}) {
|
||||
return BlogPostState(
|
||||
blog_postModelObj: blog_postModelObj ?? this.blog_postModelObj,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class BlogPostLoadedState extends BlogPostState {
|
||||
BlogPostLoadedState(
|
||||
{this.blog_postModelObj,
|
||||
this.blog_post,
|
||||
this.author,
|
||||
this.comments,
|
||||
this.token,
|
||||
this.commentController,});
|
||||
|
||||
BlogPostModel? blog_postModelObj;
|
||||
Map<String, dynamic>? blog_post;
|
||||
Map<String, dynamic>? author;
|
||||
List<dynamic>? comments;
|
||||
TextEditingController? commentController;
|
||||
String? token;
|
||||
@override
|
||||
List<Object?> get props => [blog_postModelObj, blog_post, author, comments];
|
||||
BlogPostLoadedState copyWith(
|
||||
{BlogPostModel? blog_postModelObj,
|
||||
Map<String, dynamic>? blog_post,
|
||||
Map<String, dynamic>? author,
|
||||
TextEditingController? commentController,
|
||||
String? token,
|
||||
List<dynamic>? comments,}) {
|
||||
return BlogPostLoadedState(
|
||||
blog_postModelObj: blog_postModelObj ?? this.blog_postModelObj,
|
||||
blog_post: blog_post ?? this.blog_post,
|
||||
author: author ?? this.author,
|
||||
comments: comments ?? this.comments,
|
||||
token: token ?? this.token,
|
||||
commentController: commentController ?? this.commentController,);
|
||||
}
|
||||
}
|
||||
|
||||
class BlogPostErrorState extends BlogPostState {
|
||||
final String errorMessage;
|
||||
|
||||
BlogPostErrorState(this.errorMessage);
|
||||
|
||||
@override
|
||||
List<Object> get props => [errorMessage];
|
||||
}
|
||||
|
||||
class BlogPostInitialState extends BlogPostState {
|
||||
BlogPostInitialState({required BlogPostModel blog_postModelObj})
|
||||
: super(blog_postModelObj: blog_postModelObj);
|
||||
}
|
||||
Reference in New Issue
Block a user