diff --git a/frontend/appflowy_flutter/android/app/src/main/AndroidManifest.xml b/frontend/appflowy_flutter/android/app/src/main/AndroidManifest.xml
index 74a83ed9f2..4c4436244c 100644
--- a/frontend/appflowy_flutter/android/app/src/main/AndroidManifest.xml
+++ b/frontend/appflowy_flutter/android/app/src/main/AndroidManifest.xml
@@ -47,4 +47,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/mobile_block_action_buttons.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/mobile_block_action_buttons.dart
index 705356481e..c8c0501690 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/mobile_block_action_buttons.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/mobile_block_action_buttons.dart
@@ -67,6 +67,9 @@ class MobileBlockActionButtons extends StatelessWidget {
}
void _showBottomSheet(BuildContext context) {
+ // close the keyboard
+ editorState.updateSelectionWithReason(null, extraInfo: {});
+
showMobileBottomSheet(
context,
showHeader: true,
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/image_placeholder.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/image_placeholder.dart
index df21655f42..d8a9f43151 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/image_placeholder.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/image_placeholder.dart
@@ -104,6 +104,7 @@ class ImagePlaceholderState extends State {
} else {
return GestureDetector(
onTap: () {
+ editorState.updateSelectionWithReason(null, extraInfo: {});
showUploadImageMenu();
},
child: child,
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/image_selection_menu.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/image_selection_menu.dart
index 9a1d98a11e..261f00af89 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/image_selection_menu.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/image_selection_menu.dart
@@ -59,6 +59,7 @@ extension InsertImage on EditorState {
offset: 0,
),
);
+ transaction.selectionExtraInfo = {};
return apply(transaction);
}
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_indent_items.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_indent_items.dart
index 09ab3343ee..0188ceef2e 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_indent_items.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_indent_items.dart
@@ -1,16 +1,18 @@
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart';
-import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/util.dart';
+import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';
class IndentAndOutdentItems extends StatelessWidget {
const IndentAndOutdentItems({
super.key,
+ required this.service,
required this.editorState,
});
final EditorState editorState;
+ final AppFlowyMobileToolbarWidgetService service;
@override
Widget build(BuildContext context) {
@@ -28,6 +30,7 @@ class IndentAndOutdentItems extends StatelessWidget {
iconPadding: const EdgeInsets.symmetric(vertical: 14.0),
backgroundColor: theme.toolbarMenuItemBackgroundColor,
onTap: () {
+ service.closeItemMenu();
outdentCommand.execute(editorState);
},
),
@@ -42,6 +45,7 @@ class IndentAndOutdentItems extends StatelessWidget {
iconPadding: const EdgeInsets.symmetric(vertical: 14.0),
backgroundColor: theme.toolbarMenuItemBackgroundColor,
onTap: () {
+ service.closeItemMenu();
indentCommand.execute(editorState);
},
),
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_toolbar_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_toolbar_item.dart
index 23f5d7b273..999e6607b9 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_toolbar_item.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_toolbar_item.dart
@@ -106,6 +106,7 @@ class _TextDecorationMenuState extends State<_TextDecorationMenu> {
),
const Spacer(),
IndentAndOutdentItems(
+ service: widget.service,
editorState: editorState,
),
],
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/add_block_toolbar_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/add_block_toolbar_item.dart
index 3526bde45c..60a65ec043 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/add_block_toolbar_item.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/add_block_toolbar_item.dart
@@ -1,6 +1,7 @@
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
+import 'package:appflowy/plugins/document/presentation/editor_plugins/image/image_placeholder.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_item/mobile_add_block_toolbar_item.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_toolbar_theme.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
@@ -184,7 +185,7 @@ class _AddBlockMenu extends StatelessWidget {
onTap: () => _insertBlock(quoteNode()),
),
- // divider,
+ // divider
_AddBlockMenuItemData(
blockType: DividerBlockKeys.type,
backgroundColor: const Color(0xFF98F4CD),
@@ -197,6 +198,25 @@ class _AddBlockMenu extends StatelessWidget {
});
},
),
+
+ // image
+ _AddBlockMenuItemData(
+ blockType: DividerBlockKeys.type,
+ backgroundColor: const Color(0xFF98F4CD),
+ text: LocaleKeys.editor_image.tr(),
+ icon: FlowySvgs.m_toolbar_imae_lg,
+ onTap: () async {
+ AppGlobals.rootNavKey.currentContext?.pop(true);
+ Future.delayed(const Duration(milliseconds: 400), () async {
+ final imagePlaceholderKey = GlobalKey();
+ await editorState.insertEmptyImageBlock(imagePlaceholderKey);
+
+ WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
+ imagePlaceholderKey.currentState?.controller.show();
+ });
+ });
+ },
+ ),
];
@override
@@ -257,7 +277,7 @@ class _AddBlockMenuItem extends StatelessWidget {
borderRadius: BorderRadius.circular(20),
),
),
- padding: const EdgeInsets.all(24),
+ padding: EdgeInsets.all(20 * context.scale),
child: FlowySvg(
data.icon,
color: Colors.black,
@@ -266,7 +286,7 @@ class _AddBlockMenuItem extends StatelessWidget {
const VSpace(4),
FlowyText(
data.text,
- fontSize: 13.0,
+ fontSize: 12.0,
),
],
),
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar.dart
index 82e42cceb5..b65008a231 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar.dart
@@ -540,7 +540,8 @@ class _ToolbarItemListViewState extends State<_ToolbarItemListView> {
}
final toolbarItems = widget.toolbarItems;
- final alignment = selection.isCollapsed ? 0.0 : -1.0;
+ // use -0.4 to make sure the pilot is in the front of the toolbar item
+ final alignment = selection.isCollapsed ? 0.0 : -0.4;
final index = toolbarItems.indexWhere(
(element) => selection.isCollapsed
? element.pilotAtCollapsedSelection
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/keyboard_height_observer.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/keyboard_height_observer.dart
index a58a214db4..b4d36cbd23 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/keyboard_height_observer.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/keyboard_height_observer.dart
@@ -1,3 +1,4 @@
+import 'package:appflowy/startup/tasks/prelude.dart';
import 'package:keyboard_height_plugin/keyboard_height_plugin.dart';
typedef KeyboardHeightCallback = void Function(double height);
@@ -32,6 +33,12 @@ class KeyboardHeightObserver {
}
void notify(double height) {
+ // the keyboard height will notify twice with the same value on Android 14
+ if (DeviceInfoTask.androidSDKVersion == 34) {
+ if (height == 0 && currentKeyboardHeight == 0) {
+ return;
+ }
+ }
for (final listener in _listeners) {
listener(height);
}
diff --git a/frontend/appflowy_flutter/lib/startup/startup.dart b/frontend/appflowy_flutter/lib/startup/startup.dart
index 2005c9e76e..b27b88e0ec 100644
--- a/frontend/appflowy_flutter/lib/startup/startup.dart
+++ b/frontend/appflowy_flutter/lib/startup/startup.dart
@@ -103,6 +103,7 @@ class FlowyRunner {
// there's a flag named _enable in memory_leak_detector.dart. If it's false, the task will be ignored.
MemoryLeakDetectorTask(),
const DebugTask(),
+ const DeviceInfoTask(),
// localization
const InitLocalizationTask(),
// init the app window
diff --git a/frontend/appflowy_flutter/lib/startup/tasks/device_info_task.dart b/frontend/appflowy_flutter/lib/startup/tasks/device_info_task.dart
new file mode 100644
index 0000000000..6dd5af5032
--- /dev/null
+++ b/frontend/appflowy_flutter/lib/startup/tasks/device_info_task.dart
@@ -0,0 +1,23 @@
+import 'dart:io';
+
+import 'package:device_info_plus/device_info_plus.dart';
+
+import '../startup.dart';
+
+class DeviceInfoTask extends LaunchTask {
+ const DeviceInfoTask();
+
+ static int androidSDKVersion = -1;
+
+ @override
+ Future initialize(LaunchContext context) async {
+ final DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
+ if (Platform.isAndroid) {
+ final androidInfo = await deviceInfoPlugin.androidInfo;
+ androidSDKVersion = androidInfo.version.sdkInt;
+ }
+ }
+
+ @override
+ Future dispose() async {}
+}
diff --git a/frontend/appflowy_flutter/lib/startup/tasks/prelude.dart b/frontend/appflowy_flutter/lib/startup/tasks/prelude.dart
index 6d21cdb178..c19f9e8d65 100644
--- a/frontend/appflowy_flutter/lib/startup/tasks/prelude.dart
+++ b/frontend/appflowy_flutter/lib/startup/tasks/prelude.dart
@@ -1,6 +1,7 @@
export 'app_widget.dart';
export 'appflowy_cloud_task.dart';
export 'debug_task.dart';
+export 'device_info_task.dart';
export 'generate_router.dart';
export 'hot_key.dart';
export 'load_plugin.dart';