Display Scribe mobile (bottomsheet) only when responsive mobile
Previosuly, we display Scribe mobile (bottomsheet) if platform was mobile, so also Android or iOS tablet. Now we choose to display Scribe mobile relatively to display screens instead of platform to display the desktop Scribe (context menu) for tablets.
This commit is contained in:
+9
-2
@@ -3,6 +3,7 @@ import 'package:core/utils/html/html_utils.dart';
|
|||||||
import 'package:core/utils/platform_info.dart';
|
import 'package:core/utils/platform_info.dart';
|
||||||
import 'package:core/utils/string_convert.dart';
|
import 'package:core/utils/string_convert.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
import 'package:scribe/scribe.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/composer_controller.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/mixin/text_selection_mixin.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;
|
return isAIScribeConfigEnabled && isAIScribeEndpointAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool get isScribeMobile {
|
||||||
|
final context = Get.context;
|
||||||
|
return AiScribeMobileUtils.isScribeInMobileMode(context);
|
||||||
|
}
|
||||||
|
|
||||||
Future<String> _getTextOnlyContentInEditor() async {
|
Future<String> _getTextOnlyContentInEditor() async {
|
||||||
try {
|
try {
|
||||||
final htmlContent = await getContentInEditor();
|
final htmlContent = await getContentInEditor();
|
||||||
@@ -207,7 +213,7 @@ extension HandleAiScribeInComposerExtension on ComposerController {
|
|||||||
Future<void> onReplaceTextCallback(String text) async {
|
Future<void> onReplaceTextCallback(String text) async {
|
||||||
final selection = editorTextSelection.value?.selectedText;
|
final selection = editorTextSelection.value?.selectedText;
|
||||||
|
|
||||||
final savedSelection = PlatformInfo.isMobile ? await getSavedSelection() : "";
|
final savedSelection = isScribeMobile ? await getSavedSelection() : "";
|
||||||
|
|
||||||
final shouldReplaceEverything = (selection == null || selection.isEmpty) && savedSelection.isEmpty;
|
final shouldReplaceEverything = (selection == null || selection.isEmpty) && savedSelection.isEmpty;
|
||||||
|
|
||||||
@@ -232,7 +238,7 @@ extension HandleAiScribeInComposerExtension on ComposerController {
|
|||||||
clearFocusRecipients();
|
clearFocusRecipients();
|
||||||
clearFocusSubject();
|
clearFocusSubject();
|
||||||
|
|
||||||
if (PlatformInfo.isMobile) {
|
if (isScribeMobile) {
|
||||||
await saveAndUnfocusForModal();
|
await saveAndUnfocusForModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,6 +253,7 @@ extension HandleAiScribeInComposerExtension on ComposerController {
|
|||||||
preferredPlacement: ModalPlacement.top,
|
preferredPlacement: ModalPlacement.top,
|
||||||
crossAxisAlignment: ModalCrossAxisAlignment.start,
|
crossAxisAlignment: ModalCrossAxisAlignment.start,
|
||||||
onSelectAiScribeSuggestionAction: handleAiScribeSuggestionAction,
|
onSelectAiScribeSuggestionAction: handleAiScribeSuggestionAction,
|
||||||
|
isScribeMobile: isScribeMobile,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.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: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/composer_controller.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/ai_scribe/handle_ai_scribe_in_composer_extension.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.clearFocusRecipients();
|
||||||
controller.clearFocusSubject();
|
controller.clearFocusSubject();
|
||||||
|
|
||||||
if (PlatformInfo.isMobile) {
|
if (controller.isScribeMobile) {
|
||||||
await controller.saveAndUnfocusForModal();
|
await controller.saveAndUnfocusForModal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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/model/text_selection_model.dart';
|
||||||
export 'scribe/ai/presentation/styles/ai_scribe_styles.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_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/hover_submenu_controller.dart';
|
||||||
export 'scribe/ai/presentation/utils/context_menu/context_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';
|
export 'scribe/ai/presentation/utils/modal/ai_scribe_modal_manager.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:core/presentation/resources/image_paths.dart';
|
import 'package:core/presentation/resources/image_paths.dart';
|
||||||
import 'package:core/utils/platform_info.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:scribe/scribe.dart';
|
import 'package:scribe/scribe.dart';
|
||||||
@@ -8,6 +7,7 @@ class AiScribeModalManager {
|
|||||||
AiScribeModalManager._();
|
AiScribeModalManager._();
|
||||||
|
|
||||||
static Future<void> showAIScribeMenuModal({
|
static Future<void> showAIScribeMenuModal({
|
||||||
|
required bool isScribeMobile,
|
||||||
required ImagePaths imagePaths,
|
required ImagePaths imagePaths,
|
||||||
required List<AIScribeMenuCategory> availableCategories,
|
required List<AIScribeMenuCategory> availableCategories,
|
||||||
required OnSelectAiScribeSuggestionAction onSelectAiScribeSuggestionAction,
|
required OnSelectAiScribeSuggestionAction onSelectAiScribeSuggestionAction,
|
||||||
@@ -19,7 +19,7 @@ class AiScribeModalManager {
|
|||||||
}) async {
|
}) async {
|
||||||
final AIAction? aiAction;
|
final AIAction? aiAction;
|
||||||
|
|
||||||
if (PlatformInfo.isMobile) {
|
if (isScribeMobile) {
|
||||||
aiAction = await showMobileAIScribeMenuModal(
|
aiAction = await showMobileAIScribeMenuModal(
|
||||||
imagePaths: imagePaths,
|
imagePaths: imagePaths,
|
||||||
content: content,
|
content: content,
|
||||||
@@ -46,6 +46,7 @@ class AiScribeModalManager {
|
|||||||
if (aiAction != null) {
|
if (aiAction != null) {
|
||||||
await showAIScribeSuggestionModal(
|
await showAIScribeSuggestionModal(
|
||||||
aiAction: aiAction,
|
aiAction: aiAction,
|
||||||
|
isScribeMobile: isScribeMobile,
|
||||||
imagePaths: imagePaths,
|
imagePaths: imagePaths,
|
||||||
content: content,
|
content: content,
|
||||||
buttonPosition: buttonPosition,
|
buttonPosition: buttonPosition,
|
||||||
@@ -59,6 +60,7 @@ class AiScribeModalManager {
|
|||||||
|
|
||||||
static Future<void> showAIScribeSuggestionModal({
|
static Future<void> showAIScribeSuggestionModal({
|
||||||
required AIAction aiAction,
|
required AIAction aiAction,
|
||||||
|
required bool isScribeMobile,
|
||||||
required ImagePaths imagePaths,
|
required ImagePaths imagePaths,
|
||||||
required OnSelectAiScribeSuggestionAction onSelectAiScribeSuggestionAction,
|
required OnSelectAiScribeSuggestionAction onSelectAiScribeSuggestionAction,
|
||||||
String? content,
|
String? content,
|
||||||
@@ -67,7 +69,7 @@ class AiScribeModalManager {
|
|||||||
ModalPlacement? preferredPlacement,
|
ModalPlacement? preferredPlacement,
|
||||||
ModalCrossAxisAlignment crossAxisAlignment = ModalCrossAxisAlignment.center,
|
ModalCrossAxisAlignment crossAxisAlignment = ModalCrossAxisAlignment.center,
|
||||||
}) async {
|
}) async {
|
||||||
if (PlatformInfo.isMobile) {
|
if (isScribeMobile) {
|
||||||
await showMobileAIScribeSuggestionModal(
|
await showMobileAIScribeSuggestionModal(
|
||||||
aiAction: aiAction,
|
aiAction: aiAction,
|
||||||
imagePaths: imagePaths,
|
imagePaths: imagePaths,
|
||||||
|
|||||||
@@ -45,7 +45,12 @@ class InlineAiAssistButton extends StatelessWidget {
|
|||||||
|
|
||||||
await onTapFallback?.call();
|
await onTapFallback?.call();
|
||||||
|
|
||||||
|
if (!context.mounted) return;
|
||||||
|
|
||||||
|
final isScribeMobile = AiScribeMobileUtils.isScribeInMobileMode(context);
|
||||||
|
|
||||||
await AiScribeModalManager.showAIScribeMenuModal(
|
await AiScribeModalManager.showAIScribeMenuModal(
|
||||||
|
isScribeMobile: isScribeMobile,
|
||||||
imagePaths: imagePaths,
|
imagePaths: imagePaths,
|
||||||
availableCategories: AIScribeMenuCategory.values,
|
availableCategories: AIScribeMenuCategory.values,
|
||||||
buttonPosition: position,
|
buttonPosition: position,
|
||||||
|
|||||||
Reference in New Issue
Block a user