diff --git a/README.md b/README.md index bbedb500..e8433608 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,10 @@ For web development, use `flutter config --enable-web` for flutter and use [Reac It is required to provide EmbedBuilder, e.g. [defaultEmbedBuilderWeb](https://github.com/singerdmx/flutter-quill/blob/master/example/lib/universal_ui/universal_ui.dart#L28). +## Desktop + +It is required to provide application document directory for image button. See example in [example](https://github.com/singerdmx/flutter-quill/blob/master/example/lib/pages/home_page.dart). + ## Migrate Zefyr Data Check out [code](https://github.com/jwehrle/zefyr_quill_convert) and [doc](https://docs.google.com/document/d/1FUSrpbarHnilb7uDN5J5DDahaI0v1RMXBjj4fFSpSuY/edit?usp=sharing). diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index e0f436f8..0f0650ef 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -157,18 +157,30 @@ class _HomePageState extends State { const EdgeInsets.symmetric(vertical: 16, horizontal: 8), child: QuillToolbar.basic( controller: _controller!, - onImagePickCallback: _onImagePickCallback), + onImagePickCallback: _onImagePickCallback, + applicationPath: + !(kIsWeb || Platform.isAndroid || Platform.isIOS) + ? null + : getApplicationDirectoryForDesktop()), )) : Container( child: QuillToolbar.basic( controller: _controller!, - onImagePickCallback: _onImagePickCallback), + onImagePickCallback: _onImagePickCallback, + applicationPath: + !(kIsWeb || Platform.isAndroid || Platform.isIOS) + ? null + : getApplicationDirectoryForDesktop()), ), ], ), ); } + Future getApplicationDirectoryForDesktop() async { + return await getApplicationDocumentsDirectory(); + } + // Renders the image picked by imagePicker from local file storage // You can also upload the picked image to any server (eg : AWS s3 // or Firebase) and then return the uploaded image URL. diff --git a/example/lib/widgets/demo_scaffold.dart b/example/lib/widgets/demo_scaffold.dart index 944b7fe9..3aec94b4 100644 --- a/example/lib/widgets/demo_scaffold.dart +++ b/example/lib/widgets/demo_scaffold.dart @@ -1,8 +1,11 @@ import 'dart:convert'; +import 'dart:io'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_quill/flutter_quill.dart' hide Text; +import 'package:path_provider/path_provider.dart'; typedef DemoContentBuilder = Widget Function( BuildContext context, QuillController? controller); @@ -70,6 +73,10 @@ class _DemoScaffoldState extends State { } } + Future getApplicationDirectoryForDesktop() async { + return await getApplicationDocumentsDirectory(); + } + @override Widget build(BuildContext context) { final actions = widget.actions ?? []; @@ -90,7 +97,11 @@ class _DemoScaffoldState extends State { ), title: _loading || widget.showToolbar == false ? null - : QuillToolbar.basic(controller: _controller!), + : QuillToolbar.basic(controller: _controller!, + applicationPath: + !(kIsWeb || Platform.isAndroid || Platform.isIOS) + ? null + : getApplicationDirectoryForDesktop()), actions: actions, ), floatingActionButton: widget.floatingActionButton, diff --git a/lib/src/widgets/toolbar.dart b/lib/src/widgets/toolbar.dart index 76be1824..27558c8d 100644 --- a/lib/src/widgets/toolbar.dart +++ b/lib/src/widgets/toolbar.dart @@ -45,6 +45,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { required this.children, this.toolBarHeight = 36, this.color, + this.applicationPath, Key? key, }) : super(key: key); @@ -69,6 +70,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { bool showHistory = true, bool showHorizontalRule = false, OnImagePickCallback? onImagePickCallback, + Future? applicationPath, Key? key, }) { final isButtonGroupShown = [ @@ -160,6 +162,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { controller: controller, imageSource: ImageSource.gallery, onImagePickCallback: onImagePickCallback, + applicationPath: applicationPath, ), if (onImagePickCallback != null) ImageButton( @@ -168,6 +171,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { controller: controller, imageSource: ImageSource.camera, onImagePickCallback: onImagePickCallback, + applicationPath: applicationPath, ), if (isButtonGroupShown[0] && (isButtonGroupShown[1] || @@ -279,6 +283,8 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { /// is given. final Color? color; + final Directory? applicationPath; + @override Size get preferredSize => Size.fromHeight(toolBarHeight); diff --git a/lib/src/widgets/toolbar/image_button.dart b/lib/src/widgets/toolbar/image_button.dart index 74e9ae6d..9b20e34f 100644 --- a/lib/src/widgets/toolbar/image_button.dart +++ b/lib/src/widgets/toolbar/image_button.dart @@ -5,7 +5,6 @@ import 'package:filesystem_picker/filesystem_picker.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; -import 'package:path_provider/path_provider.dart'; import '../../models/documents/nodes/embed.dart'; import '../controller.dart'; @@ -21,6 +20,7 @@ class ImageButton extends StatelessWidget { this.fillColor, this.onImagePickCallback, this.imagePickImpl, + this.applicationPath, Key? key, }) : super(key: key); @@ -37,6 +37,8 @@ class ImageButton extends StatelessWidget { final ImageSource imageSource; + final Future? applicationPath; + @override Widget build(BuildContext context) { final theme = Theme.of(context); @@ -47,11 +49,12 @@ class ImageButton extends StatelessWidget { hoverElevation: 0, size: iconSize * 1.77, fillColor: fillColor ?? theme.canvasColor, - onPressed: () => _handleImageButtonTap(context), + onPressed: () => _handleImageButtonTap(context, applicationPath), ); } - Future _handleImageButtonTap(BuildContext context) async { + Future _handleImageButtonTap(BuildContext context, + [Future? applicationPath]) async { final index = controller.selection.baseOffset; final length = controller.selection.extentOffset - index; @@ -64,7 +67,9 @@ class ImageButton extends StatelessWidget { } else if (Platform.isAndroid || Platform.isIOS) { imageUrl = await _pickImage(imageSource); } else { - imageUrl = await _pickImageDesktop(context); + assert(applicationPath != null, + 'Desktop must provide application document directory'); + imageUrl = await _pickImageDesktop(context, applicationPath!); } } @@ -95,10 +100,11 @@ class ImageButton extends StatelessWidget { return onImagePickCallback!(File(pickedFile.path)); } - Future _pickImageDesktop(BuildContext context) async { + Future _pickImageDesktop(BuildContext context, + Future applicationPath) async { final filePath = await FilesystemPicker.open( context: context, - rootDirectory: await getApplicationDocumentsDirectory(), + rootDirectory: await applicationPath, fsType: FilesystemType.file, fileTileSelectMode: FileTileSelectMode.wholeTile, ); diff --git a/pubspec.yaml b/pubspec.yaml index 1b2216e7..6b181bd6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,7 +18,6 @@ dependencies: flutter_colorpicker: ^0.4.0 flutter_keyboard_visibility: ^5.0.0 image_picker: ^0.7.3 - path_provider: ^2.0.1 photo_view: ^0.11.1 quiver: ^3.0.0 string_validator: ^0.3.0