mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-12-24 13:44:19 +00:00
refactor: rename dialog (#8059)
* refactor: rename dialog * test: fix test
This commit is contained in:
parent
a480889c28
commit
d4f9c71ec2
@ -1,10 +1,10 @@
|
||||
import 'package:appflowy/env/cloud_env.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_ext.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialog_v2.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pbenum.dart';
|
||||
import 'package:appflowy_ui/appflowy_ui.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text_input.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
@ -38,12 +38,12 @@ void main() {
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(NavigatorTextFieldDialog), findsOneWidget);
|
||||
expect(find.byType(AFTextFieldDialog), findsOneWidget);
|
||||
|
||||
final textField = tester.widget<FlowyFormTextInput>(
|
||||
final textField = tester.widget<AFTextField>(
|
||||
find.descendant(
|
||||
of: find.byType(NavigatorTextFieldDialog),
|
||||
matching: find.byType(FlowyFormTextInput),
|
||||
of: find.byType(AFTextFieldDialog),
|
||||
matching: find.byType(AFTextField),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ void main() {
|
||||
find.byType(WorkspaceIcon),
|
||||
);
|
||||
expect(workspaceIcon.workspaceIcon, icon);
|
||||
expect(find.findTextInFlowyText(name), findsOneWidget);
|
||||
expect(workspaceIcon.workspaceName, name);
|
||||
});
|
||||
|
||||
testWidgets('verify the result again after relaunching', (tester) async {
|
||||
|
||||
@ -36,23 +36,20 @@ void main() {
|
||||
final loading = find.byType(Loading);
|
||||
await tester.pumpUntilNotFound(loading);
|
||||
|
||||
Finder success;
|
||||
|
||||
final Finder items = find.byType(WorkspaceMenuItem);
|
||||
|
||||
// delete the newly created workspace
|
||||
await tester.openCollaborativeWorkspaceMenu();
|
||||
await tester.pumpUntilFound(items);
|
||||
|
||||
final items = find.byType(WorkspaceMenuItem);
|
||||
expect(items, findsNWidgets(2));
|
||||
|
||||
final lastWorkspace = items.last;
|
||||
expect(
|
||||
tester.widget<WorkspaceMenuItem>(items.last).workspace.name,
|
||||
tester.widget<WorkspaceMenuItem>(lastWorkspace).workspace.name,
|
||||
name,
|
||||
);
|
||||
|
||||
final secondWorkspace = find.byType(WorkspaceMenuItem).last;
|
||||
await tester.hoverOnWidget(
|
||||
secondWorkspace,
|
||||
lastWorkspace,
|
||||
onHover: () async {
|
||||
// click the more button
|
||||
final moreButton = find.byType(WorkspaceMoreActionList);
|
||||
@ -68,10 +65,8 @@ void main() {
|
||||
expect(confirm, findsOneWidget);
|
||||
await tester.tapButton(find.text(LocaleKeys.button_ok.tr()));
|
||||
// delete success
|
||||
success = find.text(LocaleKeys.workspace_createSuccess.tr());
|
||||
final success = find.text(LocaleKeys.workspace_createSuccess.tr());
|
||||
await tester.pumpUntilFound(success);
|
||||
expect(success, findsOneWidget);
|
||||
await tester.pumpUntilNotFound(success);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
@ -7,7 +7,7 @@ import '../../shared/util.dart';
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('create and delete the document', () {
|
||||
group('create and delete the document:', () {
|
||||
testWidgets('create a new document when launching app in first time',
|
||||
(tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
|
||||
@ -7,6 +7,7 @@ import 'package:appflowy/shared/icon_emoji_picker/recent_icons.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_action_type.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_ui/appflowy_ui.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -521,8 +522,8 @@ extension _SubPageTestHelper on WidgetTester {
|
||||
await hoverOnPageName(currentName, onHover: () async => pumpAndSettle());
|
||||
await rightClickOnPageName(currentName);
|
||||
await tapButtonWithName(ViewMoreActionType.rename.name);
|
||||
await enterText(find.byType(TextFormField), newName);
|
||||
await tapOKButton();
|
||||
await enterText(find.byType(AFTextField), newName);
|
||||
await tapButton(find.text(LocaleKeys.button_confirm.tr()));
|
||||
await pumpAndSettle();
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,11 +38,13 @@ import 'package:appflowy/workspace/presentation/notifications/widgets/notificati
|
||||
import 'package:appflowy/workspace/presentation/notifications/widgets/notification_tab_bar.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/shared/settings_body.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_menu.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialog_v2.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/more_view_actions/more_view_actions.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/more_view_actions/widgets/common_view_action.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/view_title_bar.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_ui/appflowy_ui.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/widget/buttons/primary_button.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
@ -264,8 +266,8 @@ extension CommonOperations on WidgetTester {
|
||||
/// Rename the page.
|
||||
Future<void> renamePage(String name) async {
|
||||
await tapRenamePageButton();
|
||||
await enterText(find.byType(TextFormField), name);
|
||||
await tapOKButton();
|
||||
await enterText(find.byType(AFTextField), name);
|
||||
await tapButton(find.text(LocaleKeys.button_confirm.tr()));
|
||||
}
|
||||
|
||||
Future<void> tapTrashButton() async {
|
||||
@ -359,7 +361,7 @@ extension CommonOperations on WidgetTester {
|
||||
);
|
||||
final showRenameDialog = settingsOrFailure ?? false;
|
||||
if (showRenameDialog) {
|
||||
await tapOKButton();
|
||||
await tapButton(find.text(LocaleKeys.button_confirm.tr()));
|
||||
}
|
||||
await pumpAndSettle();
|
||||
|
||||
@ -736,8 +738,7 @@ extension CommonOperations on WidgetTester {
|
||||
final workspace = find.byType(SidebarWorkspace);
|
||||
expect(workspace, findsOneWidget);
|
||||
|
||||
await tapButton(workspace, pumpAndSettle: false);
|
||||
await pump(const Duration(seconds: 5));
|
||||
await tapButton(workspace, milliseconds: 5000);
|
||||
}
|
||||
|
||||
Future<void> createCollaborativeWorkspace(String name) async {
|
||||
@ -752,22 +753,20 @@ extension CommonOperations on WidgetTester {
|
||||
// click the create button
|
||||
final createButton = find.byKey(createWorkspaceButtonKey);
|
||||
expect(createButton, findsOneWidget);
|
||||
await tapButton(createButton, pumpAndSettle: false);
|
||||
await pump(const Duration(seconds: 5));
|
||||
|
||||
// see the create workspace dialog
|
||||
final createWorkspaceDialog = find.byType(CreateWorkspaceDialog);
|
||||
expect(createWorkspaceDialog, findsOneWidget);
|
||||
await tapButton(createButton);
|
||||
|
||||
// input the workspace name
|
||||
final workspaceNameInput = find.descendant(
|
||||
of: createWorkspaceDialog,
|
||||
of: find.byType(AFTextFieldDialog),
|
||||
matching: find.byType(TextField),
|
||||
);
|
||||
await enterText(workspaceNameInput, name);
|
||||
await pumpAndSettle();
|
||||
|
||||
await tapButtonWithName(LocaleKeys.button_ok.tr(), pumpAndSettle: false);
|
||||
await pump(const Duration(seconds: 5));
|
||||
await tapButton(
|
||||
find.text(LocaleKeys.button_confirm.tr()),
|
||||
milliseconds: 2000,
|
||||
);
|
||||
}
|
||||
|
||||
// For mobile platform to launch the app in anonymous mode
|
||||
|
||||
@ -76,15 +76,16 @@ import 'package:appflowy/util/field_type_extension.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/date_picker/widgets/clear_date_button.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/date_picker/widgets/date_type_option_button.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/date_picker/widgets/reminder_selector.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialog_v2.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/toggle/toggle.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_board/appflowy_board.dart';
|
||||
import 'package:appflowy_ui/appflowy_ui.dart';
|
||||
import 'package:calendar_view/calendar_view.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text_input.dart';
|
||||
import 'package:flowy_infra_ui/widget/buttons/primary_button.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@ -1646,18 +1647,13 @@ extension AppFlowyDatabaseTest on WidgetTester {
|
||||
|
||||
await enterText(
|
||||
find.descendant(
|
||||
of: find.byType(FlowyFormTextInput),
|
||||
matching: find.byType(TextFormField),
|
||||
of: find.byType(AFTextFieldDialog),
|
||||
matching: find.byType(AFTextField),
|
||||
),
|
||||
name,
|
||||
);
|
||||
|
||||
final field = find.byWidgetPredicate(
|
||||
(widget) =>
|
||||
widget is PrimaryTextButton &&
|
||||
widget.label == LocaleKeys.button_ok.tr(),
|
||||
);
|
||||
await tapButton(field);
|
||||
await tapButton(find.text(LocaleKeys.button_confirm.tr()));
|
||||
}
|
||||
|
||||
Future<void> deleteDatebaseView(Finder linkedView) async {
|
||||
|
||||
@ -4,8 +4,9 @@ import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sid
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialog_v2.dart';
|
||||
import 'package:appflowy_ui/appflowy_ui.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'util.dart';
|
||||
@ -31,26 +32,24 @@ extension AppFlowyWorkspace on WidgetTester {
|
||||
}
|
||||
|
||||
Future<void> changeWorkspaceName(String name) async {
|
||||
final moreButton = find.descendant(
|
||||
of: find.byType(WorkspaceMenuItem),
|
||||
matching: find.byType(WorkspaceMoreActionList),
|
||||
);
|
||||
expect(moreButton, findsOneWidget);
|
||||
final menuItem = find.byType(WorkspaceMenuItem);
|
||||
expect(menuItem, findsOneWidget);
|
||||
await hoverOnWidget(
|
||||
moreButton,
|
||||
menuItem,
|
||||
onHover: () async {
|
||||
await tapButton(moreButton);
|
||||
// wait for the menu to open
|
||||
final renameButton = find.findTextInFlowyText(
|
||||
LocaleKeys.button_rename.tr(),
|
||||
await tapButton(
|
||||
find.descendant(
|
||||
of: menuItem,
|
||||
matching: find.byType(WorkspaceMoreActionList),
|
||||
),
|
||||
);
|
||||
await tapButton(find.text(LocaleKeys.button_rename.tr()));
|
||||
final input = find.descendant(
|
||||
of: find.byType(AFTextFieldDialog),
|
||||
matching: find.byType(AFTextField),
|
||||
);
|
||||
await pumpUntilFound(renameButton);
|
||||
expect(renameButton, findsOneWidget);
|
||||
await tapButton(renameButton);
|
||||
final input = find.byType(TextFormField);
|
||||
expect(input, findsOneWidget);
|
||||
await enterText(input, name);
|
||||
await tapButton(find.text(LocaleKeys.button_ok.tr()));
|
||||
await tapButton(find.text(LocaleKeys.button_confirm.tr()));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import 'package:appflowy/workspace/application/view/view_ext.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_service.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/shared_widget.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_action_type.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialog_v2.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
|
||||
import 'package:appflowy_ui/appflowy_ui.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
@ -88,19 +89,19 @@ class SharedSection extends StatelessWidget {
|
||||
context.read<TabsBloc>().openTab(view);
|
||||
break;
|
||||
case ViewMoreActionType.rename:
|
||||
await NavigatorTextFieldDialog(
|
||||
await showAFTextFieldDialog(
|
||||
context: context,
|
||||
title: LocaleKeys.disclosureAction_rename.tr(),
|
||||
autoSelectAllText: true,
|
||||
value: view.nameOrDefault,
|
||||
initialValue: view.nameOrDefault,
|
||||
maxLength: 256,
|
||||
onConfirm: (newValue, _) {
|
||||
onConfirm: (newValue) {
|
||||
// can not use bloc here because it has been disposed.
|
||||
ViewBackendService.updateView(
|
||||
viewId: view.id,
|
||||
name: newValue,
|
||||
);
|
||||
},
|
||||
).show(context);
|
||||
);
|
||||
break;
|
||||
case ViewMoreActionType.leaveSharedPage:
|
||||
// show a dialog to confirm the action
|
||||
|
||||
@ -7,6 +7,7 @@ import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
|
||||
import 'package:appflowy/shared/icon_emoji_picker/tab.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_ext.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_service.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialog_v2.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
@ -227,10 +228,11 @@ class _TabBarItemButtonState extends State<TabBarItemButton> {
|
||||
action: TabBarViewAction.rename,
|
||||
itemHeight: ActionListSizes.itemHeight,
|
||||
onSelected: (action) {
|
||||
NavigatorTextFieldDialog(
|
||||
showAFTextFieldDialog(
|
||||
context: context,
|
||||
title: LocaleKeys.menuAppHeader_renameDialog.tr(),
|
||||
value: widget.view.nameOrDefault,
|
||||
onConfirm: (newValue, _) {
|
||||
initialValue: widget.view.nameOrDefault,
|
||||
onConfirm: (newValue) {
|
||||
context.read<DatabaseTabBarBloc>().add(
|
||||
DatabaseTabBarEvent.renameView(
|
||||
widget.view.id,
|
||||
@ -238,7 +240,7 @@ class _TabBarItemButtonState extends State<TabBarItemButton> {
|
||||
),
|
||||
);
|
||||
},
|
||||
).show(context);
|
||||
);
|
||||
menuController.close();
|
||||
},
|
||||
),
|
||||
|
||||
@ -9,7 +9,7 @@ import 'package:appflowy/workspace/application/view/view_ext.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_service.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_action_type.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_more_action_button.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialog_v2.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
@ -41,19 +41,19 @@ class FavoriteMoreActions extends StatelessWidget {
|
||||
PopoverContainer.maybeOf(context)?.closeAll();
|
||||
break;
|
||||
case ViewMoreActionType.rename:
|
||||
NavigatorTextFieldDialog(
|
||||
showAFTextFieldDialog(
|
||||
context: context,
|
||||
title: LocaleKeys.disclosureAction_rename.tr(),
|
||||
autoSelectAllText: true,
|
||||
value: view.nameOrDefault,
|
||||
initialValue: view.nameOrDefault,
|
||||
maxLength: 256,
|
||||
onConfirm: (newValue, _) {
|
||||
onConfirm: (newValue) {
|
||||
// can not use bloc here because it has been disposed.
|
||||
ViewBackendService.updateView(
|
||||
viewId: view.id,
|
||||
name: newValue,
|
||||
);
|
||||
},
|
||||
).show(context);
|
||||
);
|
||||
PopoverContainer.maybeOf(context)?.closeAll();
|
||||
break;
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/shared_w
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/space_action_type.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/space_more_popup.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_add_button.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialog_v2.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
@ -213,12 +214,12 @@ class _SidebarSpaceHeaderState extends State<SidebarSpaceHeader> {
|
||||
}
|
||||
|
||||
Future<void> _showRenameDialog() async {
|
||||
await NavigatorTextFieldDialog(
|
||||
await showAFTextFieldDialog(
|
||||
context: context,
|
||||
title: LocaleKeys.space_rename.tr(),
|
||||
value: widget.space.name,
|
||||
autoSelectAllText: true,
|
||||
initialValue: widget.space.name,
|
||||
hintText: LocaleKeys.space_spaceName.tr(),
|
||||
onConfirm: (name, _) {
|
||||
onConfirm: (name) {
|
||||
context.read<SpaceBloc>().add(
|
||||
SpaceEvent.rename(
|
||||
space: widget.space,
|
||||
@ -226,7 +227,7 @@ class _SidebarSpaceHeaderState extends State<SidebarSpaceHeader> {
|
||||
),
|
||||
);
|
||||
},
|
||||
).show(context);
|
||||
);
|
||||
}
|
||||
|
||||
void _showManageSpaceDialog(BuildContext context) {
|
||||
|
||||
@ -3,6 +3,7 @@ import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/shared/af_role_pb_extension.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/members/workspace_member_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialog_v2.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||
@ -155,12 +156,12 @@ class _WorkspaceMoreActionWrapper extends CustomActionCell {
|
||||
},
|
||||
);
|
||||
case WorkspaceMoreAction.rename:
|
||||
await NavigatorTextFieldDialog(
|
||||
await showAFTextFieldDialog(
|
||||
context: context,
|
||||
title: LocaleKeys.workspace_renameWorkspace.tr(),
|
||||
value: workspace.name,
|
||||
initialValue: workspace.name,
|
||||
hintText: '',
|
||||
autoSelectAllText: true,
|
||||
onConfirm: (name, context) async {
|
||||
onConfirm: (name) async {
|
||||
workspaceBloc.add(
|
||||
UserWorkspaceEvent.renameWorkspace(
|
||||
workspaceId: workspace.workspaceId,
|
||||
@ -168,7 +169,7 @@ class _WorkspaceMoreActionWrapper extends CustomActionCell {
|
||||
),
|
||||
);
|
||||
},
|
||||
).show(context);
|
||||
);
|
||||
case WorkspaceMoreAction.leave:
|
||||
await showConfirmDialog(
|
||||
context: context,
|
||||
|
||||
@ -9,6 +9,7 @@ import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_actions.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/members/workspace_member_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialog_v2.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||
@ -333,26 +334,6 @@ class _WorkspaceInfo extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class CreateWorkspaceDialog extends StatelessWidget {
|
||||
const CreateWorkspaceDialog({
|
||||
super.key,
|
||||
required this.onConfirm,
|
||||
});
|
||||
|
||||
final void Function(String name) onConfirm;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return NavigatorTextFieldDialog(
|
||||
title: LocaleKeys.workspace_create.tr(),
|
||||
value: '',
|
||||
hintText: '',
|
||||
autoSelectAllText: true,
|
||||
onConfirm: (name, _) => onConfirm(name),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _CreateWorkspaceButton extends StatelessWidget {
|
||||
const _CreateWorkspaceButton();
|
||||
|
||||
@ -399,7 +380,10 @@ class _CreateWorkspaceButton extends StatelessWidget {
|
||||
Future<void> _showCreateWorkspaceDialog(BuildContext context) async {
|
||||
if (context.mounted) {
|
||||
final workspaceBloc = context.read<UserWorkspaceBloc>();
|
||||
await CreateWorkspaceDialog(
|
||||
await showAFTextFieldDialog(
|
||||
context: context,
|
||||
title: LocaleKeys.workspace_create.tr(),
|
||||
initialValue: '',
|
||||
onConfirm: (name) {
|
||||
workspaceBloc.add(
|
||||
UserWorkspaceEvent.createWorkspace(
|
||||
@ -408,7 +392,7 @@ class _CreateWorkspaceButton extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
},
|
||||
).show(context);
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import 'package:appflowy/workspace/presentation/home/menu/view/draggable_view_it
|
||||
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_more_action_button.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialog_v2.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/more_view_actions/widgets/lock_page_action.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/rename_view_popover.dart';
|
||||
@ -766,15 +767,15 @@ class _SingleInnerViewItemState extends State<SingleInnerViewItem> {
|
||||
break;
|
||||
case ViewMoreActionType.rename:
|
||||
unawaited(
|
||||
NavigatorTextFieldDialog(
|
||||
showAFTextFieldDialog(
|
||||
context: context,
|
||||
title: LocaleKeys.disclosureAction_rename.tr(),
|
||||
autoSelectAllText: true,
|
||||
value: widget.view.nameOrDefault,
|
||||
maxLength: 256,
|
||||
onConfirm: (newValue, _) {
|
||||
initialValue: widget.view.nameOrDefault,
|
||||
onConfirm: (newValue) {
|
||||
context.read<ViewBloc>().add(ViewEvent.rename(newValue));
|
||||
},
|
||||
).show(context),
|
||||
maxLength: 256,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case ViewMoreActionType.delete:
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy_ui/appflowy_ui.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
typedef SimpleAFDialogAction = (String, void Function(BuildContext)?);
|
||||
@ -36,9 +38,6 @@ Future<void> showSimpleAFDialog({
|
||||
AFModalHeader(
|
||||
leading: Text(
|
||||
title,
|
||||
style: theme.textStyle.heading4.prominent(
|
||||
color: theme.textColorScheme.primary,
|
||||
),
|
||||
),
|
||||
trailing: [
|
||||
AFGhostButton.normal(
|
||||
@ -100,3 +99,158 @@ Future<void> showSimpleAFDialog({
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Shows a dialog for renaming an item with a text field.
|
||||
/// The API is flexible: either provide a callback for confirmation or use the
|
||||
/// returned Future to get the new value.
|
||||
///
|
||||
Future<String?> showAFTextFieldDialog({
|
||||
required BuildContext context,
|
||||
required String title,
|
||||
required String initialValue,
|
||||
void Function(String)? onConfirm,
|
||||
bool barrierDismissible = true,
|
||||
bool selectAll = true,
|
||||
int? maxLength,
|
||||
String? hintText,
|
||||
}) {
|
||||
return showDialog<String?>(
|
||||
context: context,
|
||||
barrierColor: AppFlowyTheme.of(context).surfaceColorScheme.overlay,
|
||||
barrierDismissible: barrierDismissible,
|
||||
builder: (context) {
|
||||
return AFTextFieldDialog(
|
||||
title: title,
|
||||
initialValue: initialValue,
|
||||
onConfirm: onConfirm,
|
||||
selectAll: selectAll,
|
||||
maxLength: maxLength,
|
||||
hintText: hintText,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
class AFTextFieldDialog extends StatefulWidget {
|
||||
const AFTextFieldDialog({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.initialValue,
|
||||
this.onConfirm,
|
||||
this.selectAll = true,
|
||||
this.maxLength,
|
||||
this.hintText,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final String initialValue;
|
||||
final void Function(String)? onConfirm;
|
||||
final bool selectAll;
|
||||
final int? maxLength;
|
||||
final String? hintText;
|
||||
|
||||
@override
|
||||
State<AFTextFieldDialog> createState() => _AFTextFieldDialogState();
|
||||
}
|
||||
|
||||
class _AFTextFieldDialogState extends State<AFTextFieldDialog> {
|
||||
final textController = TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
textController.value = TextEditingValue(
|
||||
text: widget.initialValue,
|
||||
selection: widget.selectAll
|
||||
? TextSelection(
|
||||
baseOffset: 0,
|
||||
extentOffset: widget.initialValue.length,
|
||||
)
|
||||
: TextSelection.collapsed(
|
||||
offset: widget.initialValue.length,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
textController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = AppFlowyTheme.of(context);
|
||||
|
||||
return AFModal(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: AFModalDimension.S,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
AFModalHeader(
|
||||
leading: Text(
|
||||
widget.title,
|
||||
),
|
||||
trailing: [
|
||||
AFGhostButton.normal(
|
||||
onTap: () => Navigator.of(context).pop(),
|
||||
padding: EdgeInsets.all(theme.spacing.xs),
|
||||
builder: (context, isHovering, disabled) {
|
||||
return FlowySvg(
|
||||
FlowySvgs.toast_close_s,
|
||||
size: Size.square(20),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
Flexible(
|
||||
child: AFModalBody(
|
||||
child: AFTextField(
|
||||
autoFocus: true,
|
||||
size: AFTextFieldSize.m,
|
||||
hintText: widget.hintText,
|
||||
maxLength: widget.maxLength,
|
||||
controller: textController,
|
||||
onSubmitted: (_) {
|
||||
handleConfirm();
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
AFModalFooter(
|
||||
trailing: [
|
||||
AFOutlinedTextButton.normal(
|
||||
text: LocaleKeys.button_cancel.tr(),
|
||||
onTap: () => Navigator.of(context).pop(),
|
||||
),
|
||||
ValueListenableBuilder(
|
||||
valueListenable: textController,
|
||||
builder: (contex, value, child) {
|
||||
return AFFilledTextButton.primary(
|
||||
text: LocaleKeys.button_confirm.tr(),
|
||||
disabled: value.text.trim().isEmpty,
|
||||
onTap: handleConfirm,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void handleConfirm() {
|
||||
final text = textController.text.trim();
|
||||
|
||||
if (text.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
widget.onConfirm?.call(text);
|
||||
Navigator.of(context).pop(text);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/startup/tasks/app_widget.dart';
|
||||
import 'package:appflowy/util/theme_extension.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/shared_widget.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text_input.dart';
|
||||
import 'package:flowy_infra_ui/widget/buttons/primary_button.dart';
|
||||
import 'package:flowy_infra_ui/widget/buttons/secondary_button.dart';
|
||||
import 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart';
|
||||
@ -74,107 +72,6 @@ class _NavigatorCustomDialog extends State<NavigatorCustomDialog> {
|
||||
}
|
||||
}
|
||||
|
||||
class NavigatorTextFieldDialog extends StatefulWidget {
|
||||
const NavigatorTextFieldDialog({
|
||||
super.key,
|
||||
required this.title,
|
||||
this.autoSelectAllText = false,
|
||||
required this.value,
|
||||
required this.onConfirm,
|
||||
this.onCancel,
|
||||
this.maxLength,
|
||||
this.hintText,
|
||||
});
|
||||
|
||||
final String value;
|
||||
final String title;
|
||||
final VoidCallback? onCancel;
|
||||
final void Function(String, BuildContext) onConfirm;
|
||||
final bool autoSelectAllText;
|
||||
final int? maxLength;
|
||||
final String? hintText;
|
||||
|
||||
@override
|
||||
State<NavigatorTextFieldDialog> createState() =>
|
||||
_NavigatorTextFieldDialogState();
|
||||
}
|
||||
|
||||
class _NavigatorTextFieldDialogState extends State<NavigatorTextFieldDialog> {
|
||||
String newValue = "";
|
||||
final controller = TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
newValue = widget.value;
|
||||
controller.text = newValue;
|
||||
if (widget.autoSelectAllText) {
|
||||
controller.selection = TextSelection(
|
||||
baseOffset: 0,
|
||||
extentOffset: newValue.length,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StyledDialog(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
FlowyText.medium(
|
||||
widget.title,
|
||||
color: Theme.of(context).colorScheme.tertiary,
|
||||
fontSize: FontSizes.s16,
|
||||
),
|
||||
VSpace(Insets.m),
|
||||
FlowyFormTextInput(
|
||||
hintText:
|
||||
widget.hintText ?? LocaleKeys.dialogCreatePageNameHint.tr(),
|
||||
controller: controller,
|
||||
textStyle: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall
|
||||
?.copyWith(fontSize: FontSizes.s16),
|
||||
maxLength: widget.maxLength,
|
||||
showCounter: false,
|
||||
autoFocus: true,
|
||||
onChanged: (text) {
|
||||
newValue = text;
|
||||
},
|
||||
onEditingComplete: () {
|
||||
widget.onConfirm(newValue, context);
|
||||
AppGlobals.nav.pop();
|
||||
},
|
||||
),
|
||||
VSpace(Insets.xl),
|
||||
OkCancelButton(
|
||||
onOkPressed: () {
|
||||
if (newValue.isEmpty) {
|
||||
showToastNotification(
|
||||
message: LocaleKeys.space_spaceNameCannotBeEmpty.tr(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
widget.onConfirm(newValue, context);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
onCancelPressed: () {
|
||||
widget.onCancel?.call();
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NavigatorAlertDialog extends StatefulWidget {
|
||||
const NavigatorAlertDialog({
|
||||
super.key,
|
||||
|
||||
@ -61,12 +61,17 @@ class AFModalHeader extends StatelessWidget {
|
||||
left: theme.spacing.xxl,
|
||||
right: theme.spacing.xxl,
|
||||
),
|
||||
child: Row(
|
||||
spacing: theme.spacing.s,
|
||||
children: [
|
||||
Expanded(child: leading),
|
||||
...trailing,
|
||||
],
|
||||
child: DefaultTextStyle(
|
||||
style: theme.textStyle.heading4.prominent(
|
||||
color: theme.textColorScheme.primary,
|
||||
),
|
||||
child: Row(
|
||||
spacing: theme.spacing.s,
|
||||
children: [
|
||||
Expanded(child: leading),
|
||||
...trailing,
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'package:appflowy_ui/src/theme/theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
typedef AFTextFieldValidator = (bool result, String errorText) Function(
|
||||
TextEditingController controller,
|
||||
@ -32,6 +33,7 @@ class AFTextField extends StatefulWidget {
|
||||
this.groupId = EditableText,
|
||||
this.focusNode,
|
||||
this.readOnly = false,
|
||||
this.maxLength,
|
||||
});
|
||||
|
||||
/// The hint text to display when the text field is empty.
|
||||
@ -82,6 +84,9 @@ class AFTextField extends StatefulWidget {
|
||||
/// Readonly.
|
||||
final bool readOnly;
|
||||
|
||||
/// The maximum length of the text field.
|
||||
final int? maxLength;
|
||||
|
||||
@override
|
||||
State<AFTextField> createState() => _AFTextFieldState();
|
||||
}
|
||||
@ -181,6 +186,8 @@ class _AFTextFieldState extends AFTextFieldState {
|
||||
onChanged: widget.onChanged,
|
||||
onSubmitted: widget.onSubmitted,
|
||||
autofocus: widget.autoFocus ?? false,
|
||||
maxLength: widget.maxLength,
|
||||
maxLengthEnforcement: MaxLengthEnforcement.truncateAfterCompositionEnds,
|
||||
decoration: InputDecoration(
|
||||
hintText: widget.hintText,
|
||||
hintStyle: theme.textStyle.body.standard(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user