Skip to content

Commit 1e80c84

Browse files
committed
Fix Scribe mobile issues
- Fix Scribe replace on mobile when opened from menu bar (to be complete this fix needs this PR Enough-Software/enough_html_editor#37) - Ensure all mobile editor call are awaited - Do not clear text if a selection has been restored (which mean we replace a selection) - Avoid collapseToEnd crash
1 parent 4c26bf1 commit 1e80c84

3 files changed

Lines changed: 30 additions & 30 deletions

File tree

core/lib/utils/html/html_utils.dart

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ class HtmlUtils {
197197
script: '''
198198
(() => {
199199
const selection = window.getSelection();
200-
if (selection) {
200+
if (selection && selection.rangeCount > 0) {
201201
selection.collapseToEnd()
202202
}
203203
})();''',
@@ -220,9 +220,10 @@ class HtmlUtils {
220220
const selection = window.getSelection();
221221
if (selection && selection.rangeCount > 0) {
222222
window._savedRange = selection.getRangeAt(0).cloneRange();
223-
return true;
223+
return selection.toString();
224224
}
225-
return false;
225+
delete window._savedRange;
226+
return "";
226227
})();''',
227228
name: 'saveSelection');
228229

@@ -234,10 +235,10 @@ class HtmlUtils {
234235
if (selection) {
235236
selection.removeAllRanges();
236237
selection.addRange(window._savedRange);
237-
return true;
238+
return selection.toString();
238239
}
239240
}
240-
return false;
241+
return "";
241242
})();''',
242243
name: 'restoreSelection');
243244

lib/features/composer/presentation/controller/rich_text_mobile_tablet_controller.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ class RichTextMobileTabletController extends GetxController {
2121

2222
Future<void> focus() async {
2323
try {
24-
await htmlEditorApi?.webViewController.evaluateJavascript(source: "document.getElementById('editor').focus();");
24+
await htmlEditorApi?.webViewController.evaluateJavascript(source: '''
25+
(() => {
26+
document.getElementById('editor').focus();
27+
})();''');
2528
} catch (e) {
2629
logWarning('RichTextMobileTabletController::focus:Exception: $e');
2730
}

lib/features/composer/presentation/extensions/ai_scribe/handle_ai_scribe_in_composer_extension.dart

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ extension HandleAiScribeInComposerExtension on ComposerController {
3535
}
3636

3737
Future<void> insertTextInEditor(String text) async {
38+
if (PlatformInfo.isMobile) {
39+
await ensureMobileEditorFocused();
40+
}
41+
3842
try {
3943
final htmlContent = StringConvert.convertTextContentToHtmlContent(text);
4044

@@ -46,7 +50,7 @@ extension HandleAiScribeInComposerExtension on ComposerController {
4650

4751
richTextWebController?.editorController.insertHtml(htmlContent);
4852
} else {
49-
richTextMobileTabletController?.htmlEditorApi?.insertHtml(htmlContent);
53+
await richTextMobileTabletController?.htmlEditorApi?.insertHtml(htmlContent);
5054
}
5155
} catch (e) {
5256
logWarning('$runtimeType::insertTextInEditor:Exception = $e');
@@ -71,45 +75,45 @@ extension HandleAiScribeInComposerExtension on ComposerController {
7175
}
7276
}
7377

74-
Future<bool> saveSelection() async {
78+
Future<String> saveSelection() async {
7579
try {
7680
if (PlatformInfo.isWeb) {
7781
final result = await richTextWebController?.editorController.evaluateJavascriptWeb(
7882
HtmlUtils.saveSelection.name,
7983
hasReturnValue: true,
80-
) ?? false;
84+
);
8185
return result;
8286
} else {
8387
final result = await richTextMobileTabletController?.htmlEditorApi?.webViewController
8488
.evaluateJavascript(
8589
source: HtmlUtils.saveSelection.script,
86-
) ?? false;
90+
);
8791
return result;
8892
}
8993
} catch (e) {
9094
logError('$runtimeType::saveSelection:Exception = $e');
91-
return false;
95+
return "";
9296
}
9397
}
9498

95-
Future<bool> restoreSelection() async {
99+
Future<String> restoreSelection() async {
96100
try {
97101
if (PlatformInfo.isWeb) {
98102
final result = await richTextWebController?.editorController.evaluateJavascriptWeb(
99103
HtmlUtils.restoreSelection.name,
100104
hasReturnValue: true,
101-
) ?? false;
105+
);
102106
return result;
103107
} else {
104108
final result = await richTextMobileTabletController?.htmlEditorApi?.webViewController
105109
.evaluateJavascript(
106110
source: HtmlUtils.restoreSelection.script,
107-
) ?? false;
111+
);
108112
return result;
109113
}
110114
} catch (e) {
111115
logError('$runtimeType::restoreSelection:Exception = $e');
112-
return false;
116+
return "";
113117
}
114118
}
115119

@@ -142,10 +146,8 @@ extension HandleAiScribeInComposerExtension on ComposerController {
142146
}
143147

144148
Future<void> saveAndUnfocusForModal() async {
145-
final saved = await saveSelection();
146-
if (saved) {
147-
await unfocusEditor();
148-
}
149+
await saveSelection();
150+
await unfocusEditor();
149151
}
150152

151153
Future<void> ensureMobileEditorFocused() async {
@@ -156,12 +158,12 @@ extension HandleAiScribeInComposerExtension on ComposerController {
156158
}
157159
}
158160

159-
void clearTextInEditor() {
161+
Future<void> clearTextInEditor() async {
160162
try {
161163
if (PlatformInfo.isWeb) {
162164
richTextWebController?.editorController.setText('');
163165
} else {
164-
richTextMobileTabletController?.htmlEditorApi?.setText('');
166+
await richTextMobileTabletController?.htmlEditorApi?.setText('');
165167
}
166168
} catch (e) {
167169
logWarning('$runtimeType::clearTextInEditor:Exception = $e');
@@ -178,12 +180,10 @@ extension HandleAiScribeInComposerExtension on ComposerController {
178180
Future<void> onReplaceTextCallback(String text) async {
179181
final selection = editorTextSelection.value?.selectedText;
180182

181-
if (PlatformInfo.isMobile) {
182-
await restoreSelection();
183-
}
183+
final isSelectionRestored = PlatformInfo.isMobile ? await restoreSelection() : "";
184184

185-
if (selection == null || selection.isEmpty) {
186-
clearTextInEditor();
185+
if ((selection == null || selection.isEmpty) && isSelectionRestored.isEmpty) {
186+
await clearTextInEditor();
187187
}
188188

189189
await insertTextInEditor(text);
@@ -215,10 +215,6 @@ extension HandleAiScribeInComposerExtension on ComposerController {
215215
AiScribeSuggestionActions action,
216216
String suggestionText,
217217
) async {
218-
if (PlatformInfo.isMobile) {
219-
await ensureMobileEditorFocused();
220-
}
221-
222218
switch (action) {
223219
case AiScribeSuggestionActions.replace:
224220
await onReplaceTextCallback(suggestionText);

0 commit comments

Comments
 (0)