feat: start local server for iOS
This commit is contained in:
parent
f4f1802eb6
commit
8954f86086
@ -41,5 +41,10 @@
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -62,13 +62,6 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
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:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
@ -179,4 +172,4 @@ packages:
|
||||
version: "2.0.7"
|
||||
sdks:
|
||||
dart: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=1.22.2"
|
||||
flutter: ">=1.22.0"
|
||||
|
@ -2,7 +2,8 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Button {
|
||||
IconData icon;
|
||||
IconData? icon;
|
||||
Function? onTap;
|
||||
|
||||
Button({this.icon = Icons.format_bold});
|
||||
Button({this.icon, this.onTap});
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ class _RichEditorState extends State<RichEditor> {
|
||||
WebViewController? _controller;
|
||||
String text = "";
|
||||
final Key _mapKey = UniqueKey();
|
||||
String assetPath = 'packages/rich_editor/assets/editor/editor.html';
|
||||
|
||||
int port = 5321;
|
||||
LocalServer? localServer;
|
||||
@ -22,6 +23,41 @@ class _RichEditorState extends State<RichEditor> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
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
|
||||
@ -31,14 +67,24 @@ class _RichEditorState extends State<RichEditor> {
|
||||
GroupedTab(controller: _controller),
|
||||
Flexible(
|
||||
child: WebView(
|
||||
initialUrl:
|
||||
'file:///android_asset/flutter_assets/packages/rich_editor/assets/editor/editor.html',
|
||||
key: _mapKey,
|
||||
// initialUrl:
|
||||
// 'file:///android_asset/flutter_assets/packages/rich_editor/assets/editor/editor.html',
|
||||
onWebViewCreated: (WebViewController controller) {
|
||||
_controller = controller;
|
||||
print('WebView created');
|
||||
setState(() {});
|
||||
if (!Platform.isAndroid) {
|
||||
print('Loading');
|
||||
_loadHtmlFromAssets();
|
||||
} else {
|
||||
_controller!.loadUrl('file:///android_asset/flutter_assets/$assetPath');
|
||||
}
|
||||
},
|
||||
javascriptMode: JavascriptMode.unrestricted,
|
||||
onWebResourceError: (e) {
|
||||
print("error ${e.description}");
|
||||
},
|
||||
),
|
||||
// child: InAppWebView(
|
||||
// initialFile: 'packages/rich_editor/assets/editor/index.html',
|
||||
|
@ -1,32 +1,144 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rich_editor/src/models/button.dart';
|
||||
|
||||
import 'javascript_executor_base.dart';
|
||||
|
||||
List<Button> buttons = [
|
||||
Button(icon: Icons.format_bold),
|
||||
Button(icon: Icons.format_italic),
|
||||
Button(icon: Icons.format_underline),
|
||||
Button(icon: Icons.format_strikethrough),
|
||||
Button(icon: Icons.superscript),
|
||||
Button(icon: Icons.subscript),
|
||||
Button(
|
||||
icon: Icons.format_bold,
|
||||
onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
|
||||
await javascriptExecutorBase.setBold(),
|
||||
),
|
||||
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.undo),
|
||||
Button(icon: Icons.redo),
|
||||
Button(icon: Icons.format_quote),
|
||||
Button(icon: Icons.text_format),
|
||||
Button(icon: Icons.font_download),
|
||||
Button(icon: Icons.format_size),
|
||||
Button(icon: Icons.format_color_text),
|
||||
Button(icon: Icons.format_color_fill),
|
||||
Button(icon: Icons.format_indent_decrease),
|
||||
Button(icon: Icons.format_indent_increase),
|
||||
Button(icon: Icons.format_align_left_outlined),
|
||||
Button(icon: Icons.format_align_center),
|
||||
Button(icon: Icons.format_align_right),
|
||||
Button(icon: Icons.format_align_justify),
|
||||
Button(icon: Icons.format_list_bulleted),
|
||||
Button(icon: Icons.format_list_numbered),
|
||||
Button(icon: Icons.link),
|
||||
Button(icon: Icons.image),
|
||||
Button(icon: Icons.check_box_outlined),
|
||||
Button(
|
||||
icon: Icons.undo,
|
||||
onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
|
||||
await javascriptExecutorBase.undo(),
|
||||
),
|
||||
Button(
|
||||
icon: Icons.redo,
|
||||
onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
|
||||
await javascriptExecutorBase.redo(),
|
||||
),
|
||||
Button(
|
||||
icon: Icons.format_quote,
|
||||
onTap: (JavascriptExecutorBase javascriptExecutorBase) async =>
|
||||
await javascriptExecutorBase.setBlockQuote(),
|
||||
),
|
||||
Button(
|
||||
icon: Icons.text_format,
|
||||
onTap: (JavascriptExecutorBase javascriptExecutorBase, String name) async =>
|
||||
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),
|
||||
];
|
||||
];
|
||||
|
@ -15,8 +15,7 @@ class JavascriptExecutorBase {
|
||||
|
||||
setHtml(String html) async {
|
||||
String? baseUrl;
|
||||
await executeJavascript(
|
||||
"setHtml('" + encodeHtml(html) + "', '$baseUrl');");
|
||||
await executeJavascript("setHtml('" + encodeHtml(html) + "', '$baseUrl');");
|
||||
}
|
||||
|
||||
getHtml() async {
|
||||
@ -66,6 +65,11 @@ class JavascriptExecutorBase {
|
||||
await executeJavascript("setTextColor('$hex')");
|
||||
}
|
||||
|
||||
setTextBackgroundColor(Color? color) async {
|
||||
String? hex = color!.toHexColorString();
|
||||
await executeJavascript("setTextBackgroundColor('$hex')");
|
||||
}
|
||||
|
||||
setFontName(String fontName) async {
|
||||
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.
|
||||
/// Rotation can be one of the following values: 0, 90, 180, 270.
|
||||
insertImage(String url, String alt,
|
||||
String? width, String? height, int? rotation) async {
|
||||
insertImage(String url,
|
||||
{String? alt, int? width, int? height, int? rotation}) async {
|
||||
if (rotation == null) rotation = 0;
|
||||
if (width == null) width = 300;
|
||||
if (height == null) height = 300;
|
||||
if (alt == null) alt = '';
|
||||
await executeJavascript(
|
||||
"insertImage('$url', '$alt', '$width', '$height', $rotation)",
|
||||
);
|
||||
|
@ -29,7 +29,7 @@ class TabButton extends StatelessWidget {
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
child: Icon(
|
||||
icon,
|
||||
color: Colors.white,
|
||||
color: Theme.of(context).accentColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -17,8 +17,9 @@ class GroupedTab extends StatelessWidget {
|
||||
if (controller != null) {
|
||||
javascriptExecutorBase.init(controller!);
|
||||
}
|
||||
|
||||
return Container(
|
||||
color: Color(0xff424242),
|
||||
// color: Color(0xff424242),
|
||||
height: 59.0,
|
||||
child: Column(
|
||||
children: [
|
||||
@ -27,29 +28,13 @@ class GroupedTab extends StatelessWidget {
|
||||
shrinkWrap: true,
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: [
|
||||
for(Button button in buttons)
|
||||
for (Button button in buttons)
|
||||
TabButton(
|
||||
icon: button.icon,
|
||||
onTap: () async {
|
||||
print('BOLDDD');
|
||||
javascriptExecutorBase.setBold();
|
||||
String? html = await javascriptExecutorBase.getHtml();
|
||||
print(html!);
|
||||
button.onTap!(javascriptExecutorBase);
|
||||
},
|
||||
)
|
||||
// TabButton(
|
||||
// icon: Icons.link,
|
||||
// onTap: () async {
|
||||
// javascriptExecutorBase.insertLink(
|
||||
// 'https://github.com/JideGuru/rich_editor', 'git');
|
||||
// },
|
||||
// ),
|
||||
// TabButton(
|
||||
// icon: Icons.format_bold,
|
||||
// onTap: () async {
|
||||
// javascriptExecutorBase.setBold();
|
||||
// },
|
||||
// )
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -55,13 +55,6 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
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:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
@ -165,4 +158,4 @@ packages:
|
||||
version: "2.0.7"
|
||||
sdks:
|
||||
dart: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=1.22.2"
|
||||
flutter: ">=1.22.0"
|
||||
|
@ -1,7 +1,7 @@
|
||||
name: rich_editor
|
||||
description: A new Flutter package.
|
||||
version: 0.0.1
|
||||
homepage:
|
||||
homepage: https://github.com/JideGuru/rich_editor
|
||||
|
||||
environment:
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
@ -11,7 +11,7 @@ dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
webview_flutter: ^2.0.4
|
||||
flutter_inappwebview: ^5.3.2
|
||||
# flutter_inappwebview: ^5.3.2
|
||||
mime: ^1.0.0
|
||||
|
||||
dev_dependencies:
|
||||
|
Loading…
Reference in New Issue
Block a user