feat: start local server for iOS
This commit is contained in:
parent
f4f1802eb6
commit
8954f86086
@ -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>
|
||||||
|
@ -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"
|
||||||
|
@ -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});
|
||||||
}
|
}
|
||||||
|
@ -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',
|
||||||
|
@ -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),
|
||||||
];
|
];
|
@ -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)",
|
||||||
);
|
);
|
||||||
|
@ -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,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -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();
|
|
||||||
// },
|
|
||||||
// )
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -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"
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user