Skip to content

Commit bba1851

Browse files
committed
SymTextViewer - Hover line action (Improvements)
1 parent 536c3be commit bba1851

File tree

7 files changed

+41
-17
lines changed

7 files changed

+41
-17
lines changed

example/lib/pages/kalpataru_demo_page/demo_load_from_markdown_page.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@ class DemoLoadFromMarkdownPage extends StatefulWidget {
1313
}
1414

1515
class _KalpataruLoadFromMarkdownPage extends State<DemoLoadFromMarkdownPage> {
16-
// List<String> examples = [_markdownExample1, _markdownExample2, _markdownExample3];
17-
List<String> examples = [_markdownExample4];
16+
List<String> examples = [
17+
_markdownExample1,
18+
_markdownExample2,
19+
_markdownExample3,
20+
_markdownExample4
21+
];
1822

1923
@override
2024
void initState() {

lib/src/models/documents/nodes/line.dart

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:math' as math;
22

33
import 'package:collection/collection.dart';
44
import 'package:flutter_quill/src/utils/sym_regex.dart';
5+
import 'package:uuid/uuid.dart';
56

67
import '../../quill_delta.dart';
78
import '../attribute.dart';
@@ -19,9 +20,20 @@ import 'node.dart';
1920
/// When a line contains an embed, it fully occupies the line, no other embeds
2021
/// or text nodes are allowed.
2122
class Line extends Container<Leaf?> {
23+
Line() : super() {
24+
const uuid = Uuid();
25+
_generatedLineId = uuid.v5(Uuid.NAMESPACE_NIL, uuid.v1());
26+
}
27+
28+
late String _generatedLineId;
29+
2230
String get lineId {
23-
final matchId = SymRegex.BLOCK_IDENTIFIER.firstMatch(super.toPlainText());
24-
return matchId?.group(0) ?? '';
31+
final matchId = SymRegex.TEXTS_INSIDE_DOUBLE_SQUARE_BRACKET
32+
.firstMatch(super.toPlainText());
33+
return matchId?.group(0)
34+
?.replaceAll('space-', '')
35+
.replaceAll('face-', '')
36+
.replaceAll('zet-', '') ?? _generatedLineId;
2537
}
2638

2739
@override
@@ -76,8 +88,9 @@ class Line extends Container<Leaf?> {
7688
@override
7789
String toPlainText() => '${super.toPlainText()}\n';
7890

79-
String toPlainTextWithoutLineId() =>
80-
super.toPlainText().replaceAll(SymRegex.BLOCK_IDENTIFIER, '');
91+
String toPlainTextWithoutLineId() => super
92+
.toPlainText()
93+
.replaceAll(SymRegex.BLOCK_IDENTIFIER_INSIDE_DOUBLE_SQR_BRACKET, '');
8194

8295
@override
8396
String toString() {

lib/src/utils/color.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ class SymColors {
134134
static const Color light_textTertiary = Color(0xFF757575);
135135
static const Color light_textQuaternary = Color(0xFF9E9E9E);
136136
static const Color light_bgSurface1 = Color(0xFFF5F5F5);
137+
static const Color light_bgSurface2 = Color(0xFFEEEEEE);
137138
static const Color light_iconPrimary = Color(0xFF212121);
138139

139140
static const Color dark_bgSurface2 = Color(0xFF242424);

lib/src/utils/sym_regex.dart

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
class SymRegex {
22
SymRegex._();
33

4-
static final LINEBREAK_BLOCK_IDENTIFIER = RegExp(r'\[\[\^.{40,43}\]\](?=\\n)'); // match [[^space-22b480bd-440b-4805-84c8-e38cc3275c87]] inside **Markdown**[[^space-22b480bd-440b-4805-84c8-e38cc3275c87]]\\n
5-
static final BLOCK_IDENTIFIER = RegExp(r'\[\[\^.{40,43}\]\]'); // match [[^space-22b480bd-440b-4805-84c8-e38cc3275c87]] inside **Markdown**[[^space-22b480bd-440b-4805-84c8-e38cc3275c87]] (without linebreak)
6-
static final BLOCK_REFERENCE = RegExp(r'!\[\[.+[\^|\#].+\]\]');
4+
static final BLOCK_IDENTIFIER_INSIDE_DOUBLE_SQR_BRACKET_BEFORE_LINEBREAK = RegExp(r'\[\[\^.{36,43}\]\](?=\\n)'); // match '[[^space-22b480bd-440b-4805-84c8-e38cc3275c87]]' inside '**Markdown**[[^space-22b480bd-440b-4805-84c8-e38cc3275c87]]\\n'
5+
static final BLOCK_IDENTIFIER_INSIDE_DOUBLE_SQR_BRACKET = RegExp(r'\[\[\^.{36,43}\]\]'); // match '[[^space-22b480bd-440b-4805-84c8-e38cc3275c87]]' inside '**Markdown**[[^space-22b480bd-440b-4805-84c8-e38cc3275c87]]' (without linebreak)
6+
static final BLOCK_REFERENCE = RegExp(r'!\[\[.+[\^|\#].+\]\]'); // UNTESTED
77

8-
static final REMOVE_IMAGE_BLOCK_IDENTIFIER = RegExp(r'!\[[^\]]*\]\((.*?)\s*("(?:.*[^"])")?\s*\)(\[\[\^.{40,43}\]\]\\\\n)');
9-
static final REMOVE_IMAGE = RegExp(r'!\[[^\]]*\]\((.*?)\s*("(?:.*[^"])")?\s*\)');
8+
static final IMAGE_MD_BEFORE_BLOCK_IDENTIFIER_INSIDE_DOUBLE_SQR_BRACKET_BEFORE_LINEBREAK = RegExp(r'!\[[^\]]*\]\((.*?)\s*("(?:.*[^"])")?\s*\)(\[\[\^.{36,43}\]\]\\\\n)'); // match '![desc](image_url.com)[[^space-52aa7567-9e89-4d68-92d9-754d75e7680f]]\\n' inside '**Markdown ![desc](image_url.com)[[^space-52aa7567-9e89-4d68-92d9-754d75e7680f]]\\n'
9+
static final IMAGE_MD = RegExp(r'!\[[^\]]*\]\((.*?)\s*("(?:.*[^"])")?\s*\)'); // match '![desc](image_url.com)' inside '**Markdown ![desc](image_url.com) **Markdown'
1010

11-
static final TEXTS_INSIDE_BRACKET = RegExp(r'(?<=\().+?(?=\))');
11+
static final TEXTS_INSIDE_BRACKET = RegExp(r'(?<=\().+?(?=\))'); // match 'image_url.com' inside '**Markdown ![desc](image_url.com) **Markdown'
12+
static final TEXTS_INSIDE_DOUBLE_SQUARE_BRACKET = RegExp(r'(?<=\[\[\^).{36,43}(?=\]\])'); // match 'space-52aa7567-9e89-4d68-92d9-754d75e7680f' inside '**Markdown**[[^space-52aa7567-9e89-4d68-92d9-754d75e7680f]]'
1213
}

lib/src/widgets/sym_widgets/sym_text_viewer/sym_text_viewer.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ class _SymTextViewerState extends State<SymTextViewer>
138138
borderRadius: BorderRadius.all(Radius.circular(4))),
139139
child: InkWell(
140140
onTap: () {
141+
print('LL:: line id: ${box.line.lineId}');
141142
_showMenuOptionOverlay(box);
142143
},
143144
child: Padding(
@@ -315,8 +316,11 @@ class _SymTextViewerState extends State<SymTextViewer>
315316
var markdownToDecode = widget.markdownData;
316317
if (widget.maxHeight != null) {
317318
markdownToDecode = widget.markdownData
318-
.replaceAll(SymRegex.REMOVE_IMAGE_BLOCK_IDENTIFIER, '')
319-
.replaceAll(SymRegex.REMOVE_IMAGE, '');
319+
.replaceAll(
320+
SymRegex
321+
.IMAGE_MD_BEFORE_BLOCK_IDENTIFIER_INSIDE_DOUBLE_SQR_BRACKET_BEFORE_LINEBREAK,
322+
'')
323+
.replaceAll(SymRegex.IMAGE_MD, '');
320324
}
321325
final doc = Document.fromMarkdown(markdownToDecode);
322326
widget._controller = QuillController(
@@ -409,7 +413,7 @@ class _SymTextViewerState extends State<SymTextViewer>
409413
final textViewer = QuillStyles(data: _styles, child: child);
410414

411415
if (widget.maxHeight != null) {
412-
final images = SymRegex.REMOVE_IMAGE.allMatches(widget.markdownData);
416+
final images = SymRegex.IMAGE_MD.allMatches(widget.markdownData);
413417

414418
if (images.isNotEmpty) {
415419
final image = images.first.group(0);

lib/src/widgets/text_line.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ class TextLine extends StatelessWidget {
197197
res = res.merge(TextStyle(backgroundColor: backgroundColor));
198198
}
199199

200-
return TextSpan(text: textNode.value.replaceAll(SymRegex.BLOCK_IDENTIFIER, ''), style: res);
200+
return TextSpan(text: textNode.value.replaceAll(SymRegex.BLOCK_IDENTIFIER_INSIDE_DOUBLE_SQR_BRACKET, ''), style: res);
201201
}
202202

203203
TextStyle _merge(TextStyle a, TextStyle b) {
@@ -922,7 +922,7 @@ class RenderEditableTextLine extends RenderEditableBox
922922
}
923923

924924
if (isLineSelected) {
925-
_paintLineBody(context, effectiveOffset, SymColors.hoverColor);
925+
_paintLineBody(context, effectiveOffset, SymColors.light_bgSurface2);
926926
}
927927

928928
if (hasFocus &&

pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ dependencies:
2525
youtube_player_flutter: ^8.0.0
2626
google_fonts: ^2.1.0
2727
charcode: ^1.2.0
28+
uuid: ^3.0.4
2829

2930
dev_dependencies:
3031
flutter_test:

0 commit comments

Comments
 (0)