import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:image_picker/image_picker.dart'; import '../embed_types.dart'; import 'image_video_utils.dart'; class ImageButton extends StatelessWidget { const ImageButton({ required this.icon, required this.controller, this.iconSize = kDefaultIconSize, this.onImagePickCallback, this.fillColor, this.filePickImpl, this.webImagePickImpl, this.mediaPickSettingSelector, this.iconTheme, this.dialogTheme, this.tooltip, this.linkRegExp, Key? key, }) : super(key: key); final IconData icon; final double iconSize; final Color? fillColor; final QuillController controller; final OnImagePickCallback? onImagePickCallback; final WebImagePickImpl? webImagePickImpl; final FilePickImpl? filePickImpl; final MediaPickSettingSelector? mediaPickSettingSelector; final QuillIconTheme? iconTheme; final QuillDialogTheme? dialogTheme; final String? tooltip; final RegExp? linkRegExp; @override Widget build(BuildContext context) { final theme = Theme.of(context); final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; final iconFillColor = iconTheme?.iconUnselectedFillColor ?? (fillColor ?? theme.canvasColor); return QuillIconButton( icon: Icon(icon, size: iconSize, color: iconColor), tooltip: tooltip, highlightElevation: 0, hoverElevation: 0, size: iconSize * 1.77, fillColor: iconFillColor, borderRadius: iconTheme?.borderRadius ?? 2, onPressed: () => _onPressedHandler(context), ); } Future _onPressedHandler(BuildContext context) async { final onImagePickCallbackRef = onImagePickCallback; if (onImagePickCallbackRef == null) { await _typeLink(context); return; } final selector = mediaPickSettingSelector ?? ImageVideoUtils.selectMediaPickSetting; final source = await selector(context); if (source == null) { return; } switch (source) { case MediaPickSetting.Gallery: _pickImage(context); break; case MediaPickSetting.Link: await _typeLink(context); break; case MediaPickSetting.Camera: await ImageVideoUtils.handleImageButtonTap( context, controller, ImageSource.camera, onImagePickCallbackRef, filePickImpl: filePickImpl, webImagePickImpl: webImagePickImpl, ); break; case MediaPickSetting.Video: throw ArgumentError( 'Sorry but this is the Image button and not the video one', ); } // This will not work for the pick image using camera (bug fix) // if (source != null) { // if (source == MediaPickSetting.Gallery) { // } else { // _typeLink(context); // } } void _pickImage(BuildContext context) => ImageVideoUtils.handleImageButtonTap( context, controller, ImageSource.gallery, onImagePickCallback!, filePickImpl: filePickImpl, webImagePickImpl: webImagePickImpl, ); Future _typeLink(BuildContext context) async { final value = await showDialog( context: context, builder: (_) => LinkDialog( dialogTheme: dialogTheme, linkRegExp: linkRegExp, ), ); _linkSubmitted(value); } void _linkSubmitted(String? value) { if (value != null && value.isNotEmpty) { final index = controller.selection.baseOffset; final length = controller.selection.extentOffset - index; controller.replaceText(index, length, BlockEmbed.image(value), null); } } }