feat: start local server for iOS

This commit is contained in:
jideguru 2021-05-27 02:11:25 +01:00
parent f4f1802eb6
commit 8954f86086
10 changed files with 214 additions and 72 deletions

View File

@ -41,5 +41,10 @@
</array> </array>
<key>UIViewControllerBasedStatusBarAppearance</key> <key>UIViewControllerBasedStatusBarAppearance</key>
<false/> <false/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
</dict> </dict>
</plist> </plist>

View File

@ -62,13 +62,6 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_inappwebview:
dependency: transitive
description:
name: flutter_inappwebview
url: "https://pub.dartlang.org"
source: hosted
version: "5.3.2"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -179,4 +172,4 @@ packages:
version: "2.0.7" version: "2.0.7"
sdks: sdks:
dart: ">=2.12.0 <3.0.0" dart: ">=2.12.0 <3.0.0"
flutter: ">=1.22.2" flutter: ">=1.22.0"

View File

@ -2,7 +2,8 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class Button { class Button {
IconData icon; IconData? icon;
Function? onTap;
Button({this.icon = Icons.format_bold}); Button({this.icon, this.onTap});
} }

View File

@ -14,6 +14,7 @@ class _RichEditorState extends State<RichEditor> {
WebViewController? _controller; WebViewController? _controller;
String text = ""; String text = "";
final Key _mapKey = UniqueKey(); final Key _mapKey = UniqueKey();
String assetPath = 'packages/rich_editor/assets/editor/editor.html';
int port = 5321; int port = 5321;
LocalServer? localServer; LocalServer? localServer;
@ -22,6 +23,41 @@ class _RichEditorState extends State<RichEditor> {
void initState() { void initState() {
super.initState(); super.initState();
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView(); if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
if (!Platform.isAndroid) {
initServer();
}
}
initServer() {
localServer = LocalServer(port);
localServer!.start(handleRequest);
}
void handleRequest(HttpRequest request) {
try {
if (request.method == 'GET' &&
request.uri.queryParameters['query'] == "getRawTeXHTML") {
} else {}
} catch (e) {
print('Exception in handleRequest: $e');
}
}
@override
void dispose() {
if (_controller != null) {
_controller = null;
}
if (!Platform.isAndroid) {
localServer!.close();
}
super.dispose();
}
_loadHtmlFromAssets() async {
final filePath = assetPath;
_controller!.loadUrl("http://localhost:$port/$filePath");
} }
@override @override
@ -31,14 +67,24 @@ class _RichEditorState extends State<RichEditor> {
GroupedTab(controller: _controller), GroupedTab(controller: _controller),
Flexible( Flexible(
child: WebView( child: WebView(
initialUrl: key: _mapKey,
'file:///android_asset/flutter_assets/packages/rich_editor/assets/editor/editor.html', // initialUrl:
// 'file:///android_asset/flutter_assets/packages/rich_editor/assets/editor/editor.html',
onWebViewCreated: (WebViewController controller) { onWebViewCreated: (WebViewController controller) {
_controller = controller; _controller = controller;
print('WebView created'); print('WebView created');
setState(() {}); setState(() {});
if (!Platform.isAndroid) {
print('Loading');
_loadHtmlFromAssets();
} else {
_controller!.loadUrl('file:///android_asset/flutter_assets/$assetPath');
}
}, },
javascriptMode: JavascriptMode.unrestricted, javascriptMode: JavascriptMode.unrestricted,
onWebResourceError: (e) {
print("error ${e.description}");
},
), ),
// child: InAppWebView( // child: InAppWebView(
// initialFile: 'packages/rich_editor/assets/editor/index.html', // initialFile: 'packages/rich_editor/assets/editor/index.html',

View File

@ -1,32 +1,144 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:rich_editor/src/models/button.dart'; import 'package:rich_editor/src/models/button.dart';
import 'javascript_executor_base.dart';
List<Button> buttons = [ List<Button> buttons = [
Button(icon: Icons.format_bold), Button(
Button(icon: Icons.format_italic), icon: Icons.format_bold,
Button(icon: Icons.format_underline), onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
Button(icon: Icons.format_strikethrough), await javascriptExecutorBase.setBold(),
Button(icon: Icons.superscript), ),
Button(icon: Icons.subscript), Button(
icon: Icons.format_italic,
onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
await javascriptExecutorBase.setItalic(),
),
Button(
icon: Icons.link,
onTap: (JavascriptExecutorBase javascriptExecutorBase) async {
await javascriptExecutorBase.insertLink(
'https://github.com/JideGuru',
'Sample',
);
},
),
Button(
icon: Icons.image,
onTap: (JavascriptExecutorBase javascriptExecutorBase) async {
await javascriptExecutorBase.insertImage(
'https://avatars.githubusercontent.com/u/24323581?v=4',
alt: 'Jide',
height: 200,
width: 200,
);
},
),
Button(
icon: Icons.format_underline,
onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
await javascriptExecutorBase.setUnderline(),
),
Button(
icon: Icons.format_strikethrough,
onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
await javascriptExecutorBase.setStrikeThrough(),
),
Button(
icon: Icons.superscript,
onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
await javascriptExecutorBase.setSuperscript(),
),
Button(
icon: Icons.subscript,
onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
await javascriptExecutorBase.setSubscript(),
),
Button(icon: Icons.format_clear), Button(icon: Icons.format_clear),
Button(icon: Icons.undo), Button(
Button(icon: Icons.redo), icon: Icons.undo,
Button(icon: Icons.format_quote), onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
Button(icon: Icons.text_format), await javascriptExecutorBase.undo(),
Button(icon: Icons.font_download), ),
Button(icon: Icons.format_size), Button(
Button(icon: Icons.format_color_text), icon: Icons.redo,
Button(icon: Icons.format_color_fill), onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
Button(icon: Icons.format_indent_decrease), await javascriptExecutorBase.redo(),
Button(icon: Icons.format_indent_increase), ),
Button(icon: Icons.format_align_left_outlined), Button(
Button(icon: Icons.format_align_center), icon: Icons.format_quote,
Button(icon: Icons.format_align_right), onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
Button(icon: Icons.format_align_justify), await javascriptExecutorBase.setBlockQuote(),
Button(icon: Icons.format_list_bulleted), ),
Button(icon: Icons.format_list_numbered), Button(
Button(icon: Icons.link), icon: Icons.text_format,
Button(icon: Icons.image), onTap: (JavascriptExecutorBase javascriptExecutorBase, String name) async =>
Button(icon: Icons.check_box_outlined), await javascriptExecutorBase.removeFormat(),
),
Button(
icon: Icons.font_download,
onTap: (JavascriptExecutorBase javascriptExecutorBase, String name) async =>
await javascriptExecutorBase.setFontName(name),
),
Button(
icon: Icons.format_size,
onTap: (JavascriptExecutorBase javascriptExecutorBase, int size) async =>
await javascriptExecutorBase.setFontSize(size),
),
Button(
icon: Icons.format_color_text,
onTap: (JavascriptExecutorBase javascriptExecutorBase, Color color) async =>
await javascriptExecutorBase.setTextColor(color),
),
Button(
icon: Icons.format_color_fill,
onTap: (JavascriptExecutorBase javascriptExecutorBase, Color color) async =>
await javascriptExecutorBase.setTextBackgroundColor(color),
),
Button(
icon: Icons.format_indent_increase,
onTap: (JavascriptExecutorBase javascriptExecutorBase, int size) async =>
await javascriptExecutorBase.setIndent(),
),
Button(
icon: Icons.format_indent_decrease,
onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
await javascriptExecutorBase.setOutdent(),
),
Button(
icon: Icons.format_align_left_outlined,
onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
await javascriptExecutorBase.setJustifyLeft(),
),
Button(
icon: Icons.format_align_center,
onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
await javascriptExecutorBase.setJustifyCenter(),
),
Button(
icon: Icons.format_align_right,
onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
await javascriptExecutorBase.setJustifyRight(),
),
Button(
icon: Icons.format_align_justify,
onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
await javascriptExecutorBase.setJustifyFull(),
),
Button(
icon: Icons.format_list_bulleted,
onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
await javascriptExecutorBase.insertBulletList(),
),
Button(
icon: Icons.format_list_numbered,
onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
await javascriptExecutorBase.insertNumberedList(),
),
Button(
icon: Icons.check_box_outlined,
onTap: (JavascriptExecutorBase javascriptExecutorBase, String text) async =>
await javascriptExecutorBase.insertCheckbox(text),
),
Button(icon: Icons.search), Button(icon: Icons.search),
]; ];

View File

@ -15,8 +15,7 @@ class JavascriptExecutorBase {
setHtml(String html) async { setHtml(String html) async {
String? baseUrl; String? baseUrl;
await executeJavascript( await executeJavascript("setHtml('" + encodeHtml(html) + "', '$baseUrl');");
"setHtml('" + encodeHtml(html) + "', '$baseUrl');");
} }
getHtml() async { getHtml() async {
@ -66,6 +65,11 @@ class JavascriptExecutorBase {
await executeJavascript("setTextColor('$hex')"); await executeJavascript("setTextColor('$hex')");
} }
setTextBackgroundColor(Color? color) async {
String? hex = color!.toHexColorString();
await executeJavascript("setTextBackgroundColor('$hex')");
}
setFontName(String fontName) async { setFontName(String fontName) async {
await executeJavascript("setFontName('$fontName')"); await executeJavascript("setFontName('$fontName')");
} }
@ -136,9 +140,12 @@ class JavascriptExecutorBase {
/// The rotation parameter is used to signal that the image is rotated and should be rotated by CSS by given value. /// The rotation parameter is used to signal that the image is rotated and should be rotated by CSS by given value.
/// Rotation can be one of the following values: 0, 90, 180, 270. /// Rotation can be one of the following values: 0, 90, 180, 270.
insertImage(String url, String alt, insertImage(String url,
String? width, String? height, int? rotation) async { {String? alt, int? width, int? height, int? rotation}) async {
if (rotation == null) rotation = 0; if (rotation == null) rotation = 0;
if (width == null) width = 300;
if (height == null) height = 300;
if (alt == null) alt = '';
await executeJavascript( await executeJavascript(
"insertImage('$url', '$alt', '$width', '$height', $rotation)", "insertImage('$url', '$alt', '$width', '$height', $rotation)",
); );

View File

@ -29,7 +29,7 @@ class TabButton extends StatelessWidget {
padding: const EdgeInsets.all(5.0), padding: const EdgeInsets.all(5.0),
child: Icon( child: Icon(
icon, icon,
color: Colors.white, color: Theme.of(context).accentColor,
), ),
), ),
), ),

View File

@ -17,8 +17,9 @@ class GroupedTab extends StatelessWidget {
if (controller != null) { if (controller != null) {
javascriptExecutorBase.init(controller!); javascriptExecutorBase.init(controller!);
} }
return Container( return Container(
color: Color(0xff424242), // color: Color(0xff424242),
height: 59.0, height: 59.0,
child: Column( child: Column(
children: [ children: [
@ -27,29 +28,13 @@ class GroupedTab extends StatelessWidget {
shrinkWrap: true, shrinkWrap: true,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
children: [ children: [
for(Button button in buttons) for (Button button in buttons)
TabButton( TabButton(
icon: button.icon, icon: button.icon,
onTap: () async { onTap: () async {
print('BOLDDD'); button.onTap!(javascriptExecutorBase);
javascriptExecutorBase.setBold();
String? html = await javascriptExecutorBase.getHtml();
print(html!);
}, },
) )
// TabButton(
// icon: Icons.link,
// onTap: () async {
// javascriptExecutorBase.insertLink(
// 'https://github.com/JideGuru/rich_editor', 'git');
// },
// ),
// TabButton(
// icon: Icons.format_bold,
// onTap: () async {
// javascriptExecutorBase.setBold();
// },
// )
], ],
), ),
), ),

View File

@ -55,13 +55,6 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_inappwebview:
dependency: "direct main"
description:
name: flutter_inappwebview
url: "https://pub.dartlang.org"
source: hosted
version: "5.3.2"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -165,4 +158,4 @@ packages:
version: "2.0.7" version: "2.0.7"
sdks: sdks:
dart: ">=2.12.0 <3.0.0" dart: ">=2.12.0 <3.0.0"
flutter: ">=1.22.2" flutter: ">=1.22.0"

View File

@ -1,7 +1,7 @@
name: rich_editor name: rich_editor
description: A new Flutter package. description: A new Flutter package.
version: 0.0.1 version: 0.0.1
homepage: homepage: https://github.com/JideGuru/rich_editor
environment: environment:
sdk: ">=2.12.0 <3.0.0" sdk: ">=2.12.0 <3.0.0"
@ -11,7 +11,7 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
webview_flutter: ^2.0.4 webview_flutter: ^2.0.4
flutter_inappwebview: ^5.3.2 # flutter_inappwebview: ^5.3.2
mime: ^1.0.0 mime: ^1.0.0
dev_dependencies: dev_dependencies: