feat: display number in latin or roman format (#595)

This commit is contained in:
q200892907 2023-11-18 13:48:17 +08:00 • committed by GitHub
commit c63d664513
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 101 additions and 3 deletions

View file

@ -1,6 +1,7 @@
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/editor/block_component/base_component/block_icon_builder.dart'; import 'package:appflowy_editor/src/editor/block_component/base_component/block_icon_builder.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:numerus/roman/roman.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class NumberedListBlockKeys { class NumberedListBlockKeys {
@ -207,7 +208,6 @@ class _NumberedListIcon extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final editorState = context.read<EditorState>(); final editorState = context.read<EditorState>();
final text = editorState.editorStyle.textStyleConfiguration.text; final text = editorState.editorStyle.textStyleConfiguration.text;
final level = _NumberedListIconBuilder(node: node).level;
return Container( return Container(
constraints: const BoxConstraints(minWidth: 26, minHeight: 22), constraints: const BoxConstraints(minWidth: 26, minHeight: 22),
padding: const EdgeInsets.only(right: 4.0), padding: const EdgeInsets.only(right: 4.0),
@ -217,7 +217,10 @@ class _NumberedListIcon extends StatelessWidget {
applyHeightToFirstAscent: false, applyHeightToFirstAscent: false,
applyHeightToLastDescent: false, applyHeightToLastDescent: false,
), ),
TextSpan(text: '$level.', style: text.combine(textStyle)), TextSpan(
text: node.levelString,
style: text.combine(textStyle),
),
textDirection: direction, textDirection: direction,
), ),
), ),
@ -225,6 +228,21 @@ class _NumberedListIcon extends StatelessWidget {
} }
} }
extension on Node {
String get levelString {
final builder = _NumberedListIconBuilder(node: this);
final indexInRootLevel = builder.indexInRootLevel;
final indexInSameLevel = builder.indexInSameLevel;
final level = indexInRootLevel % 3;
final levelString = switch (level) {
1 => indexInSameLevel.latin,
2 => indexInSameLevel.roman,
_ => '$indexInSameLevel',
};
return '$levelString.';
}
}
class _NumberedListIconBuilder { class _NumberedListIconBuilder {
_NumberedListIconBuilder({ _NumberedListIconBuilder({
required this.node, required this.node,
@ -232,7 +250,21 @@ class _NumberedListIconBuilder {
final Node node; final Node node;
int get level { // the level of the current node
int get indexInRootLevel {
var level = 0;
var parent = node.parent;
while (parent != null) {
if (parent.type == NumberedListBlockKeys.type) {
level++;
}
parent = parent.parent;
}
return level;
}
// the index of the current level
int get indexInSameLevel {
int level = 1; int level = 1;
Node? previous = node.previous; Node? previous = node.previous;
@ -253,3 +285,20 @@ class _NumberedListIconBuilder {
return level; return level;
} }
} }
extension on int {
String get latin {
String result = '';
int number = this;
while (number > 0) {
int remainder = (number - 1) % 26;
result = String.fromCharCode(remainder + 65) + result;
number = (number - 1) ~/ 26;
}
return result.toLowerCase();
}
String get roman {
return toRomanNumeralString() ?? '$this';
}
}

View file

@ -47,6 +47,7 @@ dependencies:
string_validator: ^1.0.0 string_validator: ^1.0.0
universal_html: ^2.2.4 universal_html: ^2.2.4
keyboard_height_plugin: ^0.0.4 keyboard_height_plugin: ^0.0.4
numerus: ^2.1.2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View file

@ -124,5 +124,53 @@ void main() async {
await editor.dispose(); await editor.dispose();
}); });
testWidgets('number, latin and roman', (tester) async {
final delta = Delta()..insert(text);
final editor = tester.editor
..addNode(
// 1.
numberedListNode(
delta: delta,
children: [
// a.
numberedListNode(
delta: delta,
children: [
numberedListNode(delta: delta), // Ⅰ.
numberedListNode(delta: delta), // ⅠⅠ.
numberedListNode(delta: delta), // ⅠⅠⅠ.
],
),
// b.
numberedListNode(
delta: delta,
children: [
numberedListNode(delta: delta), // Ⅰ.
numberedListNode(delta: delta), // ⅠⅠ.
numberedListNode(delta: delta), // ⅠⅠⅠ.
],
),
],
),
)
..addNode(
// 2.
numberedListNode(
delta: delta,
),
);
await editor.startTesting();
for (final number in ['1.', '2.']) {
expect(find.text(number, findRichText: true), findsOneWidget);
}
for (final latin in ['a.', 'b.']) {
expect(find.text(latin, findRichText: true), findsOneWidget);
}
for (final roman in ['I.', 'II.', 'III.']) {
expect(find.text(roman, findRichText: true), findsNWidgets(2));
}
});
}); });
} }