Skip to content

Commit

Permalink
Update and enhance settings
Browse files Browse the repository at this point in the history
  • Loading branch information
TomBursch committed Feb 1, 2024
1 parent 64fe83d commit 1569638
Show file tree
Hide file tree
Showing 21 changed files with 1,477 additions and 1,147 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:kitchenowl/models/category.dart';
import 'package:kitchenowl/models/household.dart';
import 'package:kitchenowl/models/item.dart';
import 'package:kitchenowl/services/api/api_service.dart';
import 'package:kitchenowl/services/transaction_handler.dart';
import 'package:kitchenowl/services/transactions/category.dart';

class HouseholdSettingsItemsCubit extends Cubit<HouseholdSettingsItemsState> {
final Household household;

HouseholdSettingsItemsCubit(this.household)
: super(const LoadingHouseholdSettingsItemsState()) {
refresh();
}

Future<void> refresh() async {
final items = ApiService.getInstance().getAllItems(household);
final categories = TransactionHandler.getInstance().runTransaction(
TransactionCategoriesGet(household: household),
);
if (await items != null) {
emit(HouseholdSettingsItemsState(
items: (await items)!,
categories: await categories,
));
}
}
}

class HouseholdSettingsItemsState extends Equatable {
final List<Item> items;
final List<Category> categories;

const HouseholdSettingsItemsState({
this.items = const [],
this.categories = const [],
});

@override
List<Object?> get props => [items, categories];
}

class LoadingHouseholdSettingsItemsState extends HouseholdSettingsItemsState {
const LoadingHouseholdSettingsItemsState();
}
12 changes: 12 additions & 0 deletions kitchenowl/lib/helpers/build_context_extension.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

extension ReadOrNull on BuildContext {
T? readOrNull<T>() {
try {
return read<T>();
} on ProviderNotFoundException catch (_) {
return null;
}
}
}
1 change: 1 addition & 0 deletions kitchenowl/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,7 @@
"loginTo": "Login to",
"logout": "Logout",
"logoutName": "Logout {name}",
"longPressToReorder": "Long press to reorder",
"markAsPaid": "Mark as paid",
"mealPlanner": "Meal planner",
"member": "Member",
Expand Down
207 changes: 113 additions & 94 deletions kitchenowl/lib/pages/household_add_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:kitchenowl/models/user.dart';
import 'package:kitchenowl/pages/user_search_page.dart';
import 'package:kitchenowl/widgets/settings_household/sliver_household_feature_settings.dart';
import 'package:kitchenowl/widgets/user_list_tile.dart';
import 'package:sliver_tools/sliver_tools.dart';

class HouseholdAddPage extends StatefulWidget {
final String? locale;
Expand Down Expand Up @@ -50,120 +51,138 @@ class _HouseholdAddPageState extends State<HouseholdAddPage> {
body: CustomScrollView(
primary: true,
slivers: [
SliverList(
delegate: SliverChildListDelegate([
BlocBuilder<HouseholdAddCubit, HouseholdAddState>(
bloc: cubit,
buildWhen: (previous, current) =>
previous.image != current.image,
builder: (context, state) => ImageSelector(
image: state.image,
setImage: cubit.setImage,
SliverCrossAxisConstrained(
maxCrossAxisExtent: 600,
child: SliverList(
delegate: SliverChildListDelegate([
BlocBuilder<HouseholdAddCubit, HouseholdAddState>(
bloc: cubit,
buildWhen: (previous, current) =>
previous.image != current.image,
builder: (context, state) => ImageSelector(
image: state.image,
setImage: cubit.setImage,
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
child: TextField(
onChanged: (s) => cubit.setName(s),
textInputAction: TextInputAction.next,
textCapitalization: TextCapitalization.sentences,
decoration: InputDecoration(
labelText: AppLocalizations.of(context)!.name,
Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
child: TextField(
onChanged: (s) => cubit.setName(s),
textInputAction: TextInputAction.next,
textCapitalization: TextCapitalization.sentences,
decoration: InputDecoration(
labelText: AppLocalizations.of(context)!.name,
),
),
),
),
]),
]),
),
),
const SliverPadding(
padding: EdgeInsets.symmetric(horizontal: 16),
sliver: SliverHouseholdFeatureSettings<HouseholdAddCubit,
SliverCrossAxisConstrained(
maxCrossAxisExtent: 600,
child: const SliverHouseholdFeatureSettings<HouseholdAddCubit,
HouseholdAddState>(
askConfirmation: false,
languageCanBeChanged: true,
showProfile: false,
),
),
SliverPadding(
padding: const EdgeInsets.fromLTRB(16, 16, 16, 0),
sliver: SliverToBoxAdapter(
child: Row(
children: [
Expanded(
child: Text(
'${AppLocalizations.of(context)!.members}:',
style: Theme.of(context).textTheme.titleLarge,
SliverCrossAxisConstrained(
maxCrossAxisExtent: 600,
child: SliverToBoxAdapter(
child: const Divider(indent: 16, endIndent: 16),
),
),
SliverCrossAxisConstrained(
maxCrossAxisExtent: 600,
child: SliverPadding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 0),
sliver: SliverToBoxAdapter(
child: Row(
children: [
Expanded(
child: Text(
'${AppLocalizations.of(context)!.members}:',
style: Theme.of(context).textTheme.titleLarge,
),
),
),
LoadingIconButton(
icon: const Icon(Icons.add),
tooltip: AppLocalizations.of(context)!.memberAdd,
onPressed: () async {
final user = await Navigator.of(context)
.push<User>(MaterialPageRoute(
builder: (ctx) => UserSearchPage(
disabledUser: cubit.state.members,
),
));
if (user == null) return;
LoadingIconButton(
icon: const Icon(Icons.add),
tooltip: AppLocalizations.of(context)!.memberAdd,
onPressed: () async {
final user = await Navigator.of(context)
.push<User>(MaterialPageRoute(
builder: (ctx) => UserSearchPage(
disabledUser: cubit.state.members,
),
));
if (user == null) return;

return cubit.addMember(Member.fromUser(user));
},
padding: EdgeInsets.zero,
),
],
return cubit.addMember(Member.fromUser(user));
},
padding: EdgeInsets.zero,
),
],
),
),
),
),
BlocBuilder<HouseholdAddCubit, HouseholdAddState>(
bloc: cubit,
buildWhen: (previous, current) =>
previous.members.length != current.members.length,
builder: (context, state) => SliverList(
delegate: SliverChildBuilderDelegate(
childCount: state.members.length,
(context, i) => Dismissible(
key: ValueKey<Member>(state.members[i]),
confirmDismiss: (direction) async {
return !state.members[i].hasAdminRights();
},
onDismissed: (direction) {
cubit.removeMember(state.members[i]);
},
child: UserListTile(
user: state.members[i],
markSelf: true,
trailing: state.members[i].hasAdminRights()
? Icon(
Icons.admin_panel_settings_rounded,
color: state.members[i].owner
? Colors.redAccent
: null,
)
: null,
SliverCrossAxisConstrained(
maxCrossAxisExtent: 600,
child: BlocBuilder<HouseholdAddCubit, HouseholdAddState>(
bloc: cubit,
buildWhen: (previous, current) =>
previous.members.length != current.members.length,
builder: (context, state) => SliverList(
delegate: SliverChildBuilderDelegate(
childCount: state.members.length,
(context, i) => Dismissible(
key: ValueKey<Member>(state.members[i]),
confirmDismiss: (direction) async {
return !state.members[i].hasAdminRights();
},
onDismissed: (direction) {
cubit.removeMember(state.members[i]);
},
child: UserListTile(
user: state.members[i],
markSelf: true,
trailing: state.members[i].hasAdminRights()
? Icon(
Icons.admin_panel_settings_rounded,
color: state.members[i].owner
? Colors.redAccent
: null,
)
: null,
),
),
),
),
),
),
SliverPadding(
padding: const EdgeInsets.all(16),
sliver: SliverToBoxAdapter(
child: BlocBuilder<HouseholdAddCubit, HouseholdAddState>(
bloc: cubit,
builder: (context, state) => LoadingElevatedButton(
onPressed: state.isValid()
? () async {
Household? household = await cubit.create();
if (!mounted || household == null) return;
Navigator.of(context).pop(UpdateEnum.updated);
context.go(
'/household/${household.id}/${household.viewOrdering?.firstOrNull.toString()}',
extra: household,
);
}
: null,
child: Text(
AppLocalizations.of(context)!.add,
SliverCrossAxisConstrained(
maxCrossAxisExtent: 600,
child: SliverPadding(
padding: const EdgeInsets.all(16),
sliver: SliverToBoxAdapter(
child: BlocBuilder<HouseholdAddCubit, HouseholdAddState>(
bloc: cubit,
builder: (context, state) => LoadingElevatedButton(
onPressed: state.isValid()
? () async {
Household? household = await cubit.create();
if (!mounted || household == null) return;
Navigator.of(context).pop(UpdateEnum.updated);
context.go(
'/household/${household.id}/${household.viewOrdering?.firstOrNull.toString()}',
extra: household,
);
}
: null,
child: Text(
AppLocalizations.of(context)!.add,
),
),
),
),
Expand Down
Loading

0 comments on commit 1569638

Please sign in to comment.