refactor: used flutter_inappwebview instead of webview_flutter

This commit is contained in:
jideguru
2021-06-04 13:58:03 +01:00
parent 0ba6803269
commit 7677e120cc
17 changed files with 152 additions and 399 deletions

View File

@@ -1 +1,2 @@
/// Position the inbuilt Toolbar or use your custom toolbar
enum BarPosition { TOP, BOTTOM, CUSTOM }

View File

@@ -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

View File

@@ -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() {

View File

@@ -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,

View File

@@ -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']),
)
],

View File

@@ -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);

View File

@@ -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']),
)
],

View 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,);
}
}