add header style
This commit is contained in:
@@ -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();
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-8
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user