refactor: used flutter_inappwebview instead of webview_flutter
This commit is contained in:
@@ -1 +1,2 @@
|
||||
/// Position the inbuilt Toolbar or use your custom toolbar
|
||||
enum BarPosition { TOP, BOTTOM, CUSTOM }
|
||||
@@ -4,12 +4,13 @@ import 'dart:io';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
import 'package:rich_editor/src/models/enum/bar_position.dart';
|
||||
import 'package:rich_editor/src/models/rich_editor_options.dart';
|
||||
import 'package:rich_editor/src/services/local_server.dart';
|
||||
import 'package:rich_editor/src/utils/javascript_executor_base.dart';
|
||||
import 'package:rich_editor/src/widgets/editor_tool_bar.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
// import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
class RichEditor extends StatefulWidget {
|
||||
final String? value;
|
||||
@@ -30,10 +31,12 @@ class RichEditor extends StatefulWidget {
|
||||
}
|
||||
|
||||
class RichEditorState extends State<RichEditor> {
|
||||
WebViewController? _controller;
|
||||
InAppWebViewController? _controller;
|
||||
final Key _mapKey = UniqueKey();
|
||||
String assetPath = 'packages/rich_editor/assets/editor/editor.html';
|
||||
|
||||
// InAppWebViewController? webViewController;
|
||||
|
||||
int port = 5321;
|
||||
String html = '';
|
||||
LocalServer? localServer;
|
||||
@@ -42,8 +45,7 @@ class RichEditorState extends State<RichEditor> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
|
||||
if (!Platform.isAndroid) {
|
||||
if (Platform.isIOS) {
|
||||
_initServer();
|
||||
}
|
||||
}
|
||||
@@ -76,7 +78,11 @@ class RichEditorState extends State<RichEditor> {
|
||||
|
||||
_loadHtmlFromAssets() async {
|
||||
final filePath = assetPath;
|
||||
_controller!.loadUrl("http://localhost:$port/$filePath");
|
||||
_controller!.loadUrl(
|
||||
urlRequest: URLRequest(
|
||||
url: Uri.tryParse('http://localhost:$port/$filePath'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -86,42 +92,50 @@ class RichEditorState extends State<RichEditor> {
|
||||
Visibility(
|
||||
visible: widget.editorOptions!.barPosition == BarPosition.TOP,
|
||||
child: EditorToolBar(
|
||||
controller: _controller,
|
||||
getImageUrl: widget.getImageUrl,
|
||||
javascriptExecutor: javascriptExecutor,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: WebView(
|
||||
child: InAppWebView(
|
||||
key: _mapKey,
|
||||
onWebViewCreated: (WebViewController controller) async {
|
||||
onWebViewCreated: (controller) async {
|
||||
_controller = controller;
|
||||
setState(() {});
|
||||
if (!Platform.isAndroid) {
|
||||
await _loadHtmlFromAssets();
|
||||
} else {
|
||||
await _controller!
|
||||
.loadUrl('file:///android_asset/flutter_assets/$assetPath');
|
||||
await _controller!.loadUrl(
|
||||
urlRequest: URLRequest(
|
||||
url: Uri.tryParse(
|
||||
'file:///android_asset/flutter_assets/$assetPath'),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
onLoadStop: (controller, link) async {
|
||||
javascriptExecutor.init(_controller!);
|
||||
},
|
||||
onPageFinished: (link) async {
|
||||
await _setInitialValues();
|
||||
_addJSListener();
|
||||
},
|
||||
javascriptMode: JavascriptMode.unrestricted,
|
||||
gestureNavigationEnabled: true,
|
||||
// javascriptMode: JavascriptMode.unrestricted,
|
||||
// gestureNavigationEnabled: false,
|
||||
gestureRecognizers: [
|
||||
Factory(() => VerticalDragGestureRecognizer()..onUpdate = (_) {}),
|
||||
].toSet(),
|
||||
onWebResourceError: (e) {
|
||||
print("error ${e.description}");
|
||||
onLoadError: (controller, url, code, e) {
|
||||
print("error $e $code");
|
||||
},
|
||||
onConsoleMessage: (controller, consoleMessage) async {
|
||||
print(
|
||||
'WebView Message: $consoleMessage',
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: widget.editorOptions!.barPosition == BarPosition.BOTTOM,
|
||||
child: EditorToolBar(
|
||||
controller: _controller,
|
||||
getImageUrl: widget.getImageUrl,
|
||||
javascriptExecutor: javascriptExecutor,
|
||||
),
|
||||
@@ -148,6 +162,14 @@ class RichEditorState extends State<RichEditor> {
|
||||
.setBaseFontFamily(widget.editorOptions!.baseFontFamily!);
|
||||
}
|
||||
|
||||
_addJSListener() async {
|
||||
_controller!.addJavaScriptHandler(
|
||||
handlerName: 'editor-state-changed-callback://',
|
||||
callback: (c) {
|
||||
print('Callback $c');
|
||||
});
|
||||
}
|
||||
|
||||
/// Get current HTML from editor
|
||||
Future<String?> getHtml() async {
|
||||
try {
|
||||
@@ -170,7 +192,7 @@ class RichEditorState extends State<RichEditor> {
|
||||
/// Clear editor content using Javascript
|
||||
clear() {
|
||||
_controller!.evaluateJavascript(
|
||||
'document.getElementById(\'editor\').innerHTML = "";');
|
||||
source: 'document.getElementById(\'editor\').innerHTML = "";');
|
||||
}
|
||||
|
||||
/// Focus and Show the keyboard using JavaScript
|
||||
@@ -192,7 +214,7 @@ class RichEditorState extends State<RichEditor> {
|
||||
" link.media = \"all\";" +
|
||||
" head.appendChild(link);" +
|
||||
"}) ();";
|
||||
_controller!.evaluateJavascript(jsCSSImport);
|
||||
_controller!.evaluateJavascript(source: jsCSSImport);
|
||||
}
|
||||
|
||||
/// if html is equal to html RichTextEditor sets by default at start
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
import 'package:rich_editor/src/extensions/extensions.dart';
|
||||
import 'package:rich_editor/src/models/editor_state.dart';
|
||||
import 'package:rich_editor/src/models/enum/command_name.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
import '../models/command_state.dart';
|
||||
|
||||
/// A class that handles all editor-related javascript functions
|
||||
class JavascriptExecutorBase {
|
||||
WebViewController? _controller;
|
||||
InAppWebViewController? _controller;
|
||||
|
||||
String defaultHtml = "<p>\u200B</p>";
|
||||
|
||||
@@ -22,12 +22,12 @@ class JavascriptExecutorBase {
|
||||
var didHtmlChange = false;
|
||||
Map<CommandName, CommandState> commandStates = {};
|
||||
|
||||
init(WebViewController controller) {
|
||||
init(InAppWebViewController? controller) {
|
||||
_controller = controller;
|
||||
}
|
||||
|
||||
executeJavascript(String command) async {
|
||||
return await _controller!.evaluateJavascript('editor.$command');
|
||||
return await _controller!.evaluateJavascript(source: 'editor.$command');
|
||||
}
|
||||
|
||||
String getCachedHtml() {
|
||||
|
||||
@@ -7,20 +7,17 @@ import 'package:rich_editor/src/widgets/fonts_dialog.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/tab_button.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
import 'color_picker_dialog.dart';
|
||||
import 'font_size_dialog.dart';
|
||||
import 'heading_dialog.dart';
|
||||
|
||||
class EditorToolBar extends StatelessWidget {
|
||||
final WebViewController? controller;
|
||||
final Function(File image)? getImageUrl;
|
||||
final Function(File video)? getVideoUrl;
|
||||
final JavascriptExecutorBase javascriptExecutor;
|
||||
|
||||
EditorToolBar({
|
||||
this.controller,
|
||||
this.getImageUrl,
|
||||
this.getVideoUrl,
|
||||
required this.javascriptExecutor,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_html/flutter_html.dart';
|
||||
|
||||
import 'html_text.dart';
|
||||
|
||||
class FontSizeDialog extends StatelessWidget {
|
||||
List formats = [
|
||||
@@ -22,7 +23,7 @@ class FontSizeDialog extends StatelessWidget {
|
||||
children: [
|
||||
for (Map format in formats)
|
||||
InkWell(
|
||||
child: Html(data: format['title']),
|
||||
child: HtmlText(html: format['title']),
|
||||
onTap: () => Navigator.pop(context, format['id']),
|
||||
)
|
||||
],
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_html/flutter_html.dart';
|
||||
import 'package:path/path.dart';
|
||||
import 'package:rich_editor/src/models/system_font.dart';
|
||||
import 'package:rich_editor/src/utils/font_list_parser.dart';
|
||||
|
||||
import 'html_text.dart';
|
||||
|
||||
class FontsDialog extends StatelessWidget {
|
||||
List<SystemFont> getSystemFonts() {
|
||||
return FontListParser().getSystemFonts();
|
||||
@@ -19,8 +20,8 @@ class FontsDialog extends StatelessWidget {
|
||||
children: [
|
||||
for (SystemFont font in getSystemFonts())
|
||||
InkWell(
|
||||
child: Html(
|
||||
data: '<p style="font-family:${font.name}">'
|
||||
child: HtmlText(
|
||||
html: '<p style="font-family:${font.name}">'
|
||||
'${basename(font.path!)}</p>'),
|
||||
onTap: () {
|
||||
Navigator.pop(context, font.name);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_html/flutter_html.dart';
|
||||
|
||||
import 'html_text.dart';
|
||||
|
||||
class HeadingDialog extends StatelessWidget {
|
||||
List formats = [
|
||||
@@ -27,7 +28,7 @@ class HeadingDialog extends StatelessWidget {
|
||||
children: [
|
||||
for (Map format in formats)
|
||||
InkWell(
|
||||
child: Html(data: format['title']),
|
||||
child: HtmlText(html: format['title']),
|
||||
onTap: () => Navigator.pop(context, format['id']),
|
||||
)
|
||||
],
|
||||
|
||||
13
lib/src/widgets/html_text.dart
Normal file
13
lib/src/widgets/html_text.dart
Normal file
@@ -0,0 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
|
||||
|
||||
class HtmlText extends StatelessWidget {
|
||||
final String html;
|
||||
|
||||
HtmlText({required this.html});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(child: HtmlWidget(html), height: 40.0,);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user