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 5f157fd24..037e973c0 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 @@ -3,6 +3,7 @@ import 'package:core/utils/html/html_utils.dart'; import 'package:core/utils/platform_info.dart'; import 'package:core/utils/string_convert.dart'; import 'package:flutter/material.dart'; +import 'package:get/get.dart'; import 'package:scribe/scribe.dart'; import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart'; import 'package:tmail_ui_user/features/composer/presentation/mixin/text_selection_mixin.dart'; @@ -21,6 +22,11 @@ extension HandleAiScribeInComposerExtension on ComposerController { return isAIScribeConfigEnabled && isAIScribeEndpointAvailable; } + bool get isScribeMobile { + final context = Get.context; + return AiScribeMobileUtils.isScribeInMobileMode(context); + } + Future _getTextOnlyContentInEditor() async { try { final htmlContent = await getContentInEditor(); @@ -207,7 +213,7 @@ extension HandleAiScribeInComposerExtension on ComposerController { Future onReplaceTextCallback(String text) async { final selection = editorTextSelection.value?.selectedText; - final savedSelection = PlatformInfo.isMobile ? await getSavedSelection() : ""; + final savedSelection = isScribeMobile ? await getSavedSelection() : ""; final shouldReplaceEverything = (selection == null || selection.isEmpty) && savedSelection.isEmpty; @@ -232,7 +238,7 @@ extension HandleAiScribeInComposerExtension on ComposerController { clearFocusRecipients(); clearFocusSubject(); - if (PlatformInfo.isMobile) { + if (isScribeMobile) { await saveAndUnfocusForModal(); } @@ -247,6 +253,7 @@ extension HandleAiScribeInComposerExtension on ComposerController { preferredPlacement: ModalPlacement.top, crossAxisAlignment: ModalCrossAxisAlignment.start, onSelectAiScribeSuggestionAction: handleAiScribeSuggestionAction, + isScribeMobile: isScribeMobile, ); } diff --git a/lib/features/composer/presentation/widgets/ai_scribe/composer_ai_scribe_selection_overlay.dart b/lib/features/composer/presentation/widgets/ai_scribe/composer_ai_scribe_selection_overlay.dart index 46b072066..93da1828b 100644 --- a/lib/features/composer/presentation/widgets/ai_scribe/composer_ai_scribe_selection_overlay.dart +++ b/lib/features/composer/presentation/widgets/ai_scribe/composer_ai_scribe_selection_overlay.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:core/utils/platform_info.dart'; import 'package:scribe/scribe/ai/presentation/widgets/overlay/ai_selection_overlay.dart'; import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart'; import 'package:tmail_ui_user/features/composer/presentation/extensions/ai_scribe/handle_ai_scribe_in_composer_extension.dart'; @@ -34,7 +33,7 @@ class ComposerAiScribeSelectionOverlay extends StatelessWidget { controller.clearFocusRecipients(); controller.clearFocusSubject(); - if (PlatformInfo.isMobile) { + if (controller.isScribeMobile) { await controller.saveAndUnfocusForModal(); } } diff --git a/scribe/lib/scribe.dart b/scribe/lib/scribe.dart index a9fed6417..bc420893b 100644 --- a/scribe/lib/scribe.dart +++ b/scribe/lib/scribe.dart @@ -22,6 +22,7 @@ export 'scribe/ai/presentation/model/modal/modal_placement.dart'; export 'scribe/ai/presentation/model/text_selection_model.dart'; export 'scribe/ai/presentation/styles/ai_scribe_styles.dart'; export 'scribe/ai/presentation/utils/ai_scribe_constants.dart'; +export 'scribe/ai/presentation/utils/ai_scribe_mobile_utils.dart'; export 'scribe/ai/presentation/utils/context_menu/hover_submenu_controller.dart'; export 'scribe/ai/presentation/utils/context_menu/context_submenu_controller.dart'; export 'scribe/ai/presentation/utils/modal/ai_scribe_modal_manager.dart'; diff --git a/scribe/lib/scribe/ai/presentation/utils/ai_scribe_mobile_utils.dart b/scribe/lib/scribe/ai/presentation/utils/ai_scribe_mobile_utils.dart new file mode 100644 index 000000000..2dc2c716e --- /dev/null +++ b/scribe/lib/scribe/ai/presentation/utils/ai_scribe_mobile_utils.dart @@ -0,0 +1,8 @@ +import 'package:core/presentation/utils/responsive_utils.dart'; +import 'package:flutter/material.dart'; + +class AiScribeMobileUtils { + static bool isScribeInMobileMode(BuildContext? context) { + return context != null && ResponsiveUtils().isMobile(context); + } +} \ No newline at end of file diff --git a/scribe/lib/scribe/ai/presentation/utils/modal/ai_scribe_modal_manager.dart b/scribe/lib/scribe/ai/presentation/utils/modal/ai_scribe_modal_manager.dart index 8d421b6ff..677ec68ff 100644 --- a/scribe/lib/scribe/ai/presentation/utils/modal/ai_scribe_modal_manager.dart +++ b/scribe/lib/scribe/ai/presentation/utils/modal/ai_scribe_modal_manager.dart @@ -1,5 +1,4 @@ import 'package:core/presentation/resources/image_paths.dart'; -import 'package:core/utils/platform_info.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:scribe/scribe.dart'; @@ -8,6 +7,7 @@ class AiScribeModalManager { AiScribeModalManager._(); static Future showAIScribeMenuModal({ + required bool isScribeMobile, required ImagePaths imagePaths, required List availableCategories, required OnSelectAiScribeSuggestionAction onSelectAiScribeSuggestionAction, @@ -19,7 +19,7 @@ class AiScribeModalManager { }) async { final AIAction? aiAction; - if (PlatformInfo.isMobile) { + if (isScribeMobile) { aiAction = await showMobileAIScribeMenuModal( imagePaths: imagePaths, content: content, @@ -46,6 +46,7 @@ class AiScribeModalManager { if (aiAction != null) { await showAIScribeSuggestionModal( aiAction: aiAction, + isScribeMobile: isScribeMobile, imagePaths: imagePaths, content: content, buttonPosition: buttonPosition, @@ -59,6 +60,7 @@ class AiScribeModalManager { static Future showAIScribeSuggestionModal({ required AIAction aiAction, + required bool isScribeMobile, required ImagePaths imagePaths, required OnSelectAiScribeSuggestionAction onSelectAiScribeSuggestionAction, String? content, @@ -67,7 +69,7 @@ class AiScribeModalManager { ModalPlacement? preferredPlacement, ModalCrossAxisAlignment crossAxisAlignment = ModalCrossAxisAlignment.center, }) async { - if (PlatformInfo.isMobile) { + if (isScribeMobile) { await showMobileAIScribeSuggestionModal( aiAction: aiAction, imagePaths: imagePaths, diff --git a/scribe/lib/scribe/ai/presentation/widgets/button/inline_ai_assist_button.dart b/scribe/lib/scribe/ai/presentation/widgets/button/inline_ai_assist_button.dart index 2ec3fa582..ee4c71222 100644 --- a/scribe/lib/scribe/ai/presentation/widgets/button/inline_ai_assist_button.dart +++ b/scribe/lib/scribe/ai/presentation/widgets/button/inline_ai_assist_button.dart @@ -45,7 +45,12 @@ class InlineAiAssistButton extends StatelessWidget { await onTapFallback?.call(); + if (!context.mounted) return; + + final isScribeMobile = AiScribeMobileUtils.isScribeInMobileMode(context); + await AiScribeModalManager.showAIScribeMenuModal( + isScribeMobile: isScribeMobile, imagePaths: imagePaths, availableCategories: AIScribeMenuCategory.values, buttonPosition: position,