chore: add linters conforming to style guide (#59)

Relates: #56 #57
This commit is contained in:
Mathias Mogensen 2023-04-12 14:37:50 +02:00 • committed by GitHub
commit cf5e83d370
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
60 changed files with 1875 additions and 1198 deletions

View file

@ -2,3 +2,13 @@ include: package:flutter_lints/flutter.yaml
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
linter:
rules:
- always_declare_return_types
- require_trailing_commas
- unnecessary_raw_strings
- use_decorated_box
analyzer:
exclude:
- lib/src/l10n/**

View file

@ -52,7 +52,8 @@ extension TextCommands on EditorState {
if (BuiltInAttributeKey.globalStyleKeys.contains(key)) {
final attr = n.attributes
..removeWhere(
(key, _) => BuiltInAttributeKey.globalStyleKeys.contains(key))
(key, _) => BuiltInAttributeKey.globalStyleKeys.contains(key),
)
..addAll(attributes)
..addAll({
BuiltInAttributeKey.subtype: key,

View file

@ -247,7 +247,9 @@ class Delta extends Iterable<TextOperation> {
@override
int get length {
return _operations.fold(
0, (previousValue, element) => previousValue + element.length);
0,
(previousValue, element) => previousValue + element.length,
);
}
/// Returns a Delta that is equivalent to applying the operations of own Delta, followed by another Delta.

View file

@ -58,11 +58,13 @@ class Transaction {
/// The [attributes] will be merged into the existing attributes.
void updateNode(Node node, Attributes attributes) {
final inverted = invertAttributes(node.attributes, attributes);
add(UpdateOperation(
add(
UpdateOperation(
node.path,
{...attributes},
inverted,
));
),
);
}
/// Deletes the [Node] in the document.
@ -170,10 +172,12 @@ extension TextTransaction on Transaction {
..delete(firstLength - firstOffset)
..addAll(second.delta.slice(secondOffset, secondLength)),
);
afterSelection = Selection.collapsed(Position(
afterSelection = Selection.collapsed(
Position(
path: first.path,
offset: firstOffset,
));
),
);
}
void splitText(TextNode textNode, int offset) {
@ -188,10 +192,12 @@ extension TextTransaction on Transaction {
delta: second,
),
);
afterSelection = Selection.collapsed(Position(
afterSelection = Selection.collapsed(
Position(
path: path,
offset: 0,
));
),
);
}
/// Inserts the text content at a specified index.

View file

@ -80,7 +80,8 @@ extension DeltaAttributesExtensions on Attributes {
if (containsKey(BuiltInAttributeKey.backgroundColor) &&
this[BuiltInAttributeKey.backgroundColor] is String) {
return Color(
int.tryParse(this[BuiltInAttributeKey.backgroundColor]) ?? whiteInt);
int.tryParse(this[BuiltInAttributeKey.backgroundColor]) ?? whiteInt,
);
}
return null;
}

View file

@ -300,16 +300,20 @@ class Overlay extends StatefulWidget {
final List<DiagnosticsNode> information = <DiagnosticsNode>[
ErrorSummary('No Overlay widget found.'),
ErrorDescription(
'${debugRequiredFor.runtimeType} widgets require an Overlay widget ancestor for correct operation.'),
'${debugRequiredFor.runtimeType} widgets require an Overlay widget ancestor for correct operation.',
),
ErrorHint(
'The most common way to add an Overlay to an application is to include a MaterialApp or Navigator widget in the runApp() call.'),
'The most common way to add an Overlay to an application is to include a MaterialApp or Navigator widget in the runApp() call.',
),
DiagnosticsProperty<Widget>(
'The specific widget that failed to find an overlay was',
debugRequiredFor,
style: DiagnosticsTreeStyle.errorProperty),
style: DiagnosticsTreeStyle.errorProperty,
),
if (context.widget != debugRequiredFor)
context.describeElement(
'The context from which that widget was searching for an overlay was'),
'The context from which that widget was searching for an overlay was',
),
];
throw FlutterError.fromParts(information);
@ -352,10 +356,14 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin {
/// It is an error to specify both `above` and `below`.
void insert(OverlayEntry entry, {OverlayEntry? below, OverlayEntry? above}) {
assert(_debugVerifyInsertPosition(above, below));
assert(!_entries.contains(entry),
'The specified entry is already present in the Overlay.');
assert(entry._overlay == null,
'The specified entry is already present in another Overlay.');
assert(
!_entries.contains(entry),
'The specified entry is already present in the Overlay.',
);
assert(
entry._overlay == null,
'The specified entry is already present in another Overlay.',
);
entry._overlay = this;
setState(() {
_entries.insert(_insertionIndex(below, above), entry);
@ -369,8 +377,11 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin {
/// Otherwise, the entries are inserted on top.
///
/// It is an error to specify both `above` and `below`.
void insertAll(Iterable<OverlayEntry> entries,
{OverlayEntry? below, OverlayEntry? above}) {
void insertAll(
Iterable<OverlayEntry> entries, {
OverlayEntry? below,
OverlayEntry? above,
}) {
assert(_debugVerifyInsertPosition(above, below));
assert(
entries.every((OverlayEntry entry) => !_entries.contains(entry)),
@ -390,8 +401,11 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin {
});
}
bool _debugVerifyInsertPosition(OverlayEntry? above, OverlayEntry? below,
{Iterable<OverlayEntry>? newEntries}) {
bool _debugVerifyInsertPosition(
OverlayEntry? above,
OverlayEntry? below, {
Iterable<OverlayEntry>? newEntries,
}) {
assert(
above == null || below == null,
'Only one of `above` and `below` may be specified.',
@ -430,21 +444,29 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin {
/// below.
///
/// It is an error to specify both `above` and `below`.
void rearrange(Iterable<OverlayEntry> newEntries,
{OverlayEntry? below, OverlayEntry? above}) {
void rearrange(
Iterable<OverlayEntry> newEntries, {
OverlayEntry? below,
OverlayEntry? above,
}) {
final List<OverlayEntry> newEntriesList = newEntries is List<OverlayEntry>
? newEntries
: newEntries.toList(growable: false);
assert(
_debugVerifyInsertPosition(above, below, newEntries: newEntriesList));
_debugVerifyInsertPosition(above, below, newEntries: newEntriesList),
);
assert(
newEntriesList.every((OverlayEntry entry) =>
entry._overlay == null || entry._overlay == this),
newEntriesList.every(
(OverlayEntry entry) =>
entry._overlay == null || entry._overlay == this,
),
'One or more of the specified entries are already present in another Overlay.',
);
assert(
newEntriesList.every((OverlayEntry entry) =>
_entries.indexOf(entry) == _entries.lastIndexOf(entry)),
newEntriesList.every(
(OverlayEntry entry) =>
_entries.indexOf(entry) == _entries.lastIndexOf(entry),
),
'One or more of the specified entries are specified multiple times.',
);
if (newEntriesList.isEmpty) return;
@ -509,17 +531,21 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin {
final OverlayEntry entry = _entries[i];
if (onstage) {
onstageCount += 1;
children.add(_OverlayEntryWidget(
children.add(
_OverlayEntryWidget(
key: entry._key,
entry: entry,
));
),
);
if (entry.opaque) onstage = false;
} else if (entry.maintainState) {
children.add(_OverlayEntryWidget(
children.add(
_OverlayEntryWidget(
key: entry._key,
entry: entry,
tickerEnabled: false,
));
),
);
}
}
return _Theatre(
@ -684,26 +710,34 @@ class _RenderTheatre extends RenderBox
@override
double computeMinIntrinsicWidth(double height) {
return RenderStack.getIntrinsicDimension(_firstOnstageChild,
(RenderBox child) => child.getMinIntrinsicWidth(height));
return RenderStack.getIntrinsicDimension(
_firstOnstageChild,
(RenderBox child) => child.getMinIntrinsicWidth(height),
);
}
@override
double computeMaxIntrinsicWidth(double height) {
return RenderStack.getIntrinsicDimension(_firstOnstageChild,
(RenderBox child) => child.getMaxIntrinsicWidth(height));
return RenderStack.getIntrinsicDimension(
_firstOnstageChild,
(RenderBox child) => child.getMaxIntrinsicWidth(height),
);
}
@override
double computeMinIntrinsicHeight(double width) {
return RenderStack.getIntrinsicDimension(_firstOnstageChild,
(RenderBox child) => child.getMinIntrinsicHeight(width));
return RenderStack.getIntrinsicDimension(
_firstOnstageChild,
(RenderBox child) => child.getMinIntrinsicHeight(width),
);
}
@override
double computeMaxIntrinsicHeight(double width) {
return RenderStack.getIntrinsicDimension(_firstOnstageChild,
(RenderBox child) => child.getMaxIntrinsicHeight(width));
return RenderStack.getIntrinsicDimension(
_firstOnstageChild,
(RenderBox child) => child.getMaxIntrinsicHeight(width),
);
}
@override
@ -764,7 +798,11 @@ class _RenderTheatre extends RenderBox
_resolvedAlignment!.alongOffset(size - child.size as Offset);
} else {
_hasVisualOverflow = RenderStack.layoutPositionedChild(
child, childParentData, size, _resolvedAlignment!) ||
child,
childParentData,
size,
_resolvedAlignment!,
) ||
_hasVisualOverflow;
}

View file

@ -22,17 +22,17 @@ class HistoryItem extends LinkedListEntry<HistoryItem> {
/// to the item.
///
/// The caller should create a new [HistoryItem].
seal() {
void seal() {
_sealed = true;
}
bool get sealed => _sealed;
add(Operation op) {
void add(Operation op) {
operations.add(op);
}
addAll(Iterable<Operation> iterable) {
void addAll(Iterable<Operation> iterable) {
operations.addAll(iterable);
}
@ -56,7 +56,7 @@ class FixedSizeStack {
FixedSizeStack(this.maxSize);
push(HistoryItem stackItem) {
void push(HistoryItem stackItem) {
if (_list.length >= maxSize) {
_list.remove(_list.first);
}
@ -74,7 +74,7 @@ class FixedSizeStack {
return last;
}
clear() {
void clear() {
_list.clear();
}
@ -110,7 +110,7 @@ class UndoManager {
return last;
}
undo() {
void undo() {
Log.editor.debug('undo');
final s = state;
if (s == null) {
@ -130,7 +130,7 @@ class UndoManager {
);
}
redo() {
void redo() {
Log.editor.debug('redo');
final s = state;
if (s == null) {

View file

@ -103,7 +103,8 @@ class HTMLToNodesConverter {
for (final child in element.nodes.toList()) {
if (child is html.Element) {
result.addAll(
_handleElement(child, {"subtype": BuiltInAttributeKey.quote}));
_handleElement(child, {"subtype": BuiltInAttributeKey.quote}),
);
}
}
@ -115,8 +116,10 @@ class HTMLToNodesConverter {
return _handleContainer(childNodes);
}
List<Node> _handleElement(html.Element element,
[Map<String, dynamic>? attributes]) {
List<Node> _handleElement(
html.Element element, [
Map<String, dynamic>? attributes,
]) {
if (element.localName == HTMLTag.h1) {
return [_handleHeadingElement(element, HTMLTag.h1)];
} else if (element.localName == HTMLTag.h2) {
@ -142,8 +145,10 @@ class HTMLToNodesConverter {
}
}
Node _handleParagraph(html.Element element,
[Map<String, dynamic>? attributes]) {
Node _handleParagraph(
html.Element element, [
Map<String, dynamic>? attributes,
]) {
_inParagraph = true;
final node = _handleRichText(element, attributes);
_inParagraph = false;
@ -171,7 +176,8 @@ class HTMLToNodesConverter {
}
Attributes? _getDeltaAttributesFromHtmlAttributes(
LinkedHashMap<Object, String> htmlAttributes) {
LinkedHashMap<Object, String> htmlAttributes,
) {
final attrs = <String, dynamic>{};
final styleString = htmlAttributes["style"];
final cssMap = _cssStringToMap(styleString);
@ -209,7 +215,7 @@ class HTMLToNodesConverter {
return attrs.isEmpty ? null : attrs;
}
_assignTextDecorations(Attributes attrs, String decorationStr) {
void _assignTextDecorations(Attributes attrs, String decorationStr) {
final decorations = decorationStr.split(" ");
for (final d in decorations) {
if (d == "line-through") {
@ -220,7 +226,7 @@ class HTMLToNodesConverter {
}
}
_handleRichTextElement(Delta delta, html.Element element) {
void _handleRichTextElement(Delta delta, html.Element element) {
if (element.localName == HTMLTag.span) {
delta.insert(
element.text,
@ -242,11 +248,18 @@ class HTMLToNodesConverter {
attributes: {BuiltInAttributeKey.italic: true},
);
} else if (element.localName == HTMLTag.underline) {
delta.insert(element.text,
attributes: {BuiltInAttributeKey.underline: true});
delta.insert(
element.text,
attributes: {BuiltInAttributeKey.underline: true},
);
} else if ([HTMLTag.italic, HTMLTag.em].contains(element.localName)) {
delta
.insert(element.text, attributes: {BuiltInAttributeKey.italic: true});
} else if (element.localName == HTMLTag.del) {
delta.insert(element.text,
attributes: {BuiltInAttributeKey.strikethrough: true});
delta.insert(
element.text,
attributes: {BuiltInAttributeKey.strikethrough: true},
);
} else if (element.localName == HTMLTag.code) {
delta.insert(element.text, attributes: {BuiltInAttributeKey.code: true});
} else {
@ -258,8 +271,10 @@ class HTMLToNodesConverter {
/// be regarded as a checkbox block.
///
/// A container contains a <img /> will be regarded as a image block
Node _handleRichText(html.Element element,
[Map<String, dynamic>? attributes]) {
Node _handleRichText(
html.Element element, [
Map<String, dynamic>? attributes,
]) {
final image = element.querySelector(HTMLTag.image);
if (image != null) {
final imageNode = _handleImage(image);
@ -284,13 +299,16 @@ class HTMLToNodesConverter {
}
}
final textNode = TextNode(delta: delta, attributes: {
final textNode = TextNode(
delta: delta,
attributes: {
if (attributes != null) ...attributes,
if (isCheckbox) ...{
BuiltInAttributeKey.subtype: BuiltInAttributeKey.checkbox,
BuiltInAttributeKey.checkbox: checked,
}
});
},
);
return textNode;
}
@ -306,10 +324,12 @@ class HTMLToNodesConverter {
List<Node> _handleUnorderedList(html.Element element) {
final result = <Node>[];
for (var child in element.children) {
result.addAll(_handleListElement(
result.addAll(
_handleListElement(
child,
{"subtype": BuiltInAttributeKey.bulletedList},
));
),
);
}
return result;
}
@ -318,8 +338,12 @@ class HTMLToNodesConverter {
final result = <Node>[];
for (var i = 0; i < element.children.length; i++) {
final child = element.children[i];
result.addAll(_handleListElement(
child, {"subtype": BuiltInAttributeKey.numberList, "number": i + 1}));
result.addAll(
_handleListElement(
child,
{"subtype": BuiltInAttributeKey.numberList, "number": i + 1},
),
);
}
return result;
}
@ -332,11 +356,14 @@ class HTMLToNodesConverter {
delta.insert(element.text);
return TextNode(
attributes: {"subtype": "heading", "heading": headingStyle},
delta: delta);
delta: delta,
);
}
List<Node> _handleListElement(html.Element element,
[Map<String, dynamic>? attributes]) {
List<Node> _handleListElement(
html.Element element, [
Map<String, dynamic>? attributes,
]) {
final result = <Node>[];
final childNodes = element.nodes.toList();
for (final child in childNodes) {
@ -367,15 +394,19 @@ class NodesToHTMLConverter {
/// This container is used to save the list elements temporarily.
html.Element? _stashListContainer;
NodesToHTMLConverter(
{required this.nodes, this.startOffset, this.endOffset}) {
NodesToHTMLConverter({
required this.nodes,
this.startOffset,
this.endOffset,
}) {
if (nodes.isEmpty) {
return;
} else if (nodes.length == 1) {
final first = nodes.first;
if (first is TextNode) {
nodes[0] = first.copyWith(
delta: first.delta.slice(startOffset ?? 0, endOffset));
delta: first.delta.slice(startOffset ?? 0, endOffset),
);
}
} else {
final first = nodes.first;
@ -411,16 +442,17 @@ class NodesToHTMLConverter {
return _result;
}
_addTextNode(TextNode textNode, {int? end}) {
void _addTextNode(TextNode textNode, {int? end}) {
_addElement(textNode, _textNodeToHtml(textNode, end: end));
}
_addElement(TextNode textNode, html.Element element) {
void _addElement(TextNode textNode, html.Element element) {
if (element.localName == HTMLTag.list) {
final isNumbered =
textNode.attributes["subtype"] == BuiltInAttributeKey.numberList;
_stashListContainer ??= html.Element.tag(
isNumbered ? HTMLTag.orderedList : HTMLTag.unorderedList);
isNumbered ? HTMLTag.orderedList : HTMLTag.unorderedList,
);
_stashListContainer?.append(element);
} else {
if (_stashListContainer != null) {
@ -434,18 +466,22 @@ class NodesToHTMLConverter {
String toHTMLString() {
final elements = toHTMLNodes();
final copyString = elements.fold<String>(
"", ((previousValue, element) => previousValue + stringify(element)));
"",
((previousValue, element) => previousValue + stringify(element)),
);
return copyString;
}
html.Element _textNodeToHtml(TextNode textNode, {int? end}) {
String? subType = textNode.attributes["subtype"];
String? heading = textNode.attributes["heading"];
return _deltaToHtml(textNode.delta,
return _deltaToHtml(
textNode.delta,
subType: subType,
heading: heading,
end: end,
checked: textNode.attributes["checkbox"] == true);
checked: textNode.attributes["checkbox"] == true,
);
}
String _textDecorationsFromAttributes(Attributes attributes) {
@ -515,8 +551,13 @@ class NodesToHTMLConverter {
/// ```html
/// <span style="...">Text</span>
/// ```
html.Element _deltaToHtml(Delta delta,
{String? subType, String? heading, int? end, bool? checked}) {
html.Element _deltaToHtml(
Delta delta, {
String? subType,
String? heading,
int? end,
bool? checked,
}) {
if (end != null) {
delta = delta.slice(0, end);
}

View file

@ -80,7 +80,7 @@ class DocumentMarkdownDecoder extends Converter<String, Document> {
BuiltInAttributeKey.subtype: BuiltInAttributeKey.quote,
},
);
} else if (text.isNotEmpty && RegExp(r'^-*').stringMatch(text) == text) {
} else if (text.isNotEmpty && RegExp('^-*').stringMatch(text) == text) {
return Node(type: 'divider');
}

View file

@ -22,13 +22,17 @@ Document markdownToDocument(
/// Converts a [Document] to markdown.
///
/// [customParsers] is a list of custom parsers that will be used to parse the markdown.
String documentToMarkdown(Document document,
{List<NodeParser> customParsers = const []}) {
return AppFlowyEditorMarkdownCodec(encodeParsers: [
String documentToMarkdown(
Document document, {
List<NodeParser> customParsers = const [],
}) {
return AppFlowyEditorMarkdownCodec(
encodeParsers: [
...customParsers,
const TextNodeParser(),
const ImageNodeParser(),
]).encode(document);
],
).encode(document);
}
class AppFlowyEditorMarkdownCodec extends Codec<Document, String> {

View file

@ -106,7 +106,10 @@ class _ColorPickerState extends State<ColorPicker> {
}
Widget _buildColorItems(
_ColorType type, List<ColorOption> options, String? selectedColor) {
_ColorType type,
List<ColorOption> options,
String? selectedColor,
) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,

View file

@ -52,7 +52,7 @@ class _LinkMenuState extends State<LinkMenu> {
Widget build(BuildContext context) {
return SizedBox(
width: 350,
child: Container(
child: DecoratedBox(
decoration: BoxDecoration(
color: style?.selectionMenuBackgroundColor ?? Colors.white,
boxShadow: [

View file

@ -79,7 +79,9 @@ class _FlowyRichTextState extends State<FlowyRichText> with SelectableMixin {
@override
Position end() => Position(
path: widget.textNode.path, offset: widget.textNode.toPlainText().length);
path: widget.textNode.path,
offset: widget.textNode.toPlainText().length,
);
@override
Rect? getCursorRectInPosition(Position position) {
@ -92,7 +94,9 @@ class _FlowyRichTextState extends State<FlowyRichText> with SelectableMixin {
cursorHeight =
_placeholderRenderParagraph?.getFullHeightForCaret(textPosition);
cursorOffset = _placeholderRenderParagraph?.getOffsetForCaret(
textPosition, Rect.zero) ??
textPosition,
Rect.zero,
) ??
Offset.zero;
}
if (widget.cursorHeight != null && cursorHeight != null) {
@ -139,8 +143,9 @@ class _FlowyRichTextState extends State<FlowyRichText> with SelectableMixin {
@override
List<Rect> getRectsInSelection(Selection selection) {
assert(selection.isSingle &&
selection.start.path.equals(widget.textNode.path));
assert(
selection.isSingle && selection.start.path.equals(widget.textNode.path),
);
final textSelection = TextSelection(
baseOffset: selection.start.offset,
@ -196,7 +201,9 @@ class _FlowyRichTextState extends State<FlowyRichText> with SelectableMixin {
return RichText(
key: _placeholderTextKey,
textHeightBehavior: const TextHeightBehavior(
applyHeightToFirstAscent: false, applyHeightToLastDescent: false),
applyHeightToFirstAscent: false,
applyHeightToLastDescent: false,
),
text: widget.placeholderTextSpanDecorator != null
? widget.placeholderTextSpanDecorator!(textSpan)
: textSpan,
@ -303,7 +310,9 @@ class _FlowyRichTextState extends State<FlowyRichText> with SelectableMixin {
}
GestureRecognizer _buildTapHrefGestureRecognizer(
String href, Selection selection) {
String href,
Selection selection,
) {
Timer? timer;
var tapCount = 0;
final tapGestureRecognizer = TapGestureRecognizer()

View file

@ -53,7 +53,7 @@ class CursorWidgetState extends State<CursorWidget> {
}
/// force the cursor widget to show for a while
show() {
void show() {
setState(() {
showCursor = true;
});

View file

@ -40,10 +40,12 @@ class _SelectionMenuItemWidgetState extends State<SelectionMenuItemWidget> {
style: ButtonStyle(
alignment: Alignment.centerLeft,
overlayColor: MaterialStateProperty.all(
editorStyle.selectionMenuItemSelectedColor),
editorStyle.selectionMenuItemSelectedColor,
),
backgroundColor: widget.isSelected
? MaterialStateProperty.all(
editorStyle.selectionMenuItemSelectedColor)
editorStyle.selectionMenuItemSelectedColor,
)
: MaterialStateProperty.all(Colors.transparent),
),
label: Text(

View file

@ -83,10 +83,13 @@ class SelectionMenu implements SelectionMenuService {
_alignment = Alignment.topLeft;
}
_topLeft = offset;
_offset = Offset(offset.dx,
showBelow ? offset.dy : MediaQuery.of(context).size.height - offset.dy);
_offset = Offset(
offset.dx,
showBelow ? offset.dy : MediaQuery.of(context).size.height - offset.dy,
);
_selectionMenuEntry = OverlayEntry(builder: (context) {
_selectionMenuEntry = OverlayEntry(
builder: (context) {
return Positioned(
top: showBelow ? _offset.dy : null,
bottom: showBelow ? null : _offset.dy,
@ -111,7 +114,8 @@ class SelectionMenu implements SelectionMenuService {
),
),
);
});
},
);
Overlay.of(context).insert(_selectionMenuEntry!);
@ -241,7 +245,10 @@ final List<SelectionMenuItem> _defaultSelectionMenuItems = [
];
Widget _selectionMenuIcon(
String name, EditorState editorState, bool onSelected) {
String name,
EditorState editorState,
bool onSelected,
) {
return FlowySvg(
name: 'selection_menu/$name',
color: onSelected

View file

@ -119,7 +119,11 @@ class SelectionMenuItem {
transaction
..insertNode(path, node)
..afterSelection = updateSelection?.call(
editorState, path, bReplace, bInsertBefore) ??
editorState,
path,
bReplace,
bInsertBefore,
) ??
selection;
if (bReplace) {
@ -216,7 +220,7 @@ class _SelectionMenuWidgetState extends State<SelectionMenuWidget> {
return Focus(
focusNode: _focusNode,
onKey: _onKey,
child: Container(
child: DecoratedBox(
decoration: BoxDecoration(
color: widget.editorState.editorStyle.selectionMenuBackgroundColor,
boxShadow: [
@ -248,24 +252,30 @@ class _SelectionMenuWidgetState extends State<SelectionMenuWidget> {
List<Widget> itemWidgets = [];
for (var i = 0; i < items.length; i++) {
if (i != 0 && i % (widget.maxItemInRow) == 0) {
columns.add(Column(
columns.add(
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: itemWidgets,
));
),
);
itemWidgets = [];
}
itemWidgets.add(SelectionMenuItemWidget(
itemWidgets.add(
SelectionMenuItemWidget(
item: items[i],
isSelected: selectedIndex == i,
editorState: widget.editorState,
menuService: widget.menuService,
));
),
);
}
if (itemWidgets.isNotEmpty) {
columns.add(Column(
columns.add(
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: itemWidgets,
));
),
);
itemWidgets = [];
}
return Row(

View file

@ -118,7 +118,9 @@ class EditorStyle extends ThemeExtension<EditorStyle> {
@override
ThemeExtension<EditorStyle> lerp(
ThemeExtension<EditorStyle>? other, double t) {
ThemeExtension<EditorStyle>? other,
double t,
) {
if (other == null || other is! EditorStyle) {
return this;
}
@ -129,21 +131,35 @@ class EditorStyle extends ThemeExtension<EditorStyle> {
textPadding: EdgeInsets.lerp(textPadding, other.textPadding, t),
selectionColor: Color.lerp(selectionColor, other.selectionColor, t),
selectionMenuBackgroundColor: Color.lerp(
selectionMenuBackgroundColor, other.selectionMenuBackgroundColor, t),
selectionMenuBackgroundColor,
other.selectionMenuBackgroundColor,
t,
),
selectionMenuItemTextColor: Color.lerp(
selectionMenuItemTextColor, other.selectionMenuItemTextColor, t),
selectionMenuItemTextColor,
other.selectionMenuItemTextColor,
t,
),
selectionMenuItemIconColor: Color.lerp(
selectionMenuItemIconColor, other.selectionMenuItemIconColor, t),
selectionMenuItemIconColor,
other.selectionMenuItemIconColor,
t,
),
selectionMenuItemSelectedTextColor: Color.lerp(
selectionMenuItemSelectedTextColor,
other.selectionMenuItemSelectedTextColor,
t),
t,
),
selectionMenuItemSelectedIconColor: Color.lerp(
selectionMenuItemSelectedIconColor,
other.selectionMenuItemSelectedIconColor,
t),
selectionMenuItemSelectedColor: Color.lerp(selectionMenuItemSelectedColor,
other.selectionMenuItemSelectedColor, t),
t,
),
selectionMenuItemSelectedColor: Color.lerp(
selectionMenuItemSelectedColor,
other.selectionMenuItemSelectedColor,
t,
),
textStyle: TextStyle.lerp(textStyle, other.textStyle, t),
placeholderTextStyle:
TextStyle.lerp(placeholderTextStyle, other.placeholderTextStyle, t),

View file

@ -19,11 +19,17 @@ Iterable<ThemeExtension<dynamic>> get darkPluginStyleExtension => [
];
typedef TextStyleCustomizer = TextStyle Function(
EditorState editorState, TextNode textNode);
EditorState editorState,
TextNode textNode,
);
typedef PaddingCustomizer = EdgeInsets Function(
EditorState editorState, TextNode textNode);
EditorState editorState,
TextNode textNode,
);
typedef IconCustomizer = Widget Function(
EditorState editorState, TextNode textNode);
EditorState editorState,
TextNode textNode,
);
class HeadingPluginStyle extends ThemeExtension<HeadingPluginStyle> {
const HeadingPluginStyle({
@ -47,7 +53,9 @@ class HeadingPluginStyle extends ThemeExtension<HeadingPluginStyle> {
@override
ThemeExtension<HeadingPluginStyle> lerp(
ThemeExtension<HeadingPluginStyle>? other, double t) {
ThemeExtension<HeadingPluginStyle>? other,
double t,
) {
if (other is! HeadingPluginStyle) {
return this;
}
@ -105,7 +113,9 @@ class CheckboxPluginStyle extends ThemeExtension<CheckboxPluginStyle> {
@override
ThemeExtension<CheckboxPluginStyle> lerp(
ThemeExtension<CheckboxPluginStyle>? other, double t) {
ThemeExtension<CheckboxPluginStyle>? other,
double t,
) {
if (other is! CheckboxPluginStyle) {
return this;
}
@ -167,7 +177,9 @@ class BulletedListPluginStyle extends ThemeExtension<BulletedListPluginStyle> {
@override
ThemeExtension<BulletedListPluginStyle> lerp(
ThemeExtension<BulletedListPluginStyle>? other, double t) {
ThemeExtension<BulletedListPluginStyle>? other,
double t,
) {
if (other is! BulletedListPluginStyle) {
return this;
}
@ -194,7 +206,8 @@ class BulletedListPluginStyle extends ThemeExtension<BulletedListPluginStyle> {
},
);
static final dark = light.copyWith(icon: (_, __) {
static final dark = light.copyWith(
icon: (_, __) {
const iconSize = Size.square(20.0);
const iconPadding = EdgeInsets.only(right: 5.0);
return FlowySvg(
@ -204,7 +217,8 @@ class BulletedListPluginStyle extends ThemeExtension<BulletedListPluginStyle> {
color: Colors.white,
name: 'point',
);
});
},
);
}
class NumberListPluginStyle extends ThemeExtension<NumberListPluginStyle> {
@ -264,7 +278,8 @@ class NumberListPluginStyle extends ThemeExtension<NumberListPluginStyle> {
},
);
static final dark = light.copyWith(icon: (editorState, textNode) {
static final dark = light.copyWith(
icon: (editorState, textNode) {
const iconPadding = EdgeInsets.only(left: 5.0, right: 5.0);
return Container(
padding: iconPadding,
@ -276,7 +291,8 @@ class NumberListPluginStyle extends ThemeExtension<NumberListPluginStyle> {
),
),
);
});
},
);
}
class QuotedTextPluginStyle extends ThemeExtension<QuotedTextPluginStyle> {
@ -305,7 +321,9 @@ class QuotedTextPluginStyle extends ThemeExtension<QuotedTextPluginStyle> {
@override
ThemeExtension<QuotedTextPluginStyle> lerp(
ThemeExtension<QuotedTextPluginStyle>? other, double t) {
ThemeExtension<QuotedTextPluginStyle>? other,
double t,
) {
if (other is! QuotedTextPluginStyle) {
return this;
}

View file

@ -14,7 +14,9 @@ import 'dart:io' show Platform;
import 'package:flutter/material.dart' hide Overlay, OverlayEntry;
typedef ToolbarItemEventHandler = void Function(
EditorState editorState, BuildContext context);
EditorState editorState,
BuildContext context,
);
typedef ToolbarItemValidator = bool Function(EditorState editorState);
typedef ToolbarItemHighlightCallback = bool Function(EditorState editorState);
@ -413,7 +415,8 @@ void showLinkMenu(
);
}
_linkMenuOverlay = OverlayEntry(builder: (context) {
_linkMenuOverlay = OverlayEntry(
builder: (context) {
return Positioned(
top: matchRect.bottom + 5.0,
left: matchRect.left,
@ -457,7 +460,8 @@ void showLinkMenu(
),
),
);
});
},
);
Overlay.of(context)?.insert(_linkMenuOverlay!);
editorState.service.scrollService?.disable();
@ -564,7 +568,8 @@ void showColorMenu(
}
final style = editorState.editorStyle;
_colorMenuOverlay = OverlayEntry(builder: (context) {
_colorMenuOverlay = OverlayEntry(
builder: (context) {
return Positioned(
top: matchRect.bottom + 5.0,
left: matchRect.left + 10,
@ -575,11 +580,13 @@ void showColorMenu(
style.selectionMenuBackgroundColor ?? Colors.white,
pickerItemHoverColor: style.selectionMenuItemSelectedColor ??
Colors.blue.withOpacity(0.3),
pickerItemTextColor: style.selectionMenuItemTextColor ?? Colors.black,
pickerItemTextColor:
style.selectionMenuItemTextColor ?? Colors.black,
selectedFontColorHex: fontColorHex,
selectedBackgroundColorHex: backgroundColorHex,
fontColorOptions: _generateFontColorOptions(editorState),
backgroundColorOptions: _generateBackgroundColorOptions(editorState),
backgroundColorOptions:
_generateBackgroundColorOptions(editorState),
onSubmittedbackgroundColorHex: (color) {
formatHighlightColor(
editorState,
@ -597,7 +604,8 @@ void showColorMenu(
),
),
);
});
},
);
Overlay.of(context)?.insert(_colorMenuOverlay!);
editorState.service.scrollService?.disable();

Some files were not shown because too many files have changed in this diff Show more