mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: add image block on mobile (#4230)
This commit is contained in:
parent
0b3c904984
commit
30a28b12d1
@ -47,4 +47,9 @@
|
||||
</application>
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.support.customtabs.action.CustomTabsService" />
|
||||
</intent>
|
||||
</queries>
|
||||
</manifest>
|
@ -67,6 +67,9 @@ class MobileBlockActionButtons extends StatelessWidget {
|
||||
}
|
||||
|
||||
void _showBottomSheet(BuildContext context) {
|
||||
// close the keyboard
|
||||
editorState.updateSelectionWithReason(null, extraInfo: {});
|
||||
|
||||
showMobileBottomSheet(
|
||||
context,
|
||||
showHeader: true,
|
||||
|
@ -104,6 +104,7 @@ class ImagePlaceholderState extends State<ImagePlaceholder> {
|
||||
} else {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
editorState.updateSelectionWithReason(null, extraInfo: {});
|
||||
showUploadImageMenu();
|
||||
},
|
||||
child: child,
|
||||
|
@ -59,6 +59,7 @@ extension InsertImage on EditorState {
|
||||
offset: 0,
|
||||
),
|
||||
);
|
||||
transaction.selectionExtraInfo = {};
|
||||
|
||||
return apply(transaction);
|
||||
}
|
||||
|
@ -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);
|
||||
},
|
||||
),
|
||||
|
@ -106,6 +106,7 @@ class _TextDecorationMenuState extends State<_TextDecorationMenu> {
|
||||
),
|
||||
const Spacer(),
|
||||
IndentAndOutdentItems(
|
||||
service: widget.service,
|
||||
editorState: editorState,
|
||||
),
|
||||
],
|
||||
|
@ -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<ImagePlaceholderState>();
|
||||
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,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<void> initialize(LaunchContext context) async {
|
||||
final DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
|
||||
if (Platform.isAndroid) {
|
||||
final androidInfo = await deviceInfoPlugin.androidInfo;
|
||||
androidSDKVersion = androidInfo.version.sdkInt;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {}
|
||||
}
|
@ -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';
|
||||
|
Loading…
Reference in New Issue
Block a user