chore: inkwell mobile quick action sheets (#4576)

* chore: inkwell mobile quick action sheets

* chore: more subtle tap effect

* chore: improve code style
This commit is contained in:
Richard Shiue 2024-02-04 00:55:05 +08:00 committed by GitHub
parent 5cbc8b1e18
commit 8c1d0106dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 107 additions and 119 deletions

View File

@ -1,7 +1,8 @@
import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/widgets/widgets.dart'; import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_quick_action_button.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/widget/separated_flex.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
enum MobileViewItemBottomSheetBodyAction { enum MobileViewItemBottomSheetBodyAction {
@ -25,55 +26,46 @@ class MobileViewItemBottomSheetBody extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return SeparatedColumn(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ separatorBuilder: () => const Divider(
FlowyOptionTile.text( height: 8.5,
text: LocaleKeys.button_rename.tr(), thickness: 0.5,
leftIcon: const FlowySvg(
FlowySvgs.m_rename_s,
), ),
showTopBorder: false, children: [
MobileQuickActionButton(
text: LocaleKeys.button_rename.tr(),
icon: FlowySvgs.m_rename_s,
onTap: () => onAction( onTap: () => onAction(
MobileViewItemBottomSheetBodyAction.rename, MobileViewItemBottomSheetBodyAction.rename,
), ),
), ),
FlowyOptionTile.text( MobileQuickActionButton(
text: isFavorite text: isFavorite
? LocaleKeys.button_removeFromFavorites.tr() ? LocaleKeys.button_removeFromFavorites.tr()
: LocaleKeys.button_addToFavorites.tr(), : LocaleKeys.button_addToFavorites.tr(),
leftIcon: FlowySvg( icon: isFavorite
size: const Size(20, 20),
isFavorite
? FlowySvgs.m_favorite_selected_lg ? FlowySvgs.m_favorite_selected_lg
: FlowySvgs.m_favorite_unselected_lg, : FlowySvgs.m_favorite_unselected_lg,
color: isFavorite ? Colors.yellow : null, iconColor: isFavorite ? Colors.yellow : null,
),
showTopBorder: false,
onTap: () => onAction( onTap: () => onAction(
isFavorite isFavorite
? MobileViewItemBottomSheetBodyAction.removeFromFavorites ? MobileViewItemBottomSheetBodyAction.removeFromFavorites
: MobileViewItemBottomSheetBodyAction.addToFavorites, : MobileViewItemBottomSheetBodyAction.addToFavorites,
), ),
), ),
FlowyOptionTile.text( MobileQuickActionButton(
text: LocaleKeys.button_duplicate.tr(), text: LocaleKeys.button_duplicate.tr(),
leftIcon: const FlowySvg( icon: FlowySvgs.m_duplicate_s,
FlowySvgs.m_duplicate_s,
),
showTopBorder: false,
onTap: () => onAction( onTap: () => onAction(
MobileViewItemBottomSheetBodyAction.duplicate, MobileViewItemBottomSheetBodyAction.duplicate,
), ),
), ),
FlowyOptionTile.text( MobileQuickActionButton(
text: LocaleKeys.button_delete.tr(), text: LocaleKeys.button_delete.tr(),
textColor: Theme.of(context).colorScheme.error, textColor: Theme.of(context).colorScheme.error,
leftIcon: FlowySvg( icon: FlowySvgs.m_delete_s,
FlowySvgs.m_delete_s, iconColor: Theme.of(context).colorScheme.error,
color: Theme.of(context).colorScheme.error,
),
showTopBorder: false,
onTap: () => onAction( onTap: () => onAction(
MobileViewItemBottomSheetBodyAction.delete, MobileViewItemBottomSheetBodyAction.delete,
), ),

View File

@ -1,9 +1,10 @@
import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
import 'package:appflowy/mobile/presentation/widgets/widgets.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:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
enum MobileViewBottomSheetBodyAction { enum MobileViewBottomSheetBodyAction {
@ -84,55 +85,46 @@ class MobileViewBottomSheetBody extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final isFavorite = view.isFavorite; final isFavorite = view.isFavorite;
return Column( return SeparatedColumn(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ separatorBuilder: () => const Divider(
FlowyOptionTile.text( height: 8.5,
text: LocaleKeys.button_rename.tr(), thickness: 0.5,
leftIcon: const FlowySvg(
FlowySvgs.m_rename_s,
), ),
showTopBorder: false, children: [
MobileQuickActionButton(
text: LocaleKeys.button_rename.tr(),
icon: FlowySvgs.m_rename_s,
onTap: () => onAction( onTap: () => onAction(
MobileViewBottomSheetBodyAction.rename, MobileViewBottomSheetBodyAction.rename,
), ),
), ),
FlowyOptionTile.text( MobileQuickActionButton(
text: isFavorite text: isFavorite
? LocaleKeys.button_removeFromFavorites.tr() ? LocaleKeys.button_removeFromFavorites.tr()
: LocaleKeys.button_addToFavorites.tr(), : LocaleKeys.button_addToFavorites.tr(),
leftIcon: FlowySvg( icon: isFavorite
size: const Size(20, 20),
isFavorite
? FlowySvgs.m_favorite_selected_lg ? FlowySvgs.m_favorite_selected_lg
: FlowySvgs.m_favorite_unselected_lg, : FlowySvgs.m_favorite_unselected_lg,
color: isFavorite ? Colors.yellow : null, iconColor: isFavorite ? Colors.yellow : null,
),
showTopBorder: false,
onTap: () => onAction( onTap: () => onAction(
isFavorite isFavorite
? MobileViewBottomSheetBodyAction.removeFromFavorites ? MobileViewBottomSheetBodyAction.removeFromFavorites
: MobileViewBottomSheetBodyAction.addToFavorites, : MobileViewBottomSheetBodyAction.addToFavorites,
), ),
), ),
FlowyOptionTile.text( MobileQuickActionButton(
text: LocaleKeys.button_duplicate.tr(), text: LocaleKeys.button_duplicate.tr(),
leftIcon: const FlowySvg( icon: FlowySvgs.m_duplicate_s,
FlowySvgs.m_duplicate_s,
),
showTopBorder: false,
onTap: () => onAction( onTap: () => onAction(
MobileViewBottomSheetBodyAction.duplicate, MobileViewBottomSheetBodyAction.duplicate,
), ),
), ),
FlowyOptionTile.text( MobileQuickActionButton(
text: LocaleKeys.button_delete.tr(), text: LocaleKeys.button_delete.tr(),
textColor: Theme.of(context).colorScheme.error, textColor: Theme.of(context).colorScheme.error,
leftIcon: FlowySvg( icon: FlowySvgs.m_delete_s,
FlowySvgs.m_delete_s, iconColor: Theme.of(context).colorScheme.error,
color: Theme.of(context).colorScheme.error,
),
showTopBorder: false,
onTap: () => onAction( onTap: () => onAction(
MobileViewBottomSheetBodyAction.delete, MobileViewBottomSheetBodyAction.delete,
), ),

View File

@ -135,53 +135,43 @@ class _MobileRowDetailPageState extends State<MobileRowDetailPage> {
builder: (_) => Column( builder: (_) => Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Padding( MobileQuickActionButton(
padding: const EdgeInsets.symmetric(horizontal: 8.0), onTap: () =>
child: MobileQuickActionButton( _performAction(viewId, _bloc.state.currentRowId, false),
onTap: () {
final rowId = _bloc.state.currentRowId;
if (rowId == null) {
return;
}
RowBackendService.duplicateRow(viewId, rowId);
context
..pop()
..pop();
Fluttertoast.showToast(
msg: LocaleKeys.board_cardDuplicated.tr(),
gravity: ToastGravity.BOTTOM,
);
},
icon: FlowySvgs.copy_s, icon: FlowySvgs.copy_s,
text: LocaleKeys.button_duplicate.tr(), text: LocaleKeys.button_duplicate.tr(),
), ),
const Divider(height: 8.5, thickness: 0.5),
MobileQuickActionButton(
onTap: () => _performAction(viewId, _bloc.state.currentRowId, true),
text: LocaleKeys.button_delete.tr(),
textColor: Theme.of(context).colorScheme.error,
icon: FlowySvgs.m_delete_m,
iconColor: Theme.of(context).colorScheme.error,
), ),
const Divider(height: 9), ],
Padding( ),
padding: const EdgeInsets.symmetric(horizontal: 8.0), );
child: MobileQuickActionButton( }
onTap: () {
final rowId = _bloc.state.currentRowId; void _performAction(String viewId, String? rowId, bool deleteRow) {
if (rowId == null) { if (rowId == null) {
return; return;
} }
RowBackendService.deleteRow(viewId, rowId);
deleteRow
? RowBackendService.deleteRow(viewId, rowId)
: RowBackendService.duplicateRow(viewId, rowId);
context context
..pop() ..pop()
..pop(); ..pop();
Fluttertoast.showToast( Fluttertoast.showToast(
msg: LocaleKeys.board_cardDeleted.tr(), msg: deleteRow
? LocaleKeys.board_cardDeleted.tr()
: LocaleKeys.board_cardDuplicated.tr(),
gravity: ToastGravity.BOTTOM, gravity: ToastGravity.BOTTOM,
); );
},
icon: FlowySvgs.m_delete_m,
text: LocaleKeys.button_delete.tr(),
color: Theme.of(context).colorScheme.error,
),
),
],
),
);
} }
} }

View File

@ -72,18 +72,16 @@ class MobileDatabaseViewQuickActions extends StatelessWidget {
_Action action, _Action action,
VoidCallback onTap, VoidCallback onTap,
) { ) {
return Padding( return MobileQuickActionButton(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: MobileQuickActionButton(
icon: action.icon, icon: action.icon,
text: action.label, text: action.label,
color: action.color(context), textColor: action.color(context),
iconColor: action.color(context),
onTap: onTap, onTap: onTap,
),
); );
} }
Widget _divider() => const Divider(height: 9); Widget _divider() => const Divider(height: 8.5, thickness: 0.5);
} }
enum _Action { enum _Action {

View File

@ -8,30 +8,46 @@ class MobileQuickActionButton extends StatelessWidget {
required this.onTap, required this.onTap,
required this.icon, required this.icon,
required this.text, required this.text,
this.color, this.textColor,
this.iconColor,
}); });
final VoidCallback onTap; final VoidCallback onTap;
final FlowySvgData icon; final FlowySvgData icon;
final String text; final String text;
final Color? color; final Color? textColor;
final Color? iconColor;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return InkWell( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: InkWell(
onTap: onTap, onTap: onTap,
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
splashColor: Colors.transparent,
child: Container( child: Container(
height: 44, height: 44,
padding: const EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 12),
child: Row( child: Row(
children: [ children: [
FlowySvg(icon, size: const Size.square(20), color: color), FlowySvg(
const HSpace(8), icon,
FlowyText(text, fontSize: 15, color: color), size: const Size.square(20),
color: iconColor,
),
const HSpace(12),
Expanded(
child: FlowyText(
text,
fontSize: 15,
color: textColor,
),
),
], ],
), ),
), ),
),
); );
} }
} }