From 574cca0a8bdb27e7dbafad14007cbcf0ec54fe70 Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Fri, 8 Mar 2024 10:16:03 +0800 Subject: [PATCH] fix: bottom sheet color and sort ui imrprovement (#4849) --- .../presentation/base/mobile_view_page.dart | 2 +- .../bottom_sheet_view_item_body.dart | 16 ++++++---- .../bottom_sheet/bottom_sheet_view_page.dart | 16 ++++++---- .../default_mobile_action_pane.dart | 2 +- .../mobile_card_detail_screen.dart | 1 + .../field/mobile_field_bottom_sheets.dart | 2 +- .../view/database_sort_bottom_sheet.dart | 32 +++++++++++++------ .../database/view/database_view_list.dart | 1 + .../widgets/flowy_option_tile.dart | 5 +++ .../application/field/field_controller.dart | 3 +- .../setting/mobile_database_controls.dart | 1 + frontend/resources/translations/en.json | 5 +-- 12 files changed, 58 insertions(+), 28 deletions(-) diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart index 3f835da1f4..5ed50a2f1a 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart @@ -148,7 +148,7 @@ class _MobileViewPageState extends State { context, showDragHandle: true, showDivider: false, - backgroundColor: Theme.of(context).colorScheme.surface, + backgroundColor: Theme.of(context).colorScheme.background, builder: (_) => _buildViewPageBottomSheet(context), ); }, diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_item_body.dart b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_item_body.dart index 2b8209987c..624ae33b9f 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_item_body.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_item_body.dart @@ -2,7 +2,6 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_quick_action_button.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:flowy_infra_ui/widget/separated_flex.dart'; import 'package:flutter/material.dart'; enum MobileViewItemBottomSheetBodyAction { @@ -26,12 +25,8 @@ class MobileViewItemBottomSheetBody extends StatelessWidget { @override Widget build(BuildContext context) { - return SeparatedColumn( + return Column( crossAxisAlignment: CrossAxisAlignment.stretch, - separatorBuilder: () => const Divider( - height: 8.5, - thickness: 0.5, - ), children: [ MobileQuickActionButton( text: LocaleKeys.button_rename.tr(), @@ -40,6 +35,7 @@ class MobileViewItemBottomSheetBody extends StatelessWidget { MobileViewItemBottomSheetBodyAction.rename, ), ), + _divider(), MobileQuickActionButton( text: isFavorite ? LocaleKeys.button_removeFromFavorites.tr() @@ -54,6 +50,7 @@ class MobileViewItemBottomSheetBody extends StatelessWidget { : MobileViewItemBottomSheetBodyAction.addToFavorites, ), ), + _divider(), MobileQuickActionButton( text: LocaleKeys.button_duplicate.tr(), icon: FlowySvgs.m_duplicate_s, @@ -61,6 +58,7 @@ class MobileViewItemBottomSheetBody extends StatelessWidget { MobileViewItemBottomSheetBodyAction.duplicate, ), ), + _divider(), MobileQuickActionButton( text: LocaleKeys.button_delete.tr(), textColor: Theme.of(context).colorScheme.error, @@ -70,7 +68,13 @@ class MobileViewItemBottomSheetBody extends StatelessWidget { MobileViewItemBottomSheetBodyAction.delete, ), ), + _divider(), ], ); } + + Widget _divider() => const Divider( + height: 8.5, + thickness: 0.5, + ); } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_page.dart index 99ea534b09..de9d51311c 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_page.dart @@ -4,7 +4,6 @@ import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_quick_action_button.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; enum MobileViewBottomSheetBodyAction { @@ -85,12 +84,8 @@ class MobileViewBottomSheetBody extends StatelessWidget { @override Widget build(BuildContext context) { final isFavorite = view.isFavorite; - return SeparatedColumn( + return Column( crossAxisAlignment: CrossAxisAlignment.stretch, - separatorBuilder: () => const Divider( - height: 8.5, - thickness: 0.5, - ), children: [ MobileQuickActionButton( text: LocaleKeys.button_rename.tr(), @@ -99,6 +94,7 @@ class MobileViewBottomSheetBody extends StatelessWidget { MobileViewBottomSheetBodyAction.rename, ), ), + _divider(), MobileQuickActionButton( text: isFavorite ? LocaleKeys.button_removeFromFavorites.tr() @@ -113,6 +109,7 @@ class MobileViewBottomSheetBody extends StatelessWidget { : MobileViewBottomSheetBodyAction.addToFavorites, ), ), + _divider(), MobileQuickActionButton( text: LocaleKeys.button_duplicate.tr(), icon: FlowySvgs.m_duplicate_s, @@ -120,6 +117,7 @@ class MobileViewBottomSheetBody extends StatelessWidget { MobileViewBottomSheetBodyAction.duplicate, ), ), + _divider(), MobileQuickActionButton( text: LocaleKeys.button_delete.tr(), textColor: Theme.of(context).colorScheme.error, @@ -129,7 +127,13 @@ class MobileViewBottomSheetBody extends StatelessWidget { MobileViewBottomSheetBodyAction.delete, ), ), + _divider(), ], ); } + + Widget _divider() => const Divider( + height: 8.5, + thickness: 0.5, + ); } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart index 728486cdc7..f27c5b3b6f 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart @@ -54,7 +54,7 @@ enum MobilePaneActionType { context, showDragHandle: true, showDivider: false, - backgroundColor: Theme.of(context).colorScheme.surface, + backgroundColor: Theme.of(context).colorScheme.background, useRootNavigator: true, builder: (context) { return MultiBlocProvider( diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/database/card/card_detail/mobile_card_detail_screen.dart b/frontend/appflowy_flutter/lib/mobile/presentation/database/card/card_detail/mobile_card_detail_screen.dart index 2a1e8ca22b..0e462c641d 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/database/card/card_detail/mobile_card_detail_screen.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/database/card/card_detail/mobile_card_detail_screen.dart @@ -150,6 +150,7 @@ class _MobileRowDetailPageState extends State { icon: FlowySvgs.m_delete_m, iconColor: Theme.of(context).colorScheme.error, ), + const Divider(height: 8.5, thickness: 0.5), ], ), ); diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/database/field/mobile_field_bottom_sheets.dart b/frontend/appflowy_flutter/lib/mobile/presentation/database/field/mobile_field_bottom_sheets.dart index 0f20737856..a4ef722ea7 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/database/field/mobile_field_bottom_sheets.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/database/field/mobile_field_bottom_sheets.dart @@ -40,7 +40,7 @@ Future showFieldTypeGridBottomSheet( showCloseButton: true, elevation: 20, title: title, - backgroundColor: Theme.of(context).colorScheme.surface, + backgroundColor: Theme.of(context).colorScheme.background, enableDraggableScrollable: true, builder: (context) { final typeOptionMenuItemValue = mobileSupportedFieldTypes diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/database/view/database_sort_bottom_sheet.dart b/frontend/appflowy_flutter/lib/mobile/presentation/database/view/database_sort_bottom_sheet.dart index 6beb89ffeb..7270588c60 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/database/view/database_sort_bottom_sheet.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/database/view/database_sort_bottom_sheet.dart @@ -405,6 +405,8 @@ class _SortDetailContent extends StatelessWidget { final SortInfo? sortInfo; + bool get isCreatingNewSort => sortInfo == null; + @override Widget build(BuildContext context) { return Column( @@ -415,7 +417,7 @@ class _SortDetailContent extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 16), child: DefaultTabController( length: 2, - initialIndex: sortInfo == null + initialIndex: isCreatingNewSort ? 0 : sortInfo!.sortPB.condition == SortConditionPB.Ascending ? 0 @@ -487,30 +489,40 @@ class _SortDetailContent extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final fields = state.allFields - .where( - (field) => - field.canCreateSort || - sortInfo != null && sortInfo!.fieldId == field.id, - ) + .where((field) => field.canCreateSort || field.hasSort) .toList(); return ListView.builder( itemCount: fields.length, itemBuilder: (context, index) { final fieldInfo = fields[index]; - final isSelected = sortInfo == null + final isSelected = isCreatingNewSort ? context .watch() .state .newSortFieldId == fieldInfo.id : sortInfo!.fieldId == fieldInfo.id; + + final enabled = fieldInfo.canCreateSort || + isCreatingNewSort && !fieldInfo.hasSort || + !isCreatingNewSort && sortInfo!.fieldId == fieldInfo.id; + return FlowyOptionTile.checkbox( text: fieldInfo.field.name, isSelected: isSelected, + textColor: enabled ? null : Theme.of(context).disabledColor, showTopBorder: false, onTap: () { - if (!isSelected) { + if (isSelected) { + return; + } + if (enabled) { _changeFieldId(context, fieldInfo.id); + } else { + Fluttertoast.showToast( + msg: LocaleKeys.grid_sort_fieldInUse.tr(), + gravity: ToastGravity.BOTTOM, + ); } }, ); @@ -524,7 +536,7 @@ class _SortDetailContent extends StatelessWidget { } void _changeCondition(BuildContext context, SortConditionPB newCondition) { - if (sortInfo == null) { + if (isCreatingNewSort) { context.read().changeSortCondition(newCondition); } else { context.read().add( @@ -537,7 +549,7 @@ class _SortDetailContent extends StatelessWidget { } void _changeFieldId(BuildContext context, String newFieldId) { - if (sortInfo == null) { + if (isCreatingNewSort) { context.read().changeFieldId(newFieldId); } else { context.read().add( diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/database/view/database_view_list.dart b/frontend/appflowy_flutter/lib/mobile/presentation/database/view/database_view_list.dart index 73709ab1e6..4fd639c621 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/database/view/database_view_list.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/database/view/database_view_list.dart @@ -183,6 +183,7 @@ class MobileDatabaseViewListButton extends StatelessWidget { showMobileBottomSheet( context, showDragHandle: true, + backgroundColor: Theme.of(context).colorScheme.background, builder: (_) { return BlocProvider( create: (_) => diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/widgets/flowy_option_tile.dart b/frontend/appflowy_flutter/lib/mobile/presentation/widgets/flowy_option_tile.dart index 5ec4ce84d2..ceca40d019 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/widgets/flowy_option_tile.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/widgets/flowy_option_tile.dart @@ -13,6 +13,7 @@ enum FlowyOptionTileType { class FlowyOptionTile extends StatelessWidget { const FlowyOptionTile._({ + super.key, required this.type, this.showTopBorder = true, this.showBottomBorder = true, @@ -88,9 +89,11 @@ class FlowyOptionTile extends StatelessWidget { } factory FlowyOptionTile.checkbox({ + Key? key, required String text, required bool isSelected, required VoidCallback? onTap, + Color? textColor, Widget? leftIcon, Widget? content, bool showTopBorder = true, @@ -99,9 +102,11 @@ class FlowyOptionTile extends StatelessWidget { Color? backgroundColor, }) { return FlowyOptionTile._( + key: key, type: FlowyOptionTileType.checkbox, isSelected: isSelected, text: text, + textColor: textColor, content: content, onTap: onTap, fontFamily: fontFamily, diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/field/field_controller.dart b/frontend/appflowy_flutter/lib/plugins/database/application/field/field_controller.dart index c22554b31f..5beb2bba88 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/application/field/field_controller.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/application/field/field_controller.dart @@ -337,6 +337,7 @@ class FieldController { ...changeset.insertSorts.map((sort) => sort.sort.fieldId), ...changeset.updateSorts.map((sort) => sort.fieldId), ...changeset.deleteSorts.map((sort) => sort.fieldId), + ...?_sortNotifier?.sorts.map((sort) => sort.fieldId), ]); final newFieldInfos = [...fieldInfos]; @@ -367,8 +368,8 @@ class FieldController { insertSortFromChangeset(newSortInfos, changeset); updateSortFromChangeset(newSortInfos, changeset); - _sortNotifier?.sorts = newSortInfos; updateFieldInfos(newSortInfos, changeset); + _sortNotifier?.sorts = newSortInfos; }, (err) => Log.error(err), ); diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/setting/mobile_database_controls.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/setting/mobile_database_controls.dart index 7e6c9de9cc..dd3d31952e 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/setting/mobile_database_controls.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/setting/mobile_database_controls.dart @@ -150,6 +150,7 @@ void _showEditSortPanelFromToolbar( showDragHandle: true, showDivider: false, useSafeArea: false, + backgroundColor: Theme.of(context).colorScheme.background, builder: (_) { return BlocProvider.value( value: context.read(), diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 574aa0f291..a59768c013 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -679,7 +679,8 @@ "cannotFindCreatableField": "Cannot find a suitable field to sort by", "deleteAllSorts": "Delete all sorts", "addSort": "Add new sort", - "removeSorting": "Would you like to remove sorting?" + "removeSorting": "Would you like to remove sorting?", + "fieldInUse": "You are already sorting by this field" }, "row": { "duplicate": "Duplicate", @@ -1355,4 +1356,4 @@ "userIcon": "User icon" }, "noLogFiles": "There're no log files" -} +} \ No newline at end of file