mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-11-09 06:58:13 +00:00
feat: show file popover automatically (#6453)
This commit is contained in:
parent
37f99988eb
commit
cb2b933a90
@ -1,5 +1,7 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'package:appflowy/core/config/kv.dart';
|
import 'package:appflowy/core/config/kv.dart';
|
||||||
import 'package:appflowy/core/config/kv_keys.dart';
|
import 'package:appflowy/core/config/kv_keys.dart';
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
@ -8,7 +10,6 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.da
|
|||||||
import 'package:appflowy/startup/startup.dart';
|
import 'package:appflowy/startup/startup.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:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
@ -36,10 +37,6 @@ void main() {
|
|||||||
LocaleKeys.document_slashMenu_name_file.tr(),
|
LocaleKeys.document_slashMenu_name_file.tr(),
|
||||||
);
|
);
|
||||||
expect(find.byType(FileBlockComponent), findsOneWidget);
|
expect(find.byType(FileBlockComponent), findsOneWidget);
|
||||||
|
|
||||||
await tester.tap(find.byType(FileBlockComponent));
|
|
||||||
await tester.pumpAndSettle(const Duration(seconds: 1));
|
|
||||||
|
|
||||||
expect(find.byType(FileUploadMenu), findsOneWidget);
|
expect(find.byType(FileUploadMenu), findsOneWidget);
|
||||||
|
|
||||||
final image = await rootBundle.load('assets/test/images/sample.jpeg');
|
final image = await rootBundle.load('assets/test/images/sample.jpeg');
|
||||||
@ -116,9 +113,6 @@ void main() {
|
|||||||
LocaleKeys.document_slashMenu_name_file.tr(),
|
LocaleKeys.document_slashMenu_name_file.tr(),
|
||||||
);
|
);
|
||||||
expect(find.byType(FileBlockComponent), findsOneWidget);
|
expect(find.byType(FileBlockComponent), findsOneWidget);
|
||||||
|
|
||||||
await tester.tap(find.byType(FileBlockComponent));
|
|
||||||
await tester.pumpAndSettle(const Duration(seconds: 1));
|
|
||||||
expect(find.byType(FileUploadMenu), findsOneWidget);
|
expect(find.byType(FileUploadMenu), findsOneWidget);
|
||||||
|
|
||||||
// Navigate to integrate link tab
|
// Navigate to integrate link tab
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:appflowy/core/helpers/url_launcher.dart';
|
import 'package:appflowy/core/helpers/url_launcher.dart';
|
||||||
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';
|
||||||
@ -18,7 +20,6 @@ import 'package:desktop_drop/desktop_drop.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:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:open_filex/open_filex.dart';
|
import 'package:open_filex/open_filex.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@ -64,6 +65,11 @@ class FileBlockKeys {
|
|||||||
/// The value is a String, in form of user id.
|
/// The value is a String, in form of user id.
|
||||||
///
|
///
|
||||||
static const String uploadedBy = 'uploaded_by';
|
static const String uploadedBy = 'uploaded_by';
|
||||||
|
|
||||||
|
/// The GlobalKey of the FileBlockComponentState.
|
||||||
|
///
|
||||||
|
/// **Note: This value is used in extraInfos of the Node, not in the attributes.**
|
||||||
|
static const String globalKey = 'global_key';
|
||||||
}
|
}
|
||||||
|
|
||||||
enum FileUrlType {
|
enum FileUrlType {
|
||||||
@ -118,8 +124,11 @@ class FileBlockComponentBuilder extends BlockComponentBuilder {
|
|||||||
@override
|
@override
|
||||||
BlockComponentWidget build(BlockComponentContext blockComponentContext) {
|
BlockComponentWidget build(BlockComponentContext blockComponentContext) {
|
||||||
final node = blockComponentContext.node;
|
final node = blockComponentContext.node;
|
||||||
|
final extraInfos = node.extraInfos;
|
||||||
|
final key = extraInfos?[FileBlockKeys.globalKey] as GlobalKey?;
|
||||||
|
|
||||||
return FileBlockComponent(
|
return FileBlockComponent(
|
||||||
key: node.key,
|
key: key ?? node.key,
|
||||||
node: node,
|
node: node,
|
||||||
showActions: showActions(node),
|
showActions: showActions(node),
|
||||||
configuration: configuration,
|
configuration: configuration,
|
||||||
|
|||||||
@ -1,23 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
|
||||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
|
||||||
|
|
||||||
final fileMenuItem = SelectionMenuItem(
|
|
||||||
getName: () => LocaleKeys.document_plugins_file_name.tr(),
|
|
||||||
icon: (_, isSelected, style) => SelectionMenuIconWidget(
|
|
||||||
icon: Icons.file_present_outlined,
|
|
||||||
isSelected: isSelected,
|
|
||||||
style: style,
|
|
||||||
),
|
|
||||||
keywords: ['file upload', 'pdf', 'zip', 'archive', 'upload'],
|
|
||||||
handler: (editorState, _, __) async => editorState.insertEmptyFileBlock(),
|
|
||||||
);
|
|
||||||
|
|
||||||
extension InsertFile on EditorState {
|
extension InsertFile on EditorState {
|
||||||
Future<void> insertEmptyFileBlock() async {
|
Future<void> insertEmptyFileBlock(GlobalKey key) async {
|
||||||
final selection = this.selection;
|
final selection = this.selection;
|
||||||
if (selection == null || !selection.isCollapsed) {
|
if (selection == null || !selection.isCollapsed) {
|
||||||
return;
|
return;
|
||||||
@ -26,7 +13,7 @@ extension InsertFile on EditorState {
|
|||||||
if (node == null) {
|
if (node == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final file = fileNode(url: '');
|
final file = fileNode(url: '')..extraInfos = {'global_key': key};
|
||||||
final transaction = this.transaction;
|
final transaction = this.transaction;
|
||||||
|
|
||||||
// if the current node is empty paragraph, replace it with the file node
|
// if the current node is empty paragraph, replace it with the file node
|
||||||
@ -41,6 +28,7 @@ extension InsertFile on EditorState {
|
|||||||
|
|
||||||
transaction.afterSelection =
|
transaction.afterSelection =
|
||||||
Selection.collapsed(Position(path: node.path.next));
|
Selection.collapsed(Position(path: node.path.next));
|
||||||
|
transaction.selectionExtraInfo = {};
|
||||||
|
|
||||||
return apply(transaction);
|
return apply(transaction);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
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/plugins/document/presentation/editor_plugins/base/selectable_svg_widget.dart';
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/base/selectable_svg_widget.dart';
|
||||||
@ -6,7 +8,6 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/image/imag
|
|||||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/image/multi_image_block_component/multi_image_block_component.dart';
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/image/multi_image_block_component/multi_image_block_component.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
final customImageMenuItem = SelectionMenuItem(
|
final customImageMenuItem = SelectionMenuItem(
|
||||||
getName: () => AppFlowyEditorL10n.current.image,
|
getName: () => AppFlowyEditorL10n.current.image,
|
||||||
|
|||||||
@ -219,7 +219,8 @@ class _AddBlockMenu extends StatelessWidget {
|
|||||||
onTap: (_, __) async {
|
onTap: (_, __) async {
|
||||||
AppGlobals.rootNavKey.currentContext?.pop(true);
|
AppGlobals.rootNavKey.currentContext?.pop(true);
|
||||||
Future.delayed(const Duration(milliseconds: 400), () async {
|
Future.delayed(const Duration(milliseconds: 400), () async {
|
||||||
await editorState.insertEmptyFileBlock();
|
final fileGlobalKey = GlobalKey<FileBlockComponentState>();
|
||||||
|
await editorState.insertEmptyFileBlock(fileGlobalKey);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
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/plugins/document/application/prelude.dart';
|
import 'package:appflowy/plugins/document/application/prelude.dart';
|
||||||
@ -14,7 +16,6 @@ import 'package:appflowy_editor/appflowy_editor.dart';
|
|||||||
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart';
|
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
// text menu item
|
// text menu item
|
||||||
final textSlashMenuItem = SelectionMenuItem(
|
final textSlashMenuItem = SelectionMenuItem(
|
||||||
@ -541,7 +542,14 @@ SelectionMenuItem fileSlashMenuItem = SelectionMenuItem(
|
|||||||
style: style,
|
style: style,
|
||||||
),
|
),
|
||||||
keywords: ['file upload', 'pdf', 'zip', 'archive', 'upload', 'attachment'],
|
keywords: ['file upload', 'pdf', 'zip', 'archive', 'upload', 'attachment'],
|
||||||
handler: (editorState, _, __) async => editorState.insertEmptyFileBlock(),
|
handler: (editorState, _, __) async {
|
||||||
|
final fileGlobalKey = GlobalKey<FileBlockComponentState>();
|
||||||
|
await editorState.insertEmptyFileBlock(fileGlobalKey);
|
||||||
|
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
fileGlobalKey.currentState?.controller.show();
|
||||||
|
});
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _slashMenuItemNameBuilder(
|
Widget _slashMenuItemNameBuilder(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user