diff --git a/core/lib/utils/html/html_utils.dart b/core/lib/utils/html/html_utils.dart
index 45d9d4619..d0c04dff4 100644
--- a/core/lib/utils/html/html_utils.dart
+++ b/core/lib/utils/html/html_utils.dart
@@ -197,7 +197,7 @@ class HtmlUtils {
script: '''
(() => {
const selection = window.getSelection();
- if (selection) {
+ if (selection && selection.rangeCount > 0) {
selection.collapseToEnd()
}
})();''',
@@ -220,9 +220,10 @@ class HtmlUtils {
const selection = window.getSelection();
if (selection && selection.rangeCount > 0) {
window._savedRange = selection.getRangeAt(0).cloneRange();
- return true;
+ return selection.toString();
}
- return false;
+ delete window._savedRange;
+ return "";
})();''',
name: 'saveSelection');
@@ -234,10 +235,10 @@ class HtmlUtils {
if (selection) {
selection.removeAllRanges();
selection.addRange(window._savedRange);
- return true;
+ return selection.toString();
}
}
- return false;
+ return "";
})();''',
name: 'restoreSelection');
diff --git a/lib/features/composer/presentation/controller/rich_text_mobile_tablet_controller.dart b/lib/features/composer/presentation/controller/rich_text_mobile_tablet_controller.dart
index 0008c233b..37d764d2c 100644
--- a/lib/features/composer/presentation/controller/rich_text_mobile_tablet_controller.dart
+++ b/lib/features/composer/presentation/controller/rich_text_mobile_tablet_controller.dart
@@ -21,7 +21,10 @@ class RichTextMobileTabletController extends GetxController {
Future focus() async {
try {
- await htmlEditorApi?.webViewController.evaluateJavascript(source: "document.getElementById('editor').focus();");
+ await htmlEditorApi?.webViewController.evaluateJavascript(source: '''
+ (() => {
+ document.getElementById('editor').focus();
+ })();''');
} catch (e) {
logWarning('RichTextMobileTabletController::focus:Exception: $e');
}
diff --git a/lib/features/composer/presentation/extensions/ai_scribe/handle_ai_scribe_in_composer_extension.dart b/lib/features/composer/presentation/extensions/ai_scribe/handle_ai_scribe_in_composer_extension.dart
index 27ea9a451..34a7ada6c 100644
--- a/lib/features/composer/presentation/extensions/ai_scribe/handle_ai_scribe_in_composer_extension.dart
+++ b/lib/features/composer/presentation/extensions/ai_scribe/handle_ai_scribe_in_composer_extension.dart
@@ -35,6 +35,10 @@ extension HandleAiScribeInComposerExtension on ComposerController {
}
Future insertTextInEditor(String text) async {
+ if (PlatformInfo.isMobile) {
+ await ensureMobileEditorFocused();
+ }
+
try {
final htmlContent = StringConvert.convertTextContentToHtmlContent(text);
@@ -46,7 +50,7 @@ extension HandleAiScribeInComposerExtension on ComposerController {
richTextWebController?.editorController.insertHtml(htmlContent);
} else {
- richTextMobileTabletController?.htmlEditorApi?.insertHtml(htmlContent);
+ await richTextMobileTabletController?.htmlEditorApi?.insertHtml(htmlContent);
}
} catch (e) {
logWarning('$runtimeType::insertTextInEditor:Exception = $e');
@@ -71,45 +75,45 @@ extension HandleAiScribeInComposerExtension on ComposerController {
}
}
- Future saveSelection() async {
+ Future saveSelection() async {
try {
if (PlatformInfo.isWeb) {
final result = await richTextWebController?.editorController.evaluateJavascriptWeb(
HtmlUtils.saveSelection.name,
hasReturnValue: true,
- ) ?? false;
+ );
return result;
} else {
final result = await richTextMobileTabletController?.htmlEditorApi?.webViewController
.evaluateJavascript(
source: HtmlUtils.saveSelection.script,
- ) ?? false;
+ );
return result;
}
} catch (e) {
logError('$runtimeType::saveSelection:Exception = $e');
- return false;
+ return "";
}
}
- Future restoreSelection() async {
+ Future restoreSelection() async {
try {
if (PlatformInfo.isWeb) {
final result = await richTextWebController?.editorController.evaluateJavascriptWeb(
HtmlUtils.restoreSelection.name,
hasReturnValue: true,
- ) ?? false;
+ );
return result;
} else {
final result = await richTextMobileTabletController?.htmlEditorApi?.webViewController
.evaluateJavascript(
source: HtmlUtils.restoreSelection.script,
- ) ?? false;
+ );
return result;
}
} catch (e) {
logError('$runtimeType::restoreSelection:Exception = $e');
- return false;
+ return "";
}
}
@@ -142,10 +146,8 @@ extension HandleAiScribeInComposerExtension on ComposerController {
}
Future saveAndUnfocusForModal() async {
- final saved = await saveSelection();
- if (saved) {
- await unfocusEditor();
- }
+ await saveSelection();
+ await unfocusEditor();
}
Future ensureMobileEditorFocused() async {
@@ -156,12 +158,12 @@ extension HandleAiScribeInComposerExtension on ComposerController {
}
}
- void clearTextInEditor() {
+ Future clearTextInEditor() async {
try {
if (PlatformInfo.isWeb) {
richTextWebController?.editorController.setText('');
} else {
- richTextMobileTabletController?.htmlEditorApi?.setText('');
+ await richTextMobileTabletController?.htmlEditorApi?.setText('');
}
} catch (e) {
logWarning('$runtimeType::clearTextInEditor:Exception = $e');
@@ -178,12 +180,10 @@ extension HandleAiScribeInComposerExtension on ComposerController {
Future onReplaceTextCallback(String text) async {
final selection = editorTextSelection.value?.selectedText;
- if (PlatformInfo.isMobile) {
- await restoreSelection();
- }
+ final isSelectionRestored = PlatformInfo.isMobile ? await restoreSelection() : "";
- if (selection == null || selection.isEmpty) {
- clearTextInEditor();
+ if ((selection == null || selection.isEmpty) && isSelectionRestored.isEmpty) {
+ await clearTextInEditor();
}
await insertTextInEditor(text);
@@ -215,10 +215,6 @@ extension HandleAiScribeInComposerExtension on ComposerController {
AiScribeSuggestionActions action,
String suggestionText,
) async {
- if (PlatformInfo.isMobile) {
- await ensureMobileEditorFocused();
- }
-
switch (action) {
case AiScribeSuggestionActions.replace:
await onReplaceTextCallback(suggestionText);