Skip to content

Commit

Permalink
feat: Improve mobile settings UX (#541)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomBursch authored Nov 12, 2024
1 parent 3ce440e commit 3ad96ff
Show file tree
Hide file tree
Showing 13 changed files with 241 additions and 186 deletions.
30 changes: 24 additions & 6 deletions kitchenowl/lib/enums/views_enum.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:kitchenowl/app.dart';
import 'package:kitchenowl/cubits/household_cubit.dart';
import 'package:kitchenowl/kitchenowl.dart';
import 'package:kitchenowl/models/household.dart';
import 'package:kitchenowl/widgets/expense_create_fab.dart';
Expand All @@ -11,7 +13,7 @@ enum ViewsEnum {
recipes,
planner,
balances,
profile;
more;

String toLocalizedString(BuildContext context) {
final loc = AppLocalizations.of(context)!;
Expand All @@ -21,7 +23,7 @@ enum ViewsEnum {
loc.recipes,
loc.mealPlanner,
loc.balances,
loc.profile,
loc.more,
][index];
}

Expand All @@ -33,17 +35,32 @@ enum ViewsEnum {
loc.recipes,
loc.planner,
loc.balances,
loc.profile,
loc.more,
][index];
}

Widget? toIconWidget(BuildContext context) {
if (this == ViewsEnum.more) {
Household? household = context.read<HouseholdCubit>().state.household;
if (!App.isOffline && household.image != null)
return CircleAvatar(
radius: 16,
foregroundImage: getImageProvider(
context,
household.image!,
),
);
}
return null;
}

IconData toIcon(BuildContext context) {
return [
Icons.shopping_bag_outlined,
Icons.receipt_outlined,
Icons.calendar_today_outlined,
Icons.account_balance_outlined,
App.isOffline ? Icons.cloud_off_rounded : Icons.person_outline_rounded,
App.isOffline ? Icons.cloud_off_rounded : Icons.house_rounded,
][index];
}

Expand All @@ -53,7 +70,7 @@ enum ViewsEnum {
Icons.receipt_rounded,
Icons.calendar_today_rounded,
Icons.account_balance_rounded,
App.isOffline ? Icons.cloud_off_rounded : Icons.person_rounded,
App.isOffline ? Icons.cloud_off_rounded : Icons.house_rounded,
][index];
}

Expand Down Expand Up @@ -112,7 +129,8 @@ enum ViewsEnum {
case 'balances':
return ViewsEnum.balances;
case 'profile':
return ViewsEnum.profile;
case 'more':
return ViewsEnum.more;
default:
return null;
}
Expand Down
2 changes: 1 addition & 1 deletion kitchenowl/lib/models/household.dart
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class Household extends Model {
}
if (viewOrdering != null) {
data['view_ordering'] = viewOrdering!.map((e) => e.toString()).toList()
..remove(ViewsEnum.profile.toString());
..remove(ViewsEnum.more.toString());
}

return data;
Expand Down
1 change: 0 additions & 1 deletion kitchenowl/lib/pages/household_add_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ class _HouseholdAddPageState extends State<HouseholdAddPage> {
HouseholdAddState>(
askConfirmation: false,
languageCanBeChanged: true,
showProfile: false,
),
),
SliverCrossAxisConstrained(
Expand Down
16 changes: 15 additions & 1 deletion kitchenowl/lib/pages/household_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:kitchenowl/enums/views_enum.dart';
import 'package:kitchenowl/models/household.dart';
import 'package:kitchenowl/pages/household_page/household_drawer.dart';
import 'package:kitchenowl/pages/household_page/household_navigation_rail.dart';
import 'package:kitchenowl/pages/household_page/more.dart';
import 'package:kitchenowl/pages/page_not_found.dart';
import 'package:responsive_builder/responsive_builder.dart';

Expand Down Expand Up @@ -94,6 +95,17 @@ class _HouseholdPageState extends State<HouseholdPage>
case ViewsEnum.balances:
expenseListCubit.refresh();
break;
case ViewsEnum.more:
showModalBottomSheet(
context: context,
showDragHandle: true,
isScrollControlled: true,
builder: (context) => BlocProvider.value(
value: householdCubit,
child: MorePage(),
),
);
return;
default:
break;
}
Expand Down Expand Up @@ -204,11 +216,13 @@ class _HouseholdPageState extends State<HouseholdPage>
NavigationDestinationLabelBehavior.onlyShowSelected,
destinations: pages
.map((e) => NavigationDestination(
icon: Icon(e.toIcon(context)),
icon: e.toIconWidget(context) ??
Icon(e.toIcon(context)),
selectedIcon: Icon(e.toSelectedIcon(context)),
label: e.toLocalizedShortString(context),
tooltip: e.toLocalizedString(context),
))
.take(5)
.toList(),
selectedIndex: _selectedIndex,
onDestinationSelected: (i) => _onItemTapped(
Expand Down
2 changes: 1 addition & 1 deletion kitchenowl/lib/pages/household_page/_export.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export 'profile.dart';
export 'more.dart';
export 'recipe_list.dart';
export 'shoppinglist.dart';
export 'planner.dart';
Expand Down
22 changes: 3 additions & 19 deletions kitchenowl/lib/pages/household_page/household_drawer.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_blurhash/flutter_blurhash.dart';
import 'package:go_router/go_router.dart';
import 'package:kitchenowl/app.dart';
import 'package:kitchenowl/cubits/auth_cubit.dart';
import 'package:kitchenowl/cubits/household_cubit.dart';
import 'package:kitchenowl/enums/update_enum.dart';
import 'package:kitchenowl/enums/views_enum.dart';
import 'package:kitchenowl/kitchenowl.dart';
import 'package:transparent_image/transparent_image.dart';
import 'package:kitchenowl/widgets/household_image.dart';

class HouseholdDrawer extends StatelessWidget {
final int selectedIndex;
Expand Down Expand Up @@ -63,22 +62,7 @@ class HouseholdDrawer extends StatelessWidget {
if (state.household.image != null)
Padding(
padding: const EdgeInsets.only(bottom: 16),
child: ClipRRect(
borderRadius: BorderRadius.circular(14),
child: SizedBox(
height: 150,
child: FadeInImage(
fit: BoxFit.cover,
placeholder: state.household.imageHash != null
? BlurHashImage(state.household.imageHash!)
: MemoryImage(kTransparentImage) as ImageProvider,
image: getImageProvider(
context,
state.household.image!,
),
),
),
),
child: HouseholdImage(household: state.household),
),
Text(
state.household.name,
Expand All @@ -90,7 +74,7 @@ class HouseholdDrawer extends StatelessWidget {
),
),
),
...pages.where((e) => e != ViewsEnum.profile).map(
...pages.where((e) => e != ViewsEnum.more).map(
(ViewsEnum destination) {
return NavigationDrawerDestination(
label: Text(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@ class HouseholdNavigationRail extends StatelessWidget {
icon: const Icon(Icons.menu_rounded),
label: Text(AppLocalizations.of(context)!.more),
),
...pages.map((e) => NavigationRailDestination(
label: Text(e.toLocalizedString(context)),
icon: Icon(e.toIcon(context)),
selectedIcon: Icon(e.toSelectedIcon(context)),
)),
...pages
.where((e) => e != ViewsEnum.more)
.map((e) => NavigationRailDestination(
label: Text(e.toLocalizedString(context)),
icon: Icon(e.toIcon(context)),
selectedIcon: Icon(e.toSelectedIcon(context)),
)),
],
selectedIndex: selectedIndex + 1,
onDestinationSelected: (i) {
Expand Down
157 changes: 157 additions & 0 deletions kitchenowl/lib/pages/household_page/more.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import 'package:collection/collection.dart';
import 'package:kitchenowl/app.dart';
import 'package:kitchenowl/cubits/auth_cubit.dart';
import 'package:kitchenowl/cubits/household_cubit.dart';
import 'package:kitchenowl/enums/update_enum.dart';
import 'package:kitchenowl/enums/views_enum.dart';
import 'package:kitchenowl/kitchenowl.dart';
import 'package:kitchenowl/pages/household_update_page.dart';
import 'package:kitchenowl/widgets/household_image.dart';

class MorePage extends StatelessWidget {
const MorePage({super.key});

@override
Widget build(BuildContext context) {
final householdCubit = BlocProvider.of<HouseholdCubit>(context);

return SafeArea(
child: ListView(
shrinkWrap: true,
padding: const EdgeInsets.symmetric(horizontal: 8),
children: [
BlocBuilder<HouseholdCubit, HouseholdState>(
bloc: householdCubit,
builder: (context, state) => Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (state.household.image != null)
Padding(
padding: EdgeInsets.only(
bottom: !App.isOffline &&
context.read<AuthCubit>().getUser() != null &&
state.household.hasAdminRights(
context.read<AuthCubit>().getUser()!)
? 6
: 16),
child: HouseholdImage(household: state.household),
),
Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Text(
state.household.name,
style: Theme.of(context).textTheme.titleSmall,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
const Spacer(),
if (!App.isOffline &&
context.read<AuthCubit>().getUser() != null &&
state.household.hasAdminRights(
context.read<AuthCubit>().getUser()!))
IconButton(
icon: Icon(Icons.edit_rounded),
onPressed: () {
context.pop();
Navigator.of(context).push<UpdateEnum>(
MaterialPageRoute(
builder: (ctx) => HouseholdUpdatePage(
household: state.household,
),
),
);
},
),
],
),
],
),
),
const Divider(),
BlocBuilder<HouseholdCubit, HouseholdState>(
bloc: householdCubit,
buildWhen: (previous, current) =>
previous.household.viewOrdering
?.equals(current.household.viewOrdering ?? const []) ??
true,
builder: (context, state) {
List<ViewsEnum> pages =
(state.household.viewOrdering ?? ViewsEnum.values)
.where((e) => e.isViewActive(state.household))
.skip(5)
.toList();
if (pages.isEmpty) return const SizedBox();
return Column(
children: pages
.map((e) => Card(
child: ListTile(
title: Text(
e.toLocalizedString(context),
),
leading: e.toIconWidget(context) ??
Icon(e.toIcon(context)),
minLeadingWidth: 16,
onTap: () => context.go("/household"),
),
) as Widget)
.toList() +
[
const Divider(),
],
);
},
),
Card(
child: ListTile(
title: Text(
AppLocalizations.of(context)!.householdSwitch,
),
leading: const Icon(Icons.swap_horiz_rounded),
minLeadingWidth: 16,
onTap: () => context.go("/household"),
),
),
Card(
child: ListTile(
title: Text(
AppLocalizations.of(context)!.profile,
),
leading: const Icon(Icons.person_rounded),
minLeadingWidth: 16,
onTap: () {
context.pop();
context.push("/settings/account").then((res) {
if (res == UpdateEnum.updated) {
context.read<AuthCubit>().refreshUser();
}
});
},
),
),
Card(
child: ListTile(
title: Text(
AppLocalizations.of(context)!.settings,
),
leading: const Icon(Icons.settings),
minLeadingWidth: 16,
onTap: () {
context.pop();
context.push(
"/settings",
extra: householdCubit.state.household,
);
},
),
),
const SizedBox(height: 16),
],
),
);
}
}
Loading

0 comments on commit 3ad96ff

Please sign in to comment.