diff --git a/kitchenowl/lib/cubits/household_add_update/household_settings_items_cubit.dart b/kitchenowl/lib/cubits/household_add_update/household_settings_items_cubit.dart index b4438aec..0a566794 100644 --- a/kitchenowl/lib/cubits/household_add_update/household_settings_items_cubit.dart +++ b/kitchenowl/lib/cubits/household_add_update/household_settings_items_cubit.dart @@ -1,5 +1,6 @@ import 'package:equatable/equatable.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:kitchenowl/enums/shoppinglist_sorting.dart'; import 'package:kitchenowl/models/category.dart'; import 'package:kitchenowl/models/household.dart'; import 'package:kitchenowl/models/item.dart'; @@ -21,27 +22,60 @@ class HouseholdSettingsItemsCubit extends Cubit { TransactionCategoriesGet(household: household), ); if (await items != null) { + ShoppinglistSorting.sortShoppinglistItems(state.items, state.sorting); emit(HouseholdSettingsItemsState( items: (await items)!, categories: await categories, )); } } + + void incrementSorting() { + setSorting(ShoppinglistSorting + .values[(state.sorting.index + 1) % ShoppinglistSorting.values.length]); + } + + void setSorting(ShoppinglistSorting sorting) { + if (state is! LoadingHouseholdSettingsItemsState && + state.items != const []) { + ShoppinglistSorting.sortShoppinglistItems(state.items, sorting); + } + emit(state.copyWith(sorting: sorting)); + } } class HouseholdSettingsItemsState extends Equatable { final List items; final List categories; + final ShoppinglistSorting sorting; const HouseholdSettingsItemsState({ this.items = const [], this.categories = const [], + this.sorting = ShoppinglistSorting.alphabetical, }); + HouseholdSettingsItemsState copyWith({ + ShoppinglistSorting? sorting, + }) => + HouseholdSettingsItemsState( + items: this.items, + categories: this.categories, + sorting: sorting ?? this.sorting, + ); + @override - List get props => [items, categories]; + List get props => [items, categories, sorting]; } class LoadingHouseholdSettingsItemsState extends HouseholdSettingsItemsState { - const LoadingHouseholdSettingsItemsState(); + const LoadingHouseholdSettingsItemsState({super.sorting}); + + @override + HouseholdSettingsItemsState copyWith({ + ShoppinglistSorting? sorting, + }) => + LoadingHouseholdSettingsItemsState( + sorting: sorting ?? this.sorting, + ); } diff --git a/kitchenowl/lib/enums/shoppinglist_sorting.dart b/kitchenowl/lib/enums/shoppinglist_sorting.dart index 5967beae..d7ab665d 100644 --- a/kitchenowl/lib/enums/shoppinglist_sorting.dart +++ b/kitchenowl/lib/enums/shoppinglist_sorting.dart @@ -6,7 +6,7 @@ enum ShoppinglistSorting { category; static void sortShoppinglistItems( - List shoppinglist, + List shoppinglist, ShoppinglistSorting sorting, ) { if (shoppinglist.isEmpty) return; diff --git a/kitchenowl/lib/pages/settings_household/household_settings_items_page.dart b/kitchenowl/lib/pages/settings_household/household_settings_items_page.dart index 4e1d976a..2337bcbd 100644 --- a/kitchenowl/lib/pages/settings_household/household_settings_items_page.dart +++ b/kitchenowl/lib/pages/settings_household/household_settings_items_page.dart @@ -1,8 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:kitchenowl/cubits/household_add_update/household_settings_items_cubit.dart'; +import 'package:kitchenowl/enums/shoppinglist_sorting.dart'; import 'package:kitchenowl/kitchenowl.dart'; +import 'package:kitchenowl/models/category.dart'; import 'package:kitchenowl/models/household.dart'; +import 'package:kitchenowl/models/item.dart'; +import 'package:kitchenowl/widgets/home_page/sliver_category_item_grid_list.dart'; class HouseholdSettingsItemsPage extends StatefulWidget { final Household household; @@ -36,26 +40,75 @@ class _HouseholdSettingsItemsPageState @override Widget build(BuildContext context) { return Scaffold( - body: CustomScrollView( - slivers: [ - SliverAppBar( - title: Text(AppLocalizations.of(context)!.items), - floating: true, - ), + body: BlocBuilder( - bloc: cubit, - builder: (context, state) { - return SliverItemGridList( + bloc: cubit, + builder: (context, state) { + dynamic body; + + if (state.sorting != ShoppinglistSorting.category || + state is LoadingHouseholdSettingsItemsState && + state.items.isEmpty) { + body = SliverItemGridList( + isLoading: state is LoadingHouseholdSettingsItemsState, + items: state.items, + household: widget.household, + categories: state.categories, + onRefresh: cubit.refresh, + allRaised: true, + ); + } else { + List grids = []; + // add items from categories + for (int i = 0; i < state.categories.length + 1; i++) { + Category? category = + i < state.categories.length ? state.categories[i] : null; + final List items = + state.items.where((e) => e.category == category).toList(); + if (items.isEmpty) continue; + + grids.add(SliverCategoryItemGridList( + name: category?.name ?? + AppLocalizations.of(context)!.uncategorized, isLoading: state is LoadingHouseholdSettingsItemsState, - items: state.items, household: widget.household, categories: state.categories, onRefresh: cubit.refresh, allRaised: true, - ); - }, - ), - ], + items: items, + )); + } + body = grids; + } + + return CustomScrollView( + slivers: [ + SliverAppBar( + title: Text(AppLocalizations.of(context)!.items), + floating: true, + ), + SliverToBoxAdapter( + child: LeftRightWrap( + left: const SizedBox(), + right: Padding( + padding: const EdgeInsets.only(right: 16, bottom: 6), + child: TrailingIconTextButton( + onPressed: cubit.incrementSorting, + text: state.sorting == ShoppinglistSorting.alphabetical + ? AppLocalizations.of(context)!.sortingAlphabetical + : state.sorting == ShoppinglistSorting.algorithmic + ? AppLocalizations.of(context)!.sortingAlgorithmic + : AppLocalizations.of(context)!.category, + icon: const Icon(Icons.sort), + ), + ), + ), + ), + if (body is List) ...body, + if (body is! List) body, + ], + ); + }, ), ); } diff --git a/kitchenowl/lib/widgets/home_page/sliver_category_item_grid_list.dart b/kitchenowl/lib/widgets/home_page/sliver_category_item_grid_list.dart index ee8e9d2f..2b522eed 100644 --- a/kitchenowl/lib/widgets/home_page/sliver_category_item_grid_list.dart +++ b/kitchenowl/lib/widgets/home_page/sliver_category_item_grid_list.dart @@ -1,8 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:kitchenowl/cubits/household_cubit.dart'; import 'package:kitchenowl/kitchenowl.dart'; import 'package:kitchenowl/models/category.dart'; +import 'package:kitchenowl/models/household.dart'; import 'package:kitchenowl/models/item.dart'; import 'package:kitchenowl/models/shoppinglist.dart'; import 'package:sliver_tools/sliver_tools.dart'; @@ -18,8 +17,11 @@ class SliverCategoryItemGridList extends StatefulWidget { final List items; final List? categories; // forwarded to item page on long press final ShoppingList? shoppingList; // forwarded to item page on long press + final Household? + household; // forwarded to item page on long press for offline functionality final bool Function(T)? selected; final bool isLoading; + final bool? allRaised; const SliverCategoryItemGridList({ super.key, @@ -29,10 +31,12 @@ class SliverCategoryItemGridList extends StatefulWidget { this.onPressed, this.onLongPressed, this.items = const [], + this.household, this.categories, this.shoppingList, this.selected, this.isLoading = false, + this.allRaised, }); @override @@ -90,11 +94,11 @@ class _SliverCategoryItemGridListState onLongPressed: widget.onLongPressed, items: widget.items, categories: widget.categories, - household: - BlocProvider.of(context).state.household, + household: widget.household, shoppingList: widget.shoppingList, selected: widget.selected, isLoading: widget.isLoading, + allRaised: widget.allRaised, ), ), ],