TF-3427 Implement print draft
Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
@@ -234,6 +234,8 @@ extension AppColor on Color {
|
||||
static const colorStarredSearchFilterIcon = Color(0xFFFFCC00);
|
||||
static const colorMobileSearchFilterButton = Color(0xFFEBEDF0);
|
||||
static const colorContactViewClearFilterButton = Color(0x001C3D0D);
|
||||
static const steelGrayA540 = Color(0xFF55687D);
|
||||
static const blue700 = Color(0xFF208BFF);
|
||||
|
||||
static const mapGradientColor = [
|
||||
[Color(0xFF21D4FD), Color(0xFFB721FF)],
|
||||
|
||||
@@ -35,6 +35,7 @@ import 'package:tmail_ui_user/features/email/data/network/email_api.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/repository/email_repository_impl.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/print_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/transform_html_email_content_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/data/datasource/mailbox_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/data/datasource/state_datasource.dart';
|
||||
@@ -226,6 +227,8 @@ class ComposerBindings extends BaseBindings {
|
||||
));
|
||||
Get.lazyPut(() => RestoreEmailInlineImagesInteractor(
|
||||
Get.find<ComposerCacheRepository>()));
|
||||
Get.lazyPut(() => PrintEmailInteractor(
|
||||
Get.find<EmailRepository>()));
|
||||
|
||||
IdentityInteractorsBindings().dependencies();
|
||||
}
|
||||
@@ -251,6 +254,7 @@ class ComposerBindings extends BaseBindings {
|
||||
Get.find<GetAlwaysReadReceiptSettingInteractor>(),
|
||||
Get.find<CreateNewAndSendEmailInteractor>(),
|
||||
Get.find<CreateNewAndSaveEmailToDraftsInteractor>(),
|
||||
Get.find<PrintEmailInteractor>(),
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ import 'package:tmail_ui_user/features/email/domain/exceptions/email_exceptions.
|
||||
import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/transform_html_email_content_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/print_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/transform_html_email_content_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/extensions/presentation_email_extension.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
|
||||
@@ -127,6 +128,7 @@ class ComposerController extends BaseController
|
||||
final bccRecipientState = PrefixRecipientState.disabled.obs;
|
||||
final identitySelected = Rxn<Identity>();
|
||||
final listFromIdentities = RxList<Identity>();
|
||||
final isEmailChanged = Rx<bool>(false);
|
||||
|
||||
final LocalFilePickerInteractor _localFilePickerInteractor;
|
||||
final LocalImagePickerInteractor _localImagePickerInteractor;
|
||||
@@ -140,6 +142,7 @@ class ComposerController extends BaseController
|
||||
final GetAlwaysReadReceiptSettingInteractor _getAlwaysReadReceiptSettingInteractor;
|
||||
final CreateNewAndSendEmailInteractor _createNewAndSendEmailInteractor;
|
||||
final CreateNewAndSaveEmailToDraftsInteractor _createNewAndSaveEmailToDraftsInteractor;
|
||||
final PrintEmailInteractor printEmailInteractor;
|
||||
|
||||
GetAllAutoCompleteInteractor? _getAllAutoCompleteInteractor;
|
||||
GetAutoCompleteInteractor? _getAutoCompleteInteractor;
|
||||
@@ -196,6 +199,7 @@ class ComposerController extends BaseController
|
||||
ButtonState _closeComposerButtonState = ButtonState.enabled;
|
||||
ButtonState _saveToDraftButtonState = ButtonState.enabled;
|
||||
ButtonState _sendButtonState = ButtonState.enabled;
|
||||
ButtonState printDraftButtonState = ButtonState.enabled;
|
||||
SignatureStatus _identityContentOnOpenPolicy = SignatureStatus.editedAvailable;
|
||||
int? _savedEmailDraftHash;
|
||||
bool _restoringSignatureButton = false;
|
||||
@@ -224,6 +228,7 @@ class ComposerController extends BaseController
|
||||
this._getAlwaysReadReceiptSettingInteractor,
|
||||
this._createNewAndSendEmailInteractor,
|
||||
this._createNewAndSaveEmailToDraftsInteractor,
|
||||
this.printEmailInteractor,
|
||||
);
|
||||
|
||||
@override
|
||||
@@ -452,7 +457,7 @@ class ComposerController extends BaseController
|
||||
return null;
|
||||
}
|
||||
|
||||
final emailContent = await _getContentInEditor();
|
||||
final emailContent = await getContentInEditor();
|
||||
|
||||
return CreateEmailRequest(
|
||||
session: mailboxDashBoardController.sessionCurrent!,
|
||||
@@ -968,7 +973,7 @@ class ComposerController extends BaseController
|
||||
_handleSendMessages(context);
|
||||
}
|
||||
|
||||
Future<String> _getContentInEditor() async {
|
||||
Future<String> getContentInEditor() async {
|
||||
try {
|
||||
final htmlTextEditor = PlatformInfo.isWeb
|
||||
? _textEditorWeb
|
||||
@@ -977,7 +982,7 @@ class ComposerController extends BaseController
|
||||
? htmlTextEditor!.removeEditorStartTag()
|
||||
: '';
|
||||
} catch (e) {
|
||||
logError('ComposerController::_getContentInEditor:Exception = $e');
|
||||
logError('ComposerController::getContentInEditor:Exception = $e');
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -997,7 +1002,7 @@ class ComposerController extends BaseController
|
||||
popBack();
|
||||
}
|
||||
|
||||
final emailContent = await _getContentInEditor();
|
||||
final emailContent = await getContentInEditor();
|
||||
final cancelToken = CancelToken();
|
||||
final resultState = await _showSendingMessageDialog(
|
||||
emailContent: emailContent,
|
||||
@@ -1239,7 +1244,7 @@ class ComposerController extends BaseController
|
||||
}
|
||||
|
||||
Future<int> _hashDraftEmail() async {
|
||||
final emailContent = await _getContentInEditor();
|
||||
final emailContent = await getContentInEditor();
|
||||
|
||||
final savedEmailDraft = SavedEmailDraft(
|
||||
subject: subjectEmail.value ?? '',
|
||||
@@ -1255,18 +1260,21 @@ class ComposerController extends BaseController
|
||||
return savedEmailDraft.hashCode;
|
||||
}
|
||||
|
||||
int get emptyDraftEmailHash => SavedEmailDraft.empty().hashCode;
|
||||
|
||||
Future<void> _updateSavedEmailDraftHash() async {
|
||||
_savedEmailDraftHash = await _hashDraftEmail();
|
||||
}
|
||||
|
||||
Future<void> _initEmailDraftHash() async {
|
||||
if (composerArguments.value?.emailActionType != EmailActionType.compose
|
||||
&& composerArguments.value?.emailActionType != EmailActionType.editDraft
|
||||
) {
|
||||
return;
|
||||
}
|
||||
final draftEmailHash = await _hashDraftEmail();
|
||||
|
||||
_savedEmailDraftHash = await _hashDraftEmail();
|
||||
isEmailChanged.value = draftEmailHash != emptyDraftEmailHash;
|
||||
|
||||
if (composerArguments.value?.emailActionType == EmailActionType.compose ||
|
||||
composerArguments.value?.emailActionType == EmailActionType.editDraft) {
|
||||
_savedEmailDraftHash = await _hashDraftEmail();
|
||||
}
|
||||
}
|
||||
|
||||
void handleClickSaveAsDraftsButton(BuildContext context) async {
|
||||
@@ -1287,7 +1295,7 @@ class ComposerController extends BaseController
|
||||
return;
|
||||
}
|
||||
|
||||
final emailContent = await _getContentInEditor();
|
||||
final emailContent = await getContentInEditor();
|
||||
final cancelToken = CancelToken();
|
||||
final resultState = await _showSavingMessageToDraftsDialog(
|
||||
emailContent: emailContent,
|
||||
@@ -2268,7 +2276,7 @@ class ComposerController extends BaseController
|
||||
|
||||
popBack();
|
||||
|
||||
final emailContent = await _getContentInEditor();
|
||||
final emailContent = await getContentInEditor();
|
||||
final draftEmailId = _getDraftEmailId();
|
||||
log('ComposerController::_handleSaveMessageToDraft: draftEmailId = $draftEmailId');
|
||||
final cancelToken = CancelToken();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/views/responsive/responsive_widget.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -6,6 +7,7 @@ import 'package:model/email/prefix_email_address.dart';
|
||||
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/popup_item_widget.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/composer_print_draft_extension.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/model/prefix_recipient_state.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/styles/composer_style.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/view/web/desktop_responsive_container_view.dart';
|
||||
@@ -43,6 +45,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Obx(() => MobileResponsiveAppBarComposerWidget(
|
||||
imagePaths: controller.imagePaths,
|
||||
isCodeViewEnabled: controller.richTextWebController!.codeViewEnabled,
|
||||
isFormattingOptionsEnabled: controller.richTextWebController!.isFormattingOptionsEnabled,
|
||||
openRichToolbarAction: controller.richTextWebController!.toggleFormattingOptions,
|
||||
@@ -509,6 +512,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
),
|
||||
),
|
||||
Obx(() => BottomBarComposerWidget(
|
||||
imagePaths: controller.imagePaths,
|
||||
isCodeViewEnabled: controller.richTextWebController!.codeViewEnabled,
|
||||
isFormattingOptionsEnabled: controller.richTextWebController!.isFormattingOptionsEnabled,
|
||||
hasReadReceipt: controller.hasRequestReadReceipt.value,
|
||||
@@ -520,6 +524,8 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
saveToDraftAction: () => controller.handleClickSaveAsDraftsButton(context),
|
||||
sendMessageAction: () => controller.handleClickSendButton(context),
|
||||
requestReadReceiptAction: () => controller.toggleRequestReadReceipt(context),
|
||||
isPrintDraftEnabled: controller.isEmailChanged.isTrue,
|
||||
onPrintDraftAction: () => controller.printDraft(context),
|
||||
)),
|
||||
],
|
||||
),
|
||||
@@ -788,6 +794,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
),
|
||||
),
|
||||
Obx(() => BottomBarComposerWidget(
|
||||
imagePaths: controller.imagePaths,
|
||||
isCodeViewEnabled: controller.richTextWebController!.codeViewEnabled,
|
||||
isFormattingOptionsEnabled: controller.richTextWebController!.isFormattingOptionsEnabled,
|
||||
hasReadReceipt: controller.hasRequestReadReceipt.value,
|
||||
@@ -799,6 +806,8 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
saveToDraftAction: () => controller.handleClickSaveAsDraftsButton(context),
|
||||
sendMessageAction: () => controller.handleClickSendButton(context),
|
||||
requestReadReceiptAction: () => controller.toggleRequestReadReceipt(context),
|
||||
isPrintDraftEnabled: controller.isEmailChanged.isTrue,
|
||||
onPrintDraftAction: () => controller.printDraft(context),
|
||||
)),
|
||||
],
|
||||
),
|
||||
@@ -893,6 +902,21 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
}
|
||||
)
|
||||
),
|
||||
if (controller.isEmailChanged.isTrue)
|
||||
PopupMenuItem(
|
||||
padding: EdgeInsets.zero,
|
||||
child: PopupItemWidget(
|
||||
controller.imagePaths.icPrinter,
|
||||
AppLocalizations.of(context).print,
|
||||
colorIcon: AppColor.steelGrayA540,
|
||||
styleName: ComposerStyle.popupItemTextStyle,
|
||||
padding: ComposerStyle.popupItemPadding,
|
||||
onCallbackAction: () {
|
||||
popBack();
|
||||
controller.printDraft(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
PopupMenuItem(
|
||||
padding: EdgeInsets.zero,
|
||||
child: PopupItemWidget(
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
|
||||
import 'package:core/domain/extensions/datetime_extension.dart';
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:model/extensions/list_email_address_extension.dart';
|
||||
import 'package:model/extensions/presentation_email_extension.dart';
|
||||
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||
import 'package:tmail_ui_user/features/base/state/button_state.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/widgets/web/print_draft_dialog_view.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/model/email_print.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/print_email_state.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
extension ComposerPrintDraftExtension on ComposerController {
|
||||
|
||||
Future<void> printDraft(BuildContext context) async {
|
||||
if (printDraftButtonState == ButtonState.disabled) {
|
||||
log('ComposerPrintDraftExtension::printDraft: Printing draft');
|
||||
return;
|
||||
}
|
||||
printDraftButtonState = ButtonState.disabled;
|
||||
|
||||
if (composerArguments.value == null ||
|
||||
mailboxDashBoardController.sessionCurrent == null ||
|
||||
mailboxDashBoardController.accountId.value == null) {
|
||||
log('ComposerPrintDraftExtension::printDraft: SESSION or ACCOUNT_ID or ARGUMENTS is NULL');
|
||||
printDraftButtonState = ButtonState.enabled;
|
||||
return;
|
||||
}
|
||||
|
||||
final locale = Localizations.localeOf(context);
|
||||
final appLocalizations = AppLocalizations.of(context);
|
||||
|
||||
final emailContent = await getContentInEditor();
|
||||
|
||||
final resultState = await _showPrintDraftsDialog(
|
||||
appLocalizations: appLocalizations,
|
||||
locale: locale,
|
||||
emailContent: emailContent,
|
||||
);
|
||||
|
||||
if (resultState is PrintEmailFailure) {
|
||||
printDraftButtonState = ButtonState.enabled;
|
||||
|
||||
if (context.mounted) {
|
||||
appToast.showToastErrorMessage(context, appLocalizations.printingFailed);
|
||||
}
|
||||
} else if (resultState is PrintEmailSuccess) {
|
||||
printDraftButtonState = ButtonState.enabled;
|
||||
}
|
||||
}
|
||||
|
||||
Future<dynamic> _showPrintDraftsDialog({
|
||||
required AppLocalizations appLocalizations,
|
||||
required Locale locale,
|
||||
required String emailContent,
|
||||
}) {
|
||||
final presentationEmail = composerArguments.value!.presentationEmail;
|
||||
|
||||
final childWidget = PointerInterceptor(
|
||||
child: PrintDraftDialogView(
|
||||
emailPrint: EmailPrint(
|
||||
appName: appLocalizations.app_name,
|
||||
userName: mailboxDashBoardController.userEmail,
|
||||
attachments: uploadController.attachmentsUploaded,
|
||||
emailContent: emailContent,
|
||||
locale: locale.toLanguageTag(),
|
||||
fromPrefix: appLocalizations.from_email_address_prefix,
|
||||
toPrefix: appLocalizations.to_email_address_prefix,
|
||||
ccPrefix: appLocalizations.cc_email_address_prefix,
|
||||
bccPrefix: appLocalizations.bcc_email_address_prefix,
|
||||
replyToPrefix: appLocalizations.replyToEmailAddressPrefix,
|
||||
titleAttachment: appLocalizations.attachments.toLowerCase(),
|
||||
toAddress: listToEmailAddress.toSet().toEscapeHtmlStringUseCommaSeparator(),
|
||||
ccAddress: listCcEmailAddress.toSet().toEscapeHtmlStringUseCommaSeparator(),
|
||||
bccAddress: listBccEmailAddress.toSet().toEscapeHtmlStringUseCommaSeparator(),
|
||||
sender: composerArguments.value!.presentationEmail?.from?.isNotEmpty == true
|
||||
? composerArguments.value!.presentationEmail?.from!.first
|
||||
: null,
|
||||
receiveTime: presentationEmail?.getReceivedAt(
|
||||
locale.toLanguageTag(),
|
||||
pattern: presentationEmail.receivedAt
|
||||
?.value
|
||||
.toLocal()
|
||||
.toPatternForPrinting(locale.toLanguageTag()),
|
||||
) ?? '',
|
||||
subject: presentationEmail?.subject,
|
||||
),
|
||||
printEmailInteractor: printEmailInteractor,
|
||||
),
|
||||
);
|
||||
|
||||
return Get.dialog(
|
||||
childWidget,
|
||||
barrierDismissible: false,
|
||||
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,20 @@ class SavedEmailDraft with EquatableMixin {
|
||||
required this.identity,
|
||||
required this.hasReadReceipt,
|
||||
});
|
||||
|
||||
|
||||
factory SavedEmailDraft.empty() {
|
||||
return SavedEmailDraft(
|
||||
subject: '',
|
||||
content: '',
|
||||
toRecipients: {},
|
||||
ccRecipients: {},
|
||||
bccRecipients: {},
|
||||
attachments: [],
|
||||
identity: null,
|
||||
hasReadReceipt: false,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
content,
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:core/presentation/views/button/tmail_button_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/styles/web/bottom_bar_composer_widget_style.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class BottomBarComposerWidget extends StatelessWidget {
|
||||
|
||||
final ImagePaths imagePaths;
|
||||
final bool isCodeViewEnabled;
|
||||
final bool isPrintDraftEnabled;
|
||||
final bool isFormattingOptionsEnabled;
|
||||
final bool hasReadReceipt;
|
||||
final VoidCallback openRichToolbarAction;
|
||||
@@ -18,12 +20,13 @@ class BottomBarComposerWidget extends StatelessWidget {
|
||||
final VoidCallback saveToDraftAction;
|
||||
final VoidCallback sendMessageAction;
|
||||
final VoidCallback requestReadReceiptAction;
|
||||
final VoidCallback onPrintDraftAction;
|
||||
|
||||
final _imagePaths = Get.find<ImagePaths>();
|
||||
|
||||
BottomBarComposerWidget({
|
||||
const BottomBarComposerWidget({
|
||||
super.key,
|
||||
required this.imagePaths,
|
||||
required this.isCodeViewEnabled,
|
||||
required this.isPrintDraftEnabled,
|
||||
required this.isFormattingOptionsEnabled,
|
||||
required this.hasReadReceipt,
|
||||
required this.openRichToolbarAction,
|
||||
@@ -34,6 +37,7 @@ class BottomBarComposerWidget extends StatelessWidget {
|
||||
required this.saveToDraftAction,
|
||||
required this.sendMessageAction,
|
||||
required this.requestReadReceiptAction,
|
||||
required this.onPrintDraftAction,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -45,7 +49,7 @@ class BottomBarComposerWidget extends StatelessWidget {
|
||||
child: Row(
|
||||
children: [
|
||||
TMailButtonWidget.fromIcon(
|
||||
icon: _imagePaths.icRichToolbar,
|
||||
icon: imagePaths.icRichToolbar,
|
||||
borderRadius: BottomBarComposerWidgetStyle.iconRadius,
|
||||
padding: BottomBarComposerWidgetStyle.richTextIconPadding,
|
||||
backgroundColor: isFormattingOptionsEnabled
|
||||
@@ -60,7 +64,7 @@ class BottomBarComposerWidget extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(width: BottomBarComposerWidgetStyle.space),
|
||||
TMailButtonWidget.fromIcon(
|
||||
icon: _imagePaths.icAttachFile,
|
||||
icon: imagePaths.icAttachFile,
|
||||
iconColor: BottomBarComposerWidgetStyle.iconColor,
|
||||
borderRadius: BottomBarComposerWidgetStyle.iconRadius,
|
||||
backgroundColor: Colors.transparent,
|
||||
@@ -73,7 +77,7 @@ class BottomBarComposerWidget extends StatelessWidget {
|
||||
AbsorbPointer(
|
||||
absorbing: isCodeViewEnabled,
|
||||
child: TMailButtonWidget.fromIcon(
|
||||
icon: _imagePaths.icInsertImage,
|
||||
icon: imagePaths.icInsertImage,
|
||||
iconColor: BottomBarComposerWidgetStyle.iconColor,
|
||||
borderRadius: BottomBarComposerWidgetStyle.iconRadius,
|
||||
backgroundColor: Colors.transparent,
|
||||
@@ -85,7 +89,7 @@ class BottomBarComposerWidget extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(width: BottomBarComposerWidgetStyle.space),
|
||||
TMailButtonWidget.fromIcon(
|
||||
icon: _imagePaths.icStyleCodeView,
|
||||
icon: imagePaths.icStyleCodeView,
|
||||
iconColor: isCodeViewEnabled
|
||||
? BottomBarComposerWidgetStyle.selectedIconColor
|
||||
: BottomBarComposerWidgetStyle.iconColor,
|
||||
@@ -100,7 +104,7 @@ class BottomBarComposerWidget extends StatelessWidget {
|
||||
),
|
||||
const Spacer(),
|
||||
TMailButtonWidget.fromIcon(
|
||||
icon: _imagePaths.icDeleteMailbox,
|
||||
icon: imagePaths.icDeleteMailbox,
|
||||
borderRadius: BottomBarComposerWidgetStyle.iconRadius,
|
||||
padding: BottomBarComposerWidgetStyle.iconPadding,
|
||||
iconSize: BottomBarComposerWidgetStyle.iconSize,
|
||||
@@ -109,7 +113,7 @@ class BottomBarComposerWidget extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(width: BottomBarComposerWidgetStyle.space),
|
||||
TMailButtonWidget.fromIcon(
|
||||
icon: _imagePaths.icReadReceipt,
|
||||
icon: imagePaths.icReadReceipt,
|
||||
borderRadius: BottomBarComposerWidgetStyle.iconRadius,
|
||||
padding: BottomBarComposerWidgetStyle.iconPadding,
|
||||
iconSize: BottomBarComposerWidgetStyle.iconSize,
|
||||
@@ -122,8 +126,21 @@ class BottomBarComposerWidget extends StatelessWidget {
|
||||
onTapActionCallback: requestReadReceiptAction,
|
||||
),
|
||||
const SizedBox(width: BottomBarComposerWidgetStyle.space),
|
||||
if (isPrintDraftEnabled)
|
||||
TMailButtonWidget.fromIcon(
|
||||
icon: imagePaths.icPrinter,
|
||||
borderRadius: BottomBarComposerWidgetStyle.iconRadius,
|
||||
padding: BottomBarComposerWidgetStyle.iconPadding,
|
||||
iconSize: BottomBarComposerWidgetStyle.iconSize,
|
||||
iconColor: AppColor.steelGrayA540,
|
||||
margin: const EdgeInsetsDirectional.only(
|
||||
end: BottomBarComposerWidgetStyle.space,
|
||||
),
|
||||
tooltipMessage: AppLocalizations.of(context).print,
|
||||
onTapActionCallback: onPrintDraftAction,
|
||||
),
|
||||
TMailButtonWidget.fromIcon(
|
||||
icon: _imagePaths.icSaveToDraft,
|
||||
icon: imagePaths.icSaveToDraft,
|
||||
borderRadius: BottomBarComposerWidgetStyle.iconRadius,
|
||||
padding: BottomBarComposerWidgetStyle.iconPadding,
|
||||
iconSize: BottomBarComposerWidgetStyle.iconSize,
|
||||
@@ -133,7 +150,7 @@ class BottomBarComposerWidget extends StatelessWidget {
|
||||
const SizedBox(width: BottomBarComposerWidgetStyle.sendButtonSpace),
|
||||
TMailButtonWidget(
|
||||
text: AppLocalizations.of(context).send,
|
||||
icon: _imagePaths.icSend,
|
||||
icon: imagePaths.icSend,
|
||||
iconAlignment: TextDirection.rtl,
|
||||
padding: BottomBarComposerWidgetStyle.sendButtonPadding,
|
||||
iconSize: BottomBarComposerWidgetStyle.iconSize,
|
||||
|
||||
+10
-11
@@ -1,7 +1,6 @@
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:core/presentation/views/button/tmail_button_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/styles/mobile_app_bar_composer_widget_style.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
@@ -9,6 +8,7 @@ typedef OnOpenContextMenuAction = Function(RelativeRect position);
|
||||
|
||||
class MobileResponsiveAppBarComposerWidget extends StatelessWidget {
|
||||
|
||||
final ImagePaths imagePaths;
|
||||
final bool isCodeViewEnabled;
|
||||
final bool isSendButtonEnabled;
|
||||
final bool isFormattingOptionsEnabled;
|
||||
@@ -19,10 +19,9 @@ class MobileResponsiveAppBarComposerWidget extends StatelessWidget {
|
||||
final OnOpenContextMenuAction openContextMenuAction;
|
||||
final VoidCallback openRichToolbarAction;
|
||||
|
||||
final _imagePaths = Get.find<ImagePaths>();
|
||||
|
||||
MobileResponsiveAppBarComposerWidget({
|
||||
const MobileResponsiveAppBarComposerWidget({
|
||||
super.key,
|
||||
required this.imagePaths,
|
||||
required this.isCodeViewEnabled,
|
||||
required this.isFormattingOptionsEnabled,
|
||||
required this.isSendButtonEnabled,
|
||||
@@ -43,7 +42,7 @@ class MobileResponsiveAppBarComposerWidget extends StatelessWidget {
|
||||
child: Row(
|
||||
children: [
|
||||
TMailButtonWidget.fromIcon(
|
||||
icon: _imagePaths.icCancel,
|
||||
icon: imagePaths.icCancel,
|
||||
backgroundColor: Colors.transparent,
|
||||
tooltipMessage: AppLocalizations.of(context).saveAndClose,
|
||||
iconSize: MobileAppBarComposerWidgetStyle.iconSize,
|
||||
@@ -52,7 +51,7 @@ class MobileResponsiveAppBarComposerWidget extends StatelessWidget {
|
||||
),
|
||||
const Spacer(),
|
||||
TMailButtonWidget.fromIcon(
|
||||
icon: _imagePaths.icRichToolbar,
|
||||
icon: imagePaths.icRichToolbar,
|
||||
padding: MobileAppBarComposerWidgetStyle.richTextIconPadding,
|
||||
backgroundColor: isFormattingOptionsEnabled
|
||||
? MobileAppBarComposerWidgetStyle.selectedBackgroundColor
|
||||
@@ -66,7 +65,7 @@ class MobileResponsiveAppBarComposerWidget extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(width: MobileAppBarComposerWidgetStyle.space),
|
||||
TMailButtonWidget.fromIcon(
|
||||
icon: _imagePaths.icAttachFile,
|
||||
icon: imagePaths.icAttachFile,
|
||||
iconColor: MobileAppBarComposerWidgetStyle.iconColor,
|
||||
backgroundColor: Colors.transparent,
|
||||
iconSize: MobileAppBarComposerWidgetStyle.iconSize,
|
||||
@@ -76,7 +75,7 @@ class MobileResponsiveAppBarComposerWidget extends StatelessWidget {
|
||||
const SizedBox(width: MobileAppBarComposerWidgetStyle.space),
|
||||
if (!isCodeViewEnabled)
|
||||
TMailButtonWidget.fromIcon(
|
||||
icon: _imagePaths.icInsertImage,
|
||||
icon: imagePaths.icInsertImage,
|
||||
iconColor: MobileAppBarComposerWidgetStyle.iconColor,
|
||||
backgroundColor: Colors.transparent,
|
||||
iconSize: MobileAppBarComposerWidgetStyle.iconSize,
|
||||
@@ -86,8 +85,8 @@ class MobileResponsiveAppBarComposerWidget extends StatelessWidget {
|
||||
const SizedBox(width: MobileAppBarComposerWidgetStyle.space),
|
||||
TMailButtonWidget.fromIcon(
|
||||
icon: isSendButtonEnabled
|
||||
? _imagePaths.icSendMobile
|
||||
: _imagePaths.icSendDisable,
|
||||
? imagePaths.icSendMobile
|
||||
: imagePaths.icSendDisable,
|
||||
backgroundColor: Colors.transparent,
|
||||
padding: MobileAppBarComposerWidgetStyle.iconPadding,
|
||||
iconSize: MobileAppBarComposerWidgetStyle.sendButtonIconSize,
|
||||
@@ -96,7 +95,7 @@ class MobileResponsiveAppBarComposerWidget extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(width: MobileAppBarComposerWidgetStyle.space),
|
||||
TMailButtonWidget.fromIcon(
|
||||
icon: _imagePaths.icMore,
|
||||
icon: imagePaths.icMore,
|
||||
iconColor: MobileAppBarComposerWidgetStyle.iconColor,
|
||||
backgroundColor: Colors.transparent,
|
||||
iconSize: MobileAppBarComposerWidgetStyle.iconSize,
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:dartz/dartz.dart' as dartz;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/model/email_print.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/print_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/print_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
||||
|
||||
class PrintDraftDialogView extends StatefulWidget {
|
||||
|
||||
final EmailPrint emailPrint;
|
||||
final PrintEmailInteractor printEmailInteractor;
|
||||
|
||||
const PrintDraftDialogView({
|
||||
super.key,
|
||||
required this.emailPrint,
|
||||
required this.printEmailInteractor,
|
||||
});
|
||||
|
||||
@override
|
||||
State<PrintDraftDialogView> createState() => _PrintDraftDialogViewState();
|
||||
}
|
||||
|
||||
class _PrintDraftDialogViewState extends State<PrintDraftDialogView> {
|
||||
|
||||
StreamSubscription? _streamSubscription;
|
||||
final ValueNotifier<dartz.Either<Failure, Success>?> _viewStateNotifier = ValueNotifier(null);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_streamSubscription = widget.printEmailInteractor
|
||||
.execute(widget.emailPrint)
|
||||
.listen(
|
||||
_handleDataStream,
|
||||
onError: _handleErrorStream
|
||||
);
|
||||
}
|
||||
|
||||
void _handleDataStream(dartz.Either<Failure, Success> newState) {
|
||||
_viewStateNotifier.value = newState;
|
||||
|
||||
newState.fold(
|
||||
(failure) {
|
||||
if (failure is PrintEmailFailure) {
|
||||
popBack(result: failure);
|
||||
}
|
||||
},
|
||||
(success) {
|
||||
if (success is PrintEmailSuccess) {
|
||||
popBack(result: success);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void _handleErrorStream(Object error, StackTrace stackTrace) {
|
||||
logError('_PrintDraftDialogViewState::_handleErrorStream: Exception = $error');
|
||||
popBack(result: PrintEmailFailure(exception: error));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Dialog(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(12))),
|
||||
insetPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 24.0,
|
||||
vertical: 16.0
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||
color: Colors.white,
|
||||
),
|
||||
width: min(context.width, 400),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
width: double.infinity,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
padding: const EdgeInsetsDirectional.symmetric(vertical: 8, horizontal: 12),
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||
color: AppColor.colorItemSelected,
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
AppLocalizations.of(context).print,
|
||||
style: Theme.of(context).textTheme.labelLarge?.copyWith(
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 17
|
||||
),
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 16, end: 16, top: 12, bottom: 4),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'${AppLocalizations.of(context).status}:',
|
||||
style: Theme.of(context).textTheme.labelMedium?.copyWith(
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: _viewStateNotifier,
|
||||
builder: (context, value, child) {
|
||||
if (value == null) {
|
||||
return child!;
|
||||
}
|
||||
|
||||
return value.fold(
|
||||
(failure) => child!,
|
||||
(success) {
|
||||
return Text(
|
||||
'${_getStatusMessage(success)}...',
|
||||
style: Theme.of(context).textTheme.labelSmall?.copyWith(
|
||||
color: AppColor.labelColor,
|
||||
fontSize: 14
|
||||
),
|
||||
);
|
||||
}
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
'...',
|
||||
style: Theme.of(context).textTheme.labelSmall?.copyWith(
|
||||
color: AppColor.labelColor,
|
||||
fontSize: 14
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 16, end: 16, top: 4, bottom: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'${AppLocalizations.of(context).progress}:',
|
||||
style: Theme.of(context).textTheme.labelMedium?.copyWith(
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: LinearProgressIndicator(
|
||||
color: Colors.white.withOpacity(0.6),
|
||||
backgroundColor: AppColor.primaryColor,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _getStatusMessage(Success success) {
|
||||
if (success is PrintEmailLoading) {
|
||||
return AppLocalizations.of(context).printingInProgress;
|
||||
} else {
|
||||
return AppLocalizations.of(context).printingFailed;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_streamSubscription?.cancel();
|
||||
_viewStateNotifier.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'package:core/data/model/print_attachment.dart';
|
||||
import 'package:core/domain/extensions/datetime_extension.dart';
|
||||
import 'package:core/presentation/extensions/html_extension.dart';
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:core/presentation/utils/html_transformer/transform_configuration.dart';
|
||||
@@ -8,7 +7,6 @@ import 'package:core/utils/file_utils.dart';
|
||||
import 'package:core/utils/print_utils.dart';
|
||||
import 'package:filesize/filesize.dart';
|
||||
import 'package:model/email/attachment.dart';
|
||||
import 'package:model/extensions/email_extension.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource/print_file_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/model/email_print.dart';
|
||||
@@ -37,14 +35,6 @@ class PrintFileDataSourceImpl extends PrintFileDataSource {
|
||||
final emailContentEscaped = await _transformHtmlEmailContent(
|
||||
emailPrint.emailContent);
|
||||
|
||||
final sender = emailPrint.emailInformation.from?.isNotEmpty == true
|
||||
? emailPrint.emailInformation.from!.first
|
||||
: null;
|
||||
final receiveTime = emailPrint.emailInformation.getReceivedAt(
|
||||
newLocale: emailPrint.locale,
|
||||
pattern: emailPrint.emailInformation.receivedAt?.value.toLocal().toPatternForPrinting(emailPrint.locale)
|
||||
);
|
||||
|
||||
final List<PrintAttachment> listPrintAttachment = [];
|
||||
|
||||
if (emailPrint.attachments?.isNotEmpty == true) {
|
||||
@@ -62,11 +52,11 @@ class PrintFileDataSourceImpl extends PrintFileDataSource {
|
||||
return await _printUtils.printEmail(
|
||||
appName: emailPrint.appName,
|
||||
userName: emailPrint.userName,
|
||||
subject: emailPrint.emailInformation.subject?.escapeLtGtHtmlString() ?? '',
|
||||
subject: emailPrint.subject?.escapeLtGtHtmlString() ?? '',
|
||||
emailContent: emailContentEscaped,
|
||||
senderName: sender?.name.escapeLtGtHtmlString() ?? '',
|
||||
senderEmailAddress: sender?.email ?? '',
|
||||
dateTime: receiveTime,
|
||||
senderName: emailPrint.sender?.name.escapeLtGtHtmlString() ?? '',
|
||||
senderEmailAddress: emailPrint.sender?.email ?? '',
|
||||
dateTime: emailPrint.receiveTime,
|
||||
fromPrefix: emailPrint.fromPrefix,
|
||||
toPrefix: emailPrint.toPrefix,
|
||||
ccPrefix: emailPrint.ccPrefix,
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||
import 'package:model/email/attachment.dart';
|
||||
|
||||
class EmailPrint with EquatableMixin {
|
||||
final String appName;
|
||||
final String userName;
|
||||
final Email emailInformation;
|
||||
final String emailContent;
|
||||
final String locale;
|
||||
final String toPrefix;
|
||||
@@ -14,16 +13,18 @@ class EmailPrint with EquatableMixin {
|
||||
final String bccPrefix;
|
||||
final String replyToPrefix;
|
||||
final String titleAttachment;
|
||||
final String receiveTime;
|
||||
final List<Attachment>? attachments;
|
||||
final String? toAddress;
|
||||
final String? ccAddress;
|
||||
final String? bccAddress;
|
||||
final String? replyToAddress;
|
||||
final EmailAddress? sender;
|
||||
final String? subject;
|
||||
|
||||
EmailPrint({
|
||||
required this.appName,
|
||||
required this.userName,
|
||||
required this.emailInformation,
|
||||
required this.emailContent,
|
||||
required this.locale,
|
||||
required this.fromPrefix,
|
||||
@@ -32,18 +33,20 @@ class EmailPrint with EquatableMixin {
|
||||
required this.bccPrefix,
|
||||
required this.replyToPrefix,
|
||||
required this.titleAttachment,
|
||||
required this.receiveTime,
|
||||
this.attachments,
|
||||
this.toAddress,
|
||||
this.ccAddress,
|
||||
this.bccAddress,
|
||||
this.replyToAddress,
|
||||
this.sender,
|
||||
this.subject,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
appName,
|
||||
userName,
|
||||
emailInformation,
|
||||
emailContent,
|
||||
locale,
|
||||
fromPrefix,
|
||||
@@ -52,11 +55,14 @@ class EmailPrint with EquatableMixin {
|
||||
bccPrefix,
|
||||
replyToPrefix,
|
||||
titleAttachment,
|
||||
receiveTime,
|
||||
attachments,
|
||||
toAddress,
|
||||
ccAddress,
|
||||
bccAddress,
|
||||
replyToAddress,
|
||||
sender,
|
||||
subject,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -65,9 +71,9 @@ extension EmailPrintExtension on EmailPrint {
|
||||
return EmailPrint(
|
||||
appName: appName,
|
||||
userName: userName,
|
||||
emailInformation: emailInformation,
|
||||
emailContent: newEmailContent,
|
||||
titleAttachment: titleAttachment,
|
||||
receiveTime: receiveTime,
|
||||
locale: locale,
|
||||
fromPrefix: fromPrefix,
|
||||
toPrefix: toPrefix,
|
||||
@@ -79,6 +85,8 @@ extension EmailPrintExtension on EmailPrint {
|
||||
ccAddress: ccAddress,
|
||||
bccAddress: bccAddress,
|
||||
replyToAddress: replyToAddress,
|
||||
sender: sender,
|
||||
subject: subject,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ class PrintEmailInteractor {
|
||||
|
||||
Stream<Either<Failure, Success>> execute(EmailPrint emailPrint) async* {
|
||||
try {
|
||||
yield Right(PrintEmailLoading());
|
||||
await emailRepository.printEmail(emailPrint);
|
||||
yield Right(PrintEmailSuccess());
|
||||
} catch (e) {
|
||||
|
||||
@@ -1742,25 +1742,38 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
|
||||
_printEmailButtonState = ButtonState.disabled;
|
||||
|
||||
final locale = Localizations.localeOf(context);
|
||||
final appLocalizations = AppLocalizations.of(context);
|
||||
|
||||
consumeState(
|
||||
_printEmailInteractor.execute(
|
||||
EmailPrint(
|
||||
appName: AppLocalizations.of(context).app_name,
|
||||
appName: appLocalizations.app_name,
|
||||
userName: mailboxDashBoardController.userEmail,
|
||||
emailInformation: email.toEmail(),
|
||||
attachments: currentEmailLoaded.value!.attachments,
|
||||
emailContent: currentEmailLoaded.value!.htmlContent,
|
||||
locale: Localizations.localeOf(context).toLanguageTag(),
|
||||
fromPrefix: AppLocalizations.of(context).from_email_address_prefix,
|
||||
toPrefix: AppLocalizations.of(context).to_email_address_prefix,
|
||||
ccPrefix: AppLocalizations.of(context).cc_email_address_prefix,
|
||||
bccPrefix: AppLocalizations.of(context).bcc_email_address_prefix,
|
||||
replyToPrefix: AppLocalizations.of(context).replyToEmailAddressPrefix,
|
||||
titleAttachment: AppLocalizations.of(context).attachments.toLowerCase(),
|
||||
locale: locale.toLanguageTag(),
|
||||
fromPrefix: appLocalizations.from_email_address_prefix,
|
||||
toPrefix: appLocalizations.to_email_address_prefix,
|
||||
ccPrefix: appLocalizations.cc_email_address_prefix,
|
||||
bccPrefix: appLocalizations.bcc_email_address_prefix,
|
||||
replyToPrefix: appLocalizations.replyToEmailAddressPrefix,
|
||||
titleAttachment: appLocalizations.attachments.toLowerCase(),
|
||||
toAddress: email.to?.listEmailAddressToString(isFullEmailAddress: true),
|
||||
ccAddress: email.cc?.listEmailAddressToString(isFullEmailAddress: true),
|
||||
bccAddress: email.bcc?.listEmailAddressToString(isFullEmailAddress: true),
|
||||
replyToAddress: email.replyTo?.listEmailAddressToString(isFullEmailAddress: true),
|
||||
sender: email.from?.isNotEmpty == true
|
||||
? email.from!.first
|
||||
: null,
|
||||
receiveTime: email.getReceivedAt(
|
||||
locale.toLanguageTag(),
|
||||
pattern: email.receivedAt
|
||||
?.value
|
||||
.toLocal()
|
||||
.toPatternForPrinting(locale.toLanguageTag()),
|
||||
),
|
||||
subject: email.subject,
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -44,6 +44,7 @@ import 'package:tmail_ui_user/features/composer/presentation/model/formatting_op
|
||||
import 'package:tmail_ui_user/features/composer/presentation/model/saved_email_draft.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/print_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/transform_html_email_content_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
|
||||
import 'package:tmail_ui_user/features/login/data/network/interceptors/authorization_interceptors.dart';
|
||||
@@ -156,6 +157,7 @@ class MockMailboxDashBoardController extends Mock implements MailboxDashBoardCon
|
||||
MockSpec<GetAlwaysReadReceiptSettingInteractor>(),
|
||||
MockSpec<CreateNewAndSendEmailInteractor>(),
|
||||
MockSpec<CreateNewAndSaveEmailToDraftsInteractor>(),
|
||||
MockSpec<PrintEmailInteractor>(),
|
||||
|
||||
// Additional Getx dependencies mock specs
|
||||
MockSpec<NetworkConnectionController>(fallbackGenerators: fallbackGenerators),
|
||||
@@ -197,6 +199,7 @@ void main() {
|
||||
late MockGetAlwaysReadReceiptSettingInteractor mockGetAlwaysReadReceiptSettingInteractor;
|
||||
late MockCreateNewAndSendEmailInteractor mockCreateNewAndSendEmailInteractor;
|
||||
late MockCreateNewAndSaveEmailToDraftsInteractor mockCreateNewAndSaveEmailToDraftsInteractor;
|
||||
late MockPrintEmailInteractor mockPrintEmailInteractor;
|
||||
|
||||
// Declaration Getx dependencies
|
||||
final mockMailboxDashBoardController = MockMailboxDashBoardController();
|
||||
@@ -262,6 +265,7 @@ void main() {
|
||||
mockGetAlwaysReadReceiptSettingInteractor = MockGetAlwaysReadReceiptSettingInteractor();
|
||||
mockCreateNewAndSendEmailInteractor = MockCreateNewAndSendEmailInteractor();
|
||||
mockCreateNewAndSaveEmailToDraftsInteractor = MockCreateNewAndSaveEmailToDraftsInteractor();
|
||||
mockPrintEmailInteractor = MockPrintEmailInteractor();
|
||||
|
||||
composerController = ComposerController(
|
||||
mockLocalFilePickerInteractor,
|
||||
@@ -275,7 +279,8 @@ void main() {
|
||||
mockTransformHtmlEmailContentInteractor,
|
||||
mockGetAlwaysReadReceiptSettingInteractor,
|
||||
mockCreateNewAndSendEmailInteractor,
|
||||
mockCreateNewAndSaveEmailToDraftsInteractor
|
||||
mockCreateNewAndSaveEmailToDraftsInteractor,
|
||||
mockPrintEmailInteractor,
|
||||
);
|
||||
|
||||
mockHtmlEditorApi = MockHtmlEditorApi();
|
||||
|
||||
Reference in New Issue
Block a user