first commit

This commit is contained in:
jideguru
2021-05-26 23:42:34 +01:00
commit 386a8f518a
89 changed files with 3630 additions and 0 deletions

32
lib/constants.dart Normal file
View File

@@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
import 'package:rich_editor/src/models/button.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_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.search),
];

3
lib/rich_editor.dart Normal file
View File

@@ -0,0 +1,3 @@
library rich_editor;
export 'package:rich_editor/src/rendering/rich_editor.dart';

View File

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

View File

@@ -0,0 +1,46 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:rich_editor/src/services/local_server.dart';
import 'package:rich_editor/src/widgets/tabs.dart';
import 'package:webview_flutter/webview_flutter.dart';
class RichEditor extends StatefulWidget {
@override
_RichEditorState createState() => _RichEditorState();
}
class _RichEditorState extends State<RichEditor> {
WebViewController? _controller;
String text = "";
final Key _mapKey = UniqueKey();
int port = 5321;
LocalServer? localServer;
@override
void initState() {
super.initState();
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
GroupedTab(),
Flexible(
child: WebView(
initialUrl: 'file:///android_asset/flutter_assets/packages/rich_editor/assets/editor/editor.html',
onWebViewCreated: (WebViewController controller) {
_controller = _controller;
setState(() {});
},
),
// child: InAppWebView(
// initialFile: 'packages/rich_editor/assets/editor/index.html',
// ),
)
],
);
}
}

View File

@@ -0,0 +1,124 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:mime/mime.dart';
/*
* credit thanks to https://github.com/shah-xad/flutter_tex/blob/master/lib/src/utils/tex_view_server.dart
*/
class LocalServer {
HttpServer? server;
final int port;
LocalServer(this.port);
///Closes the server.
Future<void> close() async {
if (this.server != null) {
await this.server?.close(force: true);
this.server = null;
}
}
///Starts the server
Future<void> start(Function(HttpRequest request) request) async {
if (this.server != null) {
throw Exception('Server already started on http://localhost:$port');
}
var completer = new Completer();
runZoned(() {
HttpServer.bind('localhost', port, shared: true).then((server) {
this.server = server;
server.listen((HttpRequest httpRequest) async {
request(httpRequest);
var body = <int>[];
var path = httpRequest.requestedUri.path;
path = (path.startsWith('/')) ? path.substring(1) : path;
path += (path.endsWith('/')) ? 'index.html' : '';
try {
body = (await rootBundle.load(path)).buffer.asUint8List();
} catch (e) {
print(e.toString());
httpRequest.response.close();
return;
}
var contentType = ['text', 'html'];
if (!httpRequest.requestedUri.path.endsWith('/') &&
httpRequest.requestedUri.pathSegments.isNotEmpty) {
var mimeType = lookupMimeType(httpRequest.requestedUri.path,
headerBytes: body);
if (mimeType != null) {
contentType = mimeType.split('/');
}
}
httpRequest.response.headers.contentType =
new ContentType(contentType[0], contentType[1], charset: 'utf-8');
httpRequest.response.add(body);
httpRequest.response.close();
});
completer.complete();
});
}, onError: (e, stackTrace) => print('Error: $e $stackTrace'));
return completer.future;
}
}
class WebSocketServer {
HttpServer? server;
final int port;
WebSocketServer(this.port);
///Closes the server.
Future<void> close() async {
if (this.server != null) {
await this.server?.close(force: true);
this.server = null;
}
}
///Starts the server
Future<void> start() async {
if (this.server != null) {
throw Exception('Server already started on http://localhost:$port');
}
var completer = new Completer();
runZoned(() {
HttpServer.bind('localhost', port, shared: true).then(
(HttpServer server) {
print('[+]WebSocket listening at -- ws://localhost:$port/');
this.server = server;
server.listen((HttpRequest request) {
WebSocketTransformer.upgrade(request).then((WebSocket ws) {
ws.listen(
(data) {
print(
'\t\t${request.connectionInfo?.remoteAddress} -- ${data.toString()}');
Timer(Duration(seconds: 1), () {
if (ws.readyState == WebSocket.open)
// checking connection state helps to avoid unprecedented errors
ws.add("dfdfdfdfdfd");
});
},
onDone: () => print('[+]Done :)'),
onError: (err) => print('[!]Error -- ${err.toString()}'),
cancelOnError: true,
);
// request.response.close();
}, onError: (err) => print('[!]Error -- ${err.toString()}'));
}, onError: (err) => print('[!]Error -- ${err.toString()}'));
completer.complete();
}, onError: (err) => print('[!]Error -- ${err.toString()}'));
}, onError: (err) => print('[!]Error -- ${err.toString()}'));
return completer.future;
}
}

View File

@@ -0,0 +1,40 @@
import 'package:flutter/material.dart';
class TabButton extends StatelessWidget {
final IconData icon;
TabButton({this.icon = Icons.format_bold});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 5.0),
child: Container(
height: 45.0,
width: 45.0,
decoration: BoxDecoration(
// color: Color(0xff212121),
borderRadius: BorderRadius.all(
Radius.circular(5.0),
),
),
child: Material(
type: MaterialType.transparency,
child: InkWell(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
onTap: () {},
child: Center(
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Icon(
icon,
color: Colors.white,
),
),
),
),
),
),
);
}
}

41
lib/src/widgets/tabs.dart Normal file
View File

@@ -0,0 +1,41 @@
import 'package:flutter/material.dart';
import 'package:rich_editor/constants.dart';
import 'package:rich_editor/src/models/button.dart';
import 'package:rich_editor/src/widgets/tab_button.dart';
import 'package:webview_flutter/webview_flutter.dart';
class GroupedTab extends StatelessWidget {
final WebViewController? controller;
GroupedTab({this.controller});
@override
Widget build(BuildContext context) {
return Container(
color: Color(0xff424242),
height: 59.0,
child: Column(
children: [
Flexible(
child: ListView(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
children: [
for(Button button in buttons)
InkWell(
onTap: () {
print('BOLDDD');
controller?.evaluateJavascript('setBold()');
},
child: TabButton(
icon: button.icon,
),
)
],
),
),
],
),
);
}
}

0
lib/util.dart Normal file
View File