TF-1194 create new default identity: add presentation layer
This commit is contained in:
@@ -10,21 +10,13 @@ import 'package:jmap_dart_client/jmap/identities/identity.dart';
|
|||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||||
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
|
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
|
||||||
import 'package:tmail_ui_user/features/base/widget/popup_menu_overlay_widget.dart';
|
|
||||||
import 'package:tmail_ui_user/features/base/widget/drop_down_button_widget.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/composer_loading_mixin.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/mixin/composer_loading_mixin.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/font_name_type.dart';
|
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/model/header_style_type.dart';
|
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/model/order_list_type.dart';
|
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/model/paragraph_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/screen_display_mode.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.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/composer/presentation/widgets/toolbar_rich_text_builder.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';
|
||||||
import 'package:tmail_ui_user/features/upload/presentation/model/upload_file_state.dart';
|
import 'package:tmail_ui_user/features/upload/presentation/model/upload_file_state.dart';
|
||||||
import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart';
|
import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart';
|
||||||
@@ -72,7 +64,7 @@ class ComposerView extends GetWidget<ComposerController>
|
|||||||
Expanded(child: Column(
|
Expanded(child: Column(
|
||||||
children: [
|
children: [
|
||||||
_buildAttachmentsWidget(context),
|
_buildAttachmentsWidget(context),
|
||||||
_buildToolbarRichTextWidget(context),
|
ToolbarRichTextWebBuilder(richTextWebController: controller.richTextWebController),
|
||||||
buildInlineLoadingView(controller),
|
buildInlineLoadingView(controller),
|
||||||
_buildEditorForm(context)
|
_buildEditorForm(context)
|
||||||
]
|
]
|
||||||
@@ -368,7 +360,7 @@ class ComposerView extends GetWidget<ComposerController>
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
_buildAttachmentsWidget(context),
|
_buildAttachmentsWidget(context),
|
||||||
_buildToolbarRichTextWidget(context),
|
ToolbarRichTextWebBuilder(richTextWebController: controller.richTextWebController),
|
||||||
buildInlineLoadingView(controller),
|
buildInlineLoadingView(controller),
|
||||||
_buildEditorForm(context)
|
_buildEditorForm(context)
|
||||||
]
|
]
|
||||||
@@ -739,7 +731,7 @@ class ComposerView extends GetWidget<ComposerController>
|
|||||||
Widget _buildAttachmentsWidget(BuildContext context) {
|
Widget _buildAttachmentsWidget(BuildContext context) {
|
||||||
return Obx(() {
|
return Obx(() {
|
||||||
final attachments = controller.uploadController.listUploadAttachments;
|
final attachments = controller.uploadController.listUploadAttachments;
|
||||||
if (attachments.isNotEmpty) {
|
if (attachments.isNotEmpty) {
|
||||||
return Column(children: [
|
return Column(children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
@@ -846,193 +838,4 @@ class ComposerView extends GetWidget<ComposerController>
|
|||||||
return constraints.maxHeight > 0 ? constraints.maxHeight * 0.4 : 150.0;
|
return constraints.maxHeight > 0 ? constraints.maxHeight * 0.4 : 150.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildToolbarRichTextWidget(BuildContext context) {
|
|
||||||
return Obx(() {
|
|
||||||
final richTextController = controller.richTextWebController;
|
|
||||||
final codeViewEnabled = richTextController.codeViewEnabled;
|
|
||||||
final opacity = codeViewEnabled ? 0.5 : 1.0;
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
padding: const EdgeInsets.only(left: 20, top: 8, bottom: 8),
|
|
||||||
alignment: Alignment.centerLeft,
|
|
||||||
child: Wrap(
|
|
||||||
crossAxisAlignment: WrapCrossAlignment.center,
|
|
||||||
runSpacing: 8,
|
|
||||||
children: [
|
|
||||||
AbsorbPointer(
|
|
||||||
absorbing: codeViewEnabled,
|
|
||||||
child: DropDownMenuHeaderStyleWidget(
|
|
||||||
icon: buildWrapIconStyleText(
|
|
||||||
isSelected: richTextController.isMenuHeaderStyleOpen,
|
|
||||||
icon: SvgPicture.asset(RichTextStyleType.headerStyle.getIcon(imagePaths),
|
|
||||||
color: AppColor.colorDefaultRichTextButton.withOpacity(opacity),
|
|
||||||
fit: BoxFit.fill),
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 5),
|
|
||||||
tooltip: RichTextStyleType.headerStyle.getTooltipButton(context)
|
|
||||||
),
|
|
||||||
items: HeaderStyleType.values,
|
|
||||||
onMenuStateChange: (isOpen) {
|
|
||||||
log('ComposerView::_buildToolbarRichTextWidget(): MenuHeaderStyleStatus: $isOpen');
|
|
||||||
final newStatus = isOpen
|
|
||||||
? DropdownMenuFontStatus.open
|
|
||||||
: DropdownMenuFontStatus.closed;
|
|
||||||
richTextController.menuHeaderStyleStatus.value = newStatus;
|
|
||||||
},
|
|
||||||
onChanged: (newStyle) => richTextController.applyHeaderStyle(newStyle)),
|
|
||||||
),
|
|
||||||
AbsorbPointer(
|
|
||||||
absorbing: codeViewEnabled,
|
|
||||||
child: Container(
|
|
||||||
width: 130,
|
|
||||||
padding: const EdgeInsets.only(left: 4.0, right: 4.0),
|
|
||||||
child: DropDownButtonWidget<FontNameType>(
|
|
||||||
items: FontNameType.values,
|
|
||||||
itemSelected: richTextController.selectedFontName.value,
|
|
||||||
onChanged: (newFont) => richTextController.applyNewFontStyle(newFont),
|
|
||||||
onMenuStateChange: (isOpen) {
|
|
||||||
log('ComposerView::_buildToolbarRichTextWidget(): MenuFontStatus: $isOpen');
|
|
||||||
final newStatus = isOpen
|
|
||||||
? DropdownMenuFontStatus.open
|
|
||||||
: DropdownMenuFontStatus.closed;
|
|
||||||
richTextController.menuFontStatus.value = newStatus;
|
|
||||||
},
|
|
||||||
heightItem: 40,
|
|
||||||
sizeIconChecked: 16,
|
|
||||||
radiusButton: 8,
|
|
||||||
opacity: opacity,
|
|
||||||
dropdownWidth: 200,
|
|
||||||
colorButton: richTextController.isMenuFontOpen
|
|
||||||
? AppColor.colorBackgroundWrapIconStyleCode
|
|
||||||
: Colors.white,
|
|
||||||
iconArrowDown: SvgPicture.asset(imagePaths.icStyleArrowDown),
|
|
||||||
tooltip: RichTextStyleType.fontName.getTooltipButton(context),
|
|
||||||
supportSelectionIcon: true)),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 4.0),
|
|
||||||
child: AbsorbPointer(
|
|
||||||
absorbing: codeViewEnabled,
|
|
||||||
child: buildWrapIconStyleText(
|
|
||||||
icon: buildIconWithTooltip(
|
|
||||||
path: RichTextStyleType.textColor.getIcon(imagePaths),
|
|
||||||
color: richTextController.selectedTextColor.value,
|
|
||||||
tooltip: RichTextStyleType.textColor.getTooltipButton(context),
|
|
||||||
opacity: opacity),
|
|
||||||
onTap: () => richTextController.applyRichTextStyle(context, RichTextStyleType.textColor)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 4.0),
|
|
||||||
child: AbsorbPointer(
|
|
||||||
absorbing: codeViewEnabled,
|
|
||||||
child: buildWrapIconStyleText(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 9, horizontal: 7),
|
|
||||||
spacing: 3,
|
|
||||||
icon: buildIconColorBackgroundText(
|
|
||||||
iconData: RichTextStyleType.textBackgroundColor.getIconData(),
|
|
||||||
colorSelected: richTextController.selectedTextBackgroundColor.value,
|
|
||||||
tooltip: RichTextStyleType.textBackgroundColor.getTooltipButton(context),
|
|
||||||
opacity: opacity),
|
|
||||||
onTap: () => richTextController.applyRichTextStyle(context, RichTextStyleType.textBackgroundColor)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 4.0),
|
|
||||||
child: buildWrapIconStyleText(
|
|
||||||
hasDropdown: false,
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 5),
|
|
||||||
icon: Wrap(children: [
|
|
||||||
AbsorbPointer(
|
|
||||||
absorbing: codeViewEnabled,
|
|
||||||
child: buildIconStyleText(
|
|
||||||
path: RichTextStyleType.bold.getIcon(imagePaths),
|
|
||||||
isSelected: richTextController.isTextStyleTypeSelected(RichTextStyleType.bold),
|
|
||||||
tooltip: RichTextStyleType.bold.getTooltipButton(context),
|
|
||||||
opacity: opacity,
|
|
||||||
onTap: () => richTextController.applyRichTextStyle(context, RichTextStyleType.bold)),
|
|
||||||
),
|
|
||||||
AbsorbPointer(
|
|
||||||
absorbing: codeViewEnabled,
|
|
||||||
child: buildIconStyleText(
|
|
||||||
path: RichTextStyleType.italic.getIcon(imagePaths),
|
|
||||||
isSelected: richTextController.isTextStyleTypeSelected(RichTextStyleType.italic),
|
|
||||||
tooltip: RichTextStyleType.italic.getTooltipButton(context),
|
|
||||||
opacity: opacity,
|
|
||||||
onTap: () => richTextController.applyRichTextStyle(context, RichTextStyleType.italic)),
|
|
||||||
),
|
|
||||||
AbsorbPointer(
|
|
||||||
absorbing: codeViewEnabled,
|
|
||||||
child: buildIconStyleText(
|
|
||||||
path: RichTextStyleType.underline.getIcon(imagePaths),
|
|
||||||
isSelected: richTextController.isTextStyleTypeSelected(RichTextStyleType.underline),
|
|
||||||
tooltip: RichTextStyleType.underline.getTooltipButton(context),
|
|
||||||
opacity: opacity,
|
|
||||||
onTap: () => richTextController.applyRichTextStyle(context, RichTextStyleType.underline)),
|
|
||||||
),
|
|
||||||
AbsorbPointer(
|
|
||||||
absorbing: codeViewEnabled,
|
|
||||||
child: buildIconStyleText(
|
|
||||||
path: RichTextStyleType.strikeThrough.getIcon(imagePaths),
|
|
||||||
isSelected: richTextController.isTextStyleTypeSelected(
|
|
||||||
RichTextStyleType.strikeThrough),
|
|
||||||
tooltip: RichTextStyleType.strikeThrough.getTooltipButton(context),
|
|
||||||
opacity: opacity,
|
|
||||||
onTap: () => richTextController.applyRichTextStyle(context, RichTextStyleType.strikeThrough)),
|
|
||||||
)
|
|
||||||
])),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 4.0),
|
|
||||||
child: AbsorbPointer(
|
|
||||||
absorbing: codeViewEnabled,
|
|
||||||
child: PopupMenuOverlayWidget(
|
|
||||||
controller: richTextController.menuParagraphController,
|
|
||||||
listButtonAction: ParagraphType.values
|
|
||||||
.map((paragraph) => paragraph.buildButtonWidget(
|
|
||||||
context,
|
|
||||||
imagePaths,
|
|
||||||
(paragraph) => richTextController.applyParagraphType(paragraph)))
|
|
||||||
.toList(),
|
|
||||||
iconButton: buildWrapIconStyleText(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 5),
|
|
||||||
spacing: 3,
|
|
||||||
isSelected: richTextController.focusMenuParagraph.value,
|
|
||||||
icon: buildIconWithTooltip(
|
|
||||||
path: richTextController.selectedParagraph.value.getIcon(imagePaths),
|
|
||||||
color: AppColor.colorDefaultRichTextButton,
|
|
||||||
opacity: opacity,
|
|
||||||
tooltip: RichTextStyleType.paragraph.getTooltipButton(context))),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 4.0),
|
|
||||||
child: AbsorbPointer(
|
|
||||||
absorbing: codeViewEnabled,
|
|
||||||
child: PopupMenuOverlayWidget(
|
|
||||||
controller: richTextController.menuOrderListController,
|
|
||||||
listButtonAction: OrderListType.values
|
|
||||||
.map((orderType) => orderType.buildButtonWidget(
|
|
||||||
context,
|
|
||||||
imagePaths,
|
|
||||||
(orderType) => richTextController.applyOrderListType(orderType)))
|
|
||||||
.toList(),
|
|
||||||
iconButton: buildWrapIconStyleText(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 5),
|
|
||||||
spacing: 3,
|
|
||||||
isSelected: richTextController.focusMenuOrderList.value,
|
|
||||||
icon: buildIconWithTooltip(
|
|
||||||
path: richTextController.selectedOrderList.value.getIcon(imagePaths),
|
|
||||||
color: AppColor.colorDefaultRichTextButton,
|
|
||||||
opacity: opacity,
|
|
||||||
tooltip: RichTextStyleType.orderList.getTooltipButton(context))),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
]
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:core/presentation/resources/image_paths.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:tmail_ui_user/features/base/widget/drop_down_button_widget.dart';
|
||||||
|
import 'package:tmail_ui_user/features/base/widget/popup_menu_overlay_widget.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_web_controller.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/font_name_type.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/model/header_style_type.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/model/order_list_type.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/model/paragraph_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/drop_down_menu_header_style_widget.dart';
|
||||||
|
|
||||||
|
class ToolbarRichTextWebBuilder extends StatelessWidget with RichTextButtonMixin {
|
||||||
|
|
||||||
|
final RichTextWebController richTextWebController;
|
||||||
|
final ImagePaths _imagePaths = Get.find<ImagePaths>();
|
||||||
|
|
||||||
|
ToolbarRichTextWebBuilder({
|
||||||
|
Key? key,
|
||||||
|
required this.richTextWebController
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Obx(() {
|
||||||
|
final codeViewEnabled = richTextWebController.codeViewEnabled;
|
||||||
|
final opacity = codeViewEnabled ? 0.5 : 1.0;
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.only(left: 20, top: 8, bottom: 8),
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Wrap(
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
runSpacing: 8,
|
||||||
|
children: [
|
||||||
|
AbsorbPointer(
|
||||||
|
absorbing: codeViewEnabled,
|
||||||
|
child: DropDownMenuHeaderStyleWidget(
|
||||||
|
icon: buildWrapIconStyleText(
|
||||||
|
isSelected: richTextWebController.isMenuHeaderStyleOpen,
|
||||||
|
icon: SvgPicture.asset(RichTextStyleType.headerStyle.getIcon(_imagePaths),
|
||||||
|
color: AppColor.colorDefaultRichTextButton.withOpacity(opacity),
|
||||||
|
fit: BoxFit.fill),
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 5),
|
||||||
|
tooltip: RichTextStyleType.headerStyle.getTooltipButton(context)
|
||||||
|
),
|
||||||
|
items: HeaderStyleType.values,
|
||||||
|
onMenuStateChange: (isOpen) {
|
||||||
|
log('ComposerView::_buildToolbarRichTextWidget(): MenuHeaderStyleStatus: $isOpen');
|
||||||
|
final newStatus = isOpen
|
||||||
|
? DropdownMenuFontStatus.open
|
||||||
|
: DropdownMenuFontStatus.closed;
|
||||||
|
richTextWebController.menuHeaderStyleStatus.value = newStatus;
|
||||||
|
},
|
||||||
|
onChanged: (newStyle) => richTextWebController.applyHeaderStyle(newStyle)),
|
||||||
|
),
|
||||||
|
AbsorbPointer(
|
||||||
|
absorbing: codeViewEnabled,
|
||||||
|
child: Container(
|
||||||
|
width: 130,
|
||||||
|
padding: const EdgeInsets.only(left: 4.0, right: 4.0),
|
||||||
|
child: DropDownButtonWidget<FontNameType>(
|
||||||
|
items: FontNameType.values,
|
||||||
|
itemSelected: richTextWebController.selectedFontName.value,
|
||||||
|
onChanged: (newFont) => richTextWebController.applyNewFontStyle(newFont),
|
||||||
|
onMenuStateChange: (isOpen) {
|
||||||
|
log('ComposerView::_buildToolbarRichTextWidget(): MenuFontStatus: $isOpen');
|
||||||
|
final newStatus = isOpen
|
||||||
|
? DropdownMenuFontStatus.open
|
||||||
|
: DropdownMenuFontStatus.closed;
|
||||||
|
richTextWebController.menuFontStatus.value = newStatus;
|
||||||
|
},
|
||||||
|
heightItem: 40,
|
||||||
|
sizeIconChecked: 16,
|
||||||
|
radiusButton: 8,
|
||||||
|
opacity: opacity,
|
||||||
|
dropdownWidth: 200,
|
||||||
|
colorButton: richTextWebController.isMenuFontOpen
|
||||||
|
? AppColor.colorBackgroundWrapIconStyleCode
|
||||||
|
: Colors.white,
|
||||||
|
iconArrowDown: SvgPicture.asset(_imagePaths.icStyleArrowDown),
|
||||||
|
tooltip: RichTextStyleType.fontName.getTooltipButton(context),
|
||||||
|
supportSelectionIcon: true)),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 4.0),
|
||||||
|
child: AbsorbPointer(
|
||||||
|
absorbing: codeViewEnabled,
|
||||||
|
child: buildWrapIconStyleText(
|
||||||
|
icon: buildIconWithTooltip(
|
||||||
|
path: RichTextStyleType.textColor.getIcon(_imagePaths),
|
||||||
|
color: richTextWebController.selectedTextColor.value,
|
||||||
|
tooltip: RichTextStyleType.textColor.getTooltipButton(context),
|
||||||
|
opacity: opacity),
|
||||||
|
onTap: () => richTextWebController.applyRichTextStyle(context, RichTextStyleType.textColor)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 4.0),
|
||||||
|
child: AbsorbPointer(
|
||||||
|
absorbing: codeViewEnabled,
|
||||||
|
child: buildWrapIconStyleText(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 9, horizontal: 7),
|
||||||
|
spacing: 3,
|
||||||
|
icon: buildIconColorBackgroundText(
|
||||||
|
iconData: RichTextStyleType.textBackgroundColor.getIconData(),
|
||||||
|
colorSelected: richTextWebController.selectedTextBackgroundColor.value,
|
||||||
|
tooltip: RichTextStyleType.textBackgroundColor.getTooltipButton(context),
|
||||||
|
opacity: opacity),
|
||||||
|
onTap: () => richTextWebController.applyRichTextStyle(context, RichTextStyleType.textBackgroundColor)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 4.0),
|
||||||
|
child: buildWrapIconStyleText(
|
||||||
|
hasDropdown: false,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 5),
|
||||||
|
icon: Wrap(children: [
|
||||||
|
AbsorbPointer(
|
||||||
|
absorbing: codeViewEnabled,
|
||||||
|
child: buildIconStyleText(
|
||||||
|
path: RichTextStyleType.bold.getIcon(_imagePaths),
|
||||||
|
isSelected: richTextWebController.isTextStyleTypeSelected(RichTextStyleType.bold),
|
||||||
|
tooltip: RichTextStyleType.bold.getTooltipButton(context),
|
||||||
|
opacity: opacity,
|
||||||
|
onTap: () => richTextWebController.applyRichTextStyle(context, RichTextStyleType.bold)),
|
||||||
|
),
|
||||||
|
AbsorbPointer(
|
||||||
|
absorbing: codeViewEnabled,
|
||||||
|
child: buildIconStyleText(
|
||||||
|
path: RichTextStyleType.italic.getIcon(_imagePaths),
|
||||||
|
isSelected: richTextWebController.isTextStyleTypeSelected(RichTextStyleType.italic),
|
||||||
|
tooltip: RichTextStyleType.italic.getTooltipButton(context),
|
||||||
|
opacity: opacity,
|
||||||
|
onTap: () => richTextWebController.applyRichTextStyle(context, RichTextStyleType.italic)),
|
||||||
|
),
|
||||||
|
AbsorbPointer(
|
||||||
|
absorbing: codeViewEnabled,
|
||||||
|
child: buildIconStyleText(
|
||||||
|
path: RichTextStyleType.underline.getIcon(_imagePaths),
|
||||||
|
isSelected: richTextWebController.isTextStyleTypeSelected(RichTextStyleType.underline),
|
||||||
|
tooltip: RichTextStyleType.underline.getTooltipButton(context),
|
||||||
|
opacity: opacity,
|
||||||
|
onTap: () => richTextWebController.applyRichTextStyle(context, RichTextStyleType.underline)),
|
||||||
|
),
|
||||||
|
AbsorbPointer(
|
||||||
|
absorbing: codeViewEnabled,
|
||||||
|
child: buildIconStyleText(
|
||||||
|
path: RichTextStyleType.strikeThrough.getIcon(_imagePaths),
|
||||||
|
isSelected: richTextWebController.isTextStyleTypeSelected(
|
||||||
|
RichTextStyleType.strikeThrough),
|
||||||
|
tooltip: RichTextStyleType.strikeThrough.getTooltipButton(context),
|
||||||
|
opacity: opacity,
|
||||||
|
onTap: () => richTextWebController.applyRichTextStyle(context, RichTextStyleType.strikeThrough)),
|
||||||
|
)
|
||||||
|
])),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 4.0),
|
||||||
|
child: AbsorbPointer(
|
||||||
|
absorbing: codeViewEnabled,
|
||||||
|
child: PopupMenuOverlayWidget(
|
||||||
|
controller: richTextWebController.menuParagraphController,
|
||||||
|
listButtonAction: ParagraphType.values
|
||||||
|
.map((paragraph) => paragraph.buildButtonWidget(
|
||||||
|
context,
|
||||||
|
_imagePaths,
|
||||||
|
(paragraph) => richTextWebController.applyParagraphType(paragraph)))
|
||||||
|
.toList(),
|
||||||
|
iconButton: buildWrapIconStyleText(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 5),
|
||||||
|
spacing: 3,
|
||||||
|
isSelected: richTextWebController.focusMenuParagraph.value,
|
||||||
|
icon: buildIconWithTooltip(
|
||||||
|
path: richTextWebController.selectedParagraph.value.getIcon(_imagePaths),
|
||||||
|
color: AppColor.colorDefaultRichTextButton,
|
||||||
|
opacity: opacity,
|
||||||
|
tooltip: RichTextStyleType.paragraph.getTooltipButton(context))),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 4.0),
|
||||||
|
child: AbsorbPointer(
|
||||||
|
absorbing: codeViewEnabled,
|
||||||
|
child: PopupMenuOverlayWidget(
|
||||||
|
controller: richTextWebController.menuOrderListController,
|
||||||
|
listButtonAction: OrderListType.values
|
||||||
|
.map((orderType) => orderType.buildButtonWidget(
|
||||||
|
context,
|
||||||
|
_imagePaths,
|
||||||
|
(orderType) => richTextWebController.applyOrderListType(orderType)))
|
||||||
|
.toList(),
|
||||||
|
iconButton: buildWrapIconStyleText(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 5),
|
||||||
|
spacing: 3,
|
||||||
|
isSelected: richTextWebController.focusMenuOrderList.value,
|
||||||
|
icon: buildIconWithTooltip(
|
||||||
|
path: richTextWebController.selectedOrderList.value.getIcon(_imagePaths),
|
||||||
|
color: AppColor.colorDefaultRichTextButton,
|
||||||
|
opacity: opacity,
|
||||||
|
tooltip: RichTextStyleType.orderList.getTooltipButton(context))),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,16 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:core/core.dart';
|
import 'package:core/core.dart';
|
||||||
import 'package:enough_html_editor/enough_html_editor.dart' as html_editor_mobile;
|
import 'package:enough_html_editor/enough_html_editor.dart' as html_editor_mobile;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.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:html_editor_enhanced/html_editor.dart' as html_editor_browser;
|
import 'package:html_editor_enhanced/html_editor.dart' as html_editor_browser;
|
||||||
|
import 'package:html_editor_enhanced/html_editor.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||||
import 'package:rich_text_composer/views/keyboard_richtext.dart';
|
import 'package:rich_text_composer/views/keyboard_richtext.dart';
|
||||||
import 'package:rich_text_composer/views/widgets/rich_text_keyboard_toolbar.dart';
|
import 'package:rich_text_composer/views/widgets/rich_text_keyboard_toolbar.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/widgets/toolbar_rich_text_builder.dart';
|
||||||
import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_controller.dart';
|
import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_controller.dart';
|
||||||
import 'package:tmail_ui_user/features/identity_creator/presentation/model/identity_creator_arguments.dart';
|
import 'package:tmail_ui_user/features/identity_creator/presentation/model/identity_creator_arguments.dart';
|
||||||
import 'package:tmail_ui_user/features/identity_creator/presentation/model/signature_type.dart';
|
import 'package:tmail_ui_user/features/identity_creator/presentation/model/signature_type.dart';
|
||||||
@@ -14,6 +18,8 @@ import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/ide
|
|||||||
import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_field_no_editable_builder.dart';
|
import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_field_no_editable_builder.dart';
|
||||||
import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_input_field_builder.dart';
|
import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_input_field_builder.dart';
|
||||||
import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_input_with_drop_list_field_builder.dart';
|
import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_input_with_drop_list_field_builder.dart';
|
||||||
|
import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/set_default_identity_checkbox_builder.dart';
|
||||||
|
import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_identities_state.dart';
|
||||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/identity_action_type.dart';
|
import 'package:tmail_ui_user/features/manage_account/presentation/model/identity_action_type.dart';
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
|
|
||||||
@@ -44,15 +50,12 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ResponsiveWidget(
|
return ResponsiveWidget(
|
||||||
responsiveUtils: _responsiveUtils,
|
responsiveUtils: _responsiveUtils,
|
||||||
mobile: Scaffold(
|
mobile: GestureDetector(
|
||||||
backgroundColor: Colors.white,
|
onTap: () => controller.clearFocusEditor(context),
|
||||||
body: GestureDetector(
|
child: SizedBox(
|
||||||
onTap: () => controller.clearFocusEditor(context),
|
height: MediaQuery.of(context).size.height * 0.95,
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
child: ClipRRect(
|
child: BuildUtils.isWeb ? Scaffold(body: _buildBodyMobile(context)) : _buildBodyMobile(context),
|
||||||
borderRadius: const BorderRadius.only(topRight: Radius.circular(14), topLeft: Radius.circular(14)),
|
|
||||||
child: _buildBodyMobile(context)
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
@@ -90,11 +93,11 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
|
|||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.all(Radius.circular(16))),
|
borderRadius: BorderRadius.all(Radius.circular(16))),
|
||||||
width: _responsiveUtils.getSizeScreenWidth(context) * 0.9,
|
width: _responsiveUtils.getSizeScreenWidth(context) * 0.85,
|
||||||
height: _responsiveUtils.getSizeScreenHeight(context) * 0.9,
|
height: _responsiveUtils.getSizeScreenHeight(context) * 0.6,
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(16)),
|
borderRadius: const BorderRadius.all(Radius.circular(16)),
|
||||||
child: _buildBodyDesktop(context)
|
child: _buildBodyMobile(context)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)),
|
)),
|
||||||
@@ -123,11 +126,44 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
|
|||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.all(Radius.circular(16))),
|
borderRadius: BorderRadius.all(Radius.circular(16))),
|
||||||
width: _responsiveUtils.getSizeScreenWidth(context) * 0.9,
|
width: _responsiveUtils.getSizeScreenWidth(context) * 0.85,
|
||||||
height: _responsiveUtils.getSizeScreenHeight(context) * 0.9,
|
height: _responsiveUtils.getSizeScreenHeight(context) * 0.6,
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(16)),
|
borderRadius: const BorderRadius.all(Radius.circular(16)),
|
||||||
child: _buildBodyDesktop(context)
|
child: _buildBodyMobile(context)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
landscapeTablet: Scaffold(
|
||||||
|
backgroundColor: Colors.black.withAlpha(24),
|
||||||
|
body: GestureDetector(
|
||||||
|
onTap: () => controller.clearFocusEditor(context),
|
||||||
|
child: KeyboardRichText(
|
||||||
|
richTextController: controller.keyboardRichTextController,
|
||||||
|
keyBroadToolbar: RichTextKeyboardToolBar(
|
||||||
|
backgroundKeyboardToolBarColor: AppColor.colorBackgroundKeyboard,
|
||||||
|
richTextController: controller.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,
|
||||||
|
),
|
||||||
|
child: Center(child: Card(
|
||||||
|
color: Colors.transparent,
|
||||||
|
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16))),
|
||||||
|
child: Container(
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(16))),
|
||||||
|
width: _responsiveUtils.getSizeScreenWidth(context) * 0.65,
|
||||||
|
height: _responsiveUtils.getSizeScreenHeight(context) * 0.8,
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(16)),
|
||||||
|
child: _buildBodyMobile(context)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)),
|
)),
|
||||||
@@ -137,7 +173,10 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
|
|||||||
desktop: Scaffold(
|
desktop: Scaffold(
|
||||||
backgroundColor: Colors.black.withAlpha(24),
|
backgroundColor: Colors.black.withAlpha(24),
|
||||||
body: GestureDetector(
|
body: GestureDetector(
|
||||||
onTap: () => controller.clearFocusEditor(context),
|
onTap: () {
|
||||||
|
controller.clearFocusEditor(context);
|
||||||
|
debugPrint('${MediaQuery.of(context).size.width}');
|
||||||
|
},
|
||||||
child: Center(child: Card(
|
child: Center(child: Card(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16))),
|
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16))),
|
||||||
@@ -145,11 +184,11 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
|
|||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.all(Radius.circular(16))),
|
borderRadius: BorderRadius.all(Radius.circular(16))),
|
||||||
width: _responsiveUtils.getSizeScreenWidth(context) * 0.4,
|
width: max(_responsiveUtils.getSizeScreenWidth(context) * 0.4, 600),
|
||||||
height: _responsiveUtils.getSizeScreenHeight(context) * 0.9,
|
height: _responsiveUtils.getSizeScreenHeight(context) * 0.75,
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(16)),
|
borderRadius: const BorderRadius.all(Radius.circular(16)),
|
||||||
child: _buildBodyDesktop(context)
|
child: _buildBodyMobile(context)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)),
|
)),
|
||||||
@@ -158,319 +197,209 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBodyDesktop(BuildContext context) {
|
Widget _buildBodyMobile(BuildContext context) {
|
||||||
return Stack(
|
return GestureDetector(
|
||||||
children: [
|
onTap: () => controller.clearFocusEditor(context),
|
||||||
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
child: Stack(
|
||||||
Padding(
|
children: [
|
||||||
padding: const EdgeInsets.only(left: 24, top: 24),
|
Column(children: [
|
||||||
child: Obx(() => Text(controller.actionType.value == IdentityActionType.create
|
Padding(
|
||||||
? AppLocalizations.of(context).new_identity.inCaps
|
padding: const EdgeInsets.only(top: 14),
|
||||||
: AppLocalizations.of(context).edit_identity.inCaps,
|
child: Text(controller.actionType.value == IdentityActionType.create
|
||||||
style: const TextStyle(
|
? AppLocalizations.of(context).createNewIdentity.inCaps
|
||||||
fontWeight: FontWeight.bold,
|
: AppLocalizations.of(context).edit_identity.inCaps,
|
||||||
fontSize: 24,
|
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: Colors.black))),
|
||||||
color: Colors.black)))),
|
const SizedBox(height: 8),
|
||||||
const SizedBox(height: 8),
|
Expanded(
|
||||||
Expanded(child: SingleChildScrollView(
|
child: KeyboardRichText(
|
||||||
controller: controller.scrollController,
|
keyBroadToolbar: RichTextKeyboardToolBar(
|
||||||
physics: const ClampingScrollPhysics(),
|
titleBack: AppLocalizations.of(context).titleFormat,
|
||||||
child: Padding(
|
backgroundKeyboardToolBarColor: AppColor.colorBackgroundKeyboard,
|
||||||
padding: const EdgeInsets.all(24.0),
|
isLandScapeMode: _responsiveUtils.isLandscapeMobile(context),
|
||||||
child: Column(children: [
|
richTextController: controller.keyboardRichTextController,
|
||||||
Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
titleQuickStyleBottomSheet: AppLocalizations.of(context).titleQuickStyles,
|
||||||
Expanded(child: Obx(() => (IdentityInputFieldBuilder(
|
titleBackgroundBottomSheet: AppLocalizations.of(context).titleBackground,
|
||||||
|
titleForegroundBottomSheet: AppLocalizations.of(context).titleForeground,
|
||||||
|
titleFormatBottomSheet: AppLocalizations.of(context).titleFormat,
|
||||||
|
),
|
||||||
|
richTextController: controller.keyboardRichTextController,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
controller: controller.scrollController,
|
||||||
|
physics: const ClampingScrollPhysics(),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(24.0),
|
||||||
|
child: Column(children: [
|
||||||
|
Obx(() => (IdentityInputFieldBuilder(
|
||||||
AppLocalizations.of(context).name,
|
AppLocalizations.of(context).name,
|
||||||
controller.errorNameIdentity.value,
|
controller.errorNameIdentity.value,
|
||||||
|
AppLocalizations.of(context).required,
|
||||||
editingController: controller.inputNameIdentityController,
|
editingController: controller.inputNameIdentityController,
|
||||||
focusNode: controller.inputNameIdentityFocusNode,
|
focusNode: controller.inputNameIdentityFocusNode,
|
||||||
isMandatory: true)
|
isMandatory: true)
|
||||||
..addOnChangeInputNameAction((value) => controller.updateNameIdentity(context, value)))
|
..addOnChangeInputNameAction((value) => controller.updateNameIdentity(context, value)))
|
||||||
.build())),
|
.build()),
|
||||||
const SizedBox(width: 24),
|
const SizedBox(height: 24),
|
||||||
Expanded(child: Obx(() {
|
Obx(() {
|
||||||
if (controller.actionType.value == IdentityActionType.create) {
|
if (controller.actionType.value == IdentityActionType.create) {
|
||||||
return (IdentityDropListFieldBuilder(
|
return (IdentityDropListFieldBuilder(
|
||||||
|
_imagePaths,
|
||||||
|
AppLocalizations.of(context).email.inCaps,
|
||||||
|
controller.emailOfIdentity.value,
|
||||||
|
controller.listEmailAddressDefault)
|
||||||
|
..addOnSelectEmailAddressDropListAction((emailAddress) =>
|
||||||
|
controller.updateEmailOfIdentity(emailAddress))
|
||||||
|
).build();
|
||||||
|
} else {
|
||||||
|
return IdentityFieldNoEditableBuilder(
|
||||||
|
AppLocalizations.of(context).email.inCaps,
|
||||||
|
controller.emailOfIdentity.value
|
||||||
|
).build();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
Obx(() => (IdentityDropListFieldBuilder(
|
||||||
_imagePaths,
|
_imagePaths,
|
||||||
AppLocalizations.of(context).email.inCaps,
|
AppLocalizations.of(context).reply_to,
|
||||||
controller.emailOfIdentity.value,
|
controller.replyToOfIdentity.value,
|
||||||
controller.listEmailAddressDefault)
|
controller.listEmailAddressOfReplyTo)
|
||||||
..addOnSelectEmailAddressDropListAction((emailAddress) =>
|
..addOnSelectEmailAddressDropListAction((newEmailAddress) =>
|
||||||
controller.updateEmailOfIdentity(emailAddress))
|
controller.updaterReplyToOfIdentity(newEmailAddress)))
|
||||||
).build();
|
.build()),
|
||||||
} else {
|
const SizedBox(height: 24),
|
||||||
return IdentityFieldNoEditableBuilder(
|
Obx(() => (IdentityInputWithDropListFieldBuilder(
|
||||||
AppLocalizations.of(context).email.inCaps,
|
AppLocalizations.of(context).bcc_to,
|
||||||
controller.emailOfIdentity.value
|
controller.errorBccIdentity.value,
|
||||||
).build();
|
controller.inputBccIdentityController)
|
||||||
}
|
..addOnSelectedSuggestionAction((newEmailAddress) {
|
||||||
})),
|
controller.inputBccIdentityController?.text = newEmailAddress?.email ?? '';
|
||||||
]),
|
controller.updateBccOfIdentity(newEmailAddress);
|
||||||
const SizedBox(height: 24),
|
})
|
||||||
Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
..addOnChangeInputSuggestionAction((pattern) {
|
||||||
Expanded(child: Obx(() => (IdentityDropListFieldBuilder(
|
controller.validateInputBccAddress(context, pattern);
|
||||||
_imagePaths,
|
if (pattern == null || pattern.trim().isEmpty) {
|
||||||
AppLocalizations.of(context).reply_to_address,
|
controller.updateBccOfIdentity(null);
|
||||||
controller.replyToOfIdentity.value,
|
} else {
|
||||||
controller.listEmailAddressOfReplyTo)
|
controller.updateBccOfIdentity(EmailAddress(null, pattern));
|
||||||
..addOnSelectEmailAddressDropListAction((emailAddress) =>
|
}
|
||||||
controller.updaterReplyToOfIdentity(emailAddress)))
|
})
|
||||||
.build())),
|
..addOnSuggestionCallbackAction((pattern) =>
|
||||||
const SizedBox(width: 24),
|
controller.getSuggestionEmailAddress(pattern)))
|
||||||
Expanded(child: Obx(() => (IdentityInputWithDropListFieldBuilder(
|
.build()
|
||||||
AppLocalizations.of(context).bcc_to_address,
|
),
|
||||||
controller.errorBccIdentity.value,
|
const SizedBox(height: 32),
|
||||||
controller.inputBccIdentityController)
|
Row(
|
||||||
..addOnSelectedSuggestionAction((newEmailAddress) {
|
children: [
|
||||||
controller.inputBccIdentityController?.text = newEmailAddress?.email ?? '';
|
Text(AppLocalizations.of(context).signature,
|
||||||
controller.updateBccOfIdentity(newEmailAddress);
|
style: const TextStyle(
|
||||||
})
|
fontWeight: FontWeight.normal,
|
||||||
..addOnChangeInputSuggestionAction((pattern) {
|
fontSize: 14,
|
||||||
controller.validateInputBccAddress(context, pattern);
|
color: AppColor.colorContentEmail,
|
||||||
if (pattern == null || pattern.trim().isEmpty) {
|
|
||||||
controller.updateBccOfIdentity(null);
|
|
||||||
} else {
|
|
||||||
controller.updateBccOfIdentity(EmailAddress(null, pattern));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
..addOnSuggestionCallbackAction((pattern) =>
|
|
||||||
controller.getSuggestionEmailAddress(pattern)))
|
|
||||||
.build()
|
|
||||||
)),
|
|
||||||
]),
|
|
||||||
const SizedBox(height: 32),
|
|
||||||
Row(children: [
|
|
||||||
Text(AppLocalizations.of(context).signature,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.normal,
|
|
||||||
fontSize: 14,
|
|
||||||
color: AppColor.colorContentEmail)),
|
|
||||||
const Spacer(),
|
|
||||||
Obx(() => _buildSignatureButton(context, SignatureType.plainText)),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Obx(() => _buildSignatureButton(context, SignatureType.htmlTemplate)),
|
|
||||||
]),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
Obx(() => Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
border: Border.all(color: AppColor.colorInputBorderCreateMailbox),
|
|
||||||
color: Colors.white),
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16),
|
|
||||||
child: Stack(
|
|
||||||
children: [
|
|
||||||
if (controller.signatureType.value == SignatureType.plainText)
|
|
||||||
_buildSignaturePlainTextTemplate(context)
|
|
||||||
else
|
|
||||||
_buildSignatureHtmlTemplate(context)
|
|
||||||
]
|
|
||||||
),
|
|
||||||
))
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 24),
|
|
||||||
alignment: Alignment.centerRight,
|
|
||||||
color: Colors.white,
|
|
||||||
child: Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
buildTextButton(
|
|
||||||
AppLocalizations.of(context).cancel,
|
|
||||||
textStyle: const TextStyle(
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
fontSize: 17,
|
|
||||||
color: AppColor.colorTextButton),
|
|
||||||
backgroundColor: AppColor.emailAddressChipColor,
|
|
||||||
width: 128,
|
|
||||||
height: 44,
|
|
||||||
radius: 10,
|
|
||||||
onTap: () => controller.closeView(context)),
|
|
||||||
const SizedBox(width: 12),
|
|
||||||
Obx(() => buildTextButton(
|
|
||||||
controller.actionType.value == IdentityActionType.create
|
|
||||||
? AppLocalizations.of(context).create
|
|
||||||
: AppLocalizations.of(context).save,
|
|
||||||
width: 128,
|
|
||||||
height: 44,
|
|
||||||
radius: 10,
|
|
||||||
onTap: () => controller.createNewIdentity(context))),
|
|
||||||
]
|
|
||||||
),
|
|
||||||
)
|
|
||||||
]),
|
|
||||||
Positioned(top: 8, right: 8,
|
|
||||||
child: buildIconWeb(
|
|
||||||
icon: SvgPicture.asset(_imagePaths.icCloseMailbox, fit: BoxFit.fill),
|
|
||||||
tooltip: AppLocalizations.of(context).close,
|
|
||||||
onTap: () => controller.closeView(context)))
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildBodyMobile(BuildContext context) {
|
|
||||||
return Stack(
|
|
||||||
children: [
|
|
||||||
Column(children: [
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(top: 16),
|
|
||||||
child: Text(controller.actionType.value == IdentityActionType.create
|
|
||||||
? AppLocalizations.of(context).new_identity.inCaps
|
|
||||||
: AppLocalizations.of(context).edit_identity.inCaps,
|
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 21, color: Colors.black))),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
Expanded(child: KeyboardRichText(
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
controller: controller.scrollController,
|
|
||||||
physics: const ClampingScrollPhysics(),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(24.0),
|
|
||||||
child: Column(children: [
|
|
||||||
Obx(() => (IdentityInputFieldBuilder(
|
|
||||||
AppLocalizations.of(context).name,
|
|
||||||
controller.errorNameIdentity.value,
|
|
||||||
editingController: controller.inputNameIdentityController,
|
|
||||||
focusNode: controller.inputNameIdentityFocusNode,
|
|
||||||
isMandatory: true)
|
|
||||||
..addOnChangeInputNameAction((value) => controller.updateNameIdentity(context, value)))
|
|
||||||
.build()),
|
|
||||||
const SizedBox(height: 24),
|
|
||||||
Obx(() {
|
|
||||||
if (controller.actionType.value == IdentityActionType.create) {
|
|
||||||
return (IdentityDropListFieldBuilder(
|
|
||||||
_imagePaths,
|
|
||||||
AppLocalizations.of(context).email.inCaps,
|
|
||||||
controller.emailOfIdentity.value,
|
|
||||||
controller.listEmailAddressDefault)
|
|
||||||
..addOnSelectEmailAddressDropListAction((emailAddress) =>
|
|
||||||
controller.updateEmailOfIdentity(emailAddress))
|
|
||||||
).build();
|
|
||||||
} else {
|
|
||||||
return IdentityFieldNoEditableBuilder(
|
|
||||||
AppLocalizations.of(context).email.inCaps,
|
|
||||||
controller.emailOfIdentity.value
|
|
||||||
).build();
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
const SizedBox(height: 24),
|
|
||||||
Obx(() => (IdentityDropListFieldBuilder(
|
|
||||||
_imagePaths,
|
|
||||||
AppLocalizations.of(context).reply_to_address,
|
|
||||||
controller.replyToOfIdentity.value,
|
|
||||||
controller.listEmailAddressOfReplyTo)
|
|
||||||
..addOnSelectEmailAddressDropListAction((newEmailAddress) =>
|
|
||||||
controller.updaterReplyToOfIdentity(newEmailAddress)))
|
|
||||||
.build()),
|
|
||||||
const SizedBox(height: 24),
|
|
||||||
Obx(() => (IdentityInputWithDropListFieldBuilder(
|
|
||||||
AppLocalizations.of(context).bcc_to_address,
|
|
||||||
controller.errorBccIdentity.value,
|
|
||||||
controller.inputBccIdentityController)
|
|
||||||
..addOnSelectedSuggestionAction((newEmailAddress) {
|
|
||||||
controller.inputBccIdentityController?.text = newEmailAddress?.email ?? '';
|
|
||||||
controller.updateBccOfIdentity(newEmailAddress);
|
|
||||||
})
|
|
||||||
..addOnChangeInputSuggestionAction((pattern) {
|
|
||||||
controller.validateInputBccAddress(context, pattern);
|
|
||||||
if (pattern == null || pattern.trim().isEmpty) {
|
|
||||||
controller.updateBccOfIdentity(null);
|
|
||||||
} else {
|
|
||||||
controller.updateBccOfIdentity(EmailAddress(null, pattern));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
..addOnSuggestionCallbackAction((pattern) =>
|
|
||||||
controller.getSuggestionEmailAddress(pattern)))
|
|
||||||
.build()
|
|
||||||
),
|
|
||||||
const SizedBox(height: 32),
|
|
||||||
Text(AppLocalizations.of(context).signature,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.normal,
|
|
||||||
fontSize: 14,
|
|
||||||
color: AppColor.colorContentEmail,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
|
||||||
Obx(() => _buildSignatureButton(context, SignatureType.plainText)),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Obx(() => _buildSignatureButton(context, SignatureType.htmlTemplate)),
|
|
||||||
]),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
Obx(() => Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
border: Border.all(color: AppColor.colorInputBorderCreateMailbox),
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16),
|
|
||||||
child: Stack(
|
|
||||||
children: [
|
|
||||||
if (controller.signatureType.value == SignatureType.plainText)
|
|
||||||
_buildSignaturePlainTextTemplate(context)
|
|
||||||
else
|
|
||||||
_buildSignatureHtmlTemplate(context)
|
|
||||||
]
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
const SizedBox(height: 24),
|
|
||||||
Container(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
color: Colors.white,
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: buildTextButton(
|
|
||||||
AppLocalizations.of(context).cancel,
|
|
||||||
textStyle: const TextStyle(
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
fontSize: 17,
|
|
||||||
color: AppColor.colorTextButton,
|
|
||||||
),
|
),
|
||||||
backgroundColor: AppColor.emailAddressChipColor,
|
|
||||||
width: 128,
|
|
||||||
height: 44,
|
|
||||||
radius: 10,
|
|
||||||
onTap: () => controller.closeView(context),
|
|
||||||
),
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Row(mainAxisAlignment: MainAxisAlignment.end, children: [
|
||||||
|
Obx(() => _buildSignatureButton(context, SignatureType.plainText)),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Obx(() => _buildSignatureButton(context, SignatureType.htmlTemplate)),
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Obx(() => Container(
|
||||||
|
height: 160,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
border: Border.all(color: AppColor.colorInputBorderCreateMailbox),
|
||||||
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16),
|
||||||
Expanded(
|
child: Stack(
|
||||||
child: Obx(() => buildTextButton(
|
children: [
|
||||||
controller.actionType.value == IdentityActionType.create
|
if (controller.signatureType.value == SignatureType.plainText)
|
||||||
? AppLocalizations.of(context).create
|
_buildSignaturePlainTextTemplate(context)
|
||||||
: AppLocalizations.of(context).save,
|
else
|
||||||
width: 128,
|
_buildSignatureHtmlTemplate(context)
|
||||||
height: 44,
|
]
|
||||||
radius: 10,
|
|
||||||
onTap: () => controller.createNewIdentity(context))),
|
|
||||||
),
|
),
|
||||||
|
)),
|
||||||
|
if (_responsiveUtils.isTablet(context) || _responsiveUtils.isMobile(context))...[
|
||||||
|
Obx(() => Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 27, bottom: 135),
|
||||||
|
child: SetDefaultIdentityCheckboxBuilder(
|
||||||
|
imagePaths: _imagePaths,
|
||||||
|
isCheck: controller.isDefaultIdentity.value,
|
||||||
|
onCheckboxChanged: controller.onCheckboxChanged),
|
||||||
|
)),
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
color: Colors.white,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: buildTextButton(
|
||||||
|
AppLocalizations.of(context).cancel,
|
||||||
|
textStyle: const TextStyle(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 17,
|
||||||
|
color: AppColor.colorTextButton,
|
||||||
|
),
|
||||||
|
backgroundColor: AppColor.emailAddressChipColor,
|
||||||
|
width: 128,
|
||||||
|
height: 44,
|
||||||
|
radius: 10,
|
||||||
|
onTap: () => controller.closeView(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
Expanded(
|
||||||
|
child: Obx(() => controller.viewState.value.fold(
|
||||||
|
(failure) => buildTextButton(
|
||||||
|
controller.actionType.value == IdentityActionType.create
|
||||||
|
? AppLocalizations.of(context).create
|
||||||
|
: AppLocalizations.of(context).save,
|
||||||
|
width: 128,
|
||||||
|
height: 44,
|
||||||
|
radius: 10,
|
||||||
|
onTap: () => controller.createNewIdentity(context)),
|
||||||
|
(success) {
|
||||||
|
if (success is GetAllIdentitiesLoading) {
|
||||||
|
return const Center(
|
||||||
|
key: Key('create_loading_icon'),
|
||||||
|
child: CircularProgressIndicator(color: AppColor.primaryColor));
|
||||||
|
} else {
|
||||||
|
return buildTextButton(
|
||||||
|
controller.actionType.value == IdentityActionType.create
|
||||||
|
? AppLocalizations.of(context).create
|
||||||
|
: AppLocalizations.of(context).save,
|
||||||
|
width: 128,
|
||||||
|
height: 44,
|
||||||
|
radius: 10,
|
||||||
|
onTap: () => controller.createNewIdentity(context));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
)] else ...[
|
||||||
|
_buildActionBottomDesktop(context)
|
||||||
]
|
]
|
||||||
),
|
]),
|
||||||
)
|
),
|
||||||
]),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
richTextController: controller.keyboardRichTextController,
|
]),
|
||||||
keyBroadToolbar: RichTextKeyboardToolBar(
|
Positioned(top: 2, right: 8,
|
||||||
titleBack: AppLocalizations.of(context).titleFormat,
|
child: buildIconWeb(
|
||||||
backgroundKeyboardToolBarColor: AppColor.colorBackgroundKeyboard,
|
iconSize: 24,
|
||||||
isLandScapeMode: _responsiveUtils.isLandscapeMobile(context),
|
icon: SvgPicture.asset(_imagePaths.icComposerClose, fit: BoxFit.fill, color: AppColor.colorDeleteContactIcon),
|
||||||
richTextController: controller.keyboardRichTextController,
|
tooltip: AppLocalizations.of(context).close,
|
||||||
titleQuickStyleBottomSheet: AppLocalizations.of(context).titleQuickStyles,
|
onTap: () => controller.closeView(context)))
|
||||||
titleBackgroundBottomSheet: AppLocalizations.of(context).titleBackground,
|
]
|
||||||
titleForegroundBottomSheet: AppLocalizations.of(context).titleForeground,
|
),
|
||||||
titleFormatBottomSheet: AppLocalizations.of(context).titleFormat,
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
]),
|
|
||||||
Positioned(top: 8, right: 8,
|
|
||||||
child: buildIconWeb(
|
|
||||||
icon: SvgPicture.asset(_imagePaths.icCloseMailbox, fit: BoxFit.fill),
|
|
||||||
tooltip: AppLocalizations.of(context).close,
|
|
||||||
onTap: () => controller.closeView(context)))
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -522,45 +451,134 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildSignatureHtmlTemplate(BuildContext context) {
|
Widget _buildSignatureHtmlTemplate(BuildContext context) {
|
||||||
if (BuildUtils.isWeb) {
|
final htmlEditor = BuildUtils.isWeb
|
||||||
return html_editor_browser.HtmlEditor(
|
? _buildHtmlEditorWeb(context, controller.contentHtmlEditor ?? '')
|
||||||
key: const Key('signature_html_editor_web'),
|
: _buildHtmlEditor(context, initialContent: controller.contentHtmlEditor ?? '');
|
||||||
controller: controller.signatureHtmlEditorController,
|
|
||||||
htmlEditorOptions: const html_editor_browser.HtmlEditorOptions(
|
return SizedBox(
|
||||||
hint: '',
|
height: 160,
|
||||||
darkMode: false,
|
child: Column(
|
||||||
),
|
children: [
|
||||||
blockQuotedContent: controller.contentHtmlEditor ?? '<p></p>',
|
if(BuildUtils.isWeb)
|
||||||
htmlToolbarOptions: const html_editor_browser.HtmlToolbarOptions(
|
ToolbarRichTextWebBuilder(richTextWebController: controller.richTextWebController),
|
||||||
toolbarPosition: html_editor_browser.ToolbarPosition.custom,
|
htmlEditor,
|
||||||
),
|
],
|
||||||
otherOptions: const html_editor_browser.OtherOptions(height: 230),
|
),
|
||||||
callbacks: html_editor_browser.Callbacks(onInit: () {
|
);
|
||||||
controller.signatureHtmlEditorController.setFullScreen();
|
}
|
||||||
}, onChangeContent: (String? changed) {
|
|
||||||
controller.updateContentHtmlEditor(changed);
|
Widget _buildHtmlEditorWeb(BuildContext context, String initContent) {
|
||||||
}, onFocus: () {
|
log('IdentityCreatorView::_buildHtmlEditorWeb(): initContent: $initContent');
|
||||||
FocusManager.instance.primaryFocus?.unfocus();
|
return Expanded(
|
||||||
Future.delayed(const Duration(milliseconds: 500), () {
|
child: Padding(
|
||||||
controller.signatureHtmlEditorController.setFocus();
|
padding: EdgeInsets.symmetric(
|
||||||
});
|
horizontal: _responsiveUtils.isMobile(context) ? 8 : 10),
|
||||||
}),
|
child: html_editor_browser.HtmlEditor(
|
||||||
);
|
key: const Key('identity_create_editor_web'),
|
||||||
} else {
|
controller: controller.richTextWebController.editorController,
|
||||||
return html_editor_mobile.HtmlEditor(
|
htmlEditorOptions: const HtmlEditorOptions(
|
||||||
key: controller.htmlKey,
|
hint: '',
|
||||||
minHeight: 230,
|
darkMode: false,
|
||||||
onCreated: (htmlEditorController) {
|
customBodyCssStyle: bodyCssStyleForEditor),
|
||||||
controller.keyboardRichTextController.onCreateHTMLEditor(
|
blockQuotedContent: initContent,
|
||||||
htmlEditorController,
|
htmlToolbarOptions: const HtmlToolbarOptions(
|
||||||
onFocus: controller.onFocusHTMLEditor,
|
toolbarType: ToolbarType.hide,
|
||||||
onEnterKeyDown: controller.onEnterKeyDown,
|
defaultToolbarButtons: []),
|
||||||
context: context,
|
otherOptions: const OtherOptions(height: 550),
|
||||||
);
|
callbacks: Callbacks(onBeforeCommand: (currentHtml) {
|
||||||
controller.signatureHtmlEditorMobileController = htmlEditorController;
|
log('IdentityCreatorView::_buildHtmlEditorWeb(): onBeforeCommand : $currentHtml');
|
||||||
|
controller.updateContentHtmlEditor(currentHtml);
|
||||||
|
}, onChangeContent: (changed) {
|
||||||
|
log('IdentityCreatorView::_buildHtmlEditorWeb(): onChangeContent : $changed');
|
||||||
|
controller.updateContentHtmlEditor(changed);
|
||||||
|
}, onInit: () {
|
||||||
|
log('IdentityCreatorView::_buildHtmlEditorWeb(): onInit');
|
||||||
|
controller.updateContentHtmlEditor(initContent);
|
||||||
|
controller.richTextWebController.setFullScreenEditor();
|
||||||
|
controller.richTextWebController.setEnableCodeView();
|
||||||
|
}, onFocus: () {
|
||||||
|
log('IdentityCreatorView::_buildHtmlEditorWeb(): onFocus');
|
||||||
|
FocusManager.instance.primaryFocus?.unfocus();
|
||||||
|
Future.delayed(const Duration(milliseconds: 500), () {
|
||||||
|
controller.richTextWebController.editorController.setFocus();
|
||||||
|
});
|
||||||
|
controller.richTextWebController.closeAllMenuPopup();
|
||||||
|
}, onChangeSelection: (settings) {
|
||||||
|
controller.richTextWebController.onEditorSettingsChange(settings);
|
||||||
|
}, onChangeCodeview: (contentChanged) {
|
||||||
|
log('IdentityCreatorView::_buildHtmlEditorWeb(): onChangeCodeView : $contentChanged');
|
||||||
|
controller.updateContentHtmlEditor(contentChanged);
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildHtmlEditor(BuildContext context, {String? initialContent}) {
|
||||||
|
final richTextMobileTabletController = controller.richTextMobileTabletController;
|
||||||
|
return Focus(
|
||||||
|
focusNode: controller.htmlEditorNode,
|
||||||
|
child: html_editor_mobile.HtmlEditor(
|
||||||
|
key: const Key('identity_create_editor'),
|
||||||
|
minHeight: 111,
|
||||||
|
addDefaultSelectionMenuItems: false,
|
||||||
|
initialContent: initialContent ?? '',
|
||||||
|
onCreated: (editorApi) {
|
||||||
|
richTextMobileTabletController.htmlEditorApi = editorApi;
|
||||||
|
controller.keyboardRichTextController.onCreateHTMLEditor(
|
||||||
|
editorApi,
|
||||||
|
onEnterKeyDown: controller.onEnterKeyDown,
|
||||||
|
context: context,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
initialContent: controller.contentHtmlEditor ?? '',
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildActionBottomDesktop(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
Obx(() {
|
||||||
|
return SetDefaultIdentityCheckboxBuilder(
|
||||||
|
imagePaths: _imagePaths,
|
||||||
|
isCheck: controller.isDefaultIdentity.value,
|
||||||
|
onCheckboxChanged: controller.onCheckboxChanged);
|
||||||
|
}),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 24.0, bottom: 12.0, left: 12.0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 12.0),
|
||||||
|
child: buildTextButton(
|
||||||
|
AppLocalizations.of(context).cancel,
|
||||||
|
textStyle: const TextStyle(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 17,
|
||||||
|
color: AppColor.colorTextButton,
|
||||||
|
),
|
||||||
|
backgroundColor: AppColor.emailAddressChipColor,
|
||||||
|
width: 156,
|
||||||
|
height: 44,
|
||||||
|
radius: 10,
|
||||||
|
onTap: () => controller.closeView(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
buildTextButton(
|
||||||
|
controller.actionType.value == IdentityActionType.create
|
||||||
|
? AppLocalizations.of(context).create
|
||||||
|
: AppLocalizations.of(context).save,
|
||||||
|
width: 156,
|
||||||
|
height: 44,
|
||||||
|
radius: 10,
|
||||||
|
onTap: () => controller.createNewIdentity(context)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,7 @@ extension SignatureTypeExtension on SignatureType {
|
|||||||
case SignatureType.plainText:
|
case SignatureType.plainText:
|
||||||
return AppLocalizations.of(context).plain_text;
|
return AppLocalizations.of(context).plain_text;
|
||||||
case SignatureType.htmlTemplate:
|
case SignatureType.htmlTemplate:
|
||||||
return AppLocalizations.of(context).html_template;
|
return AppLocalizations.of(context).html;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+10
-5
@@ -9,6 +9,7 @@ class IdentityInputFieldBuilder {
|
|||||||
|
|
||||||
final String _label;
|
final String _label;
|
||||||
final String? _error;
|
final String? _error;
|
||||||
|
final String? requiredIndicator;
|
||||||
final TextEditingController? editingController;
|
final TextEditingController? editingController;
|
||||||
final FocusNode? focusNode;
|
final FocusNode? focusNode;
|
||||||
final TextInputType? inputType;
|
final TextInputType? inputType;
|
||||||
@@ -18,7 +19,8 @@ class IdentityInputFieldBuilder {
|
|||||||
|
|
||||||
IdentityInputFieldBuilder(
|
IdentityInputFieldBuilder(
|
||||||
this._label,
|
this._label,
|
||||||
this._error, {
|
this._error,
|
||||||
|
this.requiredIndicator, {
|
||||||
this.isMandatory = false,
|
this.isMandatory = false,
|
||||||
this.editingController,
|
this.editingController,
|
||||||
this.focusNode,
|
this.focusNode,
|
||||||
@@ -31,10 +33,13 @@ class IdentityInputFieldBuilder {
|
|||||||
|
|
||||||
Widget build() {
|
Widget build() {
|
||||||
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||||
Text(isMandatory ? '$_label*' : _label, style: const TextStyle(
|
Text(
|
||||||
fontSize: 14,
|
isMandatory
|
||||||
fontWeight: FontWeight.normal,
|
? '$_label ($requiredIndicator)'
|
||||||
color: AppColor.colorContentEmail)),
|
: _label, style: const TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: AppColor.colorContentEmail)),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
(TextFieldBuilder()
|
(TextFieldBuilder()
|
||||||
..onChange((value) => onChangeInputNameAction?.call(value))
|
..onChange((value) => onChangeInputNameAction?.call(value))
|
||||||
|
|||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:core/presentation/resources/image_paths.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
|
|
||||||
|
typedef OnCheckboxChanged = void Function();
|
||||||
|
|
||||||
|
class SetDefaultIdentityCheckboxBuilder extends StatelessWidget {
|
||||||
|
final ImagePaths imagePaths;
|
||||||
|
final OnCheckboxChanged onCheckboxChanged;
|
||||||
|
final bool isCheck;
|
||||||
|
|
||||||
|
const SetDefaultIdentityCheckboxBuilder(
|
||||||
|
{Key? key,
|
||||||
|
required this.imagePaths,
|
||||||
|
required this.onCheckboxChanged,
|
||||||
|
required this.isCheck})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Material(
|
||||||
|
child: InkWell(
|
||||||
|
onTap: onCheckboxChanged,
|
||||||
|
child: Container(
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(4.0),
|
||||||
|
border: Border.all(color: AppColor.primaryColor, width: 2.0),
|
||||||
|
color: isCheck ? AppColor.primaryColor : Colors.transparent,
|
||||||
|
),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
imagePaths.icSelectedSB,
|
||||||
|
color: isCheck ? Colors.white : Colors.transparent,
|
||||||
|
width: 18,
|
||||||
|
height: 18,
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 8.0),
|
||||||
|
child: Text(
|
||||||
|
AppLocalizations.of(context).setDefaultIdentity,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
fontSize: 14,
|
||||||
|
color: AppColor.colorSettingExplanation,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"@@last_modified": "2023-01-12T18:44:51.610329",
|
"@@last_modified": "2023-01-16T10:06:45.070370",
|
||||||
"initializing_data": "Initializing data...",
|
"initializing_data": "Initializing data...",
|
||||||
"@initializing_data": {
|
"@initializing_data": {
|
||||||
"type": "text",
|
"type": "text",
|
||||||
@@ -1178,6 +1178,12 @@
|
|||||||
"placeholders_order": [],
|
"placeholders_order": [],
|
||||||
"placeholders": {}
|
"placeholders": {}
|
||||||
},
|
},
|
||||||
|
"setDefaultIdentity": "Set as default identity",
|
||||||
|
"@setDefaultIdentity": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders_order": [],
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
"identitiesSettingExplanation": "Select the identity or email address you want to use to send an emails",
|
"identitiesSettingExplanation": "Select the identity or email address you want to use to send an emails",
|
||||||
"@identitiesSettingExplanation": {
|
"@identitiesSettingExplanation": {
|
||||||
"type": "text",
|
"type": "text",
|
||||||
@@ -1202,14 +1208,14 @@
|
|||||||
"placeholders_order": [],
|
"placeholders_order": [],
|
||||||
"placeholders": {}
|
"placeholders": {}
|
||||||
},
|
},
|
||||||
"reply_to_address": "Reply to address",
|
"reply_to": "Reply to",
|
||||||
"@reply_to_address": {
|
"@reply_to": {
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"placeholders_order": [],
|
"placeholders_order": [],
|
||||||
"placeholders": {}
|
"placeholders": {}
|
||||||
},
|
},
|
||||||
"bcc_to_address": "Bcc to address",
|
"bcc_to": "Bcc to",
|
||||||
"@bcc_to_address": {
|
"@bcc_to": {
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"placeholders_order": [],
|
"placeholders_order": [],
|
||||||
"placeholders": {}
|
"placeholders": {}
|
||||||
@@ -1232,6 +1238,12 @@
|
|||||||
"placeholders_order": [],
|
"placeholders_order": [],
|
||||||
"placeholders": {}
|
"placeholders": {}
|
||||||
},
|
},
|
||||||
|
"html": "Html",
|
||||||
|
"@html": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders_order": [],
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
"create": "Create",
|
"create": "Create",
|
||||||
"@create": {
|
"@create": {
|
||||||
"type": "text",
|
"type": "text",
|
||||||
@@ -1244,6 +1256,12 @@
|
|||||||
"placeholders_order": [],
|
"placeholders_order": [],
|
||||||
"placeholders": {}
|
"placeholders": {}
|
||||||
},
|
},
|
||||||
|
"you_have_created_a_new_default_identity": "You have created a new default identity",
|
||||||
|
"@you_have_created_a_new_default_identity": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders_order": [],
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
"all_identities": "All identities",
|
"all_identities": "All identities",
|
||||||
"@all_identities": {
|
"@all_identities": {
|
||||||
"type": "text",
|
"type": "text",
|
||||||
@@ -2552,7 +2570,6 @@
|
|||||||
"placeholders_order": [],
|
"placeholders_order": [],
|
||||||
"placeholders": {}
|
"placeholders": {}
|
||||||
},
|
},
|
||||||
<<<<<<< HEAD
|
|
||||||
"youHaveNewMessages": "You have new messages",
|
"youHaveNewMessages": "You have new messages",
|
||||||
"@youHaveNewMessages": {
|
"@youHaveNewMessages": {
|
||||||
"type": "text",
|
"type": "text",
|
||||||
@@ -2580,5 +2597,11 @@
|
|||||||
"type": "text",
|
"type": "text",
|
||||||
"placeholders_order": [],
|
"placeholders_order": [],
|
||||||
"placeholders": {}
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"required": "required",
|
||||||
|
"@required": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders_order": [],
|
||||||
|
"placeholders": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1212,6 +1212,13 @@ class AppLocalizations {
|
|||||||
name: 'identities');
|
name: 'identities');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get setDefaultIdentity {
|
||||||
|
return Intl.message(
|
||||||
|
'Set as default identity',
|
||||||
|
name: 'setDefaultIdentity'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
String get identitiesSettingExplanation {
|
String get identitiesSettingExplanation {
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
'Select the identity or email address you want to use to send an emails',
|
'Select the identity or email address you want to use to send an emails',
|
||||||
@@ -1235,16 +1242,16 @@ class AppLocalizations {
|
|||||||
name: 'name');
|
name: 'name');
|
||||||
}
|
}
|
||||||
|
|
||||||
String get reply_to_address {
|
String get reply_to {
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
'Reply to address',
|
'Reply to',
|
||||||
name: 'reply_to_address');
|
name: 'reply_to');
|
||||||
}
|
}
|
||||||
|
|
||||||
String get bcc_to_address {
|
String get bcc_to {
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
'Bcc to address',
|
'Bcc to',
|
||||||
name: 'bcc_to_address');
|
name: 'bcc_to');
|
||||||
}
|
}
|
||||||
|
|
||||||
String get signature {
|
String get signature {
|
||||||
@@ -1265,6 +1272,12 @@ class AppLocalizations {
|
|||||||
name: 'html_template');
|
name: 'html_template');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get html {
|
||||||
|
return Intl.message(
|
||||||
|
'Html',
|
||||||
|
name: 'html');
|
||||||
|
}
|
||||||
|
|
||||||
String get create {
|
String get create {
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
'Create',
|
'Create',
|
||||||
@@ -1277,6 +1290,12 @@ class AppLocalizations {
|
|||||||
name: 'you_have_created_a_new_identity');
|
name: 'you_have_created_a_new_identity');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get you_have_created_a_new_default_identity {
|
||||||
|
return Intl.message(
|
||||||
|
'You have created a new default identity',
|
||||||
|
name: 'you_have_created_a_new_default_identity');
|
||||||
|
}
|
||||||
|
|
||||||
String get all_identities {
|
String get all_identities {
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
'All identities',
|
'All identities',
|
||||||
@@ -2683,4 +2702,10 @@ class AppLocalizations {
|
|||||||
name: 'enableSpamReport',
|
name: 'enableSpamReport',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get required {
|
||||||
|
return Intl.message(
|
||||||
|
'required',
|
||||||
|
name: 'required');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -8,8 +8,6 @@ import 'package:tmail_ui_user/features/destination_picker/presentation/destinati
|
|||||||
import 'package:tmail_ui_user/features/destination_picker/presentation/destination_picker_view.dart' deferred as destination_picker;
|
import 'package:tmail_ui_user/features/destination_picker/presentation/destination_picker_view.dart' deferred as destination_picker;
|
||||||
import 'package:tmail_ui_user/features/home/presentation/home_bindings.dart';
|
import 'package:tmail_ui_user/features/home/presentation/home_bindings.dart';
|
||||||
import 'package:tmail_ui_user/features/home/presentation/home_view.dart';
|
import 'package:tmail_ui_user/features/home/presentation/home_view.dart';
|
||||||
import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_bindings.dart';
|
|
||||||
import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_view.dart' deferred as identity_creator;
|
|
||||||
import 'package:tmail_ui_user/features/contact/presentation/contact_view.dart' deferred as contact_view;
|
import 'package:tmail_ui_user/features/contact/presentation/contact_view.dart' deferred as contact_view;
|
||||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/rules_filter_creator_bindings.dart';
|
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/rules_filter_creator_bindings.dart';
|
||||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/rules_filter_creator_view.dart' deferred as rules_filter_creator;
|
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/rules_filter_creator_view.dart' deferred as rules_filter_creator;
|
||||||
@@ -92,13 +90,6 @@ class AppPages {
|
|||||||
contact_view.loadLibrary,
|
contact_view.loadLibrary,
|
||||||
() => contact_view.ContactView()),
|
() => contact_view.ContactView()),
|
||||||
binding: ContactBindings()),
|
binding: ContactBindings()),
|
||||||
GetPage(
|
|
||||||
name: AppRoutes.identityCreator,
|
|
||||||
opaque: false,
|
|
||||||
page: () => DeferredWidget(
|
|
||||||
identity_creator.loadLibrary,
|
|
||||||
() => identity_creator.IdentityCreatorView()),
|
|
||||||
binding: IdentityCreatorBindings()),
|
|
||||||
GetPage(
|
GetPage(
|
||||||
name: AppRoutes.rulesFilterCreator,
|
name: AppRoutes.rulesFilterCreator,
|
||||||
opaque: false,
|
opaque: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user