diff --git a/lib/features/composer/presentation/composer_view.dart b/lib/features/composer/presentation/composer_view.dart index fd7318e3c..1860f9e2b 100644 --- a/lib/features/composer/presentation/composer_view.dart +++ b/lib/features/composer/presentation/composer_view.dart @@ -36,18 +36,8 @@ class ComposerView extends GetWidget { return ResponsiveWidget( responsiveUtils: controller.responsiveUtils, mobile: MobileContainerView( - keyboardRichTextController: controller.richTextMobileTabletController!.richTextController, onCloseViewAction: () => controller.handleClickCloseComposer(context), onClearFocusAction: () => controller.clearFocus(context), - onAttachFileAction: () => controller.isNetworkConnectionAvailable - ? controller.openPickAttachmentMenu( - context, - _pickAttachmentsActionTiles(context) - ) - : null, - onInsertImageAction: (constraints) => controller.isNetworkConnectionAvailable - ? controller.insertImage(context, constraints.maxWidth) - : null, backgroundColor: MobileAppBarComposerWidgetStyle.backgroundColor, childBuilder: (context, constraints) => SafeArea( left: !controller.responsiveUtils.isLandscapeMobile(context), @@ -75,6 +65,11 @@ class ComposerView extends GetWidget { _pickAttachmentsActionTiles(context) ), insertImageAction: () => controller.insertImage(context, constraints.maxWidth), + openRichToolbarAction: () => + controller.richTextMobileTabletController?.showFormatStyleBottomSheet( + context: context, + richTextController: controller.richTextMobileTabletController?.richTextController + ), )) else Obx(() => AppBarComposerWidget( @@ -95,6 +90,11 @@ class ComposerView extends GetWidget { _pickAttachmentsActionTiles(context) ), insertImageAction: () => controller.insertImage(context, constraints.maxWidth), + openRichToolbarAction: () => + controller.richTextMobileTabletController?.showFormatStyleBottomSheet( + context: context, + richTextController: controller.richTextMobileTabletController?.richTextController + ), )), Expanded( child: SafeArea( 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 4f349ba97..953cea15b 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 @@ -1,12 +1,15 @@ import 'dart:io'; +import 'package:core/presentation/utils/keyboard_utils.dart'; import 'package:core/utils/app_logger.dart'; import 'package:core/utils/html/html_utils.dart'; import 'package:file_picker/file_picker.dart'; +import 'package:flutter/cupertino.dart'; import 'package:rich_text_composer/rich_text_composer.dart'; import 'package:tmail_ui_user/features/composer/presentation/controller/base_rich_text_controller.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/header_style_type.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/inline_image.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; class RichTextMobileTabletController extends BaseRichTextController { HtmlEditorApi? htmlEditorApi; @@ -46,6 +49,28 @@ class RichTextMobileTabletController extends BaseRichTextController { } } + Future showFormatStyleBottomSheet({ + required BuildContext context, + required RichTextController? richTextController + }) async { + if (Platform.isAndroid) { + await htmlEditorApi?.storeSelectionRange(); + KeyboardUtils.hideSystemKeyboardMobile(); + } else { + await htmlEditorApi?.unfocus(); + } + + if (context.mounted) { + richTextController?.showRichTextBottomSheet( + context: context, + titleFormatBottomSheet: AppLocalizations.of(context).titleFormat, + titleQuickStyleBottomSheet: AppLocalizations.of(context).titleQuickStyles, + titleForegroundBottomSheet: AppLocalizations.of(context).titleForeground, + titleBackgroundBottomSheet: AppLocalizations.of(context).titleBackground, + ); + } + } + @override void onClose() { richTextController.dispose(); diff --git a/lib/features/composer/presentation/styles/mobile_app_bar_composer_widget_style.dart b/lib/features/composer/presentation/styles/mobile_app_bar_composer_widget_style.dart index 949625050..a3cc769e4 100644 --- a/lib/features/composer/presentation/styles/mobile_app_bar_composer_widget_style.dart +++ b/lib/features/composer/presentation/styles/mobile_app_bar_composer_widget_style.dart @@ -7,7 +7,7 @@ class MobileAppBarComposerWidgetStyle { static const double iconSize = 24; static const double space = 12; static const double iconRadius = 8; - static const double sendButtonIconSize = 28; + static const double sendButtonIconSize = 30; static const double richTextIconSize = 28; static const Color backgroundColor = AppColor.colorComposerAppBar; @@ -17,5 +17,5 @@ class MobileAppBarComposerWidgetStyle { static const EdgeInsetsGeometry padding = EdgeInsetsDirectional.symmetric(horizontal: 12); static const EdgeInsetsGeometry iconPadding = EdgeInsetsDirectional.all(3); - static const EdgeInsetsGeometry richTextIconPadding = EdgeInsetsDirectional.all(2); + static const EdgeInsetsGeometry richTextIconPadding = EdgeInsetsDirectional.all(5); } \ No newline at end of file diff --git a/lib/features/composer/presentation/view/mobile/mobile_container_view.dart b/lib/features/composer/presentation/view/mobile/mobile_container_view.dart index de1ffcd81..5e67b8006 100644 --- a/lib/features/composer/presentation/view/mobile/mobile_container_view.dart +++ b/lib/features/composer/presentation/view/mobile/mobile_container_view.dart @@ -1,33 +1,18 @@ -import 'package:core/presentation/utils/responsive_utils.dart'; -import 'package:core/utils/app_logger.dart'; import 'package:flutter/material.dart'; -import 'package:get/get.dart'; -import 'package:rich_text_composer/rich_text_composer.dart' as rich_composer; -import 'package:rich_text_composer/views/widgets/rich_text_keyboard_toolbar.dart'; +import 'package:core/utils/app_logger.dart'; import 'package:tmail_ui_user/features/composer/presentation/styles/mobile/mobile_container_view_style.dart'; -import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; - -typedef OnInsertImageAction = Function(BoxConstraints constraints); class MobileContainerView extends StatelessWidget { final Widget Function(BuildContext context, BoxConstraints constraints) childBuilder; - final rich_composer.RichTextController keyboardRichTextController; final VoidCallback onCloseViewAction; - final VoidCallback? onAttachFileAction; - final OnInsertImageAction? onInsertImageAction; final VoidCallback? onClearFocusAction; final Color? backgroundColor; - final _responsiveUtils = Get.find(); - - MobileContainerView({ + const MobileContainerView({ super.key, required this.childBuilder, - required this.keyboardRichTextController, required this.onCloseViewAction, - this.onAttachFileAction, - this.onInsertImageAction, this.onClearFocusAction, this.backgroundColor, }); @@ -48,25 +33,7 @@ class MobileContainerView extends StatelessWidget { backgroundColor: backgroundColor ?? MobileContainerViewStyle.outSideBackgroundColor, resizeToAvoidBottomInset: false, body: LayoutBuilder(builder: (context, constraints) { - return rich_composer.KeyboardRichText( - richTextController: keyboardRichTextController, - keyBroadToolbar: RichTextKeyboardToolBar( - backgroundKeyboardToolBarColor: MobileContainerViewStyle.keyboardToolbarBackgroundColor, - isLandScapeMode: _responsiveUtils.isLandscapeMobile(context), - insertAttachment: onAttachFileAction, - insertImage: () => onInsertImageAction != null - ? onInsertImageAction!(constraints) - : null, - richTextController: keyboardRichTextController, - titleQuickStyleBottomSheet: AppLocalizations.of(context).titleQuickStyles, - titleBackgroundBottomSheet: AppLocalizations.of(context).titleBackground, - titleForegroundBottomSheet: AppLocalizations.of(context).titleForeground, - titleFormatBottomSheet: AppLocalizations.of(context).titleFormat, - titleBack: AppLocalizations.of(context).format, - ), - paddingChild: EdgeInsets.zero, - child: childBuilder(context, constraints), - ); + return childBuilder(context, constraints); }) ), ) diff --git a/lib/features/composer/presentation/view/mobile/tablet_container_view.dart b/lib/features/composer/presentation/view/mobile/tablet_container_view.dart index 9af454793..a45ccb8ef 100644 --- a/lib/features/composer/presentation/view/mobile/tablet_container_view.dart +++ b/lib/features/composer/presentation/view/mobile/tablet_container_view.dart @@ -5,9 +5,10 @@ import 'package:get/get.dart'; import 'package:rich_text_composer/rich_text_composer.dart'; import 'package:rich_text_composer/views/widgets/rich_text_keyboard_toolbar.dart'; import 'package:tmail_ui_user/features/composer/presentation/styles/mobile/tablet_container_view_style.dart'; -import 'package:tmail_ui_user/features/composer/presentation/view/mobile/mobile_container_view.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; +typedef OnInsertImageAction = Function(BoxConstraints constraints); + class TabletContainerView extends StatelessWidget { final Widget Function(BuildContext context, BoxConstraints constraints) childBuilder; diff --git a/lib/features/composer/presentation/widgets/mobile/app_bar_composer_widget.dart b/lib/features/composer/presentation/widgets/mobile/app_bar_composer_widget.dart index 86e2c3903..e9ccfa030 100644 --- a/lib/features/composer/presentation/widgets/mobile/app_bar_composer_widget.dart +++ b/lib/features/composer/presentation/widgets/mobile/app_bar_composer_widget.dart @@ -12,8 +12,9 @@ class AppBarComposerWidget extends StatelessWidget { final bool isNetworkConnectionAvailable; final VoidCallback onCloseViewAction; final VoidCallback sendMessageAction; - final VoidCallback attachFileAction; - final VoidCallback insertImageAction; + final VoidCallback? attachFileAction; + final VoidCallback? insertImageAction; + final VoidCallback openRichToolbarAction; final OnOpenContextMenuAction openContextMenuAction; final _imagePaths = Get.find(); @@ -24,9 +25,10 @@ class AppBarComposerWidget extends StatelessWidget { required this.onCloseViewAction, required this.sendMessageAction, required this.openContextMenuAction, - required this.attachFileAction, - required this.insertImageAction, + required this.openRichToolbarAction, this.isNetworkConnectionAvailable = false, + this.attachFileAction, + this.insertImageAction, }); @override @@ -47,8 +49,18 @@ class AppBarComposerWidget extends StatelessWidget { onTapActionCallback: onCloseViewAction ), const Spacer(), + TMailButtonWidget.fromIcon( + icon: _imagePaths.icRichToolbar, + iconColor: MobileAppBarComposerWidgetStyle.iconColor, + backgroundColor: Colors.transparent, + iconSize: MobileAppBarComposerWidgetStyle.richTextIconSize, + padding: MobileAppBarComposerWidgetStyle.richTextIconPadding, + tooltipMessage: AppLocalizations.of(context).formattingOptions, + onTapActionCallback: openRichToolbarAction, + ), if (isNetworkConnectionAvailable) ...[ + const SizedBox(width: 4), TMailButtonWidget.fromIcon( icon: _imagePaths.icAttachFile, iconColor: MobileAppBarComposerWidgetStyle.iconColor, @@ -57,7 +69,7 @@ class AppBarComposerWidget extends StatelessWidget { tooltipMessage: AppLocalizations.of(context).attach_file, onTapActionCallback: attachFileAction, ), - const SizedBox(width: 8), + const SizedBox(width: 4), TMailButtonWidget.fromIcon( icon: _imagePaths.icInsertImage, iconColor: MobileAppBarComposerWidgetStyle.iconColor, @@ -66,7 +78,7 @@ class AppBarComposerWidget extends StatelessWidget { tooltipMessage: AppLocalizations.of(context).insertImage, onTapActionCallback: insertImageAction, ), - const SizedBox(width: 8), + const SizedBox(width: 4), ], TMailButtonWidget.fromIcon( icon: isSendButtonEnabled diff --git a/lib/features/composer/presentation/widgets/mobile/landscape_app_bar_composer_widget.dart b/lib/features/composer/presentation/widgets/mobile/landscape_app_bar_composer_widget.dart index 07603d9b1..bb7cbd183 100644 --- a/lib/features/composer/presentation/widgets/mobile/landscape_app_bar_composer_widget.dart +++ b/lib/features/composer/presentation/widgets/mobile/landscape_app_bar_composer_widget.dart @@ -12,8 +12,9 @@ class LandscapeAppBarComposerWidget extends StatelessWidget { final bool isNetworkConnectionAvailable; final VoidCallback onCloseViewAction; final VoidCallback sendMessageAction; - final VoidCallback attachFileAction; - final VoidCallback insertImageAction; + final VoidCallback? attachFileAction; + final VoidCallback? insertImageAction; + final VoidCallback openRichToolbarAction; final OnOpenContextMenuAction openContextMenuAction; final _imagePaths = Get.find(); @@ -24,9 +25,10 @@ class LandscapeAppBarComposerWidget extends StatelessWidget { required this.onCloseViewAction, required this.sendMessageAction, required this.openContextMenuAction, - required this.attachFileAction, - required this.insertImageAction, + required this.openRichToolbarAction, this.isNetworkConnectionAvailable = false, + this.attachFileAction, + this.insertImageAction, }); @override @@ -50,8 +52,18 @@ class LandscapeAppBarComposerWidget extends StatelessWidget { onTapActionCallback: onCloseViewAction ), const Spacer(), + TMailButtonWidget.fromIcon( + icon: _imagePaths.icRichToolbar, + iconColor: MobileAppBarComposerWidgetStyle.iconColor, + backgroundColor: Colors.transparent, + iconSize: MobileAppBarComposerWidgetStyle.richTextIconSize, + padding: MobileAppBarComposerWidgetStyle.richTextIconPadding, + tooltipMessage: AppLocalizations.of(context).formattingOptions, + onTapActionCallback: openRichToolbarAction, + ), if (isNetworkConnectionAvailable) ...[ + const SizedBox(width: 4), TMailButtonWidget.fromIcon( icon: _imagePaths.icAttachFile, iconColor: MobileAppBarComposerWidgetStyle.iconColor, @@ -60,7 +72,7 @@ class LandscapeAppBarComposerWidget extends StatelessWidget { tooltipMessage: AppLocalizations.of(context).attach_file, onTapActionCallback: attachFileAction, ), - const SizedBox(width: 8), + const SizedBox(width: 4), TMailButtonWidget.fromIcon( icon: _imagePaths.icInsertImage, iconColor: MobileAppBarComposerWidgetStyle.iconColor, @@ -69,7 +81,7 @@ class LandscapeAppBarComposerWidget extends StatelessWidget { tooltipMessage: AppLocalizations.of(context).insertImage, onTapActionCallback: insertImageAction, ), - const SizedBox(width: 8), + const SizedBox(width: 4), ], TMailButtonWidget.fromIcon( icon: isSendButtonEnabled