Compose email with text style for mobile
This commit is contained in:
@@ -20,6 +20,7 @@ import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete
|
|||||||
import 'package:tmail_ui_user/features/composer/domain/usecases/send_email_interactor.dart';
|
import 'package:tmail_ui_user/features/composer/domain/usecases/send_email_interactor.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/controller/rich_text_web_controller.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_web_controller.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_mobile_tablet_controller.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/session_extension.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/extensions/session_extension.dart';
|
||||||
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
|
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
|
||||||
import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart';
|
import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart';
|
||||||
@@ -135,6 +136,7 @@ class ComposerBindings extends BaseBindings {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void bindingsController() {
|
void bindingsController() {
|
||||||
|
Get.lazyPut(() => RichTextMobileTabletController());
|
||||||
Get.lazyPut(() => UploadController(Get.find<UploadAttachmentInteractor>()));
|
Get.lazyPut(() => UploadController(Get.find<UploadAttachmentInteractor>()));
|
||||||
Get.lazyPut(() => RichTextWebController());
|
Get.lazyPut(() => RichTextWebController());
|
||||||
Get.lazyPut(() => ComposerController(
|
Get.lazyPut(() => ComposerController(
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import 'package:tmail_ui_user/features/composer/domain/usecases/save_email_as_dr
|
|||||||
import 'package:tmail_ui_user/features/composer/domain/usecases/send_email_interactor.dart';
|
import 'package:tmail_ui_user/features/composer/domain/usecases/send_email_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/domain/usecases/update_email_drafts_interactor.dart';
|
import 'package:tmail_ui_user/features/composer/domain/usecases/update_email_drafts_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_web_controller.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_web_controller.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_mobile_tablet_controller.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/email_action_type_extension.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/extensions/email_action_type_extension.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/email/domain/state/get_email_content_state.dart';
|
import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart';
|
||||||
@@ -56,6 +57,7 @@ import 'package:universal_html/html.dart' as html;
|
|||||||
class ComposerController extends BaseController {
|
class ComposerController extends BaseController {
|
||||||
|
|
||||||
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
|
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
|
||||||
|
final richTextMobileTabletController = Get.find<RichTextMobileTabletController>();
|
||||||
final _appToast = Get.find<AppToast>();
|
final _appToast = Get.find<AppToast>();
|
||||||
final _imagePaths = Get.find<ImagePaths>();
|
final _imagePaths = Get.find<ImagePaths>();
|
||||||
final _responsiveUtils = Get.find<ResponsiveUtils>();
|
final _responsiveUtils = Get.find<ResponsiveUtils>();
|
||||||
@@ -93,7 +95,6 @@ class ComposerController extends BaseController {
|
|||||||
List<EmailAddress> listCcEmailAddress = <EmailAddress>[];
|
List<EmailAddress> listCcEmailAddress = <EmailAddress>[];
|
||||||
List<EmailAddress> listBccEmailAddress = <EmailAddress>[];
|
List<EmailAddress> listBccEmailAddress = <EmailAddress>[];
|
||||||
ContactSuggestionSource _contactSuggestionSource = ContactSuggestionSource.tMailContact;
|
ContactSuggestionSource _contactSuggestionSource = ContactSuggestionSource.tMailContact;
|
||||||
HtmlEditorApi? htmlEditorApi;
|
|
||||||
|
|
||||||
final subjectEmailInputController = TextEditingController();
|
final subjectEmailInputController = TextEditingController();
|
||||||
final toEmailAddressController = TextEditingController();
|
final toEmailAddressController = TextEditingController();
|
||||||
@@ -108,6 +109,8 @@ class ComposerController extends BaseController {
|
|||||||
|
|
||||||
String? get textEditorWeb => _textEditorWeb;
|
String? get textEditorWeb => _textEditorWeb;
|
||||||
|
|
||||||
|
HtmlEditorApi? get htmlEditorApi => richTextMobileTabletController.htmlEditorApi;
|
||||||
|
|
||||||
void setSubjectEmail(String subject) => subjectEmail.value = subject;
|
void setSubjectEmail(String subject) => subjectEmail.value = subject;
|
||||||
|
|
||||||
Future<String> _getEmailBodyText(BuildContext context, {
|
Future<String> _getEmailBodyText(BuildContext context, {
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import 'package:model/model.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/composer/domain/state/upload_attachment_state.dart';
|
import 'package:tmail_ui_user/features/composer/domain/state/upload_attachment_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/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/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/presentation/extensions/list_upload_file_state_extension.dart';
|
import 'package:tmail_ui_user/features/upload/presentation/extensions/list_upload_file_state_extension.dart';
|
||||||
@@ -20,7 +22,7 @@ import 'package:tmail_ui_user/features/upload/presentation/model/upload_file_sta
|
|||||||
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';
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
|
|
||||||
class ComposerView extends GetWidget<ComposerController> with AppLoaderMixin {
|
class ComposerView extends GetWidget<ComposerController> with AppLoaderMixin, RichTextButtonMixin {
|
||||||
|
|
||||||
final responsiveUtils = Get.find<ResponsiveUtils>();
|
final responsiveUtils = Get.find<ResponsiveUtils>();
|
||||||
final imagePaths = Get.find<ImagePaths>();
|
final imagePaths = Get.find<ImagePaths>();
|
||||||
@@ -461,6 +463,11 @@ class ComposerView extends GetWidget<ComposerController> with AppLoaderMixin {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 60, right: 25),
|
padding: const EdgeInsets.only(left: 60, right: 25),
|
||||||
child: Column(children: [
|
child: Column(children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 22, top: 15),
|
||||||
|
child: Obx(() => _buildRowIconStyleText()),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
Obx(() {
|
Obx(() {
|
||||||
final uploadAttachments = controller.uploadController.listUploadAttachments;
|
final uploadAttachments = controller.uploadController.listUploadAttachments;
|
||||||
if (uploadAttachments.isEmpty) {
|
if (uploadAttachments.isEmpty) {
|
||||||
@@ -490,6 +497,40 @@ class ComposerView extends GetWidget<ComposerController> with AppLoaderMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildRowIconStyleText() {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
buildIconStyleText(
|
||||||
|
path: RichTextStyleType.bold.getIcon(imagePaths),
|
||||||
|
isSelected: controller.richTextMobileTabletController.isTextStyleTypeSelected(RichTextStyleType.bold),
|
||||||
|
onTap: () async {
|
||||||
|
await controller.htmlEditorApi?.formatBold().then((value) {
|
||||||
|
controller.richTextMobileTabletController.selectTextStyleType(RichTextStyleType.bold);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
),
|
||||||
|
buildIconStyleText(
|
||||||
|
path: RichTextStyleType.italic.getIcon(imagePaths),
|
||||||
|
isSelected: controller.richTextMobileTabletController.isTextStyleTypeSelected(RichTextStyleType.italic),
|
||||||
|
onTap: () async {
|
||||||
|
await controller.htmlEditorApi?.formatItalic().then((value) {
|
||||||
|
controller.richTextMobileTabletController.selectTextStyleType(RichTextStyleType.italic);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
),
|
||||||
|
buildIconStyleText(
|
||||||
|
path: RichTextStyleType.underline.getIcon(imagePaths),
|
||||||
|
isSelected: controller.richTextMobileTabletController.isTextStyleTypeSelected(RichTextStyleType.underline),
|
||||||
|
onTap: () async {
|
||||||
|
await controller.htmlEditorApi?.formatUnderline().then((value) {
|
||||||
|
controller.richTextMobileTabletController.selectTextStyleType(RichTextStyleType.underline);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildComposerEditor(BuildContext context) {
|
Widget _buildComposerEditor(BuildContext context) {
|
||||||
return Obx(() {
|
return Obx(() {
|
||||||
final argsComposer = controller.composerArguments.value;
|
final argsComposer = controller.composerArguments.value;
|
||||||
@@ -542,7 +583,10 @@ class ComposerView extends GetWidget<ComposerController> with AppLoaderMixin {
|
|||||||
key: const Key('composer_editor'),
|
key: const Key('composer_editor'),
|
||||||
minHeight: 550,
|
minHeight: 550,
|
||||||
initialContent: initialContent,
|
initialContent: initialContent,
|
||||||
onCreated: (editorApi) => controller.htmlEditorApi = editorApi);
|
onCreated: (editorApi) {
|
||||||
|
controller.richTextMobileTabletController.htmlEditorApi = editorApi;
|
||||||
|
controller.richTextMobileTabletController.listenHtmlEditorApi();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildAttachmentsLoadingView({EdgeInsets? padding, double? size}) {
|
Widget _buildAttachmentsLoadingView({EdgeInsets? padding, double? size}) {
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import 'package:enough_html_editor/enough_html_editor.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/model/rich_text_style_type.dart';
|
||||||
|
|
||||||
|
class RichTextMobileTabletController extends GetxController {
|
||||||
|
HtmlEditorApi? htmlEditorApi;
|
||||||
|
final listTextStyleApply = RxList<RichTextStyleType>();
|
||||||
|
|
||||||
|
void listenHtmlEditorApi() {
|
||||||
|
htmlEditorApi?.onFormatSettingsChanged = (formatSettings) {
|
||||||
|
listTextStyleApply.clear();
|
||||||
|
if (formatSettings.isBold) {
|
||||||
|
listTextStyleApply.add(RichTextStyleType.bold);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formatSettings.isItalic) {
|
||||||
|
listTextStyleApply.add(RichTextStyleType.italic);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formatSettings.isUnderline) {
|
||||||
|
listTextStyleApply.add(RichTextStyleType.underline);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
selectTextStyleType(RichTextStyleType richTextStyleType) {
|
||||||
|
if (listTextStyleApply.contains(richTextStyleType)) {
|
||||||
|
listTextStyleApply.remove(richTextStyleType);
|
||||||
|
} else {
|
||||||
|
listTextStyleApply.add(richTextStyleType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isTextStyleTypeSelected(RichTextStyleType richTextStyleType) {
|
||||||
|
return listTextStyleApply.contains(richTextStyleType);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user