add header style

This commit is contained in:
ManhNTX
2022-07-28 00:25:33 +07:00
committed by Dat H. Pham
parent d6ba69424a
commit 95f9c30804
2 changed files with 87 additions and 77 deletions
@@ -5,7 +5,6 @@ import 'package:file_picker/file_picker.dart';
import 'package:filesize/filesize.dart'; import 'package:filesize/filesize.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart'; import 'package:jmap_dart_client/jmap/identities/identity.dart';
@@ -15,9 +14,10 @@ import 'package:tmail_ui_user/features/base/widget/drop_down_button_widget.dart'
import 'package:tmail_ui_user/features/composer/domain/state/download_image_as_base64_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/download_image_as_base64_state.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/rich_text_button_mixin.dart'; import 'package:tmail_ui_user/features/composer/presentation/mixin/rich_text_button_mixin.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/dropdown_menu_font_status.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/header_style_type.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/rich_text_style_type.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/rich_text_style_type.dart';
import 'package:tmail_ui_user/features/composer/presentation/widgets/attachment_file_composer_builder.dart'; import 'package:tmail_ui_user/features/composer/presentation/widgets/attachment_file_composer_builder.dart';
import 'package:tmail_ui_user/features/composer/presentation/widgets/drop_down_menu_header_style_widget.dart';
import 'package:tmail_ui_user/features/composer/presentation/widgets/email_address_input_builder.dart'; import 'package:tmail_ui_user/features/composer/presentation/widgets/email_address_input_builder.dart';
import 'package:tmail_ui_user/features/upload/domain/state/attachment_upload_state.dart'; import 'package:tmail_ui_user/features/upload/domain/state/attachment_upload_state.dart';
import 'package:tmail_ui_user/features/upload/presentation/extensions/list_upload_file_state_extension.dart'; import 'package:tmail_ui_user/features/upload/presentation/extensions/list_upload_file_state_extension.dart';
@@ -508,75 +508,82 @@ class ComposerView extends GetWidget<ComposerController> with AppLoaderMixin, Ri
} }
Widget _buildToolbarRichTextWidget(BuildContext context) { Widget _buildToolbarRichTextWidget(BuildContext context) {
return Obx(() => Container( return Obx(() {
final richTextMobileTabletController = controller.richTextMobileTabletController;
return Container(
padding: const EdgeInsets.only(left: 20, top: 8, bottom: 8), padding: const EdgeInsets.only(left: 20, top: 8, bottom: 8),
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Wrap( child: Wrap(
alignment: WrapAlignment.center, alignment: WrapAlignment.center,
crossAxisAlignment: WrapCrossAlignment.center, crossAxisAlignment: WrapCrossAlignment.center,
children: [ children: [
Container( DropDownMenuHeaderStyleWidget(
width: 200, icon: buildWrapIconStyleText(
padding: const EdgeInsets.only(right: 2), isSelected: richTextMobileTabletController.isMenuHeaderStyleOpen,
child: DropDownButtonWidget<SafeFont>( icon: SvgPicture.asset(RichTextStyleType.headerStyle.getIcon(imagePaths),
items: SafeFont.values, color: AppColor.colorDefaultRichTextButton,
itemSelected: controller.richTextMobileTabletController.selectedFontName.value, fit: BoxFit.fill),
onChanged: (newFont) => controller.richTextMobileTabletController.applyNewFontStyle(newFont), padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 5),
onMenuStateChange: (isOpen) { ),
final newStatus = isOpen items: HeaderStyleType.values,
? DropdownMenuFontStatus.open onChanged: (newStyle) => richTextMobileTabletController.applyHeaderStyle(newStyle)),
: DropdownMenuFontStatus.closed; Container(
controller.richTextMobileTabletController.menuFontStatus = newStatus; width: 200,
}, padding: const EdgeInsets.only(right: 2, left: 8),
heightItem: 38, child: DropDownButtonWidget<SafeFont>(
sizeIconChecked: 16, items: SafeFont.values,
radiusButton: 5, itemSelected: richTextMobileTabletController.selectedFontName.value,
colorButton: Colors.white, onChanged: (newFont) => richTextMobileTabletController.applyNewFontStyle(newFont),
supportSelectionIcon: true)), heightItem: 38,
Padding( sizeIconChecked: 16,
padding: const EdgeInsets.only(left: 8), radiusButton: 5,
child: buildWrapIconStyleText( colorButton: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 5), supportSelectionIcon: true)),
icon: buildIconColorBackgroundTextWithoutTooltip( Padding(
iconData: RichTextStyleType.textColor.getIconData(), padding: const EdgeInsets.only(left: 8),
colorSelected: controller.richTextMobileTabletController.selectedTextColor.value, child: buildWrapIconStyleText(
), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 5),
onTap: () => controller.richTextMobileTabletController.applyRichTextStyle(context, RichTextStyleType.textColor)), icon: buildIconColorBackgroundTextWithoutTooltip(
), iconData: RichTextStyleType.textColor.getIconData(),
Padding( colorSelected: richTextMobileTabletController.selectedTextColor.value,
padding: const EdgeInsets.symmetric(horizontal: 8), ),
child: buildWrapIconStyleText( onTap: () => richTextMobileTabletController.applyRichTextStyle(context, RichTextStyleType.textColor)),
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 5), ),
icon: buildIconColorBackgroundTextWithoutTooltip( Padding(
iconData: RichTextStyleType.textBackgroundColor.getIconData(), padding: const EdgeInsets.symmetric(horizontal: 8),
colorSelected: controller.richTextMobileTabletController.selectedTextBackgroundColor.value, child: buildWrapIconStyleText(
), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 5),
onTap: () => controller.richTextMobileTabletController.applyRichTextStyle(context, RichTextStyleType.textBackgroundColor)), icon: buildIconColorBackgroundTextWithoutTooltip(
), iconData: RichTextStyleType.textBackgroundColor.getIconData(),
buildWrapIconStyleText( colorSelected: richTextMobileTabletController.selectedTextBackgroundColor.value,
hasDropdown: false, ),
padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 5), onTap: () => richTextMobileTabletController.applyRichTextStyle(context, RichTextStyleType.textBackgroundColor)),
icon: Wrap(children: [ ),
buildIconStyleText( buildWrapIconStyleText(
path: RichTextStyleType.bold.getIcon(imagePaths), hasDropdown: false,
isSelected: controller.richTextMobileTabletController.isTextStyleTypeSelected(RichTextStyleType.bold), padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 5),
onTap: () => controller.richTextMobileTabletController.applyRichTextStyle(context, RichTextStyleType.bold)), icon: Wrap(children: [
buildIconStyleText( buildIconStyleText(
path: RichTextStyleType.italic.getIcon(imagePaths), path: RichTextStyleType.bold.getIcon(imagePaths),
isSelected: controller.richTextMobileTabletController.isTextStyleTypeSelected(RichTextStyleType.italic), isSelected: richTextMobileTabletController.isTextStyleTypeSelected(RichTextStyleType.bold),
onTap: () => controller.richTextMobileTabletController.applyRichTextStyle(context, RichTextStyleType.italic)), onTap: () => richTextMobileTabletController.applyRichTextStyle(context, RichTextStyleType.bold)),
buildIconStyleText( buildIconStyleText(
path: RichTextStyleType.underline.getIcon(imagePaths), path: RichTextStyleType.italic.getIcon(imagePaths),
isSelected: controller.richTextMobileTabletController.isTextStyleTypeSelected(RichTextStyleType.underline), isSelected: richTextMobileTabletController.isTextStyleTypeSelected(RichTextStyleType.italic),
onTap: () => controller.richTextMobileTabletController.applyRichTextStyle(context, RichTextStyleType.underline)), onTap: () => richTextMobileTabletController.applyRichTextStyle(context, RichTextStyleType.italic)),
buildIconStyleText( buildIconStyleText(
path: RichTextStyleType.strikeThrough.getIcon(imagePaths), path: RichTextStyleType.underline.getIcon(imagePaths),
isSelected: controller.richTextMobileTabletController.isTextStyleTypeSelected(RichTextStyleType.strikeThrough), isSelected: richTextMobileTabletController.isTextStyleTypeSelected(RichTextStyleType.underline),
onTap: () => controller.richTextMobileTabletController.applyRichTextStyle(context, RichTextStyleType.strikeThrough)) onTap: () => richTextMobileTabletController.applyRichTextStyle(context, RichTextStyleType.underline)),
])), buildIconStyleText(
], path: RichTextStyleType.strikeThrough.getIcon(imagePaths),
isSelected: richTextMobileTabletController.isTextStyleTypeSelected(RichTextStyleType.strikeThrough),
onTap: () => richTextMobileTabletController.applyRichTextStyle(context, RichTextStyleType.strikeThrough))
])),
],
), ),
), );
},
); );
} }
@@ -628,6 +635,7 @@ class ComposerView extends GetWidget<ComposerController> with AppLoaderMixin, Ri
} }
Widget _buildHtmlEditor(String initialContent) { Widget _buildHtmlEditor(String initialContent) {
final richTextMobileTabletController = controller.richTextMobileTabletController;
return Padding( return Padding(
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 20, top: 10), padding: const EdgeInsets.only(left: 16, right: 16, bottom: 20, top: 10),
child: HtmlEditor( child: HtmlEditor(
@@ -635,8 +643,8 @@ class ComposerView extends GetWidget<ComposerController> with AppLoaderMixin, Ri
minHeight: 550, minHeight: 550,
initialContent: initialContent, initialContent: initialContent,
onCreated: (editorApi) { onCreated: (editorApi) {
controller.richTextMobileTabletController.htmlEditorApi = editorApi; richTextMobileTabletController.htmlEditorApi = editorApi;
controller.richTextMobileTabletController.listenHtmlEditorApi(); richTextMobileTabletController.listenHtmlEditorApi();
}), }),
); );
} }
@@ -8,10 +8,10 @@ import 'package:html/parser.dart';
import 'package:model/model.dart'; import 'package:model/model.dart';
import 'package:tmail_ui_user/features/composer/presentation/controller/base_rich_text_controller.dart'; import 'package:tmail_ui_user/features/composer/presentation/controller/base_rich_text_controller.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/dropdown_menu_font_status.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/dropdown_menu_font_status.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/header_style_type.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/image_source.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/image_source.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/inline_image.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/inline_image.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/rich_text_style_type.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/rich_text_style_type.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
class RichTextMobileTabletController extends BaseRichTextController { class RichTextMobileTabletController extends BaseRichTextController {
HtmlEditorApi? htmlEditorApi; HtmlEditorApi? htmlEditorApi;
@@ -19,8 +19,10 @@ class RichTextMobileTabletController extends BaseRichTextController {
final selectedTextColor = Colors.black.obs; final selectedTextColor = Colors.black.obs;
final selectedTextBackgroundColor = Colors.white.obs; final selectedTextBackgroundColor = Colors.white.obs;
final selectedFontName = SafeFont.sansSerif.obs; final selectedFontName = SafeFont.sansSerif.obs;
final menuHeaderStyleStatus = DropdownMenuFontStatus.closed.obs;
DropdownMenuFontStatus menuFontStatus = DropdownMenuFontStatus.closed; bool get isMenuHeaderStyleOpen => menuHeaderStyleStatus.value == DropdownMenuFontStatus.open;
void listenHtmlEditorApi() { void listenHtmlEditorApi() {
htmlEditorApi?.onFormatSettingsChanged = (formatSettings) { htmlEditorApi?.onFormatSettingsChanged = (formatSettings) {
@@ -138,12 +140,6 @@ class RichTextMobileTabletController extends BaseRichTextController {
htmlEditorApi?.setFont(selectedFontName.value); htmlEditorApi?.setFont(selectedFontName.value);
} }
bool get isMenuFontOpen => menuFontStatus == DropdownMenuFontStatus.open;
void closeDropdownMenuFont() {
popBack();
}
void insertImage(InlineImage image, {double? maxWithEditor}) async { void insertImage(InlineImage image, {double? maxWithEditor}) async {
log('RichTextMobileTabletController::insertImage(): $image | maxWithEditor: $maxWithEditor'); log('RichTextMobileTabletController::insertImage(): $image | maxWithEditor: $maxWithEditor');
if (image.source == ImageSource.network) { if (image.source == ImageSource.network) {
@@ -154,4 +150,10 @@ class RichTextMobileTabletController extends BaseRichTextController {
htmlEditorApi?.insertHtml(htmlContent); htmlEditorApi?.insertHtml(htmlContent);
} }
} }
void applyHeaderStyle(HeaderStyleType? newStyle) {
final styleSelected = newStyle ?? HeaderStyleType.normal;
htmlEditorApi?.formatHeader(styleSelected.styleValue);
}
} }