feat: improve confirm deletion dialog

This commit is contained in:
Lucas.Xu 2024-07-03 10:47:59 +08:00
parent 38f49d617f
commit 59b36f67c8
6 changed files with 113 additions and 100 deletions

View File

@ -19,6 +19,7 @@ import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
class SpacePermissionSwitch extends StatefulWidget { class SpacePermissionSwitch extends StatefulWidget {
@ -222,7 +223,7 @@ class SpaceCancelOrConfirmButton extends StatelessWidget {
} }
} }
class ConfirmDeletionPopup extends StatelessWidget { class ConfirmDeletionPopup extends StatefulWidget {
const ConfirmDeletionPopup({ const ConfirmDeletionPopup({
super.key, super.key,
required this.title, required this.title,
@ -234,50 +235,67 @@ class ConfirmDeletionPopup extends StatelessWidget {
final String description; final String description;
final VoidCallback onConfirm; final VoidCallback onConfirm;
@override
State<ConfirmDeletionPopup> createState() => _ConfirmDeletionPopupState();
}
class _ConfirmDeletionPopupState extends State<ConfirmDeletionPopup> {
final focusNode = FocusNode();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return KeyboardListener(
padding: const EdgeInsets.symmetric( focusNode: focusNode,
vertical: 20.0, autofocus: true,
horizontal: 20.0, onKeyEvent: (event) {
), if (event is KeyDownEvent &&
child: Column( event.logicalKey == LogicalKeyboardKey.escape) {
mainAxisSize: MainAxisSize.min, Navigator.of(context).pop();
crossAxisAlignment: CrossAxisAlignment.start, }
children: [ },
Row( child: Padding(
children: [ padding: const EdgeInsets.symmetric(
FlowyText( vertical: 20.0,
title, horizontal: 20.0,
fontSize: 14.0, ),
), child: Column(
const Spacer(), mainAxisSize: MainAxisSize.min,
FlowyButton( crossAxisAlignment: CrossAxisAlignment.start,
useIntrinsicWidth: true, children: [
text: const FlowySvg(FlowySvgs.upgrade_close_s), Row(
onTap: () => Navigator.of(context).pop(), children: [
), FlowyText(
], widget.title,
), fontSize: 14.0,
const VSpace(8.0), ),
FlowyText.regular( const Spacer(),
description, FlowyButton(
fontSize: 12.0, useIntrinsicWidth: true,
color: Theme.of(context).hintColor, text: const FlowySvg(FlowySvgs.upgrade_close_s),
maxLines: 3, onTap: () => Navigator.of(context).pop(),
lineHeight: 1.4, ),
), ],
const VSpace(20.0), ),
SpaceCancelOrConfirmButton( const VSpace(8.0),
onCancel: () => Navigator.of(context).pop(), FlowyText.regular(
onConfirm: () { widget.description,
onConfirm(); fontSize: 12.0,
Navigator.of(context).pop(); color: Theme.of(context).hintColor,
}, maxLines: 3,
confirmButtonName: LocaleKeys.space_delete.tr(), lineHeight: 1.4,
confirmButtonColor: Theme.of(context).colorScheme.error, ),
), const VSpace(20.0),
], SpaceCancelOrConfirmButton(
onCancel: () => Navigator.of(context).pop(),
onConfirm: () {
widget.onConfirm();
Navigator.of(context).pop();
},
confirmButtonName: LocaleKeys.space_delete.tr(),
confirmButtonColor: Theme.of(context).colorScheme.error,
),
],
),
), ),
); );
} }

View File

@ -227,31 +227,14 @@ class _SidebarSpaceHeaderState extends State<SidebarSpaceHeader> {
void _showDeleteSpaceDialog(BuildContext context) { void _showDeleteSpaceDialog(BuildContext context) {
final spaceBloc = context.read<SpaceBloc>(); final spaceBloc = context.read<SpaceBloc>();
showDialog( final space = spaceBloc.state.currentSpace;
final name = space != null ? space.name : '';
showConfirmDeletionDialog(
context: context, context: context,
builder: (_) { name: name,
final space = spaceBloc.state.currentSpace; description: LocaleKeys.space_deleteConfirmationDescription.tr(),
final name = space != null ? space.name : ''; onConfirm: () {
final title = LocaleKeys.space_deleteConfirmation.tr() + name; context.read<SpaceBloc>().add(const SpaceEvent.delete(null));
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: BlocProvider.value(
value: spaceBloc,
child: SizedBox(
width: 440,
child: ConfirmDeletionPopup(
title: title,
description:
LocaleKeys.space_deleteConfirmationDescription.tr(),
onConfirm: () {
context.read<SpaceBloc>().add(const SpaceEvent.delete(null));
},
),
),
),
);
}, },
); );
} }

View File

@ -105,14 +105,16 @@ class _WorkspaceMoreActionWrapper extends CustomActionCell {
case WorkspaceMoreAction.divider: case WorkspaceMoreAction.divider:
break; break;
case WorkspaceMoreAction.delete: case WorkspaceMoreAction.delete:
await NavigatorAlertDialog( await showConfirmDeletionDialog(
title: LocaleKeys.workspace_deleteWorkspaceHintText.tr(), context: context,
confirm: () { name: workspace.name,
description: LocaleKeys.workspace_deleteWorkspaceHintText.tr(),
onConfirm: () {
workspaceBloc.add( workspaceBloc.add(
UserWorkspaceEvent.deleteWorkspace(workspace.workspaceId), UserWorkspaceEvent.deleteWorkspace(workspace.workspaceId),
); );
}, },
).show(context); );
case WorkspaceMoreAction.rename: case WorkspaceMoreAction.rename:
await NavigatorTextFieldDialog( await NavigatorTextFieldDialog(
title: LocaleKeys.workspace_renameWorkspace.tr(), title: LocaleKeys.workspace_renameWorkspace.tr(),

View File

@ -14,7 +14,6 @@ import 'package:appflowy/workspace/application/view/view_ext.dart';
import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; import 'package:appflowy/workspace/presentation/home/home_sizes.dart';
import 'package:appflowy/workspace/presentation/home/menu/menu_shared_state.dart'; import 'package:appflowy/workspace/presentation/home/menu/menu_shared_state.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/shared/rename_view_dialog.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/shared/rename_view_dialog.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/shared_widget.dart';
import 'package:appflowy/workspace/presentation/home/menu/view/draggable_view_item.dart'; import 'package:appflowy/workspace/presentation/home/menu/view/draggable_view_item.dart';
import 'package:appflowy/workspace/presentation/home/menu/view/view_action_type.dart'; import 'package:appflowy/workspace/presentation/home/menu/view/view_action_type.dart';
import 'package:appflowy/workspace/presentation/home/menu/view/view_add_button.dart'; import 'package:appflowy/workspace/presentation/home/menu/view/view_add_button.dart';
@ -726,7 +725,14 @@ class _SingleInnerViewItemState extends State<SingleInnerViewItem> {
views.map((e) => ViewBackendService.getPublishInfo(e)), views.map((e) => ViewBackendService.getPublishInfo(e)),
).then((value) => value.where((e) => e.isSuccess)); ).then((value) => value.where((e) => e.isSuccess));
if (containPublishedPage.isNotEmpty && context.mounted) { if (containPublishedPage.isNotEmpty && context.mounted) {
_showDeleteDialog(context); await showConfirmDeletionDialog(
context: context,
name: widget.view.name,
description: LocaleKeys.publish_containsPublishedPage.tr(),
onConfirm: () {
context.read<ViewBloc>().add(const ViewEvent.delete());
},
);
} else if (context.mounted) { } else if (context.mounted) {
context.read<ViewBloc>().add(const ViewEvent.delete()); context.read<ViewBloc>().add(const ViewEvent.delete());
} }
@ -790,30 +796,6 @@ class _SingleInnerViewItemState extends State<SingleInnerViewItem> {
} }
return LocaleKeys.newPageText.tr(); return LocaleKeys.newPageText.tr();
} }
void _showDeleteDialog(BuildContext context) {
showDialog(
context: context,
builder: (_) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: SizedBox(
width: 440,
child: ConfirmDeletionPopup(
title:
LocaleKeys.space_deleteConfirmation.tr() + widget.view.name,
description: LocaleKeys.publish_containsPublishedPage.tr(),
onConfirm: () {
context.read<ViewBloc>().add(const ViewEvent.delete());
},
),
),
);
},
);
}
} }
class _DotIconWidget extends StatelessWidget { class _DotIconWidget extends StatelessWidget {

View File

@ -1,5 +1,6 @@
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/startup/tasks/app_widget.dart'; import 'package:appflowy/startup/tasks/app_widget.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/shared_widget.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/size.dart'; import 'package:flowy_infra/size.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
@ -300,3 +301,30 @@ void showToastNotification(
showProgressBar: false, showProgressBar: false,
); );
} }
Future<void> showConfirmDeletionDialog({
required BuildContext context,
required String name,
required String description,
required VoidCallback onConfirm,
}) {
return showDialog(
context: context,
builder: (_) {
final title = LocaleKeys.space_deleteConfirmation.tr() + name;
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: SizedBox(
width: 440,
child: ConfirmDeletionPopup(
title: title,
description: description,
onConfirm: onConfirm,
),
),
);
},
);
}

View File

@ -82,7 +82,7 @@
"reachOut": "Reach out on Discord" "reachOut": "Reach out on Discord"
}, },
"menuTitle": "Workspaces", "menuTitle": "Workspaces",
"deleteWorkspaceHintText": "Are you sure you want to delete the workspace? This action cannot be undone.", "deleteWorkspaceHintText": "Are you sure you want to delete the workspace? This action cannot be undone, and any pages you have published will be unpublished.",
"createSuccess": "Workspace created successfully", "createSuccess": "Workspace created successfully",
"createFailed": "Failed to create workspace", "createFailed": "Failed to create workspace",
"createLimitExceeded": "You've reached the maximum workspace limit allowed for your account. If you need additional workspaces to continue your work, please request on Github", "createLimitExceeded": "You've reached the maximum workspace limit allowed for your account. If you need additional workspaces to continue your work, please request on Github",
@ -439,7 +439,7 @@
}, },
"deleteWorkspacePrompt": { "deleteWorkspacePrompt": {
"title": "Delete workspace", "title": "Delete workspace",
"content": "Are you sure you want to delete this workspace? This action cannot be undone." "content": "Are you sure you want to delete this workspace? This action cannot be undone, and any pages you have published will be unpublished."
}, },
"leaveWorkspacePrompt": { "leaveWorkspacePrompt": {
"title": "Leave workspace", "title": "Leave workspace",
@ -2008,7 +2008,7 @@
"space": { "space": {
"delete": "Delete", "delete": "Delete",
"deleteConfirmation": "Delete: ", "deleteConfirmation": "Delete: ",
"deleteConfirmationDescription": "All pages within this Space will be deleted and moved to Trash.", "deleteConfirmationDescription": "All pages within this Space will be deleted and moved to the Trash, and any published pages will be unpublished.",
"rename": "Rename Space", "rename": "Rename Space",
"changeIcon": "Change icon", "changeIcon": "Change icon",
"manage": "Manage Space", "manage": "Manage Space",