2023-10-22 01:04:38 +08:00
|
|
|
import 'dart:io';
|
|
|
|
|
2023-09-14 19:22:32 +08:00
|
|
|
import 'package:appflowy/core/config/kv.dart';
|
|
|
|
import 'package:appflowy/core/config/kv_keys.dart';
|
2023-08-30 17:21:32 +08:00
|
|
|
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
|
|
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
|
|
|
import 'package:appflowy/plugins/document/presentation/share/share_button.dart';
|
2023-09-14 19:22:32 +08:00
|
|
|
import 'package:appflowy/startup/startup.dart';
|
2023-09-11 21:32:26 -05:00
|
|
|
import 'package:appflowy/user/presentation/screens/screens.dart';
|
2023-11-02 15:24:17 +08:00
|
|
|
import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widgets.dart';
|
2023-07-31 19:06:01 +07:00
|
|
|
import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_new_page_button.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_add_button.dart';
|
|
|
|
import 'package:appflowy/workspace/presentation/home/menu/view/view_more_action_button.dart';
|
2023-06-14 06:14:41 -05:00
|
|
|
import 'package:appflowy/workspace/presentation/settings/widgets/settings_language_view.dart';
|
2023-08-30 17:21:32 +08:00
|
|
|
import 'package:appflowy_backend/log.dart';
|
2023-06-15 16:33:44 +08:00
|
|
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
2022-12-20 11:14:42 +08:00
|
|
|
import 'package:easy_localization/easy_localization.dart';
|
2023-06-12 14:29:09 +08:00
|
|
|
import 'package:flowy_infra_ui/widget/buttons/primary_button.dart';
|
2023-08-02 18:50:51 +05:30
|
|
|
import 'package:flutter/gestures.dart';
|
2023-06-12 14:29:09 +08:00
|
|
|
import 'package:flutter/material.dart';
|
2023-06-21 19:53:29 +08:00
|
|
|
import 'package:flutter/services.dart';
|
2022-12-20 11:14:42 +08:00
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
|
2023-06-12 20:32:55 +08:00
|
|
|
import 'util.dart';
|
2023-06-05 13:10:14 +08:00
|
|
|
|
2023-06-11 14:19:44 +08:00
|
|
|
extension CommonOperations on WidgetTester {
|
2023-06-12 20:32:55 +08:00
|
|
|
/// Tap the GetStart button on the launch page.
|
2022-12-20 11:14:42 +08:00
|
|
|
Future<void> tapGoButton() async {
|
2023-11-02 15:24:17 +08:00
|
|
|
// local version
|
2023-06-05 13:10:14 +08:00
|
|
|
final goButton = find.byType(GoButton);
|
2023-11-02 15:24:17 +08:00
|
|
|
if (goButton.evaluate().isNotEmpty) {
|
|
|
|
await tapButton(goButton);
|
|
|
|
} else {
|
|
|
|
// cloud version
|
|
|
|
final anonymousButton = find.byType(SignInAnonymousButton);
|
|
|
|
await tapButton(anonymousButton);
|
|
|
|
}
|
2023-10-22 01:04:38 +08:00
|
|
|
|
|
|
|
if (Platform.isWindows) {
|
|
|
|
await pumpAndSettle(const Duration(milliseconds: 200));
|
|
|
|
}
|
2022-12-20 11:14:42 +08:00
|
|
|
}
|
|
|
|
|
2023-06-12 20:32:55 +08:00
|
|
|
/// Tap the + button on the home page.
|
2023-07-31 19:06:01 +07:00
|
|
|
Future<void> tapAddViewButton({
|
2023-08-08 07:09:17 +02:00
|
|
|
String name = gettingStarted,
|
2023-07-31 19:06:01 +07:00
|
|
|
}) async {
|
|
|
|
await hoverOnPageName(
|
|
|
|
name,
|
|
|
|
onHover: () async {
|
|
|
|
final addButton = find.byType(ViewAddButton);
|
|
|
|
await tapButton(addButton);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Tap the 'New Page' Button on the sidebar.
|
|
|
|
Future<void> tapNewPageButton() async {
|
|
|
|
final newPageButton = find.byType(SidebarNewPageButton);
|
|
|
|
await tapButton(newPageButton);
|
2023-06-05 13:10:14 +08:00
|
|
|
}
|
|
|
|
|
2023-06-12 20:32:55 +08:00
|
|
|
/// Tap the create document button.
|
|
|
|
///
|
2023-07-31 19:06:01 +07:00
|
|
|
/// Must call [tapAddViewButton] first.
|
2023-06-05 13:10:14 +08:00
|
|
|
Future<void> tapCreateDocumentButton() async {
|
|
|
|
await tapButtonWithName(LocaleKeys.document_menuName.tr());
|
|
|
|
}
|
|
|
|
|
2023-06-14 22:16:33 +08:00
|
|
|
/// Tap the create grid button.
|
|
|
|
///
|
2023-07-31 19:06:01 +07:00
|
|
|
/// Must call [tapAddViewButton] first.
|
2023-06-14 22:16:33 +08:00
|
|
|
Future<void> tapCreateGridButton() async {
|
|
|
|
await tapButtonWithName(LocaleKeys.grid_menuName.tr());
|
|
|
|
}
|
|
|
|
|
2023-06-20 23:48:34 +08:00
|
|
|
/// Tap the create grid button.
|
|
|
|
///
|
2023-07-31 19:06:01 +07:00
|
|
|
/// Must call [tapAddViewButton] first.
|
2023-06-20 23:48:34 +08:00
|
|
|
Future<void> tapCreateCalendarButton() async {
|
|
|
|
await tapButtonWithName(LocaleKeys.calendar_menuName.tr());
|
|
|
|
}
|
|
|
|
|
2023-06-12 20:32:55 +08:00
|
|
|
/// Tap the import button.
|
|
|
|
///
|
2023-07-31 19:06:01 +07:00
|
|
|
/// Must call [tapAddViewButton] first.
|
2023-06-12 14:36:55 +08:00
|
|
|
Future<void> tapImportButton() async {
|
|
|
|
await tapButtonWithName(LocaleKeys.moreAction_import.tr());
|
|
|
|
}
|
|
|
|
|
2023-06-12 20:32:55 +08:00
|
|
|
/// Tap the import from text & markdown button.
|
|
|
|
///
|
|
|
|
/// Must call [tapImportButton] first.
|
2023-06-12 14:36:55 +08:00
|
|
|
Future<void> tapTextAndMarkdownButton() async {
|
|
|
|
await tapButtonWithName(LocaleKeys.importPanel_textAndMarkdown.tr());
|
|
|
|
}
|
|
|
|
|
2023-06-14 06:14:41 -05:00
|
|
|
/// Tap the LanguageSelectorOnWelcomePage widget on the launch page.
|
|
|
|
Future<void> tapLanguageSelectorOnWelcomePage() async {
|
|
|
|
final languageSelector = find.byType(LanguageSelectorOnWelcomePage);
|
|
|
|
await tapButton(languageSelector);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Tap languageItem on LanguageItemsListView.
|
|
|
|
///
|
|
|
|
/// [scrollDelta] is the distance to scroll the ListView.
|
|
|
|
/// Default value is 100
|
|
|
|
///
|
|
|
|
/// If it is positive -> scroll down.
|
|
|
|
///
|
|
|
|
/// If it is negative -> scroll up.
|
|
|
|
Future<void> tapLanguageItem({
|
|
|
|
required String languageCode,
|
|
|
|
String? countryCode,
|
|
|
|
double? scrollDelta,
|
|
|
|
}) async {
|
|
|
|
final languageItemsListView = find.descendant(
|
|
|
|
of: find.byType(ListView),
|
|
|
|
matching: find.byType(Scrollable),
|
|
|
|
);
|
|
|
|
|
|
|
|
final languageItem = find.byWidgetPredicate(
|
|
|
|
(widget) =>
|
|
|
|
widget is LanguageItem &&
|
|
|
|
widget.locale.languageCode == languageCode &&
|
|
|
|
widget.locale.countryCode == countryCode,
|
|
|
|
);
|
|
|
|
|
|
|
|
// scroll the ListView until zHCNLanguageItem shows on the screen.
|
|
|
|
await scrollUntilVisible(
|
|
|
|
languageItem,
|
|
|
|
scrollDelta ?? 100,
|
|
|
|
scrollable: languageItemsListView,
|
|
|
|
// maxHeight of LanguageItemsListView
|
|
|
|
maxScrolls: 400,
|
|
|
|
);
|
|
|
|
|
|
|
|
try {
|
|
|
|
await tapButton(languageItem);
|
|
|
|
} on FlutterError catch (e) {
|
|
|
|
Log.warn('tapLanguageItem error: $e');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-12 20:32:55 +08:00
|
|
|
/// Hover on the widget.
|
|
|
|
Future<void> hoverOnWidget(
|
|
|
|
Finder finder, {
|
|
|
|
Offset? offset,
|
2023-06-15 16:33:44 +08:00
|
|
|
Future<void> Function()? onHover,
|
2023-07-31 19:06:01 +07:00
|
|
|
bool removePointer = true,
|
2023-06-12 20:32:55 +08:00
|
|
|
}) async {
|
2023-06-14 22:16:33 +08:00
|
|
|
try {
|
|
|
|
final gesture = await createGesture(kind: PointerDeviceKind.mouse);
|
|
|
|
await gesture.addPointer(location: Offset.zero);
|
|
|
|
await pump();
|
|
|
|
await gesture.moveTo(offset ?? getCenter(finder));
|
|
|
|
await pumpAndSettle();
|
2023-06-15 16:33:44 +08:00
|
|
|
await onHover?.call();
|
|
|
|
await gesture.removePointer();
|
|
|
|
} catch (err) {
|
|
|
|
Log.error('hoverOnWidget error: $err');
|
|
|
|
}
|
2023-06-05 13:10:14 +08:00
|
|
|
}
|
|
|
|
|
2023-06-12 20:32:55 +08:00
|
|
|
/// Hover on the page name.
|
2023-06-15 16:33:44 +08:00
|
|
|
Future<void> hoverOnPageName(
|
|
|
|
String name, {
|
2023-07-31 19:06:01 +07:00
|
|
|
ViewLayoutPB layout = ViewLayoutPB.Document,
|
2023-06-15 16:33:44 +08:00
|
|
|
Future<void> Function()? onHover,
|
|
|
|
bool useLast = true,
|
|
|
|
}) async {
|
2023-07-31 19:06:01 +07:00
|
|
|
final pageNames = findPageName(name, layout: layout);
|
2023-06-15 16:33:44 +08:00
|
|
|
if (useLast) {
|
2023-07-31 19:06:01 +07:00
|
|
|
await hoverOnWidget(
|
|
|
|
pageNames.last,
|
|
|
|
onHover: onHover,
|
|
|
|
);
|
2023-06-15 16:33:44 +08:00
|
|
|
} else {
|
2023-07-31 19:06:01 +07:00
|
|
|
await hoverOnWidget(
|
|
|
|
pageNames.first,
|
|
|
|
onHover: onHover,
|
|
|
|
);
|
2023-06-15 16:33:44 +08:00
|
|
|
}
|
2023-06-12 20:32:55 +08:00
|
|
|
}
|
|
|
|
|
2023-06-15 22:43:07 +08:00
|
|
|
/// open the page with given name.
|
2023-07-31 19:06:01 +07:00
|
|
|
Future<void> openPage(
|
|
|
|
String name, {
|
|
|
|
ViewLayoutPB layout = ViewLayoutPB.Document,
|
|
|
|
}) async {
|
|
|
|
final finder = findPageName(name, layout: layout);
|
2023-06-20 23:48:34 +08:00
|
|
|
expect(finder, findsOneWidget);
|
|
|
|
await tapButton(finder);
|
2023-06-15 22:43:07 +08:00
|
|
|
}
|
|
|
|
|
2023-06-12 20:32:55 +08:00
|
|
|
/// Tap the ... button beside the page name.
|
|
|
|
///
|
|
|
|
/// Must call [hoverOnPageName] first.
|
2023-06-05 13:10:14 +08:00
|
|
|
Future<void> tapPageOptionButton() async {
|
2023-07-31 19:06:01 +07:00
|
|
|
final optionButton = find.byType(ViewMoreActionButton);
|
2023-06-05 13:10:14 +08:00
|
|
|
await tapButton(optionButton);
|
|
|
|
}
|
|
|
|
|
2023-06-12 20:32:55 +08:00
|
|
|
/// Tap the delete page button.
|
2023-06-05 13:10:14 +08:00
|
|
|
Future<void> tapDeletePageButton() async {
|
|
|
|
await tapPageOptionButton();
|
2023-07-31 19:06:01 +07:00
|
|
|
await tapButtonWithName(ViewMoreActionType.delete.name);
|
2023-06-05 13:10:14 +08:00
|
|
|
}
|
|
|
|
|
2023-06-12 20:32:55 +08:00
|
|
|
/// Tap the rename page button.
|
2023-06-12 14:29:09 +08:00
|
|
|
Future<void> tapRenamePageButton() async {
|
|
|
|
await tapPageOptionButton();
|
2023-07-31 19:06:01 +07:00
|
|
|
await tapButtonWithName(ViewMoreActionType.rename.name);
|
2023-06-12 14:29:09 +08:00
|
|
|
}
|
|
|
|
|
2023-08-02 18:50:51 +05:30
|
|
|
/// Tap the favorite page button
|
|
|
|
Future<void> tapFavoritePageButton() async {
|
|
|
|
await tapPageOptionButton();
|
|
|
|
await tapButtonWithName(ViewMoreActionType.favorite.name);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Tap the unfavorite page button
|
|
|
|
Future<void> tapUnfavoritePageButton() async {
|
|
|
|
await tapPageOptionButton();
|
|
|
|
await tapButtonWithName(ViewMoreActionType.unFavorite.name);
|
|
|
|
}
|
|
|
|
|
2023-08-08 07:09:17 +02:00
|
|
|
/// Tap the Open in a new tab button
|
|
|
|
Future<void> tapOpenInTabButton() async {
|
|
|
|
await tapPageOptionButton();
|
|
|
|
await tapButtonWithName(ViewMoreActionType.openInNewTab.name);
|
|
|
|
}
|
|
|
|
|
2023-06-12 20:32:55 +08:00
|
|
|
/// Rename the page.
|
2023-06-12 14:29:09 +08:00
|
|
|
Future<void> renamePage(String name) async {
|
|
|
|
await tapRenamePageButton();
|
|
|
|
await enterText(find.byType(TextFormField), name);
|
|
|
|
await tapOKButton();
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> tapOKButton() async {
|
|
|
|
final okButton = find.byWidgetPredicate(
|
|
|
|
(widget) =>
|
|
|
|
widget is PrimaryTextButton &&
|
2023-10-25 06:29:50 -07:00
|
|
|
widget.label == LocaleKeys.button_ok.tr(),
|
2023-06-12 14:29:09 +08:00
|
|
|
);
|
|
|
|
await tapButton(okButton);
|
|
|
|
}
|
|
|
|
|
2023-06-12 20:32:55 +08:00
|
|
|
/// Tap the restore button.
|
|
|
|
///
|
|
|
|
/// the restore button will show after the current page is deleted.
|
2023-06-05 13:10:14 +08:00
|
|
|
Future<void> tapRestoreButton() async {
|
|
|
|
final restoreButton = find.textContaining(
|
|
|
|
LocaleKeys.deletePagePrompt_restore.tr(),
|
|
|
|
);
|
|
|
|
await tapButton(restoreButton);
|
|
|
|
}
|
|
|
|
|
2023-06-12 20:32:55 +08:00
|
|
|
/// Tap the delete permanently button.
|
|
|
|
///
|
|
|
|
/// the restore button will show after the current page is deleted.
|
2023-06-05 13:10:14 +08:00
|
|
|
Future<void> tapDeletePermanentlyButton() async {
|
|
|
|
final restoreButton = find.textContaining(
|
|
|
|
LocaleKeys.deletePagePrompt_deletePermanent.tr(),
|
|
|
|
);
|
|
|
|
await tapButton(restoreButton);
|
|
|
|
}
|
2023-06-10 22:38:25 +08:00
|
|
|
|
2023-06-12 20:32:55 +08:00
|
|
|
/// Tap the share button above the document page.
|
2023-06-10 22:38:25 +08:00
|
|
|
Future<void> tapShareButton() async {
|
|
|
|
final shareButton = find.byWidgetPredicate(
|
|
|
|
(widget) => widget is DocumentShareButton,
|
|
|
|
);
|
|
|
|
await tapButton(shareButton);
|
|
|
|
}
|
|
|
|
|
2023-06-12 20:32:55 +08:00
|
|
|
/// Tap the export markdown button
|
|
|
|
///
|
|
|
|
/// Must call [tapShareButton] first.
|
2023-06-10 22:38:25 +08:00
|
|
|
Future<void> tapMarkdownButton() async {
|
|
|
|
final markdownButton = find.textContaining(
|
|
|
|
LocaleKeys.shareAction_markdown.tr(),
|
|
|
|
);
|
|
|
|
await tapButton(markdownButton);
|
|
|
|
}
|
|
|
|
|
2023-07-31 19:06:01 +07:00
|
|
|
Future<void> createNewPageWithName({
|
2023-07-15 08:45:44 +07:00
|
|
|
String? name,
|
2023-07-31 19:06:01 +07:00
|
|
|
ViewLayoutPB layout = ViewLayoutPB.Document,
|
|
|
|
String? parentName,
|
|
|
|
bool openAfterCreated = true,
|
|
|
|
}) async {
|
2023-06-15 16:33:44 +08:00
|
|
|
// create a new page
|
2023-08-08 07:09:17 +02:00
|
|
|
await tapAddViewButton(name: parentName ?? gettingStarted);
|
2023-06-15 16:33:44 +08:00
|
|
|
await tapButtonWithName(layout.menuName);
|
2023-09-14 19:22:32 +08:00
|
|
|
final settingsOrFailure = await getIt<KeyValueStorage>().getWithFormat(
|
|
|
|
KVKeys.showRenameDialogWhenCreatingNewFile,
|
|
|
|
(value) => bool.parse(value),
|
|
|
|
);
|
|
|
|
final showRenameDialog = settingsOrFailure.fold((l) => false, (r) => r);
|
|
|
|
if (showRenameDialog) {
|
|
|
|
await tapOKButton();
|
|
|
|
}
|
2023-06-15 16:33:44 +08:00
|
|
|
await pumpAndSettle();
|
|
|
|
|
|
|
|
// hover on it and change it's name
|
2023-07-15 08:45:44 +07:00
|
|
|
if (name != null) {
|
|
|
|
await hoverOnPageName(
|
|
|
|
LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
2023-07-31 19:06:01 +07:00
|
|
|
layout: layout,
|
2023-07-15 08:45:44 +07:00
|
|
|
onHover: () async {
|
|
|
|
await renamePage(name);
|
|
|
|
await pumpAndSettle();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
await pumpAndSettle();
|
|
|
|
}
|
2023-07-31 19:06:01 +07:00
|
|
|
|
|
|
|
// open the page after created
|
|
|
|
if (openAfterCreated) {
|
|
|
|
await openPage(
|
|
|
|
// if the name is null, use the default name
|
|
|
|
name ?? LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
|
|
|
layout: layout,
|
|
|
|
);
|
|
|
|
await pumpAndSettle();
|
|
|
|
}
|
2023-06-15 16:33:44 +08:00
|
|
|
}
|
2023-06-21 19:53:29 +08:00
|
|
|
|
|
|
|
Future<void> simulateKeyEvent(
|
|
|
|
LogicalKeyboardKey key, {
|
|
|
|
bool isControlPressed = false,
|
|
|
|
bool isShiftPressed = false,
|
|
|
|
bool isAltPressed = false,
|
|
|
|
bool isMetaPressed = false,
|
|
|
|
}) async {
|
|
|
|
if (isControlPressed) {
|
|
|
|
await simulateKeyDownEvent(LogicalKeyboardKey.control);
|
|
|
|
}
|
|
|
|
if (isShiftPressed) {
|
|
|
|
await simulateKeyDownEvent(LogicalKeyboardKey.shift);
|
|
|
|
}
|
|
|
|
if (isAltPressed) {
|
|
|
|
await simulateKeyDownEvent(LogicalKeyboardKey.alt);
|
|
|
|
}
|
|
|
|
if (isMetaPressed) {
|
|
|
|
await simulateKeyDownEvent(LogicalKeyboardKey.meta);
|
|
|
|
}
|
|
|
|
await simulateKeyDownEvent(key);
|
|
|
|
await simulateKeyUpEvent(key);
|
|
|
|
if (isControlPressed) {
|
|
|
|
await simulateKeyUpEvent(LogicalKeyboardKey.control);
|
|
|
|
}
|
|
|
|
if (isShiftPressed) {
|
|
|
|
await simulateKeyUpEvent(LogicalKeyboardKey.shift);
|
|
|
|
}
|
|
|
|
if (isAltPressed) {
|
|
|
|
await simulateKeyUpEvent(LogicalKeyboardKey.alt);
|
|
|
|
}
|
|
|
|
if (isMetaPressed) {
|
|
|
|
await simulateKeyUpEvent(LogicalKeyboardKey.meta);
|
|
|
|
}
|
|
|
|
await pumpAndSettle();
|
|
|
|
}
|
2023-07-12 13:13:18 +02:00
|
|
|
|
2023-08-08 07:09:17 +02:00
|
|
|
Future<void> openAppInNewTab(String name, ViewLayoutPB layout) async {
|
|
|
|
await hoverOnPageName(
|
|
|
|
name,
|
|
|
|
onHover: () async {
|
|
|
|
await tapOpenInTabButton();
|
|
|
|
await pumpAndSettle();
|
|
|
|
},
|
|
|
|
);
|
2023-07-12 13:13:18 +02:00
|
|
|
await pumpAndSettle();
|
|
|
|
}
|
2023-07-31 19:06:01 +07:00
|
|
|
|
2023-08-02 18:50:51 +05:30
|
|
|
Future<void> favoriteViewByName(
|
|
|
|
String name, {
|
|
|
|
ViewLayoutPB layout = ViewLayoutPB.Document,
|
|
|
|
}) async {
|
|
|
|
await hoverOnPageName(
|
|
|
|
name,
|
|
|
|
layout: layout,
|
2023-08-03 14:06:02 +07:00
|
|
|
useLast: true,
|
2023-08-02 18:50:51 +05:30
|
|
|
onHover: () async {
|
|
|
|
await tapFavoritePageButton();
|
|
|
|
await pumpAndSettle();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> unfavoriteViewByName(
|
|
|
|
String name, {
|
|
|
|
ViewLayoutPB layout = ViewLayoutPB.Document,
|
|
|
|
}) async {
|
|
|
|
await hoverOnPageName(
|
|
|
|
name,
|
|
|
|
layout: layout,
|
2023-08-03 14:06:02 +07:00
|
|
|
useLast: true,
|
2023-08-02 18:50:51 +05:30
|
|
|
onHover: () async {
|
|
|
|
await tapUnfavoritePageButton();
|
|
|
|
await pumpAndSettle();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-07-31 19:06:01 +07:00
|
|
|
Future<void> movePageToOtherPage({
|
|
|
|
required String name,
|
|
|
|
required String parentName,
|
|
|
|
required ViewLayoutPB layout,
|
|
|
|
required ViewLayoutPB parentLayout,
|
|
|
|
DraggableHoverPosition position = DraggableHoverPosition.center,
|
|
|
|
}) async {
|
|
|
|
final from = findPageName(name, layout: layout);
|
|
|
|
final to = findPageName(parentName, layout: parentLayout);
|
|
|
|
final gesture = await startGesture(getCenter(from));
|
|
|
|
Offset offset = Offset.zero;
|
|
|
|
switch (position) {
|
|
|
|
case DraggableHoverPosition.center:
|
|
|
|
offset = getCenter(to);
|
|
|
|
break;
|
|
|
|
case DraggableHoverPosition.top:
|
|
|
|
offset = getTopLeft(to);
|
|
|
|
break;
|
|
|
|
case DraggableHoverPosition.bottom:
|
|
|
|
offset = getBottomLeft(to);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
}
|
2023-08-03 14:06:02 +07:00
|
|
|
await gesture.moveTo(offset, timeStamp: const Duration(milliseconds: 400));
|
2023-07-31 19:06:01 +07:00
|
|
|
await gesture.up();
|
|
|
|
await pumpAndSettle();
|
|
|
|
}
|
2023-08-30 17:21:32 +08:00
|
|
|
|
|
|
|
// tap the button with [FlowySvgData]
|
|
|
|
Future<void> tapButtonWithFlowySvgData(FlowySvgData svg) async {
|
|
|
|
final button = find.byWidgetPredicate(
|
|
|
|
(widget) => widget is FlowySvg && widget.svg.path == svg.path,
|
|
|
|
);
|
|
|
|
await tapButton(button);
|
|
|
|
}
|
2023-06-15 16:33:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
extension ViewLayoutPBTest on ViewLayoutPB {
|
|
|
|
String get menuName {
|
|
|
|
switch (this) {
|
|
|
|
case ViewLayoutPB.Grid:
|
|
|
|
return LocaleKeys.grid_menuName.tr();
|
|
|
|
case ViewLayoutPB.Board:
|
|
|
|
return LocaleKeys.board_menuName.tr();
|
|
|
|
case ViewLayoutPB.Document:
|
|
|
|
return LocaleKeys.document_menuName.tr();
|
|
|
|
case ViewLayoutPB.Calendar:
|
|
|
|
return LocaleKeys.calendar_menuName.tr();
|
|
|
|
default:
|
|
|
|
throw UnsupportedError('Unsupported layout: $this');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
String get referencedMenuName {
|
|
|
|
switch (this) {
|
|
|
|
case ViewLayoutPB.Grid:
|
|
|
|
return LocaleKeys.document_plugins_referencedGrid.tr();
|
|
|
|
case ViewLayoutPB.Board:
|
|
|
|
return LocaleKeys.document_plugins_referencedBoard.tr();
|
|
|
|
case ViewLayoutPB.Calendar:
|
|
|
|
return LocaleKeys.document_plugins_referencedCalendar.tr();
|
|
|
|
default:
|
|
|
|
throw UnsupportedError('Unsupported layout: $this');
|
|
|
|
}
|
2023-06-11 14:19:44 +08:00
|
|
|
}
|
2022-12-20 11:14:42 +08:00
|
|
|
}
|