Skip to content

Commit 1e41afc

Browse files
committed
fix(tags): update cursor position when tap on embed block
1 parent 83a415e commit 1e41afc

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

lib/src/tags/hide/hide_builer.dart

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ final class BBCodeHideEmbedBuilder extends EmbedBuilder {
9393
..editorFocusNode?.requestFocus()
9494
..moveCursorToPosition(offset + 1);
9595
},
96+
onTap: () =>
97+
controller.moveCursorToPosition(node.documentOffset + node.length),
9698
initialData: info,
9799
emojiPicker: _emojiPicker,
98100
colorPicker: _colorPicker,
@@ -111,6 +113,7 @@ final class BBCodeHideEmbedBuilder extends EmbedBuilder {
111113
class _HideCard extends StatefulWidget {
112114
const _HideCard({
113115
required this.onEdited,
116+
required this.onTap,
114117
required this.initialData,
115118
required this.emojiPicker,
116119
required this.emojiProvider,
@@ -127,6 +130,9 @@ class _HideCard extends StatefulWidget {
127130
/// Callback when hide content is edited.
128131
final void Function(BBCodeHideInfo) onEdited;
129132

133+
/// See comments on _SpoilerCard.onTap
134+
final VoidCallback onTap;
135+
130136
final BBCodeEmojiPicker emojiPicker;
131137
final BBCodeColorPicker? colorPicker;
132138
final BBCodeColorPicker? backgroundColorPicker;
@@ -289,10 +295,13 @@ class _HideCardState extends State<_HideCard> {
289295
final tr = context.bbcodeL10n;
290296

291297
return GestureDetector(
292-
onTap: () async => showDialog<void>(
293-
context: context,
294-
builder: (_) => buildDialog(context),
295-
),
298+
onTap: () async {
299+
widget.onTap.call();
300+
await showDialog<void>(
301+
context: context,
302+
builder: (_) => buildDialog(context),
303+
);
304+
},
296305
child: Card(
297306
margin: EdgeInsets.zero,
298307
clipBehavior: Clip.hardEdge,

lib/src/tags/spoiler/spoiler_builder.dart

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ final class BBCodeSpoilerEmbedBuilder extends EmbedBuilder {
7878
final info = BBCodeSpoilerInfo.fromJson(node.value.data as String);
7979

8080
return _SpoilerCard(
81+
onTap: () =>
82+
controller.moveCursorToPosition(node.documentOffset + node.length),
8183
onEdited: (info) {
8284
final offset = getEmbedNode(
8385
controller,
@@ -111,6 +113,7 @@ final class BBCodeSpoilerEmbedBuilder extends EmbedBuilder {
111113
class _SpoilerCard extends StatefulWidget {
112114
const _SpoilerCard({
113115
required this.onEdited,
116+
required this.onTap,
114117
required this.initialData,
115118
required this.emojiPicker,
116119
required this.emojiProvider,
@@ -127,6 +130,22 @@ class _SpoilerCard extends StatefulWidget {
127130
/// Callback when spoiler content is edited.
128131
final void Function(BBCodeSpoilerInfo) onEdited;
129132

133+
/// Callback when spoiler card is tapped.
134+
///
135+
/// This callback is for anything need update in the outer editor.
136+
///
137+
/// Though the function body is defined by caller, things determined to be
138+
/// done includes:
139+
///
140+
/// * Update cursor position to the end side of spoiler card, when user
141+
/// finish edit, ensuring the content save process in [onEdited] do find
142+
/// the embed node using `getEmbedNode`.
143+
/// This may be an internal but upstream that an embed builder contains
144+
/// [GestureDetector] sometimes make the cursor not moved around embed
145+
/// widget causing `getEmbedNode` failed to find node: a failure on saving
146+
/// contents in document.
147+
final VoidCallback onTap;
148+
130149
final BBCodeEmojiPicker emojiPicker;
131150
final BBCodeColorPicker? colorPicker;
132151
final BBCodeColorPicker? backgroundColorPicker;
@@ -307,10 +326,14 @@ class _SpoilerCardState extends State<_SpoilerCard> {
307326
@override
308327
Widget build(BuildContext context) {
309328
return GestureDetector(
310-
onTap: () async => showDialog<void>(
311-
context: context,
312-
builder: (_) => buildDialog(context),
313-
),
329+
behavior: HitTestBehavior.deferToChild,
330+
onTap: () async {
331+
widget.onTap.call();
332+
await showDialog<void>(
333+
context: context,
334+
builder: (_) => buildDialog(context),
335+
);
336+
},
314337
child: Card(
315338
margin: EdgeInsets.zero,
316339
clipBehavior: Clip.hardEdge,

0 commit comments

Comments
 (0)