import 'dart:convert'; import 'dart:io'; import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/clipboard_service.dart'; import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart'; import 'package:appflowy/shared/icon_emoji_picker/icon_color_picker.dart'; import 'package:appflowy/shared/icon_emoji_picker/icon_picker.dart'; import 'package:appflowy/shared/icon_emoji_picker/icon_uploader.dart'; import 'package:appflowy/shared/icon_emoji_picker/tab.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/space_icon_popup.dart'; import 'package:desktop_drop/desktop_drop.dart'; import 'package:flowy_infra_ui/style_widget/primary_rounded_button.dart'; import 'package:flowy_svg/flowy_svg.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_emoji_mart/flutter_emoji_mart.dart'; import 'package:flutter_test/flutter_test.dart'; import 'base.dart'; import 'common_operations.dart'; extension EmojiTestExtension on WidgetTester { Future tapEmoji(String emoji) async { final emojiWidget = find.descendant( of: find.byType(EmojiPicker), matching: find.text(emoji), ); await tapButton(emojiWidget); } Future tapIcon(EmojiIconData icon, {bool enableColor = true}) async { final iconsData = IconsData.fromJson(jsonDecode(icon.emoji)); final pickTab = find.byType(PickerTab); expect(pickTab, findsOneWidget); await pumpAndSettle(); final iconTab = find.descendant( of: pickTab, matching: find.text(PickerTabType.icon.tr), ); expect(iconTab, findsOneWidget); await tapButton(iconTab); final selectedSvg = find.descendant( of: find.byType(FlowyIconPicker), matching: find.byWidgetPredicate( (w) => w is FlowySvg && w.svgString == iconsData.svgString, ), ); await tapButton(selectedSvg.first); if (enableColor) { final colorPicker = find.byType(IconColorPicker); expect(colorPicker, findsOneWidget); final selectedColor = find.descendant( of: colorPicker, matching: find.byWidgetPredicate((w) { if (w is Container) { final d = w.decoration; if (d is ShapeDecoration) { if (d.color == Color( int.parse(iconsData.color ?? builtInSpaceColors.first), )) { return true; } } } return false; }), ); await tapButton(selectedColor); } } Future pickImage(EmojiIconData icon) async { final pickTab = find.byType(PickerTab); expect(pickTab, findsOneWidget); await pumpAndSettle(); /// switch to custom tab final iconTab = find.descendant( of: pickTab, matching: find.text(PickerTabType.custom.tr), ); expect(iconTab, findsOneWidget); await tapButton(iconTab); /// mock for dragging image final dropTarget = find.descendant( of: find.byType(IconUploader), matching: find.byType(DropTarget), ); expect(dropTarget, findsOneWidget); final dropTargetWidget = dropTarget.evaluate().first.widget as DropTarget; dropTargetWidget.onDragDone?.call( DropDoneDetails( files: [DropItemFile(icon.emoji)], localPosition: Offset.zero, globalPosition: Offset.zero, ), ); await pumpAndSettle(const Duration(seconds: 3)); /// confirm to upload final confirmButton = find.descendant( of: find.byType(IconUploader), matching: find.byType(PrimaryRoundedButton), ); await tapButton(confirmButton); } Future pasteImageLinkAsIcon(String link) async { final pickTab = find.byType(PickerTab); expect(pickTab, findsOneWidget); await pumpAndSettle(); /// switch to custom tab final iconTab = find.descendant( of: pickTab, matching: find.text(PickerTabType.custom.tr), ); expect(iconTab, findsOneWidget); await tapButton(iconTab); // mock the clipboard await getIt() .setData(ClipboardServiceData(plainText: link)); // paste the link await simulateKeyEvent( LogicalKeyboardKey.keyV, isControlPressed: Platform.isLinux || Platform.isWindows, isMetaPressed: Platform.isMacOS, ); await pumpAndSettle(const Duration(seconds: 5)); /// confirm to upload final confirmButton = find.descendant( of: find.byType(IconUploader), matching: find.byType(PrimaryRoundedButton), ); await tapButton(confirmButton); } }