create diet screen

This commit is contained in:
Username1548
2024-11-25 16:01:02 +07:00
parent c3cb55f8a2
commit c78a90b603
42 changed files with 1742 additions and 918 deletions

View File

@@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:developer';
import 'package:easy_debounce/easy_debounce.dart';
import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/features/diets/repositories/diet_repository.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_state.dart';
import 'package:eatvio_app/features/feed/repositories/feed_repository.dart';
@@ -14,16 +15,23 @@ class DietsCubit extends Cubit<DietsState> {
late int lastPage;
bool isLoading = false;
String? _query;
String? _types;
int? _duration;
String? _sorting;
static const List<String?> _sortingValues = [
null,
'chosen_diets_count:desc',
'created_at:desc',
'created_at',
'name',
'name:desc',
];
static const List<int?> _durationValues = [null, ...durationValues];
static const List<String?> _types = [null, ...typeValues];
late final StreamSubscription likesStateSubscription;
late final StreamSubscription favoriteStateSubscription;
late final StreamSubscription commentsStateSubscription;
DietsCubit({
required this.feedRepository,
required this.dietsRepository,
}) : super(const DietsState.loading()) {
}) : super(DietsState.initial()) {
likesStateSubscription = dietsRepository.dietLikeState.listen((likesState) {
_changeDietLikeState(likesState);
});
@@ -43,35 +51,43 @@ class DietsCubit extends Cubit<DietsState> {
super.close();
}
void changeTypeFilter(int index) {
emit(state.copyWith(filterState: state.filterState.copyWith(typeIndex: index), errorMessage: null));
loadDiets(query: _query);
}
void changeSortingType(int index) {
emit(state.copyWith(filterState: state.filterState.copyWith(sortingIndex: index), errorMessage: null));
loadDiets(query: _query);
}
void changeDurationFilter(int index) {
emit(state.copyWith(filterState: state.filterState.copyWith(durationIndex: index), errorMessage: null));
loadDiets(query: _query);
}
loadDiets({
String? query,
String? types,
int? duration,
String? sorting,
}) async {
try {
_query = query;
_types = types;
_duration = duration;
_sorting = sorting;
final type = _types[state.filterState.typeIndex];
final duration = _durationValues[state.filterState.durationIndex];
final sorting = _sortingValues[state.filterState.sortingIndex];
final dietsPagination = await feedRepository.getDiets(
query: query,
types: types,
types: type,
duration: duration,
sorting: sorting,
);
lastPage = dietsPagination.meta.lastPage;
emit(
DietsState.loaded(
dietsList: dietsPagination.data,
isLoading: isLoading,
),
state.copyWith(dietsList: dietsPagination.data, isLoading: isLoading, errorMessage: null),
);
} catch (e) {
emit(
DietsState.error(
errorMessage: e.toString(),
),
state.copyWith(errorMessage: e.toString()),
);
}
}
@@ -80,7 +96,7 @@ class DietsCubit extends Cubit<DietsState> {
if (currentPage < lastPage && !isLoading) {
isLoading = true;
emit((state as DietsStateLoaded).copyWith(isLoading: isLoading));
emit((state.copyWith(isLoading: isLoading, errorMessage: null)));
try {
if (currentPage < lastPage) {
@@ -88,31 +104,30 @@ class DietsCubit extends Cubit<DietsState> {
final dietPagination = await feedRepository.getDiets(
page: currentPage,
query: _query,
types: _types,
duration: _duration,
sorting: _sorting,
types: _types[state.filterState.typeIndex],
duration: _durationValues[state.filterState.durationIndex],
sorting: _sortingValues[state.filterState.sortingIndex],
);
isLoading = false;
emit(
DietsState.loaded(
state.copyWith(
dietsList: [
...(state as DietsStateLoaded).dietsList,
...state.dietsList,
...dietPagination.data,
],
isLoading: isLoading,
errorMessage: null,
),
);
}
} catch (e) {
emit(DietsState.error(errorMessage: e.toString()));
emit(state.copyWith(errorMessage: e.toString()));
}
}
}
Future<void> likeDiet(int id, int index) async {
if (state is! DietsStateLoaded) return;
final currentDiets = (state as DietsStateLoaded).dietsList;
final currentDiets = state.dietsList;
final dietsForModification = [...currentDiets];
final currentDiet = currentDiets[index];
if (currentDiet.wasLikedByMe) {
@@ -121,11 +136,12 @@ class DietsCubit extends Cubit<DietsState> {
wasLikedByMe: false,
);
emit(
DietsState.loaded(
state.copyWith(
dietsList: [
...dietsForModification,
],
isLoading: isLoading,
errorMessage: null,
),
);
} else {
@@ -134,11 +150,12 @@ class DietsCubit extends Cubit<DietsState> {
wasLikedByMe: true,
);
emit(
DietsState.loaded(
state.copyWith(
dietsList: [
...dietsForModification,
],
isLoading: isLoading,
errorMessage: null,
),
);
}
@@ -154,17 +171,18 @@ class DietsCubit extends Cubit<DietsState> {
);
dietsForModification[index] = actualDiet;
emit(
DietsState.loaded(
state.copyWith(
dietsList: [
...dietsForModification,
],
isLoading: isLoading,
errorMessage: null,
),
);
} catch (e) {
log(e.toString());
emit(
DietsState.loaded(
state.copyWith(
dietsList: [
...currentDiets,
],
@@ -177,9 +195,7 @@ class DietsCubit extends Cubit<DietsState> {
}
void _changeDietLikeState(DietLikesState likesState) {
if (state is! DietsStateLoaded) return;
final currentDiets = (state as DietsStateLoaded).dietsList;
final currentDiets = state.dietsList;
final dietsForModification = [...currentDiets];
final currentDiet = currentDiets[likesState.index];
@@ -188,19 +204,18 @@ class DietsCubit extends Cubit<DietsState> {
wasLikedByMe: likesState.wasLikedByMe,
);
emit(
DietsState.loaded(
state.copyWith(
dietsList: [
...dietsForModification,
],
isLoading: isLoading,
errorMessage: null,
),
);
}
void _changeDietFavoriteState(DietFavoriteState favoriteState) {
if (state is! DietsStateLoaded) return;
final currentDiets = (state as DietsStateLoaded).dietsList;
final currentDiets = state.dietsList;
final dietsForModification = [...currentDiets];
final currentDiet = currentDiets[favoriteState.index];
@@ -208,19 +223,18 @@ class DietsCubit extends Cubit<DietsState> {
isFavorite: favoriteState.isFavorite,
);
emit(
DietsState.loaded(
state.copyWith(
dietsList: [
...dietsForModification,
],
isLoading: isLoading,
errorMessage: null,
),
);
}
void _changeDietCommentsState(DietCommentsState commentsState) {
if (state is! DietsStateLoaded) return;
final currentDiets = (state as DietsStateLoaded).dietsList;
final currentDiets = state.dietsList;
final dietsForModification = [...currentDiets];
final currentDiet = currentDiets[commentsState.index];
@@ -228,18 +242,18 @@ class DietsCubit extends Cubit<DietsState> {
totalComments: commentsState.totalComments,
);
emit(
DietsState.loaded(
state.copyWith(
dietsList: [
...dietsForModification,
],
isLoading: isLoading,
errorMessage: null,
),
);
}
Future<void> addDietToFavorite(int id, int index) async {
if (state is! DietsStateLoaded) return;
final currentDiets = (state as DietsStateLoaded).dietsList;
final currentDiets = state.dietsList;
final dietsForModification = [...currentDiets];
final currentDiet = currentDiets[index];
@@ -247,11 +261,12 @@ class DietsCubit extends Cubit<DietsState> {
isFavorite: true,
);
emit(
DietsState.loaded(
state.copyWith(
dietsList: [
...dietsForModification,
],
isLoading: isLoading,
errorMessage: null,
),
);
EasyDebounce.debounce(
@@ -262,21 +277,23 @@ class DietsCubit extends Cubit<DietsState> {
final diet = await dietsRepository.addToFavorite(id);
dietsForModification[index] = diet;
emit(
DietsState.loaded(
state.copyWith(
dietsList: [
...dietsForModification,
],
isLoading: isLoading,
errorMessage: null,
),
);
} catch (e) {
log(e.toString());
emit(
DietsState.loaded(
state.copyWith(
dietsList: [
...currentDiets,
],
isLoading: isLoading,
errorMessage: null,
),
);
}
@@ -285,8 +302,7 @@ class DietsCubit extends Cubit<DietsState> {
}
Future<void> removeDietFromFavorite(int id, int index) async {
if (state is! DietsStateLoaded) return;
final currentDiets = (state as DietsStateLoaded).dietsList;
final currentDiets = state.dietsList;
final dietsForModification = [...currentDiets];
final currentDiet = currentDiets[index];
@@ -294,11 +310,12 @@ class DietsCubit extends Cubit<DietsState> {
isFavorite: false,
);
emit(
DietsState.loaded(
state.copyWith(
dietsList: [
...dietsForModification,
],
isLoading: isLoading,
errorMessage: null,
),
);
EasyDebounce.debounce(
@@ -309,21 +326,23 @@ class DietsCubit extends Cubit<DietsState> {
final diet = await dietsRepository.removeFromFavorite(id);
dietsForModification[index] = diet;
emit(
DietsState.loaded(
state.copyWith(
dietsList: [
...dietsForModification,
],
isLoading: isLoading,
errorMessage: null,
),
);
} catch (e) {
log(e.toString());
emit(
DietsState.loaded(
state.copyWith(
dietsList: [
...currentDiets,
],
isLoading: isLoading,
errorMessage: null,
),
);
}

View File

@@ -4,17 +4,31 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'diets_state.freezed.dart';
@freezed
abstract class DietsState with _$DietsState {
const factory DietsState() = _DietsState;
const factory DietsState.loading() = DietsStateLoading;
const factory DietsState.loaded({
class DietsState with _$DietsState {
const factory DietsState({
required DietsFilterState filterState,
required List<Diet> dietsList,
required bool isLoading,
}) = DietsStateLoaded;
required String? errorMessage,
}) = _DietsState;
const factory DietsState.error({
required String errorMessage,
}) = DietsStateError;
factory DietsState.initial() => DietsState(
filterState: DietsFilterState(
durationIndex: 0,
sortingIndex: 0,
typeIndex: 0,
),
dietsList: [],
isLoading: true,
errorMessage: null,
);
}
@freezed
class DietsFilterState with _$DietsFilterState {
const factory DietsFilterState({
required int sortingIndex,
required int durationIndex,
required int typeIndex,
}) = _DietsFilterState;
}

View File

@@ -16,55 +16,15 @@ final _privateConstructorUsedError = UnsupportedError(
/// @nodoc
mixin _$DietsState {
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(List<Diet> dietsList, bool isLoading) loaded,
required TResult Function(String errorMessage) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(List<Diet> dietsList, bool isLoading)? loaded,
TResult? Function(String errorMessage)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(List<Diet> dietsList, bool isLoading)? loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_DietsState value) $default, {
required TResult Function(DietsStateLoading value) loading,
required TResult Function(DietsStateLoaded value) loaded,
required TResult Function(DietsStateError value) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_DietsState value)? $default, {
TResult? Function(DietsStateLoading value)? loading,
TResult? Function(DietsStateLoaded value)? loaded,
TResult? Function(DietsStateError value)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_DietsState value)? $default, {
TResult Function(DietsStateLoading value)? loading,
TResult Function(DietsStateLoaded value)? loaded,
TResult Function(DietsStateError value)? error,
required TResult orElse(),
}) =>
DietsFilterState get filterState => throw _privateConstructorUsedError;
List<Diet> get dietsList => throw _privateConstructorUsedError;
bool get isLoading => throw _privateConstructorUsedError;
String? get errorMessage => throw _privateConstructorUsedError;
/// Create a copy of DietsState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$DietsStateCopyWith<DietsState> get copyWith =>
throw _privateConstructorUsedError;
}
@@ -73,6 +33,14 @@ abstract class $DietsStateCopyWith<$Res> {
factory $DietsStateCopyWith(
DietsState value, $Res Function(DietsState) then) =
_$DietsStateCopyWithImpl<$Res, DietsState>;
@useResult
$Res call(
{DietsFilterState filterState,
List<Diet> dietsList,
bool isLoading,
String? errorMessage});
$DietsFilterStateCopyWith<$Res> get filterState;
}
/// @nodoc
@@ -87,13 +55,61 @@ class _$DietsStateCopyWithImpl<$Res, $Val extends DietsState>
/// Create a copy of DietsState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? filterState = null,
Object? dietsList = null,
Object? isLoading = null,
Object? errorMessage = freezed,
}) {
return _then(_value.copyWith(
filterState: null == filterState
? _value.filterState
: filterState // ignore: cast_nullable_to_non_nullable
as DietsFilterState,
dietsList: null == dietsList
? _value.dietsList
: dietsList // ignore: cast_nullable_to_non_nullable
as List<Diet>,
isLoading: null == isLoading
? _value.isLoading
: isLoading // ignore: cast_nullable_to_non_nullable
as bool,
errorMessage: freezed == errorMessage
? _value.errorMessage
: errorMessage // ignore: cast_nullable_to_non_nullable
as String?,
) as $Val);
}
/// Create a copy of DietsState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$DietsFilterStateCopyWith<$Res> get filterState {
return $DietsFilterStateCopyWith<$Res>(_value.filterState, (value) {
return _then(_value.copyWith(filterState: value) as $Val);
});
}
}
/// @nodoc
abstract class _$$DietsStateImplCopyWith<$Res> {
abstract class _$$DietsStateImplCopyWith<$Res>
implements $DietsStateCopyWith<$Res> {
factory _$$DietsStateImplCopyWith(
_$DietsStateImpl value, $Res Function(_$DietsStateImpl) then) =
__$$DietsStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call(
{DietsFilterState filterState,
List<Diet> dietsList,
bool isLoading,
String? errorMessage});
@override
$DietsFilterStateCopyWith<$Res> get filterState;
}
/// @nodoc
@@ -106,249 +122,19 @@ class __$$DietsStateImplCopyWithImpl<$Res>
/// Create a copy of DietsState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$DietsStateImpl implements _DietsState {
const _$DietsStateImpl();
@override
String toString() {
return 'DietsState()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$DietsStateImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(List<Diet> dietsList, bool isLoading) loaded,
required TResult Function(String errorMessage) error,
}) {
return $default();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(List<Diet> dietsList, bool isLoading)? loaded,
TResult? Function(String errorMessage)? error,
}) {
return $default?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(List<Diet> dietsList, bool isLoading)? 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(_DietsState value) $default, {
required TResult Function(DietsStateLoading value) loading,
required TResult Function(DietsStateLoaded value) loaded,
required TResult Function(DietsStateError value) error,
}) {
return $default(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_DietsState value)? $default, {
TResult? Function(DietsStateLoading value)? loading,
TResult? Function(DietsStateLoaded value)? loaded,
TResult? Function(DietsStateError value)? error,
}) {
return $default?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_DietsState value)? $default, {
TResult Function(DietsStateLoading value)? loading,
TResult Function(DietsStateLoaded value)? loaded,
TResult Function(DietsStateError value)? error,
required TResult orElse(),
}) {
if ($default != null) {
return $default(this);
}
return orElse();
}
}
abstract class _DietsState implements DietsState {
const factory _DietsState() = _$DietsStateImpl;
}
/// @nodoc
abstract class _$$DietsStateLoadingImplCopyWith<$Res> {
factory _$$DietsStateLoadingImplCopyWith(_$DietsStateLoadingImpl value,
$Res Function(_$DietsStateLoadingImpl) then) =
__$$DietsStateLoadingImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$DietsStateLoadingImplCopyWithImpl<$Res>
extends _$DietsStateCopyWithImpl<$Res, _$DietsStateLoadingImpl>
implements _$$DietsStateLoadingImplCopyWith<$Res> {
__$$DietsStateLoadingImplCopyWithImpl(_$DietsStateLoadingImpl _value,
$Res Function(_$DietsStateLoadingImpl) _then)
: super(_value, _then);
/// Create a copy of DietsState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$DietsStateLoadingImpl implements DietsStateLoading {
const _$DietsStateLoadingImpl();
@override
String toString() {
return 'DietsState.loading()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$DietsStateLoadingImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(List<Diet> dietsList, bool isLoading) loaded,
required TResult Function(String errorMessage) error,
}) {
return loading();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(List<Diet> dietsList, bool isLoading)? loaded,
TResult? Function(String errorMessage)? error,
}) {
return loading?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(List<Diet> dietsList, bool isLoading)? 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(_DietsState value) $default, {
required TResult Function(DietsStateLoading value) loading,
required TResult Function(DietsStateLoaded value) loaded,
required TResult Function(DietsStateError value) error,
}) {
return loading(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_DietsState value)? $default, {
TResult? Function(DietsStateLoading value)? loading,
TResult? Function(DietsStateLoaded value)? loaded,
TResult? Function(DietsStateError value)? error,
}) {
return loading?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_DietsState value)? $default, {
TResult Function(DietsStateLoading value)? loading,
TResult Function(DietsStateLoaded value)? loaded,
TResult Function(DietsStateError value)? error,
required TResult orElse(),
}) {
if (loading != null) {
return loading(this);
}
return orElse();
}
}
abstract class DietsStateLoading implements DietsState {
const factory DietsStateLoading() = _$DietsStateLoadingImpl;
}
/// @nodoc
abstract class _$$DietsStateLoadedImplCopyWith<$Res> {
factory _$$DietsStateLoadedImplCopyWith(_$DietsStateLoadedImpl value,
$Res Function(_$DietsStateLoadedImpl) then) =
__$$DietsStateLoadedImplCopyWithImpl<$Res>;
@useResult
$Res call({List<Diet> dietsList, bool isLoading});
}
/// @nodoc
class __$$DietsStateLoadedImplCopyWithImpl<$Res>
extends _$DietsStateCopyWithImpl<$Res, _$DietsStateLoadedImpl>
implements _$$DietsStateLoadedImplCopyWith<$Res> {
__$$DietsStateLoadedImplCopyWithImpl(_$DietsStateLoadedImpl _value,
$Res Function(_$DietsStateLoadedImpl) _then)
: super(_value, _then);
/// Create a copy of DietsState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? filterState = null,
Object? dietsList = null,
Object? isLoading = null,
Object? errorMessage = freezed,
}) {
return _then(_$DietsStateLoadedImpl(
return _then(_$DietsStateImpl(
filterState: null == filterState
? _value.filterState
: filterState // ignore: cast_nullable_to_non_nullable
as DietsFilterState,
dietsList: null == dietsList
? _value._dietsList
: dietsList // ignore: cast_nullable_to_non_nullable
@@ -357,17 +143,26 @@ class __$$DietsStateLoadedImplCopyWithImpl<$Res>
? _value.isLoading
: isLoading // ignore: cast_nullable_to_non_nullable
as bool,
errorMessage: freezed == errorMessage
? _value.errorMessage
: errorMessage // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
/// @nodoc
class _$DietsStateLoadedImpl implements DietsStateLoaded {
const _$DietsStateLoadedImpl(
{required final List<Diet> dietsList, required this.isLoading})
class _$DietsStateImpl implements _DietsState {
const _$DietsStateImpl(
{required this.filterState,
required final List<Diet> dietsList,
required this.isLoading,
required this.errorMessage})
: _dietsList = dietsList;
@override
final DietsFilterState filterState;
final List<Diet> _dietsList;
@override
List<Diet> get dietsList {
@@ -378,277 +173,233 @@ class _$DietsStateLoadedImpl implements DietsStateLoaded {
@override
final bool isLoading;
@override
final String? errorMessage;
@override
String toString() {
return 'DietsState.loaded(dietsList: $dietsList, isLoading: $isLoading)';
return 'DietsState(filterState: $filterState, dietsList: $dietsList, isLoading: $isLoading, errorMessage: $errorMessage)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$DietsStateLoadedImpl &&
other is _$DietsStateImpl &&
(identical(other.filterState, filterState) ||
other.filterState == filterState) &&
const DeepCollectionEquality()
.equals(other._dietsList, _dietsList) &&
(identical(other.isLoading, isLoading) ||
other.isLoading == isLoading));
other.isLoading == isLoading) &&
(identical(other.errorMessage, errorMessage) ||
other.errorMessage == errorMessage));
}
@override
int get hashCode => Object.hash(
runtimeType, const DeepCollectionEquality().hash(_dietsList), isLoading);
int get hashCode => Object.hash(runtimeType, filterState,
const DeepCollectionEquality().hash(_dietsList), isLoading, errorMessage);
/// Create a copy of DietsState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$DietsStateLoadedImplCopyWith<_$DietsStateLoadedImpl> get copyWith =>
__$$DietsStateLoadedImplCopyWithImpl<_$DietsStateLoadedImpl>(
this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(List<Diet> dietsList, bool isLoading) loaded,
required TResult Function(String errorMessage) error,
}) {
return loaded(dietsList, isLoading);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(List<Diet> dietsList, bool isLoading)? loaded,
TResult? Function(String errorMessage)? error,
}) {
return loaded?.call(dietsList, isLoading);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(List<Diet> dietsList, bool isLoading)? loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded(dietsList, isLoading);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_DietsState value) $default, {
required TResult Function(DietsStateLoading value) loading,
required TResult Function(DietsStateLoaded value) loaded,
required TResult Function(DietsStateError value) error,
}) {
return loaded(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_DietsState value)? $default, {
TResult? Function(DietsStateLoading value)? loading,
TResult? Function(DietsStateLoaded value)? loaded,
TResult? Function(DietsStateError value)? error,
}) {
return loaded?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_DietsState value)? $default, {
TResult Function(DietsStateLoading value)? loading,
TResult Function(DietsStateLoaded value)? loaded,
TResult Function(DietsStateError value)? error,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded(this);
}
return orElse();
}
_$$DietsStateImplCopyWith<_$DietsStateImpl> get copyWith =>
__$$DietsStateImplCopyWithImpl<_$DietsStateImpl>(this, _$identity);
}
abstract class DietsStateLoaded implements DietsState {
const factory DietsStateLoaded(
{required final List<Diet> dietsList,
required final bool isLoading}) = _$DietsStateLoadedImpl;
abstract class _DietsState implements DietsState {
const factory _DietsState(
{required final DietsFilterState filterState,
required final List<Diet> dietsList,
required final bool isLoading,
required final String? errorMessage}) = _$DietsStateImpl;
@override
DietsFilterState get filterState;
@override
List<Diet> get dietsList;
@override
bool get isLoading;
@override
String? get errorMessage;
/// Create a copy of DietsState
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$DietsStateLoadedImplCopyWith<_$DietsStateLoadedImpl> get copyWith =>
_$$DietsStateImplCopyWith<_$DietsStateImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$DietsStateErrorImplCopyWith<$Res> {
factory _$$DietsStateErrorImplCopyWith(_$DietsStateErrorImpl value,
$Res Function(_$DietsStateErrorImpl) then) =
__$$DietsStateErrorImplCopyWithImpl<$Res>;
@useResult
$Res call({String errorMessage});
mixin _$DietsFilterState {
int get sortingIndex => throw _privateConstructorUsedError;
int get durationIndex => throw _privateConstructorUsedError;
int get typeIndex => throw _privateConstructorUsedError;
/// Create a copy of DietsFilterState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$DietsFilterStateCopyWith<DietsFilterState> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
class __$$DietsStateErrorImplCopyWithImpl<$Res>
extends _$DietsStateCopyWithImpl<$Res, _$DietsStateErrorImpl>
implements _$$DietsStateErrorImplCopyWith<$Res> {
__$$DietsStateErrorImplCopyWithImpl(
_$DietsStateErrorImpl _value, $Res Function(_$DietsStateErrorImpl) _then)
: super(_value, _then);
abstract class $DietsFilterStateCopyWith<$Res> {
factory $DietsFilterStateCopyWith(
DietsFilterState value, $Res Function(DietsFilterState) then) =
_$DietsFilterStateCopyWithImpl<$Res, DietsFilterState>;
@useResult
$Res call({int sortingIndex, int durationIndex, int typeIndex});
}
/// Create a copy of DietsState
/// @nodoc
class _$DietsFilterStateCopyWithImpl<$Res, $Val extends DietsFilterState>
implements $DietsFilterStateCopyWith<$Res> {
_$DietsFilterStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of DietsFilterState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? errorMessage = null,
Object? sortingIndex = null,
Object? durationIndex = null,
Object? typeIndex = null,
}) {
return _then(_$DietsStateErrorImpl(
errorMessage: null == errorMessage
? _value.errorMessage
: errorMessage // ignore: cast_nullable_to_non_nullable
as String,
return _then(_value.copyWith(
sortingIndex: null == sortingIndex
? _value.sortingIndex
: sortingIndex // ignore: cast_nullable_to_non_nullable
as int,
durationIndex: null == durationIndex
? _value.durationIndex
: durationIndex // ignore: cast_nullable_to_non_nullable
as int,
typeIndex: null == typeIndex
? _value.typeIndex
: typeIndex // ignore: cast_nullable_to_non_nullable
as int,
) as $Val);
}
}
/// @nodoc
abstract class _$$DietsFilterStateImplCopyWith<$Res>
implements $DietsFilterStateCopyWith<$Res> {
factory _$$DietsFilterStateImplCopyWith(_$DietsFilterStateImpl value,
$Res Function(_$DietsFilterStateImpl) then) =
__$$DietsFilterStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({int sortingIndex, int durationIndex, int typeIndex});
}
/// @nodoc
class __$$DietsFilterStateImplCopyWithImpl<$Res>
extends _$DietsFilterStateCopyWithImpl<$Res, _$DietsFilterStateImpl>
implements _$$DietsFilterStateImplCopyWith<$Res> {
__$$DietsFilterStateImplCopyWithImpl(_$DietsFilterStateImpl _value,
$Res Function(_$DietsFilterStateImpl) _then)
: super(_value, _then);
/// Create a copy of DietsFilterState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? sortingIndex = null,
Object? durationIndex = null,
Object? typeIndex = null,
}) {
return _then(_$DietsFilterStateImpl(
sortingIndex: null == sortingIndex
? _value.sortingIndex
: sortingIndex // ignore: cast_nullable_to_non_nullable
as int,
durationIndex: null == durationIndex
? _value.durationIndex
: durationIndex // ignore: cast_nullable_to_non_nullable
as int,
typeIndex: null == typeIndex
? _value.typeIndex
: typeIndex // ignore: cast_nullable_to_non_nullable
as int,
));
}
}
/// @nodoc
class _$DietsStateErrorImpl implements DietsStateError {
const _$DietsStateErrorImpl({required this.errorMessage});
class _$DietsFilterStateImpl implements _DietsFilterState {
const _$DietsFilterStateImpl(
{required this.sortingIndex,
required this.durationIndex,
required this.typeIndex});
@override
final String errorMessage;
final int sortingIndex;
@override
final int durationIndex;
@override
final int typeIndex;
@override
String toString() {
return 'DietsState.error(errorMessage: $errorMessage)';
return 'DietsFilterState(sortingIndex: $sortingIndex, durationIndex: $durationIndex, typeIndex: $typeIndex)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$DietsStateErrorImpl &&
(identical(other.errorMessage, errorMessage) ||
other.errorMessage == errorMessage));
other is _$DietsFilterStateImpl &&
(identical(other.sortingIndex, sortingIndex) ||
other.sortingIndex == sortingIndex) &&
(identical(other.durationIndex, durationIndex) ||
other.durationIndex == durationIndex) &&
(identical(other.typeIndex, typeIndex) ||
other.typeIndex == typeIndex));
}
@override
int get hashCode => Object.hash(runtimeType, errorMessage);
int get hashCode =>
Object.hash(runtimeType, sortingIndex, durationIndex, typeIndex);
/// Create a copy of DietsState
/// Create a copy of DietsFilterState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$DietsStateErrorImplCopyWith<_$DietsStateErrorImpl> get copyWith =>
__$$DietsStateErrorImplCopyWithImpl<_$DietsStateErrorImpl>(
_$$DietsFilterStateImplCopyWith<_$DietsFilterStateImpl> get copyWith =>
__$$DietsFilterStateImplCopyWithImpl<_$DietsFilterStateImpl>(
this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(List<Diet> dietsList, bool isLoading) 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(List<Diet> dietsList, bool isLoading)? 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(List<Diet> dietsList, bool isLoading)? 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(_DietsState value) $default, {
required TResult Function(DietsStateLoading value) loading,
required TResult Function(DietsStateLoaded value) loaded,
required TResult Function(DietsStateError value) error,
}) {
return error(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_DietsState value)? $default, {
TResult? Function(DietsStateLoading value)? loading,
TResult? Function(DietsStateLoaded value)? loaded,
TResult? Function(DietsStateError value)? error,
}) {
return error?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_DietsState value)? $default, {
TResult Function(DietsStateLoading value)? loading,
TResult Function(DietsStateLoaded value)? loaded,
TResult Function(DietsStateError value)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(this);
}
return orElse();
}
}
abstract class DietsStateError implements DietsState {
const factory DietsStateError({required final String errorMessage}) =
_$DietsStateErrorImpl;
abstract class _DietsFilterState implements DietsFilterState {
const factory _DietsFilterState(
{required final int sortingIndex,
required final int durationIndex,
required final int typeIndex}) = _$DietsFilterStateImpl;
String get errorMessage;
@override
int get sortingIndex;
@override
int get durationIndex;
@override
int get typeIndex;
/// Create a copy of DietsState
/// Create a copy of DietsFilterState
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$DietsStateErrorImplCopyWith<_$DietsStateErrorImpl> get copyWith =>
_$$DietsFilterStateImplCopyWith<_$DietsFilterStateImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@@ -1,4 +1,5 @@
import 'package:easy_debounce/easy_debounce.dart';
import 'package:eatvio_app/features/create_diet/presentation/create_diet_screen.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_state.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart';
@@ -284,9 +285,33 @@ class _FeedScreenState extends State<FeedScreen> {
onRefresh: () => dietsCubit.loadDiets(),
child: BlocBuilder<DietsCubit, DietsState>(
builder: (BuildContext context, DietsState state) {
if (state is DietsStateLoaded) {
if (state.isLoading) {
return Scaffold(
backgroundColor: Colors.grey.shade200,
body: Center(
child: SizedBox(
height: 32,
width: 32,
child: RiveAnimation.asset(
'assets/rive_animations/loading.riv',
),
),
),
);
} else if (state.errorMessage != null) {
return Scaffold(
backgroundColor: Colors.grey.shade200,
body: Padding(
padding: const EdgeInsets.all(16),
child: Center(
child: Text(state.errorMessage ?? ''),
),
),
);
} else {
return Stack(
children: [
SizedBox.expand(),
ListView.separated(
padding: EdgeInsets.symmetric(vertical: 8),
shrinkWrap: true,
@@ -303,34 +328,13 @@ class _FeedScreenState extends State<FeedScreen> {
right: 0,
bottom: 74,
child: FilterBadge(
filterBottomSheet: DietFilterBottomSheet(),
filterBottomSheet: DietFilterBottomSheet(
dietsCubit: dietsCubit,
),
),
),
],
);
} else if (state is DietsStateError) {
return Scaffold(
backgroundColor: Colors.grey.shade200,
body: Padding(
padding: const EdgeInsets.all(16),
child: Center(
child: Text(state.errorMessage),
),
),
);
} else {
return Scaffold(
backgroundColor: Colors.grey.shade200,
body: Center(
child: SizedBox(
height: 32,
width: 32,
child: RiveAnimation.asset(
'assets/rive_animations/loading.riv',
),
),
),
);
}
},
),
@@ -472,12 +476,12 @@ class _FeedScreenState extends State<FeedScreen> {
_addItemButton() {
return InkWell(
onTap: () {
switch (_selectedChipIndex) {
case 1:
GoRouter.of(context).pushNamed('recipeCreateScreen');
switch (_selectedChipIndex) {
case 2:
GoRouter.of(context).pushNamed(CreateDietScreen.name);
break;
default:
GoRouter.of(context).pushNamed('blogPostCreateScreen');
GoRouter.of(context).pushNamed('blogPostCreateScreen');
}
},
borderRadius: BorderRadius.circular(64),

View File

@@ -2,11 +2,27 @@ import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:flutter/material.dart';
class ChoiceChipWidget extends StatelessWidget {
const ChoiceChipWidget({super.key, required this.chipsLabelList, required this.index, required this.selectedChipIndex, required this.onSelected});
const ChoiceChipWidget({
super.key,
required this.chipsLabelList,
required this.index,
required this.selectedChipIndex,
required this.onSelected,
this.padding,
this.fontSize,
this.activeColor,
this.inactiveColor,
this.fontWeight,
});
final List<String> chipsLabelList;
final int index;
final int selectedChipIndex;
final double? fontSize;
final Color? activeColor;
final Color? inactiveColor;
final FontWeight? fontWeight;
final void Function(bool) onSelected;
final EdgeInsetsGeometry? padding;
@override
Widget build(BuildContext context) {
return ChoiceChip(
@@ -17,12 +33,12 @@ class ChoiceChipWidget extends StatelessWidget {
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
padding: padding ?? const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
label: Text(chipsLabelList[index]),
labelStyle: TextStyle(
color: index == selectedChipIndex ? Colors.white : appTheme.gray600,
fontWeight: FontWeight.w500,
fontSize: 12,
color: index == selectedChipIndex ? activeColor ?? Colors.white : inactiveColor ?? appTheme.gray600,
fontWeight: fontWeight ?? FontWeight.w500,
fontSize: fontSize ?? 12,
),
selected: selectedChipIndex == index,
backgroundColor: appTheme.gray100,

View File

@@ -1,5 +1,7 @@
import 'package:eatvio_app/core/widgets/bottom_sheet_handler_bar.dart';
import 'package:eatvio_app/core/widgets/custom_divider.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart';
import 'package:eatvio_app/features/feed/presentation/widgets/duration_choice_filter_widget.dart';
import 'package:eatvio_app/features/feed/presentation/widgets/sorting_drop_down_filter.dart';
import 'package:eatvio_app/features/feed/presentation/widgets/type_choice_filter_widget.dart';
import 'package:eatvio_app/generated/l10n.dart';
@@ -8,8 +10,8 @@ import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:flutter/material.dart';
class DietFilterBottomSheet extends StatelessWidget {
const DietFilterBottomSheet({super.key});
const DietFilterBottomSheet({super.key, required this.dietsCubit});
final DietsCubit dietsCubit;
@override
Widget build(BuildContext context) {
final s = S.of(context);
@@ -29,7 +31,7 @@ class DietFilterBottomSheet extends StatelessWidget {
style: TextStyles.textMSemibold.copyWith(color: appTheme.black),
),
SizedBox(height: 12),
SortingDropDownFilter(),
SortingDropDownFilter(cubit: dietsCubit,),
SizedBox(
height: 16,
),
@@ -44,7 +46,7 @@ class DietFilterBottomSheet extends StatelessWidget {
SizedBox(
height: 12,
),
TypeChoiceFilterWidget(),
TypeChoiceFilterWidget(cubit: dietsCubit,),
SizedBox(
height: 16,
),
@@ -59,7 +61,7 @@ class DietFilterBottomSheet extends StatelessWidget {
SizedBox(
height: 12,
),
TypeChoiceFilterWidget(),
DurationChoiceFilterWidget(cubit: dietsCubit,),
SizedBox(
height: 24,
),

View File

@@ -1,84 +1,85 @@
import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/core/utils/localization_utils.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_state.dart';
import 'package:eatvio_app/features/feed/presentation/widgets/choice_chip_widget.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class DurationChoiceFilterWidget extends StatefulWidget {
const DurationChoiceFilterWidget({super.key});
const DurationChoiceFilterWidget({super.key, required this.cubit});
final DietsCubit cubit;
@override
State<DurationChoiceFilterWidget> createState() => _DurationChoiceFilterWidgetState();
}
class _DurationChoiceFilterWidgetState extends State<DurationChoiceFilterWidget> {
final List<String> chipsLabelList = [];
int selectedChipIndex = 0;
@override
void didChangeDependencies() {
final s = S.of(context);
super.didChangeDependencies();
if (chipsLabelList.isEmpty) {
chipsLabelList.add(s.all);
chipsLabelList.add('7 ${getDayForm(7, s)}');
chipsLabelList.add('14 ${getDayForm(14, s)}');
chipsLabelList.add('21 ${getDayForm(21, s)}');
durationValues.forEach((element) {
chipsLabelList.add('${element} ${getDayForm(element, s)}');
});
}
}
@override
Widget build(BuildContext context) {
return Wrap(
children: [
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 0,
selectedChipIndex: selectedChipIndex,
onSelected: (selectedValue) {
setState(() {
selectedChipIndex = 0;
});
},
),
SizedBox(
width: 8,
),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 1,
selectedChipIndex: selectedChipIndex,
onSelected: (selectedValue) {
setState(() {
selectedChipIndex = 1;
});
},
),
SizedBox(
width: 8,
),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 2,
selectedChipIndex: selectedChipIndex,
onSelected: (selectedValue) {
setState(() {
selectedChipIndex = 2;
});
},
),
SizedBox(
width: 8,
),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 3,
selectedChipIndex: selectedChipIndex,
onSelected: (selectedValue) {
setState(() {
selectedChipIndex = 3;
});
},
),
],
return BlocBuilder<DietsCubit, DietsState>(
bloc: widget.cubit,
builder: (context, state) {
return Wrap(
children: [
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 0,
selectedChipIndex: state.filterState.durationIndex,
onSelected: (selectedValue) {
widget.cubit.changeDurationFilter(0);
},
),
SizedBox(
width: 8,
),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 1,
selectedChipIndex: state.filterState.durationIndex,
onSelected: (selectedValue) {
widget.cubit.changeDurationFilter(1);
},
),
SizedBox(
width: 8,
),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 2,
selectedChipIndex: state.filterState.durationIndex,
onSelected: (selectedValue) {
widget.cubit.changeDurationFilter(2);
},
),
SizedBox(
width: 8,
),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 3,
selectedChipIndex: state.filterState.durationIndex,
onSelected: (selectedValue) {
widget.cubit.changeDurationFilter(3);
},
),
],
);
},
);
}
}

View File

@@ -1,20 +1,22 @@
import 'package:eatvio_app/core/theme/custom_text_style.dart';
import 'package:eatvio_app/core/widgets/custom_drop_down_button.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_state.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class SortingDropDownFilter extends StatefulWidget {
const SortingDropDownFilter({super.key});
const SortingDropDownFilter({super.key, required this.cubit});
final DietsCubit cubit;
@override
State<SortingDropDownFilter> createState() => _SortingDropDownFilterState();
}
class _SortingDropDownFilterState extends State<SortingDropDownFilter> {
final List<String> sortingTypes = [];
int selectedIndex = 0;
@override
void didChangeDependencies() {
super.didChangeDependencies();
@@ -30,40 +32,28 @@ class _SortingDropDownFilterState extends State<SortingDropDownFilter> {
@override
Widget build(BuildContext context) {
return DropdownButtonFormField(
icon: SvgPicture.asset(
'assets/icons/arrow_down2.svg',
width: 12,
height: 8,
),
borderRadius: BorderRadius.circular(20),
dropdownColor: appTheme.lightGray0,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(20)),
borderSide: BorderSide.none,
),
fillColor: appTheme.lightGray0,
filled: true,
),
value: sortingTypes[selectedIndex],
items: sortingTypes
.mapIndexed(
(index, value) => DropdownMenuItem(
child: Text(
sortingTypes[index],
style: TextStyles.textMMedium.copyWith(color: appTheme.black),
),
value: sortingTypes[index],
),
)
.toList(),
onChanged: (value) {
if (value != null) {
setState(() {
selectedIndex = sortingTypes.indexOf(value);
});
}
return BlocBuilder<DietsCubit, DietsState>(
bloc: widget.cubit,
builder: (context, state) {
return CustomDropDownButton(
items: sortingTypes
.mapIndexed(
(index, value) => DropdownMenuItem(
child: Text(
sortingTypes[index],
style: TextStyles.textMMedium.copyWith(color: appTheme.black),
),
value: sortingTypes[index],
),
)
.toList(),
value: sortingTypes[state.filterState.sortingIndex],
onChanged: (value) {
if (value != null) {
widget.cubit.changeSortingType(sortingTypes.indexOf(value));
}
},
);
},
);
}

View File

@@ -1,17 +1,19 @@
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_state.dart';
import 'package:eatvio_app/features/feed/presentation/widgets/choice_chip_widget.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class TypeChoiceFilterWidget extends StatefulWidget {
const TypeChoiceFilterWidget({super.key});
const TypeChoiceFilterWidget({super.key, required this.cubit});
final DietsCubit cubit;
@override
State<TypeChoiceFilterWidget> createState() => _TypeChoiceFilterWidgetState();
}
class _TypeChoiceFilterWidgetState extends State<TypeChoiceFilterWidget> {
final List<String> chipsLabelList = [];
int selectedChipIndex = 0;
@override
void didChangeDependencies() {
final s = S.of(context);
@@ -19,79 +21,74 @@ class _TypeChoiceFilterWidgetState extends State<TypeChoiceFilterWidget> {
if (chipsLabelList.isEmpty) {
chipsLabelList.add(s.all);
chipsLabelList.add(s.vegan_type);
chipsLabelList.add(s.alko_type);
chipsLabelList.add(s.corb_type);
chipsLabelList.add(s.light_type);
chipsLabelList.add(s.carb_type);
chipsLabelList.add(s.meat_type);
}
}
@override
Widget build(BuildContext context) {
return Wrap(
children: [
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 0,
selectedChipIndex: selectedChipIndex,
onSelected: (selectedValue) {
setState(() {
selectedChipIndex = 0;
});
},
),
SizedBox(
width: 8,
),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 1,
selectedChipIndex: selectedChipIndex,
onSelected: (selectedValue) {
setState(() {
selectedChipIndex = 1;
});
},
),
SizedBox(
width: 8,
),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 2,
selectedChipIndex: selectedChipIndex,
onSelected: (selectedValue) {
setState(() {
selectedChipIndex = 2;
});
},
),
SizedBox(
width: 8,
),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 3,
selectedChipIndex: selectedChipIndex,
onSelected: (selectedValue) {
setState(() {
selectedChipIndex = 3;
});
},
),
SizedBox(
width: 8,
),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 4,
selectedChipIndex: selectedChipIndex,
onSelected: (selectedValue) {
setState(() {
selectedChipIndex = 4;
});
},
),
],
return BlocBuilder<DietsCubit, DietsState>(
bloc: widget.cubit,
builder: (context, state) {
return Wrap(
children: [
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 0,
selectedChipIndex: state.filterState.typeIndex,
onSelected: (selectedValue) {
widget.cubit.changeTypeFilter(0);
},
),
SizedBox(
width: 8,
),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 1,
selectedChipIndex: state.filterState.typeIndex,
onSelected: (selectedValue) {
widget.cubit.changeTypeFilter(1);
},
),
SizedBox(
width: 8,
),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 2,
selectedChipIndex: state.filterState.typeIndex,
onSelected: (selectedValue) {
widget.cubit.changeTypeFilter(2);
},
),
SizedBox(
width: 8,
),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 3,
selectedChipIndex: state.filterState.typeIndex,
onSelected: (selectedValue) {
widget.cubit.changeTypeFilter(3);
},
),
SizedBox(
width: 8,
),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
index: 4,
selectedChipIndex: state.filterState.typeIndex,
onSelected: (selectedValue) {
widget.cubit.changeTypeFilter(4);
},
),
],
);
},
);
}
}