TF-675 Implement upload attachment on presentation layer
This commit is contained in:
@@ -3,11 +3,8 @@ import 'package:core/core.dart';
|
|||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:tmail_ui_user/features/base/base_bindings.dart';
|
import 'package:tmail_ui_user/features/base/base_bindings.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/data/datasource/composer_datasource.dart';
|
|
||||||
import 'package:tmail_ui_user/features/composer/data/datasource/contact_datasource.dart';
|
import 'package:tmail_ui_user/features/composer/data/datasource/contact_datasource.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/data/datasource_impl/composer_datasource_impl.dart';
|
|
||||||
import 'package:tmail_ui_user/features/composer/data/datasource_impl/contact_datasource_impl.dart';
|
import 'package:tmail_ui_user/features/composer/data/datasource_impl/contact_datasource_impl.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/data/network/composer_api.dart';
|
|
||||||
import 'package:tmail_ui_user/features/composer/data/repository/auto_complete_repository_impl.dart';
|
import 'package:tmail_ui_user/features/composer/data/repository/auto_complete_repository_impl.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/data/repository/composer_repository_impl.dart';
|
import 'package:tmail_ui_user/features/composer/data/repository/composer_repository_impl.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/data/repository/contact_repository_impl.dart';
|
import 'package:tmail_ui_user/features/composer/data/repository/contact_repository_impl.dart';
|
||||||
@@ -21,7 +18,6 @@ import 'package:tmail_ui_user/features/composer/domain/usecases/update_email_dra
|
|||||||
import 'package:tmail_ui_user/features/composer/domain/usecases/upload_attachment_interactor.dart';
|
import 'package:tmail_ui_user/features/composer/domain/usecases/upload_attachment_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_interactor.dart';
|
import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_interactor.dart';
|
||||||
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/upload_mutiple_attachment_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/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';
|
||||||
@@ -41,9 +37,13 @@ import 'package:tmail_ui_user/features/manage_account/data/network/manage_accoun
|
|||||||
import 'package:tmail_ui_user/features/manage_account/data/repository/manage_account_repository_impl.dart';
|
import 'package:tmail_ui_user/features/manage_account/data/repository/manage_account_repository_impl.dart';
|
||||||
import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart';
|
import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart';
|
||||||
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart';
|
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart';
|
||||||
|
import 'package:tmail_ui_user/features/upload/data/datasource/attachment_upload_datasource.dart';
|
||||||
|
import 'package:tmail_ui_user/features/upload/data/datasource_impl/attachment_upload_datasource_impl.dart';
|
||||||
|
import 'package:tmail_ui_user/features/upload/data/network/file_uploader.dart';
|
||||||
import 'package:tmail_ui_user/features/upload/domain/usecases/local_file_picker_interactor.dart';
|
import 'package:tmail_ui_user/features/upload/domain/usecases/local_file_picker_interactor.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:tmail_ui_user/features/upload/presentation/controller/upload_controller.dart';
|
||||||
import 'package:jmap_dart_client/http/http_client.dart' as jmap_http_client;
|
import 'package:jmap_dart_client/http/http_client.dart' as jmap_http_client;
|
||||||
|
import 'package:worker_manager/worker_manager.dart';
|
||||||
|
|
||||||
class ComposerBindings extends BaseBindings {
|
class ComposerBindings extends BaseBindings {
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ class ComposerBindings extends BaseBindings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _bindingsUtils() {
|
void _bindingsUtils() {
|
||||||
Get.lazyPut(() => const Uuid());
|
Get.lazyPut(() => FileUploader(Get.find<DioClient>(), Get.find<Executor>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -68,7 +68,7 @@ class ComposerBindings extends BaseBindings {
|
|||||||
dataSources.add(Get.find<TMailContactDataSourceImpl>());
|
dataSources.add(Get.find<TMailContactDataSourceImpl>());
|
||||||
}
|
}
|
||||||
|
|
||||||
Get.lazyPut(() => ComposerDataSourceImpl(Get.find<ComposerAPI>()));
|
Get.lazyPut(() => AttachmentUploadDataSourceImpl(Get.find<FileUploader>()));
|
||||||
Get.lazyPut(() => ContactDataSourceImpl());
|
Get.lazyPut(() => ContactDataSourceImpl());
|
||||||
Get.lazyPut(() => EmailDataSourceImpl(Get.find<EmailAPI>()));
|
Get.lazyPut(() => EmailDataSourceImpl(Get.find<EmailAPI>()));
|
||||||
Get.lazyPut(() => HtmlDataSourceImpl(
|
Get.lazyPut(() => HtmlDataSourceImpl(
|
||||||
@@ -82,7 +82,7 @@ class ComposerBindings extends BaseBindings {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void bindingsDataSource() {
|
void bindingsDataSource() {
|
||||||
Get.lazyPut<ComposerDataSource>(() => Get.find<ComposerDataSourceImpl>());
|
Get.lazyPut<AttachmentUploadDataSource>(() => Get.find<AttachmentUploadDataSourceImpl>());
|
||||||
Get.lazyPut<ContactDataSource>(() => Get.find<ContactDataSourceImpl>());
|
Get.lazyPut<ContactDataSource>(() => Get.find<ContactDataSourceImpl>());
|
||||||
Get.lazyPut<EmailDataSource>(() => Get.find<EmailDataSourceImpl>());
|
Get.lazyPut<EmailDataSource>(() => Get.find<EmailDataSourceImpl>());
|
||||||
Get.lazyPut<HtmlDataSource>(() => Get.find<HtmlDataSourceImpl>());
|
Get.lazyPut<HtmlDataSource>(() => Get.find<HtmlDataSourceImpl>());
|
||||||
@@ -91,7 +91,7 @@ class ComposerBindings extends BaseBindings {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void bindingsRepositoryImpl() {
|
void bindingsRepositoryImpl() {
|
||||||
Get.lazyPut(() => ComposerRepositoryImpl(Get.find<ComposerDataSource>()));
|
Get.lazyPut(() => ComposerRepositoryImpl(Get.find<AttachmentUploadDataSource>()));
|
||||||
Get.lazyPut(() => AutoCompleteRepositoryImpl(dataSources));
|
Get.lazyPut(() => AutoCompleteRepositoryImpl(dataSources));
|
||||||
Get.lazyPut(() => ContactRepositoryImpl(Get.find<ContactDataSource>()));
|
Get.lazyPut(() => ContactRepositoryImpl(Get.find<ContactDataSource>()));
|
||||||
Get.lazyPut(() => EmailRepositoryImpl(
|
Get.lazyPut(() => EmailRepositoryImpl(
|
||||||
@@ -120,7 +120,6 @@ class ComposerBindings extends BaseBindings {
|
|||||||
));
|
));
|
||||||
Get.lazyPut(() => LocalFilePickerInteractor());
|
Get.lazyPut(() => LocalFilePickerInteractor());
|
||||||
Get.lazyPut(() => UploadAttachmentInteractor(Get.find<ComposerRepository>()));
|
Get.lazyPut(() => UploadAttachmentInteractor(Get.find<ComposerRepository>()));
|
||||||
Get.lazyPut(() => UploadMultipleAttachmentInteractor(Get.find<UploadAttachmentInteractor>()));
|
|
||||||
Get.lazyPut(() => SendEmailInteractor(Get.find<EmailRepository>()));
|
Get.lazyPut(() => SendEmailInteractor(Get.find<EmailRepository>()));
|
||||||
Get.lazyPut(() => SaveEmailAsDraftsInteractor(Get.find<EmailRepository>()));
|
Get.lazyPut(() => SaveEmailAsDraftsInteractor(Get.find<EmailRepository>()));
|
||||||
Get.lazyPut(() => GetEmailContentInteractor(Get.find<EmailRepository>()));
|
Get.lazyPut(() => GetEmailContentInteractor(Get.find<EmailRepository>()));
|
||||||
@@ -130,18 +129,23 @@ class ComposerBindings extends BaseBindings {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void bindingsController() {
|
void bindingsController() {
|
||||||
|
Get.lazyPut(() => UploadController(Get.find<UploadAttachmentInteractor>()));
|
||||||
Get.lazyPut(() => ComposerController(
|
Get.lazyPut(() => ComposerController(
|
||||||
Get.find<SendEmailInteractor>(),
|
Get.find<SendEmailInteractor>(),
|
||||||
Get.find<GetAutoCompleteInteractor>(),
|
Get.find<GetAutoCompleteInteractor>(),
|
||||||
Get.find<GetAutoCompleteWithDeviceContactInteractor>(),
|
Get.find<GetAutoCompleteWithDeviceContactInteractor>(),
|
||||||
Get.find<Uuid>(),
|
|
||||||
Get.find<DeviceInfoPlugin>(),
|
Get.find<DeviceInfoPlugin>(),
|
||||||
Get.find<LocalFilePickerInteractor>(),
|
Get.find<LocalFilePickerInteractor>(),
|
||||||
Get.find<UploadMultipleAttachmentInteractor>(),
|
|
||||||
Get.find<SaveEmailAsDraftsInteractor>(),
|
Get.find<SaveEmailAsDraftsInteractor>(),
|
||||||
Get.find<GetEmailContentInteractor>(),
|
Get.find<GetEmailContentInteractor>(),
|
||||||
Get.find<UpdateEmailDraftsInteractor>(),
|
Get.find<UpdateEmailDraftsInteractor>(),
|
||||||
Get.find<GetAllIdentitiesInteractor>(),
|
Get.find<GetAllIdentitiesInteractor>(),
|
||||||
|
Get.find<UploadController>(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
Get.delete<UploadController>();
|
||||||
|
Get.delete<ComposerController>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -31,11 +31,9 @@ import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart'
|
|||||||
import 'package:tmail_ui_user/features/composer/domain/state/get_autocomplete_state.dart';
|
import 'package:tmail_ui_user/features/composer/domain/state/get_autocomplete_state.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_interactor.dart';
|
import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_with_device_contact_interactor.dart';
|
import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_with_device_contact_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/domain/state/upload_attachment_state.dart';
|
|
||||||
import 'package:tmail_ui_user/features/composer/domain/usecases/save_email_as_drafts_interactor.dart';
|
import 'package:tmail_ui_user/features/composer/domain/usecases/save_email_as_drafts_interactor.dart';
|
||||||
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/domain/usecases/upload_mutiple_attachment_interactor.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';
|
||||||
@@ -44,8 +42,10 @@ import 'package:tmail_ui_user/features/email/presentation/model/composer_argumen
|
|||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
|
||||||
import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_identities_state.dart';
|
import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_identities_state.dart';
|
||||||
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart';
|
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart';
|
||||||
|
import 'package:tmail_ui_user/features/upload/domain/model/upload_task_id.dart';
|
||||||
import 'package:tmail_ui_user/features/upload/domain/state/local_file_picker_state.dart';
|
import 'package:tmail_ui_user/features/upload/domain/state/local_file_picker_state.dart';
|
||||||
import 'package:tmail_ui_user/features/upload/domain/usecases/local_file_picker_interactor.dart';
|
import 'package:tmail_ui_user/features/upload/domain/usecases/local_file_picker_interactor.dart';
|
||||||
|
import 'package:tmail_ui_user/features/upload/presentation/controller/upload_controller.dart';
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
@@ -56,12 +56,12 @@ class ComposerController extends BaseController {
|
|||||||
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>();
|
||||||
|
final _uuid = Get.find<Uuid>();
|
||||||
|
|
||||||
final expandModeAttachments = ExpandMode.COLLAPSE.obs;
|
final expandModeAttachments = ExpandMode.COLLAPSE.obs;
|
||||||
final composerArguments = Rxn<ComposerArguments>();
|
final composerArguments = Rxn<ComposerArguments>();
|
||||||
final isEnableEmailSendButton = false.obs;
|
final isEnableEmailSendButton = false.obs;
|
||||||
final isInitialRecipient = false.obs;
|
final isInitialRecipient = false.obs;
|
||||||
final attachments = <Attachment>[].obs;
|
|
||||||
final emailContents = Rxn<List<EmailContent>>();
|
final emailContents = Rxn<List<EmailContent>>();
|
||||||
final listEmailAddressType = <PrefixEmailAddress>[].obs;
|
final listEmailAddressType = <PrefixEmailAddress>[].obs;
|
||||||
final subjectEmail = Rxn<String>();
|
final subjectEmail = Rxn<String>();
|
||||||
@@ -75,14 +75,13 @@ class ComposerController extends BaseController {
|
|||||||
final SendEmailInteractor _sendEmailInteractor;
|
final SendEmailInteractor _sendEmailInteractor;
|
||||||
final GetAutoCompleteInteractor _getAutoCompleteInteractor;
|
final GetAutoCompleteInteractor _getAutoCompleteInteractor;
|
||||||
final GetAutoCompleteWithDeviceContactInteractor _getAutoCompleteWithDeviceContactInteractor;
|
final GetAutoCompleteWithDeviceContactInteractor _getAutoCompleteWithDeviceContactInteractor;
|
||||||
final Uuid _uuid;
|
|
||||||
final LocalFilePickerInteractor _localFilePickerInteractor;
|
final LocalFilePickerInteractor _localFilePickerInteractor;
|
||||||
final UploadMultipleAttachmentInteractor _uploadMultipleAttachmentInteractor;
|
|
||||||
final DeviceInfoPlugin _deviceInfoPlugin;
|
final DeviceInfoPlugin _deviceInfoPlugin;
|
||||||
final SaveEmailAsDraftsInteractor _saveEmailAsDraftsInteractor;
|
final SaveEmailAsDraftsInteractor _saveEmailAsDraftsInteractor;
|
||||||
final GetEmailContentInteractor _getEmailContentInteractor;
|
final GetEmailContentInteractor _getEmailContentInteractor;
|
||||||
final UpdateEmailDraftsInteractor _updateEmailDraftsInteractor;
|
final UpdateEmailDraftsInteractor _updateEmailDraftsInteractor;
|
||||||
final GetAllIdentitiesInteractor _getAllIdentitiesInteractor;
|
final GetAllIdentitiesInteractor _getAllIdentitiesInteractor;
|
||||||
|
final UploadController uploadController;
|
||||||
|
|
||||||
List<EmailAddress> listToEmailAddress = <EmailAddress>[];
|
List<EmailAddress> listToEmailAddress = <EmailAddress>[];
|
||||||
List<EmailAddress> listCcEmailAddress = <EmailAddress>[];
|
List<EmailAddress> listCcEmailAddress = <EmailAddress>[];
|
||||||
@@ -129,14 +128,13 @@ class ComposerController extends BaseController {
|
|||||||
this._sendEmailInteractor,
|
this._sendEmailInteractor,
|
||||||
this._getAutoCompleteInteractor,
|
this._getAutoCompleteInteractor,
|
||||||
this._getAutoCompleteWithDeviceContactInteractor,
|
this._getAutoCompleteWithDeviceContactInteractor,
|
||||||
this._uuid,
|
|
||||||
this._deviceInfoPlugin,
|
this._deviceInfoPlugin,
|
||||||
this._localFilePickerInteractor,
|
this._localFilePickerInteractor,
|
||||||
this._uploadMultipleAttachmentInteractor,
|
|
||||||
this._saveEmailAsDraftsInteractor,
|
this._saveEmailAsDraftsInteractor,
|
||||||
this._getEmailContentInteractor,
|
this._getEmailContentInteractor,
|
||||||
this._updateEmailDraftsInteractor,
|
this._updateEmailDraftsInteractor,
|
||||||
this._getAllIdentitiesInteractor,
|
this._getAllIdentitiesInteractor,
|
||||||
|
this.uploadController,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -183,18 +181,11 @@ class ComposerController extends BaseController {
|
|||||||
(failure) {
|
(failure) {
|
||||||
if (failure is LocalFilePickerFailure || failure is LocalFilePickerCancel) {
|
if (failure is LocalFilePickerFailure || failure is LocalFilePickerCancel) {
|
||||||
_pickFileFailure(failure);
|
_pickFileFailure(failure);
|
||||||
} else if (failure is UploadAttachmentFailure
|
|
||||||
|| failure is UploadMultipleAttachmentAllFailure) {
|
|
||||||
_uploadAttachmentsFailure(failure);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(success) {
|
(success) {
|
||||||
if (success is LocalFilePickerSuccess) {
|
if (success is LocalFilePickerSuccess) {
|
||||||
_pickFileSuccess(success);
|
_pickFileSuccess(success);
|
||||||
} else if (success is UploadAttachmentSuccess
|
|
||||||
|| success is UploadMultipleAttachmentAllSuccess
|
|
||||||
|| success is UploadMultipleAttachmentHasSomeFailure) {
|
|
||||||
_uploadAttachmentsSuccess(success);
|
|
||||||
} else if (success is GetEmailContentSuccess) {
|
} else if (success is GetEmailContentSuccess) {
|
||||||
_getEmailContentSuccess(success);
|
_getEmailContentSuccess(success);
|
||||||
} if (success is GetAllIdentitiesSuccess) {
|
} if (success is GetAllIdentitiesSuccess) {
|
||||||
@@ -243,8 +234,13 @@ class ComposerController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _initAttachments(ComposerArguments arguments) {
|
void _initAttachments(ComposerArguments arguments) {
|
||||||
attachments.value = arguments.attachments ?? [];
|
if (arguments.attachments?.isNotEmpty == true) {
|
||||||
initialAttachments = arguments.attachments ?? [];
|
initialAttachments = arguments.attachments!;
|
||||||
|
uploadController.initializeUploadAttachments(arguments.attachments!);
|
||||||
|
}
|
||||||
|
if (BuildUtils.isWeb) {
|
||||||
|
expandModeAttachments.value = ExpandMode.EXPAND;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _getAllIdentities() {
|
void _getAllIdentities() {
|
||||||
@@ -466,7 +462,7 @@ class ComposerController extends BaseController {
|
|||||||
generatePartId: EmailBodyValue(emailBodyText, false, false)
|
generatePartId: EmailBodyValue(emailBodyText, false, false)
|
||||||
},
|
},
|
||||||
headerUserAgent: {IndividualHeaderIdentifier.headerUserAgent : userAgent},
|
headerUserAgent: {IndividualHeaderIdentifier.headerUserAgent : userAgent},
|
||||||
attachments: attachments.isNotEmpty ? _generateAttachments() : null,
|
attachments: uploadController.generateAttachments(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,11 +481,6 @@ class ComposerController extends BaseController {
|
|||||||
return userAgent;
|
return userAgent;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<EmailBodyPart> _generateAttachments() {
|
|
||||||
return attachments.map((attachment) =>
|
|
||||||
attachment.toEmailBodyPart(ContentDisposition.attachment.value)).toSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
void sendEmailAction(BuildContext context) async {
|
void sendEmailAction(BuildContext context) async {
|
||||||
clearFocusEditor(context);
|
clearFocusEditor(context);
|
||||||
|
|
||||||
@@ -534,7 +525,19 @@ class ComposerController extends BaseController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_validateAttachmentsSize()) {
|
if (!uploadController.allUploadAttachmentsCompleted) {
|
||||||
|
showConfirmDialogAction(
|
||||||
|
context,
|
||||||
|
AppLocalizations.of(context).messageDialogSendEmailUploadingAttachment,
|
||||||
|
AppLocalizations.of(context).got_it,
|
||||||
|
() => {},
|
||||||
|
title: AppLocalizations.of(context).sending_failed,
|
||||||
|
icon: SvgPicture.asset(_imagePaths.icSendToastError, fit: BoxFit.fill),
|
||||||
|
hasCancelButton: false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!uploadController.hasEnoughMaxAttachmentSize()) {
|
||||||
showConfirmDialogAction(
|
showConfirmDialogAction(
|
||||||
context,
|
context,
|
||||||
AppLocalizations.of(context).message_dialog_send_email_exceeds_maximum_size(
|
AppLocalizations.of(context).message_dialog_send_email_exceeds_maximum_size(
|
||||||
@@ -561,7 +564,7 @@ class ComposerController extends BaseController {
|
|||||||
final email = await _generateEmail(mapDefaultMailboxId, userProfile);
|
final email = await _generateEmail(mapDefaultMailboxId, userProfile);
|
||||||
final accountId = session.accounts.keys.first;
|
final accountId = session.accounts.keys.first;
|
||||||
final sentMailboxId = mapDefaultMailboxId[PresentationMailbox.roleSent];
|
final sentMailboxId = mapDefaultMailboxId[PresentationMailbox.roleSent];
|
||||||
final submissionCreateId = Id(_uuid.v1());
|
final submissionCreateId = Id(const Uuid().v1());
|
||||||
|
|
||||||
mailboxDashBoardController.consumeState(_sendEmailInteractor.execute(
|
mailboxDashBoardController.consumeState(_sendEmailInteractor.execute(
|
||||||
accountId,
|
accountId,
|
||||||
@@ -633,88 +636,34 @@ class ComposerController extends BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _pickFileSuccess(Success success) {
|
void _pickFileSuccess(LocalFilePickerSuccess success) {
|
||||||
if (success is LocalFilePickerSuccess) {
|
if (uploadController.hasEnoughMaxAttachmentSize(listFiles: success.pickedFiles)) {
|
||||||
if (_validateAttachmentsSize(listFiles: success.pickedFiles)) {
|
_uploadAttachmentsAction(success.pickedFiles);
|
||||||
_uploadAttachmentsAction(success.pickedFiles);
|
|
||||||
} else {
|
|
||||||
if (currentContext != null) {
|
|
||||||
showConfirmDialogAction(
|
|
||||||
currentContext!,
|
|
||||||
AppLocalizations.of(currentContext!).message_dialog_upload_attachments_exceeds_maximum_size(
|
|
||||||
filesize(mailboxDashBoardController.maxSizeAttachmentsPerEmail?.value ?? 0, 0)),
|
|
||||||
AppLocalizations.of(currentContext!).got_it,
|
|
||||||
() => {},
|
|
||||||
title: AppLocalizations.of(currentContext!).maximum_files_size,
|
|
||||||
hasCancelButton: false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _validateAttachmentsSize({List<FileInfo>? listFiles}) {
|
|
||||||
final currentTotalAttachmentsSize = attachments.totalSize();
|
|
||||||
log('ComposerController::_validateAttachmentsSize(): $currentTotalAttachmentsSize');
|
|
||||||
num uploadedTotalSize = 0;
|
|
||||||
if (listFiles != null && listFiles.isNotEmpty) {
|
|
||||||
final uploadedListSize = listFiles.map((file) => file.fileSize).toList();
|
|
||||||
uploadedTotalSize = uploadedListSize.reduce((sum, size) => sum + size);
|
|
||||||
log('ComposerController::_validateAttachmentsSize(): uploadedTotalSize: $uploadedTotalSize');
|
|
||||||
}
|
|
||||||
|
|
||||||
final totalSizeReadyToUpload = currentTotalAttachmentsSize + uploadedTotalSize;
|
|
||||||
log('ComposerController::_validateAttachmentsSize(): totalSizeReadyToUpload: $totalSizeReadyToUpload');
|
|
||||||
|
|
||||||
final maxSizeAttachmentsPerEmail = mailboxDashBoardController.maxSizeAttachmentsPerEmail?.value;
|
|
||||||
if (maxSizeAttachmentsPerEmail != null) {
|
|
||||||
return totalSizeReadyToUpload <= maxSizeAttachmentsPerEmail;
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
if (currentContext != null) {
|
||||||
|
showConfirmDialogAction(
|
||||||
|
currentContext!,
|
||||||
|
AppLocalizations.of(currentContext!).message_dialog_upload_attachments_exceeds_maximum_size(
|
||||||
|
filesize(mailboxDashBoardController.maxSizeAttachmentsPerEmail?.value ?? 0, 0)),
|
||||||
|
AppLocalizations.of(currentContext!).got_it,
|
||||||
|
() => {},
|
||||||
|
title: AppLocalizations.of(currentContext!).maximum_files_size,
|
||||||
|
hasCancelButton: false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _uploadAttachmentsAction(List<FileInfo> pickedFiles) async {
|
void _uploadAttachmentsAction(List<FileInfo> pickedFiles) async {
|
||||||
final session = mailboxDashBoardController.sessionCurrent;
|
final session = mailboxDashBoardController.sessionCurrent;
|
||||||
if (session != null) {
|
final accountId = mailboxDashBoardController.accountId.value;
|
||||||
final accountId = session.accounts.keys.first;
|
if (session != null && accountId != null) {
|
||||||
final uploadUrl = session.getUploadUrl(accountId);
|
final uploadUri = session.getUploadUri(accountId);
|
||||||
consumeState(_uploadMultipleAttachmentInteractor.execute(pickedFiles, accountId, uploadUrl));
|
uploadController.justUploadAttachmentsAction(pickedFiles, uploadUri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _uploadAttachmentsFailure(Failure failure) {
|
void deleteAttachmentUploaded(UploadTaskId uploadId) {
|
||||||
if (currentContext != null) {
|
uploadController.deleteFileUploaded(uploadId);
|
||||||
_appToast.showErrorToast(AppLocalizations.of(currentContext!).can_not_upload_this_file_as_attachments);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _uploadAttachmentsSuccess(Success success) {
|
|
||||||
if (success is UploadAttachmentSuccess) {
|
|
||||||
attachments.add(success.attachment);
|
|
||||||
} else if (success is UploadMultipleAttachmentAllSuccess) {
|
|
||||||
final listAttachment = success.listResults.where((either) => either.isRight())
|
|
||||||
.map((either) => either
|
|
||||||
.map((result) => (result as UploadAttachmentSuccess).attachment)
|
|
||||||
.toIterable().first)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
attachments.addAll(listAttachment);
|
|
||||||
} else if (success is UploadMultipleAttachmentHasSomeFailure) {
|
|
||||||
final listAttachment = success.listResults
|
|
||||||
.map((either) => either
|
|
||||||
.map((result) => (result as UploadAttachmentSuccess).attachment)
|
|
||||||
.toIterable().first)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
attachments.addAll(listAttachment);
|
|
||||||
}
|
|
||||||
if (currentContext != null) {
|
|
||||||
_appToast.showSuccessToast(AppLocalizations.of(currentContext!).attachments_uploaded_successfully);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeAttachmentAction(Attachment attachmentRemoved) {
|
|
||||||
attachments.removeWhere((attachment) => attachment == attachmentRemoved);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> _isEmailChanged(BuildContext context, ComposerArguments arguments) async {
|
Future<bool> _isEmailChanged(BuildContext context, ComposerArguments arguments) async {
|
||||||
@@ -759,7 +708,7 @@ class ComposerController extends BaseController {
|
|||||||
final oldBccEmailAddress = recipients.value1;
|
final oldBccEmailAddress = recipients.value1;
|
||||||
final isBccEmailAddressChanged = !oldBccEmailAddress.isSame(newBccEmailAddress);
|
final isBccEmailAddressChanged = !oldBccEmailAddress.isSame(newBccEmailAddress);
|
||||||
|
|
||||||
final isAttachmentsChanged = !initialAttachments.isSame(attachments.toList());
|
final isAttachmentsChanged = !initialAttachments.isSame(uploadController.attachmentsUploaded.toList());
|
||||||
|
|
||||||
if (isEmailBodyChanged || isEmailSubjectChanged
|
if (isEmailBodyChanged || isEmailSubjectChanged
|
||||||
|| isToEmailAddressChanged || isCcEmailAddressChanged
|
|| isToEmailAddressChanged || isCcEmailAddressChanged
|
||||||
@@ -816,8 +765,10 @@ class ComposerController extends BaseController {
|
|||||||
|
|
||||||
void _getEmailContentSuccess(GetEmailContentSuccess success) {
|
void _getEmailContentSuccess(GetEmailContentSuccess success) {
|
||||||
emailContents.value = success.emailContents;
|
emailContents.value = success.emailContents;
|
||||||
attachments.value = success.attachments;
|
if (success.attachments.isNotEmpty) {
|
||||||
initialAttachments = success.attachments;
|
initialAttachments = success.attachments;
|
||||||
|
uploadController.initializeUploadAttachments(success.attachments);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String? getEmailContentDraftsAsHtml() {
|
String? getEmailContentDraftsAsHtml() {
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import 'package:tmail_ui_user/features/composer/domain/state/upload_attachment_s
|
|||||||
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/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/model/upload_file_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> {
|
class ComposerView extends GetWidget<ComposerController> {
|
||||||
@@ -29,10 +31,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
return ResponsiveWidget(
|
return ResponsiveWidget(
|
||||||
responsiveUtils: responsiveUtils,
|
responsiveUtils: responsiveUtils,
|
||||||
mobile: _buildComposerViewForMobile(context),
|
mobile: _buildComposerViewForMobile(context),
|
||||||
landscapeMobile: _buildComposerViewForMobile(context),
|
|
||||||
tablet: _buildComposerViewForTablet(context),
|
tablet: _buildComposerViewForTablet(context),
|
||||||
tabletLarge: _buildComposerViewForTablet(context),
|
|
||||||
desktop: _buildComposerViewForTablet(context),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,19 +397,26 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
const Divider(color: AppColor.colorDividerComposer, height: 1),
|
const Divider(color: AppColor.colorDividerComposer, height: 1),
|
||||||
Padding(padding: const EdgeInsets.symmetric(horizontal: 16), child: _buildListButton(context)),
|
Padding(padding: const EdgeInsets.symmetric(horizontal: 16), child: _buildListButton(context)),
|
||||||
const Divider(color: AppColor.colorDividerComposer, height: 1),
|
const Divider(color: AppColor.colorDividerComposer, height: 1),
|
||||||
Obx(() => controller.attachments.isNotEmpty
|
Obx(() {
|
||||||
? Padding(
|
final uploadAttachments = controller.uploadController.listUploadAttachments;
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
if (uploadAttachments.isEmpty) {
|
||||||
child: _buildAttachmentsTitle(context, controller.attachments, controller.expandModeAttachments.value))
|
return const SizedBox.shrink();
|
||||||
: const SizedBox.shrink()),
|
} else {
|
||||||
Obx(() => controller.attachments.isEmpty
|
return Column(children: [
|
||||||
? _buildAttachmentsLoadingView()
|
Padding(
|
||||||
: const SizedBox.shrink()),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
Obx(() => controller.attachments.isNotEmpty
|
child: _buildAttachmentsTitle(context,
|
||||||
? Padding(
|
uploadAttachments,
|
||||||
padding: const EdgeInsets.only(bottom: 8, left: 16, right: 16),
|
controller.expandModeAttachments.value)),
|
||||||
child: _buildAttachmentsList(context, controller.attachments, controller.expandModeAttachments.value))
|
_buildAttachmentsLoadingView(),
|
||||||
: const SizedBox.shrink()),
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 8, left: 16, right: 16),
|
||||||
|
child: _buildAttachmentsList(context,
|
||||||
|
uploadAttachments,
|
||||||
|
controller.expandModeAttachments.value))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 20),
|
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 20),
|
||||||
child: _buildComposerEditor(context)),
|
child: _buildComposerEditor(context)),
|
||||||
@@ -453,19 +459,26 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 60, right: 25),
|
padding: const EdgeInsets.only(left: 60, right: 25),
|
||||||
child: Column(children: [
|
child: Column(children: [
|
||||||
Obx(() => controller.attachments.isNotEmpty
|
Obx(() {
|
||||||
? Padding(
|
final uploadAttachments = controller.uploadController.listUploadAttachments;
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
if (uploadAttachments.isEmpty) {
|
||||||
child: _buildAttachmentsTitle(context, controller.attachments, controller.expandModeAttachments.value))
|
return const SizedBox.shrink();
|
||||||
: const SizedBox.shrink()),
|
} else {
|
||||||
Obx(() => controller.attachments.isEmpty
|
return Column(children: [
|
||||||
? _buildAttachmentsLoadingView()
|
Padding(
|
||||||
: const SizedBox.shrink()),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
Obx(() => controller.attachments.isNotEmpty
|
child: _buildAttachmentsTitle(context,
|
||||||
? Padding(
|
uploadAttachments,
|
||||||
padding: const EdgeInsets.only(bottom: 8, left: 16, right: 16),
|
controller.expandModeAttachments.value)),
|
||||||
child: _buildAttachmentsList(context, controller.attachments, controller.expandModeAttachments.value))
|
_buildAttachmentsLoadingView(),
|
||||||
: const SizedBox.shrink()),
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 8, left: 16, right: 16),
|
||||||
|
child: _buildAttachmentsList(context,
|
||||||
|
uploadAttachments,
|
||||||
|
controller.expandModeAttachments.value))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 20, top: 10),
|
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 20, top: 10),
|
||||||
child: _buildComposerEditor(context)),
|
child: _buildComposerEditor(context)),
|
||||||
@@ -509,11 +522,15 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
: const SizedBox.shrink()));
|
: const SizedBox.shrink()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildAttachmentsTitle(BuildContext context, List<Attachment> attachments, ExpandMode expandModeAttachment) {
|
Widget _buildAttachmentsTitle(
|
||||||
|
BuildContext context,
|
||||||
|
List<UploadFileState> uploadFilesState,
|
||||||
|
ExpandMode expandModeAttachment
|
||||||
|
) {
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'${AppLocalizations.of(context).attachments} (${filesize(attachments.totalSize(), 0)}):',
|
'${AppLocalizations.of(context).attachments} (${filesize(uploadFilesState.totalSize, 0)}):',
|
||||||
style: const TextStyle(fontSize: 12, color: AppColor.colorHintEmailAddressInput, fontWeight: FontWeight.normal)),
|
style: const TextStyle(fontSize: 12, color: AppColor.colorHintEmailAddressInput, fontWeight: FontWeight.normal)),
|
||||||
_buildAttachmentsLoadingView(padding: const EdgeInsets.only(left: 16), size: 16),
|
_buildAttachmentsLoadingView(padding: const EdgeInsets.only(left: 16), size: 16),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
@@ -524,7 +541,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
expandModeAttachment == ExpandMode.EXPAND
|
expandModeAttachment == ExpandMode.EXPAND
|
||||||
? AppLocalizations.of(context).hide
|
? AppLocalizations.of(context).hide
|
||||||
: '${AppLocalizations.of(context).show_all} (${attachments.length})',
|
: '${AppLocalizations.of(context).show_all} (${uploadFilesState.length})',
|
||||||
style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 12, color: AppColor.colorTextButton)),
|
style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 12, color: AppColor.colorTextButton)),
|
||||||
onPressed: () => controller.toggleDisplayAttachments()
|
onPressed: () => controller.toggleDisplayAttachments()
|
||||||
)
|
)
|
||||||
@@ -533,23 +550,28 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildAttachmentsList(BuildContext context, List<Attachment> attachments, ExpandMode expandMode) {
|
Widget _buildAttachmentsList(
|
||||||
|
BuildContext context,
|
||||||
|
List<UploadFileState> uploadFilesState,
|
||||||
|
ExpandMode expandMode
|
||||||
|
) {
|
||||||
|
const double maxHeightItem = 60;
|
||||||
if (expandMode == ExpandMode.EXPAND) {
|
if (expandMode == ExpandMode.EXPAND) {
|
||||||
return LayoutBuilder(builder: (context, constraints) {
|
return LayoutBuilder(builder: (context, constraints) {
|
||||||
return GridView.builder(
|
return GridView.builder(
|
||||||
key: const Key('list_attachment_full'),
|
key: const Key('list_attachment_full'),
|
||||||
primary: false,
|
primary: false,
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
itemCount: attachments.length,
|
itemCount: uploadFilesState.length,
|
||||||
gridDelegate: SliverGridDelegateFixedHeight(
|
gridDelegate: SliverGridDelegateFixedHeight(
|
||||||
height: 60,
|
height: maxHeightItem,
|
||||||
crossAxisCount: _getMaxItemRowListAttachment(context, constraints),
|
crossAxisCount: _getMaxItemRowListAttachment(context, constraints),
|
||||||
crossAxisSpacing: 8.0,
|
crossAxisSpacing: 8.0,
|
||||||
mainAxisSpacing: 8.0),
|
mainAxisSpacing: 8.0),
|
||||||
itemBuilder: (context, index) =>
|
itemBuilder: (context, index) => AttachmentFileComposerBuilder(
|
||||||
(AttachmentFileComposerBuilder(context, imagePaths, attachments[index])
|
uploadFilesState[index],
|
||||||
..addOnDeleteAttachmentAction((attachment) => controller.removeAttachmentAction(attachment)))
|
onDeleteAttachmentAction: (attachment) =>
|
||||||
.build()
|
controller.deleteAttachmentUploaded(attachment.uploadTaskId))
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -557,20 +579,19 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
return Align(
|
return Align(
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 60,
|
height: maxHeightItem,
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
key: const Key('list_attachment_minimize'),
|
key: const Key('list_attachment_minimize'),
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
physics: const ClampingScrollPhysics(),
|
physics: const ClampingScrollPhysics(),
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
itemCount: attachments.length,
|
itemCount: uploadFilesState.length,
|
||||||
itemBuilder: (context, index) =>
|
itemBuilder: (context, index) => AttachmentFileComposerBuilder(
|
||||||
(AttachmentFileComposerBuilder(context, imagePaths, attachments[index],
|
uploadFilesState[index],
|
||||||
itemMargin: const EdgeInsets.only(right: 8),
|
itemMargin: const EdgeInsets.only(right: 8),
|
||||||
maxWidth: _getMaxWidthItemListAttachment(context, constraints),
|
maxWidth: _getMaxWidthItemListAttachment(context, constraints),
|
||||||
maxHeight: 60)
|
onDeleteAttachmentAction: (attachment) =>
|
||||||
..addOnDeleteAttachmentAction((attachment) => controller.removeAttachmentAction(attachment)))
|
controller.deleteAttachmentUploaded(attachment.uploadTaskId))
|
||||||
.build()
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import 'package:tmail_ui_user/features/composer/presentation/composer_controller
|
|||||||
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/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/model/upload_file_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> {
|
class ComposerView extends GetWidget<ComposerController> {
|
||||||
@@ -488,54 +490,65 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildEditorAndAttachments(BuildContext context) {
|
Widget _buildEditorAndAttachments(BuildContext context) {
|
||||||
return Column(
|
return Obx(() {
|
||||||
children: [
|
final uploadAttachments = controller.uploadController.listUploadAttachments;
|
||||||
Obx(() => controller.attachments.isNotEmpty
|
|
||||||
? Padding(
|
return Column(
|
||||||
padding: EdgeInsets.only(top: 4, bottom: 4, left: responsiveUtils.isMobile(context) ? 16 : 20, right: responsiveUtils.isMobile(context) ? 16: 0),
|
children: [
|
||||||
child: _buildAttachmentsTitle(context, controller.attachments, controller.expandModeAttachments.value))
|
if (uploadAttachments.isNotEmpty)
|
||||||
: const SizedBox.shrink()),
|
...[
|
||||||
Obx(() => controller.attachments.isEmpty
|
Padding(
|
||||||
? _buildAttachmentsLoadingView()
|
padding: EdgeInsets.only(
|
||||||
: const SizedBox.shrink()),
|
top: 4,
|
||||||
Obx(() => controller.attachments.isNotEmpty
|
bottom: 4,
|
||||||
? Padding(
|
left: responsiveUtils.isMobile(context) ? 16 : 20,
|
||||||
padding: EdgeInsets.only(bottom: 8, left: responsiveUtils.isMobile(context) ? 16 : 10, right: responsiveUtils.isMobile(context) ? 16 : 10),
|
right: responsiveUtils.isMobile(context) ? 16: 0),
|
||||||
child: _buildAttachmentsList(context, controller.attachments, controller.expandModeAttachments.value))
|
child: _buildAttachmentsTitle(context,
|
||||||
: const SizedBox.shrink()),
|
uploadAttachments,
|
||||||
Obx(() {
|
controller.expandModeAttachments.value)),
|
||||||
if (controller.composerArguments.value != null) {
|
_buildAttachmentsLoadingView(),
|
||||||
if (controller.composerArguments.value?.emailActionType == EmailActionType.compose) {
|
Padding(
|
||||||
final initContent = controller.textEditorWeb ?? ''.addEditorDefaultSpace();
|
padding: EdgeInsets.only(
|
||||||
return Expanded(child: Padding(
|
bottom: 8,
|
||||||
padding: EdgeInsets.symmetric(horizontal: responsiveUtils.isMobile(context) ? 8 : 10),
|
left: responsiveUtils.isMobile(context) ? 16 : 10,
|
||||||
child: _buildEditor(context, initContent)));
|
right: responsiveUtils.isMobile(context) ? 16 : 10),
|
||||||
} else if (controller.composerArguments.value?.emailActionType == EmailActionType.edit) {
|
child: _buildAttachmentsList(context,
|
||||||
final initContent = controller.textEditorWeb ?? controller.getEmailContentDraftsAsHtml();
|
uploadAttachments,
|
||||||
if (initContent != null) {
|
controller.expandModeAttachments.value))
|
||||||
return Expanded(child: Padding(
|
],
|
||||||
padding: EdgeInsets.symmetric(horizontal: responsiveUtils.isMobile(context) ? 8 : 10),
|
if (controller.composerArguments.value != null)
|
||||||
child: _buildEditor(context, initContent)));
|
_buildComposeEditor(context)
|
||||||
} else {
|
]
|
||||||
return const Padding(
|
);
|
||||||
padding: EdgeInsets.all(16),
|
});
|
||||||
child: SizedBox(
|
}
|
||||||
width: 30,
|
|
||||||
height: 30,
|
Widget _buildComposeEditor(BuildContext context) {
|
||||||
child: CupertinoActivityIndicator(color: AppColor.colorLoading)));
|
if (controller.composerArguments.value?.emailActionType == EmailActionType.compose) {
|
||||||
}
|
final initContent = controller.textEditorWeb ?? ''.addEditorDefaultSpace();
|
||||||
} else {
|
return Expanded(child: Padding(
|
||||||
final initContent = controller.textEditorWeb ?? controller.getEmailContentQuotedAsHtml(context, controller.composerArguments.value!);
|
padding: EdgeInsets.symmetric(horizontal: responsiveUtils.isMobile(context) ? 8 : 10),
|
||||||
return Expanded(child: Padding(
|
child: _buildEditor(context, initContent)));
|
||||||
padding: EdgeInsets.symmetric(horizontal: responsiveUtils.isMobile(context) ? 8 : 10),
|
} else if (controller.composerArguments.value?.emailActionType == EmailActionType.edit) {
|
||||||
child: _buildEditor(context, initContent)));
|
final initContent = controller.textEditorWeb ?? controller.getEmailContentDraftsAsHtml();
|
||||||
}
|
if (initContent != null) {
|
||||||
} else {
|
return Expanded(child: Padding(
|
||||||
return const SizedBox.shrink();
|
padding: EdgeInsets.symmetric(horizontal: responsiveUtils.isMobile(context) ? 8 : 10),
|
||||||
}
|
child: _buildEditor(context, initContent)));
|
||||||
}),
|
} else {
|
||||||
]
|
return const Padding(
|
||||||
);
|
padding: EdgeInsets.all(16),
|
||||||
|
child: SizedBox(
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
child: CupertinoActivityIndicator(color: AppColor.colorLoading)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final initContent = controller.textEditorWeb ?? controller.getEmailContentQuotedAsHtml(context, controller.composerArguments.value!);
|
||||||
|
return Expanded(child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: responsiveUtils.isMobile(context) ? 8 : 10),
|
||||||
|
child: _buildEditor(context, initContent)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildEditor(BuildContext context, String initContent) {
|
Widget _buildEditor(BuildContext context, String initContent) {
|
||||||
@@ -590,11 +603,14 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
: const SizedBox.shrink()));
|
: const SizedBox.shrink()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildAttachmentsTitle(BuildContext context, List<Attachment> attachments, ExpandMode expandModeAttachment) {
|
Widget _buildAttachmentsTitle(
|
||||||
|
BuildContext context,
|
||||||
|
List<UploadFileState> uploadFilesState,
|
||||||
|
ExpandMode expandModeAttachment) {
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'${AppLocalizations.of(context).attachments} (${filesize(attachments.totalSize(), 0)}):',
|
'${AppLocalizations.of(context).attachments} (${filesize(uploadFilesState.totalSize, 0)}):',
|
||||||
style: const TextStyle(fontSize: 12, color: AppColor.colorHintEmailAddressInput, fontWeight: FontWeight.normal)),
|
style: const TextStyle(fontSize: 12, color: AppColor.colorHintEmailAddressInput, fontWeight: FontWeight.normal)),
|
||||||
_buildAttachmentsLoadingView(padding: const EdgeInsets.only(left: 16), size: 16),
|
_buildAttachmentsLoadingView(padding: const EdgeInsets.only(left: 16), size: 16),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
@@ -605,7 +621,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
expandModeAttachment == ExpandMode.EXPAND
|
expandModeAttachment == ExpandMode.EXPAND
|
||||||
? AppLocalizations.of(context).hide
|
? AppLocalizations.of(context).hide
|
||||||
: '${AppLocalizations.of(context).show_all} (${attachments.length})',
|
: '${AppLocalizations.of(context).show_all} (${uploadFilesState.length})',
|
||||||
style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 12, color: AppColor.colorTextButton)),
|
style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 12, color: AppColor.colorTextButton)),
|
||||||
onPressed: () => controller.toggleDisplayAttachments()
|
onPressed: () => controller.toggleDisplayAttachments()
|
||||||
)
|
)
|
||||||
@@ -614,7 +630,10 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildAttachmentsList(BuildContext context, List<Attachment> attachments, ExpandMode expandMode) {
|
Widget _buildAttachmentsList(
|
||||||
|
BuildContext context,
|
||||||
|
List<UploadFileState> uploadFilesState,
|
||||||
|
ExpandMode expandMode) {
|
||||||
if (expandMode == ExpandMode.COLLAPSE) {
|
if (expandMode == ExpandMode.COLLAPSE) {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
} else {
|
} else {
|
||||||
@@ -628,14 +647,13 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
physics: const ClampingScrollPhysics(),
|
physics: const ClampingScrollPhysics(),
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
itemCount: attachments.length,
|
itemCount: uploadFilesState.length,
|
||||||
itemBuilder: (context, index) =>
|
itemBuilder: (context, index) => AttachmentFileComposerBuilder(
|
||||||
(AttachmentFileComposerBuilder(context, imagePaths, attachments[index],
|
uploadFilesState[index],
|
||||||
itemMargin: const EdgeInsets.only(right: 8),
|
itemMargin: const EdgeInsets.only(right: 8),
|
||||||
maxWidth: _getMaxWidthItemListAttachment(context, constraints),
|
maxWidth: _getMaxWidthItemListAttachment(context, constraints),
|
||||||
maxHeight: 60)
|
onDeleteAttachmentAction: (attachment) =>
|
||||||
..addOnDeleteAttachmentAction((attachment) => controller.removeAttachmentAction(attachment)))
|
controller.deleteAttachmentUploaded(attachment.uploadTaskId))
|
||||||
.build()
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,88 +1,131 @@
|
|||||||
|
|
||||||
import 'package:core/core.dart';
|
import 'package:core/core.dart';
|
||||||
import 'package:filesize/filesize.dart';
|
import 'package:filesize/filesize.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
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:model/model.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.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_status.dart';
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
|
|
||||||
typedef OnDeleteAttachmentAction = void Function(Attachment attachment);
|
typedef OnDeleteAttachmentAction = void Function(UploadFileState fileState);
|
||||||
|
|
||||||
class AttachmentFileComposerBuilder {
|
class AttachmentFileComposerBuilder extends StatelessWidget with AppLoaderMixin {
|
||||||
|
|
||||||
final BuildContext context;
|
final _imagePaths = Get.find<ImagePaths>();
|
||||||
final ImagePaths imagePaths;
|
|
||||||
final Attachment attachment;
|
final UploadFileState fileState;
|
||||||
final double? maxWidth;
|
final double? maxWidth;
|
||||||
final double? maxHeight;
|
|
||||||
final EdgeInsets? itemMargin;
|
final EdgeInsets? itemMargin;
|
||||||
|
final OnDeleteAttachmentAction? onDeleteAttachmentAction;
|
||||||
|
final Widget? buttonAction;
|
||||||
|
|
||||||
OnDeleteAttachmentAction? _onDeleteAttachmentAction;
|
AttachmentFileComposerBuilder(this.fileState, {
|
||||||
|
super.key,
|
||||||
|
this.maxWidth,
|
||||||
|
this.itemMargin,
|
||||||
|
this.buttonAction,
|
||||||
|
this.onDeleteAttachmentAction,
|
||||||
|
});
|
||||||
|
|
||||||
Widget? buttonAction;
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
AttachmentFileComposerBuilder(
|
|
||||||
this.context,
|
|
||||||
this.imagePaths,
|
|
||||||
this.attachment,
|
|
||||||
{
|
|
||||||
this.maxWidth,
|
|
||||||
this.maxHeight,
|
|
||||||
this.itemMargin,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
void addOnDeleteAttachmentAction(OnDeleteAttachmentAction onDeleteAttachmentAction) {
|
|
||||||
_onDeleteAttachmentAction = onDeleteAttachmentAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget build() {
|
|
||||||
return Theme(
|
return Theme(
|
||||||
data: ThemeData(
|
data: ThemeData(
|
||||||
splashColor: Colors.transparent ,
|
splashColor: Colors.transparent ,
|
||||||
highlightColor: Colors.transparent),
|
highlightColor: Colors.transparent),
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: itemMargin ?? EdgeInsets.zero,
|
margin: itemMargin ?? EdgeInsets.zero,
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
width: maxWidth,
|
width: maxWidth,
|
||||||
height: maxHeight,
|
decoration: BoxDecoration(
|
||||||
decoration: BoxDecoration(
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderRadius: BorderRadius.circular(10),
|
border: Border.all(color: AppColor.colorInputBorderCreateMailbox),
|
||||||
border: Border.all(color: AppColor.colorInputBorderCreateMailbox),
|
color: Colors.white),
|
||||||
color: Colors.white),
|
child: Stack(children: [
|
||||||
child: Stack(children: [
|
ListTile(
|
||||||
ListTile(
|
contentPadding: EdgeInsets.zero,
|
||||||
contentPadding: const EdgeInsets.only(right: kIsWeb ? 16 : 18),
|
focusColor: AppColor.primaryColor,
|
||||||
|
hoverColor: AppColor.primaryColor,
|
||||||
onTap: () {},
|
onTap: () {},
|
||||||
leading: Transform(
|
leading: Padding(
|
||||||
transform: Matrix4.translationValues(8.0, kIsWeb ? -3.0 : -5.0, 0.0),
|
padding: const EdgeInsets.only(
|
||||||
child: SvgPicture.asset(imagePaths.icFileAttachment, fit: BoxFit.fill)),
|
left: 8,
|
||||||
|
bottom: BuildUtils.isWeb ? 6 : 14),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
fileState.getIcon(_imagePaths),
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
fit: BoxFit.fill),
|
||||||
|
),
|
||||||
title: Transform(
|
title: Transform(
|
||||||
transform: Matrix4.translationValues(kIsWeb ? -4.0 : -10.0, kIsWeb ? -6.0 : -9.0, 0.0),
|
transform: Matrix4.translationValues(
|
||||||
child: Text(
|
BuildUtils.isWeb ? 0.0 : -8.0,
|
||||||
attachment.name ?? '',
|
BuildUtils.isWeb ? -8.0 : -10.0,
|
||||||
maxLines: 2,
|
0.0),
|
||||||
overflow: TextOverflow.ellipsis,
|
child: Padding(
|
||||||
style: const TextStyle(fontSize: 12, color: AppColor.colorNameEmail, fontWeight: FontWeight.w500),
|
padding: const EdgeInsets.only(right: BuildUtils.isWeb ? 20 : 16),
|
||||||
)),
|
child: Text(
|
||||||
subtitle: attachment.size != null && attachment.size?.value != 0
|
fileState.fileName,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: CommonTextStyle.defaultTextOverFlow,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Colors.black,
|
||||||
|
fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
subtitle: fileState.fileSize != 0
|
||||||
? Transform(
|
? Transform(
|
||||||
transform: Matrix4.translationValues(kIsWeb ? -4.0 : -10.0, kIsWeb ? -5.0 : -8.0, 0.0),
|
transform: Matrix4.translationValues(
|
||||||
|
BuildUtils.isWeb ? 0.0 : -8.0,
|
||||||
|
BuildUtils.isWeb ? -8.0 : -10.0,
|
||||||
|
0.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
filesize(attachment.size?.value, 0),
|
filesize(fileState.fileSize),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: CommonTextStyle.defaultTextOverFlow,
|
||||||
style: const TextStyle(fontSize: 10, color: AppColor.colorContentEmail, fontWeight: FontWeight.normal)))
|
style: const TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
color: AppColor.colorContentEmail)))
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
Positioned(right: kIsWeb ? -5 : -12, top: kIsWeb ? -5 : -12, child: buildIconWeb(
|
Positioned(
|
||||||
icon: SvgPicture.asset(imagePaths.icDeleteAttachment, fit: BoxFit.fill),
|
right: BuildUtils.isWeb ? -5 : -12,
|
||||||
tooltip: AppLocalizations.of(context).delete,
|
top: BuildUtils.isWeb ? -5 : -12,
|
||||||
onTap: () => _onDeleteAttachmentAction?.call(attachment)))
|
child: buildIconWeb(
|
||||||
]),
|
icon: SvgPicture.asset(_imagePaths.icDeleteAttachment, fit: BoxFit.fill),
|
||||||
)
|
tooltip: AppLocalizations.of(context).delete,
|
||||||
|
onTap: () {
|
||||||
|
if (onDeleteAttachmentAction != null) {
|
||||||
|
onDeleteAttachmentAction!.call(fileState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Align(alignment: Alignment.bottomCenter, child: _progressLoading),
|
||||||
|
]),
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget get _progressLoading {
|
||||||
|
switch(fileState.uploadStatus) {
|
||||||
|
case UploadFileStatus.waiting:
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 8, right: 8, top: 50),
|
||||||
|
child: horizontalLoadingWidget);
|
||||||
|
case UploadFileStatus.uploading:
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 50),
|
||||||
|
child: horizontalPercentLoadingWidget(fileState.percentUploading));
|
||||||
|
case UploadFileStatus.uploadFailed:
|
||||||
|
case UploadFileStatus.succeed:
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -406,9 +406,11 @@ class EmailView extends GetWidget<EmailController> with NetworkConnectionMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int _getAttachmentLimitDisplayed(BuildContext context) {
|
int _getAttachmentLimitDisplayed(BuildContext context) {
|
||||||
if (responsiveUtils.isScreenWithShortestSide(context)) {
|
if (responsiveUtils.isMobile(context)
|
||||||
|
|| responsiveUtils.isLandscapeMobile(context)) {
|
||||||
return 2;
|
return 2;
|
||||||
} else if (responsiveUtils.isTablet(context)) {
|
} else if (responsiveUtils.isTablet(context) ||
|
||||||
|
responsiveUtils.isLandscapeTablet(context)) {
|
||||||
return 3;
|
return 3;
|
||||||
} else {
|
} else {
|
||||||
return 4;
|
return 4;
|
||||||
|
|||||||
@@ -82,8 +82,8 @@ class AttachmentFileTileBuilder {
|
|||||||
padding: const EdgeInsets.only(left: 8, bottom: BuildUtils.isWeb ? 6 : 14),
|
padding: const EdgeInsets.only(left: 8, bottom: BuildUtils.isWeb ? 6 : 14),
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
_attachment.getIcon(_imagePaths),
|
_attachment.getIcon(_imagePaths),
|
||||||
width: 44,
|
width: 40,
|
||||||
height: 44,
|
height: 40,
|
||||||
fit: BoxFit.fill),
|
fit: BoxFit.fill),
|
||||||
),
|
),
|
||||||
title: Transform(
|
title: Transform(
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_na
|
|||||||
import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart';
|
import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/data/datasource_impl/thread_datasource_impl.dart';
|
import 'package:tmail_ui_user/features/thread/data/datasource_impl/thread_datasource_impl.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/data/network/thread_api.dart';
|
import 'package:tmail_ui_user/features/thread/data/network/thread_api.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
|
||||||
|
|
||||||
class MailboxBindings extends BaseBindings {
|
class MailboxBindings extends BaseBindings {
|
||||||
|
|
||||||
@@ -43,7 +42,6 @@ class MailboxBindings extends BaseBindings {
|
|||||||
|
|
||||||
void _bindingsUtils() {
|
void _bindingsUtils() {
|
||||||
Get.lazyPut(() => TreeBuilder());
|
Get.lazyPut(() => TreeBuilder());
|
||||||
Get.lazyPut(() => const Uuid());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -57,7 +55,6 @@ class MailboxBindings extends BaseBindings {
|
|||||||
Get.find<VerifyNameInteractor>(),
|
Get.find<VerifyNameInteractor>(),
|
||||||
Get.find<RenameMailboxInteractor>(),
|
Get.find<RenameMailboxInteractor>(),
|
||||||
Get.find<MoveMailboxInteractor>(),
|
Get.find<MoveMailboxInteractor>(),
|
||||||
Get.find<Uuid>(),
|
|
||||||
Get.find<TreeBuilder>(),
|
Get.find<TreeBuilder>(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ class MailboxController extends BaseMailboxController {
|
|||||||
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>();
|
||||||
|
final _uuid = Get.find<Uuid>();
|
||||||
|
|
||||||
final GetAllMailboxInteractor _getAllMailboxInteractor;
|
final GetAllMailboxInteractor _getAllMailboxInteractor;
|
||||||
final RefreshAllMailboxInteractor _refreshAllMailboxInteractor;
|
final RefreshAllMailboxInteractor _refreshAllMailboxInteractor;
|
||||||
@@ -83,7 +84,6 @@ class MailboxController extends BaseMailboxController {
|
|||||||
final VerifyNameInteractor _verifyNameInteractor;
|
final VerifyNameInteractor _verifyNameInteractor;
|
||||||
final RenameMailboxInteractor _renameMailboxInteractor;
|
final RenameMailboxInteractor _renameMailboxInteractor;
|
||||||
final MoveMailboxInteractor _moveMailboxInteractor;
|
final MoveMailboxInteractor _moveMailboxInteractor;
|
||||||
final Uuid _uuid;
|
|
||||||
|
|
||||||
final listMailboxSearched = <PresentationMailbox>[].obs;
|
final listMailboxSearched = <PresentationMailbox>[].obs;
|
||||||
final searchState = SearchState.initial().obs;
|
final searchState = SearchState.initial().obs;
|
||||||
@@ -110,7 +110,6 @@ class MailboxController extends BaseMailboxController {
|
|||||||
this._verifyNameInteractor,
|
this._verifyNameInteractor,
|
||||||
this._renameMailboxInteractor,
|
this._renameMailboxInteractor,
|
||||||
this._moveMailboxInteractor,
|
this._moveMailboxInteractor,
|
||||||
this._uuid,
|
|
||||||
treeBuilder,
|
treeBuilder,
|
||||||
) : super(treeBuilder);
|
) : super(treeBuilder);
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -21,7 +21,6 @@ import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_draft
|
|||||||
import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart';
|
import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart';
|
import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/composer_bindings.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/composer_bindings.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/composer_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/email/domain/model/move_action.dart';
|
import 'package:tmail_ui_user/features/email/domain/model/move_action.dart';
|
||||||
import 'package:tmail_ui_user/features/email/domain/model/move_to_mailbox_request.dart';
|
import 'package:tmail_ui_user/features/email/domain/model/move_to_mailbox_request.dart';
|
||||||
@@ -384,7 +383,7 @@ class MailboxDashBoardController extends ReloadableController {
|
|||||||
|
|
||||||
void closeComposerOverlay() {
|
void closeComposerOverlay() {
|
||||||
routerArguments = null;
|
routerArguments = null;
|
||||||
Get.delete<ComposerController>();
|
ComposerBindings().dispose();
|
||||||
composerOverlayState.value = ComposerOverlayState.inActive;
|
composerOverlayState.value = ComposerOverlayState.inActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,23 +6,15 @@ import 'package:tmail_ui_user/features/manage_account/domain/usecases/delete_ide
|
|||||||
import 'package:tmail_ui_user/features/manage_account/domain/usecases/edit_identity_interactor.dart';
|
import 'package:tmail_ui_user/features/manage_account/domain/usecases/edit_identity_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart';
|
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/identities_controller.dart';
|
import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/identities_controller.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
|
||||||
|
|
||||||
class IdentitiesBindings extends BaseBindings {
|
class IdentitiesBindings extends BaseBindings {
|
||||||
|
|
||||||
@override
|
|
||||||
void dependencies() {
|
|
||||||
Get.lazyPut(() => const Uuid());
|
|
||||||
super.dependencies();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void bindingsController() {
|
void bindingsController() {
|
||||||
Get.lazyPut(() => IdentitiesController(
|
Get.lazyPut(() => IdentitiesController(
|
||||||
Get.find<GetAllIdentitiesInteractor>(),
|
Get.find<GetAllIdentitiesInteractor>(),
|
||||||
Get.find<DeleteIdentityInteractor>(),
|
Get.find<DeleteIdentityInteractor>(),
|
||||||
Get.find<CreateNewIdentityInteractor>(),
|
Get.find<CreateNewIdentityInteractor>(),
|
||||||
Get.find<Uuid>(),
|
|
||||||
Get.find<EditIdentityInteractor>(),
|
Get.find<EditIdentityInteractor>(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -32,10 +32,10 @@ class IdentitiesController extends BaseController {
|
|||||||
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>();
|
||||||
|
final _uuid = Get.find<Uuid>();
|
||||||
|
|
||||||
final GetAllIdentitiesInteractor _getAllIdentitiesInteractor;
|
final GetAllIdentitiesInteractor _getAllIdentitiesInteractor;
|
||||||
final CreateNewIdentityInteractor _createNewIdentityInteractor;
|
final CreateNewIdentityInteractor _createNewIdentityInteractor;
|
||||||
final Uuid _uuid;
|
|
||||||
final DeleteIdentityInteractor _deleteIdentityInteractor;
|
final DeleteIdentityInteractor _deleteIdentityInteractor;
|
||||||
final EditIdentityInteractor _editIdentityInteractor;
|
final EditIdentityInteractor _editIdentityInteractor;
|
||||||
|
|
||||||
@@ -51,7 +51,6 @@ class IdentitiesController extends BaseController {
|
|||||||
this._getAllIdentitiesInteractor,
|
this._getAllIdentitiesInteractor,
|
||||||
this._deleteIdentityInteractor,
|
this._deleteIdentityInteractor,
|
||||||
this._createNewIdentityInteractor,
|
this._createNewIdentityInteractor,
|
||||||
this._uuid,
|
|
||||||
this._editIdentityInteractor,
|
this._editIdentityInteractor,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"@@last_modified": "2022-07-08T15:25:15.196374",
|
"@@last_modified": "2022-07-05T19:24:56.876056",
|
||||||
"initializing_data": "Initializing data...",
|
"initializing_data": "Initializing data...",
|
||||||
"@initializing_data": {
|
"@initializing_data": {
|
||||||
"type": "text",
|
"type": "text",
|
||||||
@@ -1561,5 +1561,11 @@
|
|||||||
"type": "text",
|
"type": "text",
|
||||||
"placeholders_order": [],
|
"placeholders_order": [],
|
||||||
"placeholders": {}
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"messageDialogSendEmailUploadingAttachment": "Your message could not be sent because it uploading attachment",
|
||||||
|
"@messageDialogSendEmailUploadingAttachment": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders_order": [],
|
||||||
|
"placeholders": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ import 'package:get/get.dart';
|
|||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart';
|
import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart';
|
||||||
import 'package:tmail_ui_user/main/utils/email_receive_manager.dart';
|
import 'package:tmail_ui_user/main/utils/email_receive_manager.dart';
|
||||||
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
class CoreBindings extends Bindings {
|
class CoreBindings extends Bindings {
|
||||||
|
|
||||||
@@ -18,6 +19,7 @@ class CoreBindings extends Bindings {
|
|||||||
_bindingToast();
|
_bindingToast();
|
||||||
_bindingDeviceManager();
|
_bindingDeviceManager();
|
||||||
_bindingReceivingSharingStream();
|
_bindingReceivingSharingStream();
|
||||||
|
_bindingUtils();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _bindingAppImagePaths() {
|
void _bindingAppImagePaths() {
|
||||||
@@ -53,4 +55,8 @@ class CoreBindings extends Bindings {
|
|||||||
void _bindingReceivingSharingStream() {
|
void _bindingReceivingSharingStream() {
|
||||||
Get.put(EmailReceiveManager());
|
Get.put(EmailReceiveManager());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _bindingUtils() {
|
||||||
|
Get.put(const Uuid());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,6 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter_appauth/flutter_appauth.dart';
|
import 'package:flutter_appauth/flutter_appauth.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:jmap_dart_client/http/http_client.dart' as JmapHttpClient;
|
import 'package:jmap_dart_client/http/http_client.dart' as JmapHttpClient;
|
||||||
import 'package:tmail_ui_user/features/composer/data/network/composer_api.dart';
|
|
||||||
import 'package:tmail_ui_user/features/email/data/network/email_api.dart';
|
import 'package:tmail_ui_user/features/email/data/network/email_api.dart';
|
||||||
import 'package:tmail_ui_user/features/login/data/local/account_cache_manager.dart';
|
import 'package:tmail_ui_user/features/login/data/local/account_cache_manager.dart';
|
||||||
import 'package:tmail_ui_user/features/login/data/local/token_oidc_cache_manager.dart';
|
import 'package:tmail_ui_user/features/login/data/local/token_oidc_cache_manager.dart';
|
||||||
@@ -77,7 +76,6 @@ class NetworkBindings extends Bindings {
|
|||||||
Get.put(EmailAPI(
|
Get.put(EmailAPI(
|
||||||
Get.find<JmapHttpClient.HttpClient>(),
|
Get.find<JmapHttpClient.HttpClient>(),
|
||||||
Get.find<DownloadManager>()));
|
Get.find<DownloadManager>()));
|
||||||
Get.put(ComposerAPI(Get.find<DioClient>()));
|
|
||||||
Get.put(ManageAccountAPI(Get.find<JmapHttpClient.HttpClient>()));
|
Get.put(ManageAccountAPI(Get.find<JmapHttpClient.HttpClient>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1601,4 +1601,11 @@ class AppLocalizations {
|
|||||||
'Russian',
|
'Russian',
|
||||||
name: 'languageRussian');
|
name: 'languageRussian');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get messageDialogSendEmailUploadingAttachment {
|
||||||
|
return Intl.message(
|
||||||
|
'Your message could not be sent because it uploading attachment',
|
||||||
|
name: 'messageDialogSendEmailUploadingAttachment'
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -16,12 +16,13 @@ extension SessionExtension on Session {
|
|||||||
return downloadUrlDecode;
|
return downloadUrlDecode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uri getUploadUrl(AccountId accountId) {
|
Uri getUploadUri(AccountId accountId) {
|
||||||
final baseUrl = '${uploadUrl.origin}${uploadUrl.path}';
|
final baseUrl = '${uploadUrl.origin}${uploadUrl.path}';
|
||||||
final uploadUriTemplate = UriTemplate('${Uri.decodeFull(baseUrl)}');
|
final uploadUriTemplate = UriTemplate('${Uri.decodeFull(baseUrl)}');
|
||||||
final uploadUri = uploadUriTemplate.expand({
|
final uploadUri = uploadUriTemplate.expand({
|
||||||
'accountId' : '${accountId.id.value}'
|
'accountId' : '${accountId.id.value}'
|
||||||
});
|
});
|
||||||
|
log('SessionExtension::getUploadUri(): uploadUri: $uploadUri');
|
||||||
return Uri.parse(uploadUri);
|
return Uri.parse(uploadUri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ class UploadResponse with EquatableMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension UploadResponseExtension on UploadResponse {
|
extension UploadResponseExtension on UploadResponse {
|
||||||
Attachment toAttachmentFile(String nameFile, {MediaType? mediaType}) {
|
Attachment toAttachment(String nameFile) {
|
||||||
return Attachment(blobId: blobId, size: UnsignedInt(size), name: nameFile, type: mediaType ?? type);
|
return Attachment(blobId: blobId, size: UnsignedInt(size), name: nameFile, type: type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,6 +172,8 @@ dependencies:
|
|||||||
# Isolate
|
# Isolate
|
||||||
worker_manager: 4.4.0
|
worker_manager: 4.4.0
|
||||||
|
|
||||||
|
async: 2.8.2
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|||||||
Reference in New Issue
Block a user