feat: added insert image and more text commands
This commit is contained in:
parent
57f6f5f198
commit
87db96d65a
@ -1,20 +1,26 @@
|
|||||||
PODS:
|
PODS:
|
||||||
- Flutter (1.0.0)
|
- Flutter (1.0.0)
|
||||||
|
- image_picker (0.0.1):
|
||||||
|
- Flutter
|
||||||
- webview_flutter (0.0.1):
|
- webview_flutter (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
|
- image_picker (from `.symlinks/plugins/image_picker/ios`)
|
||||||
- webview_flutter (from `.symlinks/plugins/webview_flutter/ios`)
|
- webview_flutter (from `.symlinks/plugins/webview_flutter/ios`)
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
Flutter:
|
Flutter:
|
||||||
:path: Flutter
|
:path: Flutter
|
||||||
|
image_picker:
|
||||||
|
:path: ".symlinks/plugins/image_picker/ios"
|
||||||
webview_flutter:
|
webview_flutter:
|
||||||
:path: ".symlinks/plugins/webview_flutter/ios"
|
:path: ".symlinks/plugins/webview_flutter/ios"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
|
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
|
||||||
|
image_picker: 50e7c7ff960e5f58faa4d1f4af84a771c671bc4a
|
||||||
webview_flutter: 9f491a9b5a66f2573946a389b2677987b0ff8c0b
|
webview_flutter: 9f491a9b5a66f2573946a389b2677987b0ff8c0b
|
||||||
|
|
||||||
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
|
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
|
||||||
|
@ -41,10 +41,13 @@
|
|||||||
</array>
|
</array>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
|
<key>NSPhotoLibraryUsageDescription</key>
|
||||||
|
<string>Used to demonstrate image picker plugin</string>
|
||||||
<key>NSAppTransportSecurity</key>
|
<key>NSAppTransportSecurity</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSAllowsArbitraryLoads</key>
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -62,11 +62,65 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_plugin_android_lifecycle:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_plugin_android_lifecycle
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.2"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_web_plugins:
|
||||||
|
dependency: transitive
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
http:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.13.3"
|
||||||
|
http_parser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http_parser
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.0"
|
||||||
|
image_picker:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.5+3"
|
||||||
|
image_picker_for_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_for_web
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
|
image_picker_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
|
js:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: js
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.6.3"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -95,6 +149,20 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.0"
|
version: "1.8.0"
|
||||||
|
pedantic:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pedantic
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.11.0"
|
||||||
|
plugin_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: plugin_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
rich_editor:
|
rich_editor:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
31
lib/src/widgets/custom_dialog_template.dart
Normal file
31
lib/src/widgets/custom_dialog_template.dart
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class CustomDialogTemplate extends StatelessWidget {
|
||||||
|
final List<Widget>? body;
|
||||||
|
final Function? onDone;
|
||||||
|
final Function? onCancel;
|
||||||
|
|
||||||
|
|
||||||
|
CustomDialogTemplate({this.body, this.onDone, this.onCancel});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
content: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: body!,
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => onDone!(),
|
||||||
|
child: Text('Done'),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => onCancel!(),
|
||||||
|
child: Text('Cancel'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
62
lib/src/widgets/insert_image_dialog.dart
Normal file
62
lib/src/widgets/insert_image_dialog.dart
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:image_picker/image_picker.dart';
|
||||||
|
|
||||||
|
import 'custom_dialog_template.dart';
|
||||||
|
|
||||||
|
class InsertImageDialog extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_InsertImageDialogState createState() => _InsertImageDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _InsertImageDialogState extends State<InsertImageDialog> {
|
||||||
|
TextEditingController link = TextEditingController();
|
||||||
|
|
||||||
|
TextEditingController alt = TextEditingController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return CustomDialogTemplate(
|
||||||
|
body: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text('Image link'),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () => getImage(),
|
||||||
|
child: Text('...'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
TextField(
|
||||||
|
controller: link,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: '',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 20.0),
|
||||||
|
Text('Alt text (optional)'),
|
||||||
|
TextField(
|
||||||
|
controller: alt,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: '',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
onDone: () => Navigator.pop(context, [link.text, alt.text]),
|
||||||
|
onCancel: () => Navigator.pop(context),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future getImage() async {
|
||||||
|
final picker = ImagePicker();
|
||||||
|
var image = await picker.getImage(
|
||||||
|
source: ImageSource.gallery,
|
||||||
|
maxWidth: 800.0,
|
||||||
|
maxHeight: 600.0,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (image != null) {
|
||||||
|
link.text = image.path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,43 +1,33 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'custom_dialog_template.dart';
|
||||||
|
|
||||||
class InsertLinkDialog extends StatelessWidget {
|
class InsertLinkDialog extends StatelessWidget {
|
||||||
TextEditingController link = TextEditingController();
|
TextEditingController link = TextEditingController();
|
||||||
TextEditingController label = TextEditingController();
|
TextEditingController label = TextEditingController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AlertDialog(
|
return CustomDialogTemplate(
|
||||||
title: Text('Insert Link'),
|
body: [
|
||||||
content: Column(
|
Text('Link'),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
TextField(
|
||||||
mainAxisSize: MainAxisSize.min,
|
controller: link,
|
||||||
children: [
|
decoration: InputDecoration(
|
||||||
Text('Link'),
|
hintText: 'type link here',
|
||||||
TextField(
|
|
||||||
controller: link,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
hintText: 'type link here',
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
SizedBox(height: 20.0),
|
|
||||||
Text('Label'),
|
|
||||||
TextField(
|
|
||||||
controller: label,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
hintText: 'type label text here',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () => Navigator.pop(context, [link.text, label.text]),
|
|
||||||
child: Text('Done'),
|
|
||||||
),
|
),
|
||||||
TextButton(
|
SizedBox(height: 20.0),
|
||||||
onPressed: () => Navigator.pop(context),
|
Text('Label'),
|
||||||
child: Text('Cancel'),
|
TextField(
|
||||||
|
controller: label,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'type label text here',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
onDone: () => Navigator.pop(context, [link.text, label.text]),
|
||||||
|
onCancel: () => Navigator.pop(context),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:rich_editor/src/utils/javascript_executor_base.dart';
|
import 'package:rich_editor/src/utils/javascript_executor_base.dart';
|
||||||
|
import 'package:rich_editor/src/widgets/insert_image_dialog.dart';
|
||||||
import 'package:rich_editor/src/widgets/insert_link_dialog.dart';
|
import 'package:rich_editor/src/widgets/insert_link_dialog.dart';
|
||||||
import 'package:rich_editor/src/widgets/tab_button.dart';
|
import 'package:rich_editor/src/widgets/tab_button.dart';
|
||||||
import 'package:webview_flutter/webview_flutter.dart';
|
import 'package:webview_flutter/webview_flutter.dart';
|
||||||
@ -49,16 +50,75 @@ class GroupedTab extends StatelessWidget {
|
|||||||
return InsertLinkDialog();
|
return InsertLinkDialog();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if(link != null)
|
if (link != null)
|
||||||
await javascriptExecutorBase.insertLink(link[0], link[1]);
|
await javascriptExecutorBase.insertLink(link[0], link[1]);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
icon: Icons.image,
|
icon: Icons.image,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.insertImage(
|
var link = await showDialog(
|
||||||
'https://avatars.githubusercontent.com/u/24323581?v=4'
|
context: context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (_) {
|
||||||
|
return InsertImageDialog();
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
if (link != null) {
|
||||||
|
await javascriptExecutorBase.insertImage(
|
||||||
|
link[0],
|
||||||
|
alt: link[1],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TabButton(
|
||||||
|
icon: Icons.format_underline,
|
||||||
|
onTap: () async {
|
||||||
|
await javascriptExecutorBase.setUnderline();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TabButton(
|
||||||
|
icon: Icons.format_strikethrough,
|
||||||
|
onTap: () async {
|
||||||
|
await javascriptExecutorBase.setStrikeThrough();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TabButton(
|
||||||
|
icon: Icons.superscript,
|
||||||
|
onTap: () async {
|
||||||
|
await javascriptExecutorBase.setSuperscript();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TabButton(
|
||||||
|
icon: Icons.subscript,
|
||||||
|
onTap: () async {
|
||||||
|
await javascriptExecutorBase.setSubscript();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TabButton(
|
||||||
|
icon: Icons.format_clear,
|
||||||
|
onTap: () async {
|
||||||
|
await javascriptExecutorBase.removeFormat();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TabButton(
|
||||||
|
icon: Icons.redo,
|
||||||
|
onTap: () async {
|
||||||
|
await javascriptExecutorBase.redo();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TabButton(
|
||||||
|
icon: Icons.undo,
|
||||||
|
onTap: () async {
|
||||||
|
await javascriptExecutorBase.undo();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
TabButton(
|
||||||
|
icon: Icons.format_quote,
|
||||||
|
onTap: () async {
|
||||||
|
await javascriptExecutorBase.setBlockQuote();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
68
pubspec.lock
68
pubspec.lock
@ -55,11 +55,65 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_plugin_android_lifecycle:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_plugin_android_lifecycle
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.2"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_web_plugins:
|
||||||
|
dependency: transitive
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
http:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.13.3"
|
||||||
|
http_parser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http_parser
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.0"
|
||||||
|
image_picker:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: image_picker
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.5+3"
|
||||||
|
image_picker_for_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_for_web
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
|
image_picker_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
|
js:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: js
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.6.3"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -88,6 +142,20 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.0"
|
version: "1.8.0"
|
||||||
|
pedantic:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pedantic
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.11.0"
|
||||||
|
plugin_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: plugin_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -11,8 +11,9 @@ dependencies:
|
|||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
webview_flutter: ^2.0.4
|
webview_flutter: ^2.0.4
|
||||||
# flutter_inappwebview: ^5.3.2
|
|
||||||
mime: ^1.0.0
|
mime: ^1.0.0
|
||||||
|
image_picker: ^0.7.5+3
|
||||||
|
# path_provider: ^2.0.2
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
Reference in New Issue
Block a user