Fix Scribe on responsive mobile
- Button was not added in MobileResponsiveAppBar - Mobile behavior related scripts were not correctly added for web composer - Mobile behavior related scripts return value was not properly handled for web composer - In responsive web, bottomsheet modal clicks were intercepted by iframe behind
This commit is contained in:
@@ -220,9 +220,12 @@ class HtmlUtils {
|
||||
const selection = window.getSelection();
|
||||
if (selection && selection.rangeCount > 0) {
|
||||
window._savedRange = selection.getRangeAt(0).cloneRange();
|
||||
return selection.toString();
|
||||
const result = selection.toString()
|
||||
window.parent.postMessage(JSON.stringify({ "type": "toDart: saveSelection", result }), "*");
|
||||
return result;
|
||||
}
|
||||
delete window._savedRange;
|
||||
window.parent.postMessage(JSON.stringify({ "type": "toDart: saveSelection", result: "" }), "*");
|
||||
return "";
|
||||
})();''',
|
||||
name: 'saveSelection');
|
||||
@@ -236,9 +239,12 @@ class HtmlUtils {
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(window._savedRange);
|
||||
delete window._savedRange;
|
||||
return selection.toString();
|
||||
const result = selection.toString()
|
||||
window.parent.postMessage(JSON.stringify({ "type": "toDart: restoreSelection", result }), "*");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
window.parent.postMessage(JSON.stringify({ "type": "toDart: restoreSelection", result: "" }), "*");
|
||||
return "";
|
||||
})();''',
|
||||
name: 'restoreSelection');
|
||||
@@ -247,8 +253,11 @@ class HtmlUtils {
|
||||
script: '''
|
||||
(() => {
|
||||
if(window._savedRange) {
|
||||
return window._savedRange.toString();
|
||||
const result = window._savedRange.toString();
|
||||
window.parent.postMessage(JSON.stringify({ "type": "toDart: getSavedSelection", result }), "*");
|
||||
return result;
|
||||
} else {
|
||||
window.parent.postMessage(JSON.stringify({ "type": "toDart: getSavedSelection", result: "" }), "*");
|
||||
return "";
|
||||
}
|
||||
})();''',
|
||||
|
||||
@@ -134,6 +134,9 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
saveToDraftsAction: () => controller.handleClickSaveAsDraftsButton(context),
|
||||
saveToTemplateAction: () => controller.handleClickSaveAsTemplateButton(context),
|
||||
deleteComposerAction: controller.handleClickDeleteComposer,
|
||||
onOpenAiAssistantModal: controller.isAIScribeAvailable
|
||||
? controller.openAIAssistantModal
|
||||
: null,
|
||||
)),
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
|
||||
+11
@@ -4,6 +4,7 @@ import 'package:core/presentation/views/button/tmail_button_widget.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:custom_pop_up_menu/custom_pop_up_menu.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:scribe/scribe/ai/presentation/widgets/button/ai_assistant_button.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/highlight_svg_icon_on_hover.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/popup_item_widget.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/popup_menu_overlay_widget.dart';
|
||||
@@ -32,6 +33,7 @@ class MobileResponsiveAppBarComposerWidget extends StatelessWidget {
|
||||
final VoidCallback saveToTemplateAction;
|
||||
final VoidCallback deleteComposerAction;
|
||||
final VoidCallback toggleMarkAsImportantAction;
|
||||
final OnOpenAiAssistantModal? onOpenAiAssistantModal;
|
||||
|
||||
const MobileResponsiveAppBarComposerWidget({
|
||||
super.key,
|
||||
@@ -55,6 +57,7 @@ class MobileResponsiveAppBarComposerWidget extends StatelessWidget {
|
||||
required this.saveToTemplateAction,
|
||||
required this.deleteComposerAction,
|
||||
required this.toggleMarkAsImportantAction,
|
||||
this.onOpenAiAssistantModal,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -74,6 +77,14 @@ class MobileResponsiveAppBarComposerWidget extends StatelessWidget {
|
||||
onTapActionCallback: onCloseViewAction
|
||||
),
|
||||
const Spacer(),
|
||||
if (onOpenAiAssistantModal != null)
|
||||
AiAssistantButton(
|
||||
imagePaths: imagePaths,
|
||||
margin: const EdgeInsetsDirectional.only(
|
||||
end: MobileAppBarComposerWidgetStyle.space,
|
||||
),
|
||||
onOpenAiAssistantModal: onOpenAiAssistantModal!,
|
||||
),
|
||||
TMailButtonWidget.fromIcon(
|
||||
icon: imagePaths.icRichToolbar,
|
||||
padding: MobileAppBarComposerWidgetStyle.richTextIconPadding,
|
||||
|
||||
@@ -205,6 +205,22 @@ class _WebEditorState extends State<WebEditorWidget> with TextSelectionMixin {
|
||||
name: HtmlUtils.deleteSelectionContent.name,
|
||||
script: HtmlUtils.deleteSelectionContent.script,
|
||||
),
|
||||
WebScript(
|
||||
name: HtmlUtils.saveSelection.name,
|
||||
script: HtmlUtils.saveSelection.script,
|
||||
),
|
||||
WebScript(
|
||||
name: HtmlUtils.restoreSelection.name,
|
||||
script: HtmlUtils.restoreSelection.script,
|
||||
),
|
||||
WebScript(
|
||||
name: HtmlUtils.getSavedSelection.name,
|
||||
script: HtmlUtils.getSavedSelection.script,
|
||||
),
|
||||
WebScript(
|
||||
name: HtmlUtils.clearSavedSelection.name,
|
||||
script: HtmlUtils.clearSavedSelection.script,
|
||||
),
|
||||
WebScript(
|
||||
name: HtmlUtils.recalculateEditorHeight(maxHeight: maxHeight).name,
|
||||
script: HtmlUtils.recalculateEditorHeight(maxHeight: maxHeight).script,
|
||||
|
||||
+34
-31
@@ -2,6 +2,7 @@ import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:core/presentation/views/button/tmail_button_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||
import 'package:scribe/scribe.dart';
|
||||
|
||||
class AiScribeMobileActionsBottomSheet extends StatefulWidget {
|
||||
@@ -196,39 +197,41 @@ class _AiScribeMobileActionsBottomSheetState
|
||||
|
||||
final hasContent = widget.content?.isNotEmpty ?? false;
|
||||
|
||||
return Container(
|
||||
height: double.infinity,
|
||||
decoration: const BoxDecoration(
|
||||
color: AIScribeColors.background,
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
_buildHeader(context, localizations),
|
||||
_buildTextCard(context),
|
||||
if(hasContent)
|
||||
Flexible(
|
||||
child: ValueListenableBuilder<AiScribeCategoryContextMenuAction?>(
|
||||
valueListenable: _selectedCategory,
|
||||
builder: (context, selectedCategory, _) {
|
||||
return selectedCategory == null
|
||||
? _buildMenuListView(menuActions)
|
||||
: _buildSubmenuListView();
|
||||
},
|
||||
return PointerInterceptor(
|
||||
child: Container(
|
||||
height: double.infinity,
|
||||
decoration: const BoxDecoration(
|
||||
color: AIScribeColors.background,
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
_buildHeader(context, localizations),
|
||||
_buildTextCard(context),
|
||||
if(hasContent)
|
||||
Flexible(
|
||||
child: ValueListenableBuilder<AiScribeCategoryContextMenuAction?>(
|
||||
valueListenable: _selectedCategory,
|
||||
builder: (context, selectedCategory, _) {
|
||||
return selectedCategory == null
|
||||
? _buildMenuListView(menuActions)
|
||||
: _buildSubmenuListView();
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
_buildBottomBar(context),
|
||||
],
|
||||
_buildBottomBar(context),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
+23
-20
@@ -1,5 +1,6 @@
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||
import 'package:scribe/scribe.dart';
|
||||
|
||||
class AiScribeMobileSuggestionBottomSheet extends StatefulWidget {
|
||||
@@ -41,27 +42,29 @@ class _AiScribeMobileSuggestionBottomSheetState
|
||||
Widget build(BuildContext context) {
|
||||
final localizations = ScribeLocalizations.of(context);
|
||||
|
||||
return Container(
|
||||
height: double.infinity,
|
||||
decoration: const BoxDecoration(
|
||||
color: AIScribeColors.background,
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Padding(
|
||||
padding: AIScribeSizes.suggestionHeaderPadding,
|
||||
child: AiScribeSuggestionHeader(
|
||||
title: aiAction.getLabel(localizations),
|
||||
imagePaths: imagePaths,
|
||||
return PointerInterceptor(
|
||||
child: Container(
|
||||
height: double.infinity,
|
||||
decoration: const BoxDecoration(
|
||||
color: AIScribeColors.background,
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Padding(
|
||||
padding: AIScribeSizes.suggestionHeaderPadding,
|
||||
child: AiScribeSuggestionHeader(
|
||||
title: aiAction.getLabel(localizations),
|
||||
imagePaths: imagePaths,
|
||||
),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: buildStateContent(context),
|
||||
),
|
||||
],
|
||||
Flexible(
|
||||
child: buildStateContent(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user