Rich text editor for Flutter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

170 lines
5.2 KiB

import 'dart:convert' show jsonEncode;
import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart';
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'
show FlutterQuillEmbeds, QuillSharedExtensionsConfigurations;
import 'package:quill_html_converter/quill_html_converter.dart';
import 'package:share_plus/share_plus.dart' show Share;
import '../extensions/scaffold_messenger.dart';
import '../shared/widgets/home_screen_button.dart';
import 'my_quill_editor.dart';
import 'my_quill_toolbar.dart';
@immutable
class QuillScreenArgs {
const QuillScreenArgs({required this.document});
final Document document;
}
class QuillScreen extends StatefulWidget {
const QuillScreen({
required this.args,
super.key,
});
final QuillScreenArgs args;
static const routeName = '/quill';
@override
State<QuillScreen> createState() => _QuillScreenState();
}
class _QuillScreenState extends State<QuillScreen> {
final _controller = QuillController.basic();
final _editorFocusNode = FocusNode();
final _editorScrollController = ScrollController();
var _isReadOnly = false;
@override
void initState() {
super.initState();
_controller.document = widget.args.document;
}
// Future<void> _init() async {
// final reader = await ClipboardReader.readClipboard();
// if (reader.canProvide(Formats.htmlText)) {
// final html = await reader.readValue(Formats.htmlText);
// if (html == null) {
// return;
// }
// final delta = DeltaHtmlExt.fromHtml(html);
// _controller.document = Document.fromDelta(delta);
// }
// }
@override
void dispose() {
_controller.dispose();
_editorFocusNode.dispose();
_editorScrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Quill'),
actions: [
IconButton(
tooltip: 'Load with HTML',
onPressed: () {
final html = _controller.document.toDelta().toHtml();
_controller.document =
Document.fromDelta(QuillController.fromHtml(html));
},
icon: const Icon(Icons.html),
),
IconButton(
tooltip: 'Share',
onPressed: () {
final plainText = _controller.document.toPlainText(
FlutterQuillEmbeds.defaultEditorBuilders(),
);
if (plainText.trim().isEmpty) {
ScaffoldMessenger.of(context).showText(
"We can't share empty document, please enter some text first",
);
return;
}
Share.share(plainText);
},
icon: const Icon(Icons.share),
),
IconButton(
tooltip: 'Print to log',
onPressed: () {
print(
jsonEncode(_controller.document.toDelta().toJson()),
);
ScaffoldMessenger.of(context).showText(
'The quill delta json has been printed to the log.',
);
},
icon: const Icon(Icons.print),
),
const HomeScreenButton(),
],
),
body: Column(
children: [
if (!_isReadOnly)
MyQuillToolbar(
controller: _controller,
focusNode: _editorFocusNode,
),
Builder(
builder: (context) {
return Expanded(
child: MyQuillEditor(
configurations: QuillEditorConfigurations(
sharedConfigurations: _sharedConfigurations,
controller: _controller,
readOnly: _isReadOnly,
customStyles: const DefaultStyles(),
elementOptions: const QuillEditorElementOptions(
codeBlock: QuillEditorCodeBlockElementOptions(
enableLineNumbers: true,
),
// orderedList: QuillEditorOrderedListElementOptions(
// backgroundColor: Colors.amber,
// fontColor: Colors.black,
// ),
// unorderedList: QuillEditorUnOrderedListElementOptions(
// backgroundColor: Colors.green,
// fontColor: Colors.red,
// ),
),
),
scrollController: _editorScrollController,
focusNode: _editorFocusNode,
),
);
},
),
],
),
floatingActionButton: FloatingActionButton(
child: Icon(_isReadOnly ? Icons.lock : Icons.edit),
onPressed: () => setState(() => _isReadOnly = !_isReadOnly),
),
);
}
QuillSharedConfigurations get _sharedConfigurations {
return const QuillSharedConfigurations(
// locale: Locale('en'),
extraConfigurations: {
QuillSharedExtensionsConfigurations.key:
QuillSharedExtensionsConfigurations(
assetsPrefix: 'assets', // Defaults to assets
),
},
);
}
}