TF-32 Add presentation layer of export attachment for ios platform

This commit is contained in:
dab246
2021-09-16 09:46:49 +07:00
committed by Dat H. Pham
parent afae25a97a
commit d168900975
19 changed files with 517 additions and 119 deletions
+6
View File
@@ -1,5 +1,6 @@
import UIKit
import Flutter
import flutter_downloader
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
@@ -8,6 +9,11 @@ import Flutter
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
FlutterDownloaderPlugin.setPluginRegistrantCallback { registry in
if (!registry.hasPlugin("FlutterDownloaderPlugin")) {
FlutterDownloaderPlugin.register(with: registry.registrar(forPlugin: "FlutterDownloaderPlugin")!)
}
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
+2
View File
@@ -26,6 +26,8 @@
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>To save photo to library, we need permission to access your photo library.</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
@@ -7,6 +7,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/download_attachments_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/export_attachment_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_interactor.dart';
import 'package:tmail_ui_user/features/email/presentation/email_controller.dart';
@@ -22,17 +23,20 @@ class EmailBindings extends Bindings {
Get.lazyPut<EmailRepository>(() => Get.find<EmailRepositoryImpl>());
Get.lazyPut(() => GetEmailContentInteractor(Get.find<EmailRepository>()));
Get.lazyPut(() => MarkAsEmailReadInteractor(Get.find<EmailRepository>()));
Get.put(EmailController(
Get.find<GetEmailContentInteractor>(),
Get.find<MarkAsEmailReadInteractor>()));
Get.lazyPut(() => CredentialRepositoryImpl(Get.find<SharedPreferences>()));
Get.lazyPut<CredentialRepository>(() => Get.find<CredentialRepositoryImpl>());
Get.lazyPut(() => DownloadAttachmentsInteractor(
Get.find<EmailRepository>(),
Get.find<CredentialRepository>()));
Get.lazyPut(() => ExportAttachmentInteractor(
Get.find<EmailRepository>(),
Get.find<CredentialRepository>()));
Get.put(EmailController(
Get.find<GetEmailContentInteractor>(),
Get.find<DownloadAttachmentsInteractor>(),
Get.find<DeviceManager>()));
Get.find<GetEmailContentInteractor>(),
Get.find<MarkAsEmailReadInteractor>(),
Get.find<DownloadAttachmentsInteractor>(),
Get.find<DeviceManager>(),
Get.find<AppToast>(),
Get.find<ExportAttachmentInteractor>()));
}
}
@@ -1,16 +1,21 @@
import 'dart:io';
import 'package:core/core.dart';
import 'package:dartz/dartz.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:model/model.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/email/domain/state/download_attachments_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/export_attachment_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/download_attachments_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_state.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/export_attachment_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_interactor.dart';
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
@@ -18,6 +23,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_da
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:share/share.dart' as share_library;
class EmailController extends BaseController {
@@ -28,22 +34,27 @@ class EmailController extends BaseController {
final MarkAsEmailReadInteractor _markAsEmailReadInteractor;
final DownloadAttachmentsInteractor _downloadAttachmentsInteractor;
final DeviceManager _deviceManager;
final AppToast _appToast;
final ExportAttachmentInteractor _exportAttachmentInteractor;
final emailAddressExpandMode = ExpandMode.COLLAPSE.obs;
EmailContent? emailContent;
final attachmentsExpandMode = ExpandMode.COLLAPSE.obs;
final emailContent = Rxn<EmailContent>();
EmailController(this._getEmailContentInteractor, this._markAsEmailReadInteractor);
EmailController(
this._getEmailContentInteractor,
this._markAsEmailReadInteractor,
this._downloadAttachmentsInteractor,
this._deviceManager
this._deviceManager,
this._appToast,
this._exportAttachmentInteractor,
);
@override
void onReady() {
super.onReady();
mailboxDashBoardController.selectedEmail.listen((presentationEmail) {
toggleDisplayEmailAddressAction(expandMode: ExpandMode.COLLAPSE);
_clearEmailContent();
final accountId = mailboxDashBoardController.accountId.value;
if (accountId != null && presentationEmail != null) {
_getEmailContentAction(accountId, presentationEmail.id);
@@ -75,13 +86,19 @@ class EmailController extends BaseController {
(failure) {
if (failure is MarkAsEmailReadFailure) {
_markAsEmailReadFailure(failure);
} else if (failure is DownloadAttachmentsFailure) {
_downloadAttachmentsFailure(failure);
} else if (failure is ExportAttachmentFailure) {
_exportAttachmentFailureAction(failure);
}
},
(success) {
if (success is GetEmailContentSuccess) {
emailContent = success.emailContent;
emailContent.value = success.emailContent;
} else if (success is MarkAsEmailReadSuccess) {
_markAsEmailReadSuccess(success);
} else if (success is ExportAttachmentSuccess) {
_exportAttachmentSuccessAction(success);
}
});
}
@@ -90,6 +107,12 @@ class EmailController extends BaseController {
void onError(error) {
}
void _clearEmailContent() {
toggleDisplayEmailAddressAction(expandMode: ExpandMode.COLLAPSE);
attachmentsExpandMode.value = ExpandMode.COLLAPSE;
emailContent.value = null;
}
void toggleDisplayEmailAddressAction({required ExpandMode expandMode}) {
emailAddressExpandMode.value = expandMode;
}
@@ -114,10 +137,17 @@ class EmailController extends BaseController {
backToThreadView();
}
void toggleDisplayAttachmentsAction() {
final newExpandMode = attachmentsExpandMode.value == ExpandMode.COLLAPSE
? ExpandMode.EXPAND
: ExpandMode.COLLAPSE;
attachmentsExpandMode.value = newExpandMode;
}
void downloadAttachments(BuildContext context, List<Attachment> attachments) async {
final needRequestPermission = await _deviceManager.isNeedRequestStoragePermissionOnAndroid();
if (Platform.isAndroid && needRequestPermission) {
if (needRequestPermission) {
final status = await Permission.storage.status;
switch (status) {
case PermissionStatus.granted:
@@ -147,10 +177,55 @@ class EmailController extends BaseController {
final accountId = mailboxDashBoardController.accountId.value;
if (accountId != null && mailboxDashBoardController.sessionCurrent != null) {
final baseDownloadUrl = mailboxDashBoardController.sessionCurrent!.getDownloadUrl();
await _downloadAttachmentsInteractor.execute(attachments, accountId, baseDownloadUrl)
.then((result) => result.fold(
(failure) => AppLocalizations.of(context).attachment_download_failed,
(success) => AppLocalizations.of(context).attachment_download_successfully));
consumeState(_downloadAttachmentsInteractor.execute(attachments, accountId, baseDownloadUrl));
}
}
void _downloadAttachmentsFailure(Failure failure) {
if (Get.context != null) {
_appToast.showErrorToast(AppLocalizations.of(Get.context!).attachment_download_failed);
}
}
void exportAttachment(BuildContext context, Attachment attachment) {
final cancelToken = CancelToken();
_showDownloadingFileDialog(context, attachment, cancelToken);
_exportAttachmentAction(attachment, cancelToken);
}
void _showDownloadingFileDialog(BuildContext context, Attachment attachment, CancelToken cancelToken) {
showCupertinoDialog(
context: context,
builder: (_) => (DownloadingFileDialogBuilder()
..key(Key('downloading_file_dialog'))
..title(AppLocalizations.of(context).preparing_to_export)
..content(AppLocalizations.of(context).downloading_file(attachment.name ?? ''))
..actionText(AppLocalizations.of(context).cancel)
..addCancelDownloadActionClick(() {
cancelToken.cancel([AppLocalizations.of(context).user_cancel_download_file]);
Get.back();
}))
.build());
}
void _exportAttachmentAction(Attachment attachment, CancelToken cancelToken) async {
final accountId = mailboxDashBoardController.accountId.value;
if (accountId != null && mailboxDashBoardController.sessionCurrent != null) {
final baseDownloadUrl = mailboxDashBoardController.sessionCurrent!.getDownloadUrl();
consumeState(_exportAttachmentInteractor.execute(attachment, accountId, baseDownloadUrl, cancelToken));
}
}
void _exportAttachmentFailureAction(Failure failure) {
if (failure is ExportAttachmentFailure && !(failure.exception is CancelDownloadFileException)) {
popBack();
}
}
void _exportAttachmentSuccessAction(Success success) async {
popBack();
if (success is ExportAttachmentSuccess) {
await share_library.Share.shareFiles([success.filePath]);
}
}
@@ -165,12 +240,12 @@ class EmailController extends BaseController {
void pressEmailAction(EmailActionType emailActionType) {
if (canComposeEmail()) {
Get.toNamed(
push(
AppRoutes.COMPOSER,
arguments: ComposerArguments(
emailActionType: emailActionType,
presentationEmail: mailboxDashBoardController.selectedEmail.value!,
emailContent: emailContent,
emailContent: emailContent.value,
session: mailboxDashBoardController.sessionCurrent!,
userProfile: mailboxDashBoardController.userProfile.value!,
mapMailboxId: mailboxDashBoardController.mapMailboxId));
+140 -51
View File
@@ -1,17 +1,21 @@
import 'dart:io';
import 'package:core/core.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:model/model.dart';
import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart';
import 'package:tmail_ui_user/features/email/presentation/email_controller.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/app_bar_mail_widget_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_file_tile_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/bottom_bar_mail_widget_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/extensions/email_content_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/extensions/list_attachment_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/message_content_tile_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/sender_and_receiver_information_tile_builder.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:filesize/filesize.dart';
class EmailView extends GetWidget {
@@ -138,11 +142,11 @@ class EmailView extends GetWidget {
imagePaths,
emailController.mailboxDashBoardController.selectedEmail.value,
emailController.emailAddressExpandMode.value)
.onOpenExpandAddressReceiverActionClick(() => emailController.toggleDisplayEmailAddressAction(expandMode: ExpandMode.EXPAND))
.onOpenExpandAddressReceiverActionClick(() => emailController.toggleDisplayAttachmentsAction())
.build()),
_buildLoadingView(),
_buildListMessageContent(),
_buildListAttachments(context),
_buildListMessageContent(),
],
)
);
@@ -150,66 +154,151 @@ class EmailView extends GetWidget {
Widget _buildListAttachments(BuildContext context) {
if (emailController.mailboxDashBoardController.selectedEmail.value?.hasAttachment == true) {
return Obx(() => emailController.viewState.value.fold(
(failure) => SizedBox.shrink(),
(success) {
if (success is GetEmailContentSuccess && success.emailContent != null) {
final attachments = success.emailContent!.getListAttachment();
return attachments.isNotEmpty
? GridView.builder(
key: Key('list_attachment'),
primary: false,
shrinkWrap: true,
padding: EdgeInsets.only(top: 16),
itemCount: attachments.length,
gridDelegate: SliverGridDelegateFixedHeight(
height: 60,
crossAxisCount: responsiveUtils.isMobile(context) ? 2 : 4,
crossAxisSpacing: 16.0,
mainAxisSpacing: 8.0),
itemBuilder: (context, index) =>
(AttachmentFileTileBuilder(imagePaths, attachments[index])
..onDownloadAttachmentFileActionClick((attachment) =>
emailController.downloadAttachments(context, [attachment])))
.build())
return Obx(() {
if (emailController.emailContent.value != null) {
final attachments = emailController.emailContent.value!.getListAttachment();
return attachments.isNotEmpty
? _buildAttachmentsBody(context, attachments)
: SizedBox.shrink();
} else {
return SizedBox.shrink();
}
})
);
} else {
return SizedBox.shrink();
}
});
} else {
return SizedBox.shrink();
}
}
int _getAttachmentLimitDisplayed(BuildContext context) {
if (responsiveUtils.isMobile(context)) {
return 2;
} else if (responsiveUtils.isTablet(context)) {
return 4;
} else {
return 3;
}
}
Widget _buildAttachmentsBody(BuildContext context, List<Attachment> attachments) {
final attachmentLimitDisplayed = _getAttachmentLimitDisplayed(context);
final countAttachments = _getListAttachmentsSize(
context,
emailController.attachmentsExpandMode.value,
attachments,
attachmentLimitDisplayed);
final isExpand = emailController.attachmentsExpandMode.value == ExpandMode.EXPAND
&& attachments.length > attachmentLimitDisplayed;
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (isExpand)
Padding(
padding: EdgeInsets.zero,
child: _buildAttachmentsHeader(context, attachments)),
GridView.builder(
key: Key('list_attachment'),
primary: false,
shrinkWrap: true,
padding: EdgeInsets.only(top: isExpand ? 0 : 16),
itemCount: countAttachments,
gridDelegate: SliverGridDelegateFixedHeight(
height: 60,
crossAxisCount: attachmentLimitDisplayed,
crossAxisSpacing: 16.0,
mainAxisSpacing: 8.0),
itemBuilder: (context, index) =>
(AttachmentFileTileBuilder(
imagePaths,
attachments[index],
attachments.length,
attachmentLimitDisplayed)
..setExpandMode((countAttachments - 1 == index) ? emailController.attachmentsExpandMode.value : null)
..onExpandAttachmentActionClick(() => emailController.toggleDisplayAttachmentsAction())
..onDownloadAttachmentFileActionClick((attachment) {
if (Platform.isAndroid) {
emailController.downloadAttachments(context, [attachment]);
} else {
emailController.exportAttachment(context, attachment);
}
}))
.build())
],
);
}
int _getListAttachmentsSize(
BuildContext context,
ExpandMode expandMode,
List<Attachment> attachments,
int limitDisplayAttachment
) {
if (attachments.length > limitDisplayAttachment) {
return expandMode == ExpandMode.EXPAND
? attachments.length
: attachments.sublist(0, limitDisplayAttachment).length;
} else {
return attachments.length;
}
}
Widget _buildAttachmentsHeader(BuildContext context, List<Attachment> attachments) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${AppLocalizations.of(context).count_attachment(attachments.length)}',
style: TextStyle(fontSize: 12, color: AppColor.baseTextColor)),
Padding(
padding: EdgeInsets.only(left: 8),
child: Text(
'(${filesize(attachments.totalSize(), 1)})',
style: TextStyle(fontSize: 12, color: AppColor.nameUserColor, fontWeight: FontWeight.w500)))
],
),
if (attachments.length > 2)
Padding(
padding: EdgeInsets.only(left: 8),
child: IconButton(
icon: SvgPicture.asset(imagePaths.icExpandAttachment,
width: 20,
height: 20,
fit: BoxFit.fill),
onPressed: () => emailController.toggleDisplayAttachmentsAction()
))
],
);
}
Widget _buildListMessageContent() {
return Obx(() => emailController.viewState.value.fold(
(failure) => SizedBox.shrink(),
(success) {
if (success is GetEmailContentSuccess && success.emailContent != null) {
final messageContents = success.emailContent!.getListMessageContent();
final attachmentsInline = success.emailContent!.getListAttachmentInline();
return messageContents.isNotEmpty
? ListView.builder(
primary: false,
shrinkWrap: true,
padding: EdgeInsets.only(top: 16),
key: Key('list_message_content'),
itemCount: messageContents.length,
itemBuilder: (context, index) =>
return Obx(() {
if (emailController.emailContent.value != null) {
final messageContents = emailController.emailContent.value!.getListMessageContent();
final attachmentsInline = emailController.emailContent.value!.getListAttachmentInline();
return messageContents.isNotEmpty
? ListView.builder(
primary: false,
shrinkWrap: true,
padding: EdgeInsets.only(top: 16),
key: Key('list_message_content'),
itemCount: messageContents.length,
itemBuilder: (context, index) =>
MessageContentTileBuilder(
htmlMessagePurifier: htmlMessagePurifier,
messageContent: messageContents[index],
attachmentInlines: attachmentsInline,
session: emailController.mailboxDashBoardController.sessionCurrent,
accountId: emailController.mailboxDashBoardController.accountId.value)
.build())
: SizedBox.shrink();
} else {
return SizedBox.shrink();
}
})
);
.build())
: SizedBox.shrink();
} else {
return SizedBox.shrink();
}
});
}
}
@@ -0,0 +1,14 @@
import 'package:model/model.dart';
extension ListAttachmentExtension on List<Attachment> {
num totalSize() {
num totalSize = 0;
forEach((attachment) {
if (attachment.size != null) {
totalSize += attachment.size!.value;
}
});
return totalSize;
}
}
@@ -7,20 +7,38 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:model/model.dart';
typedef OnDownloadAttachmentFileActionClick = void Function(Attachment attachment);
typedef OnExpandAttachmentActionClick = void Function();
class AttachmentFileTileBuilder {
final ImagePaths _imagePaths;
final Attachment _attachment;
final int _attachmentSize;
final int _limitDisplayAttachment;
ExpandMode? _expandMode;
OnDownloadAttachmentFileActionClick? _onDownloadAttachmentFileActionClick;
OnExpandAttachmentActionClick? _onExpandAttachmentActionClick;
AttachmentFileTileBuilder(this._imagePaths, this._attachment);
AttachmentFileTileBuilder(
this._imagePaths,
this._attachment,
this._attachmentSize,
this._limitDisplayAttachment,
);
void onDownloadAttachmentFileActionClick(OnDownloadAttachmentFileActionClick onDownloadAttachmentFileActionClick) {
_onDownloadAttachmentFileActionClick = onDownloadAttachmentFileActionClick;
}
void onExpandAttachmentActionClick(OnExpandAttachmentActionClick onExpandAttachmentActionClick) {
_onExpandAttachmentActionClick = onExpandAttachmentActionClick;
}
void setExpandMode(ExpandMode? expandMode) {
_expandMode = expandMode;
}
Widget build() {
return Theme(
data: ThemeData(
@@ -35,37 +53,72 @@ class AttachmentFileTileBuilder {
color: Colors.white),
child: MediaQuery(
data: MediaQueryData(padding: EdgeInsets.zero),
child: ListTile(
contentPadding: EdgeInsets.zero,
focusColor: AppColor.primaryColor,
hoverColor: AppColor.primaryColor,
onTap: () {
if (_onDownloadAttachmentFileActionClick != null) {
_onDownloadAttachmentFileActionClick!(_attachment);
}},
leading: Transform(
transform: Matrix4.translationValues(14.0, 2.0, 0.0),
child: SvgPicture.asset(_imagePaths.icAttachmentFile, width: 24, height: 24, fit: BoxFit.fill)),
title: Transform(
transform: Matrix4.translationValues(-8.0, -8.0, 0.0),
child: Text(
_attachment.name ?? '',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 12, color: AppColor.attachmentFileNameColor, fontWeight: FontWeight.w500),
)),
subtitle: _attachment.size != null && _attachment.size?.value != 0
? Transform(
child: Stack(
alignment: AlignmentDirectional.bottomEnd,
children: [
ListTile(
contentPadding: EdgeInsets.zero,
focusColor: AppColor.primaryColor,
hoverColor: AppColor.primaryColor,
onTap: () {
if (_onDownloadAttachmentFileActionClick != null) {
_onDownloadAttachmentFileActionClick!(_attachment);
}},
leading: Transform(
transform: Matrix4.translationValues(14.0, 2.0, 0.0),
child: SvgPicture.asset(_imagePaths.icAttachmentFile, width: 24, height: 24, fit: BoxFit.fill)),
title: Transform(
transform: Matrix4.translationValues(-8.0, -8.0, 0.0),
child: Text(
filesize(_attachment.size?.value),
_attachment.name ?? '',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 12, color: AppColor.attachmentFileSizeColor)))
: null
),
style: TextStyle(fontSize: 12, color: AppColor.attachmentFileNameColor, fontWeight: FontWeight.w500),
)),
subtitle: _attachment.size != null && _attachment.size?.value != 0
? Transform(
transform: Matrix4.translationValues(-8.0, -8.0, 0.0),
child: Text(
filesize(_attachment.size?.value),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 12, color: AppColor.attachmentFileSizeColor)))
: null
),
Transform(
transform: Matrix4.translationValues(5.0, 5.0, 0.0),
child: IconButton(
icon: SvgPicture.asset(_imagePaths.icDownload, width: 24, height: 24, fit: BoxFit.fill),
onPressed: () {
if (_onDownloadAttachmentFileActionClick != null) {
_onDownloadAttachmentFileActionClick!(_attachment);
}
}
)),
if (_attachmentSize > _limitDisplayAttachment && _expandMode == ExpandMode.COLLAPSE) _buildItemBackground()
]
)
)
)
);
}
Widget _buildItemBackground() {
return GestureDetector(
onTap: () {
if (_onExpandAttachmentActionClick != null) {
_onExpandAttachmentActionClick!();
}
},
child: Stack(
alignment: AlignmentDirectional.center,
children: [
Container(color: AppColor.backgroundCountAttachment),
Text(
'+${_attachmentSize - _limitDisplayAttachment + 1}',
style: TextStyle(fontSize: 16, color: Colors.white, fontWeight: FontWeight.bold))
],
),
);
}
}
@@ -5,6 +5,7 @@ import 'package:get/get.dart';
import 'package:tmail_ui_user/features/login/domain/state/get_credential_state.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/get_credential_interactor.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
class HomeController extends GetxController {
final GetCredentialInteractor _getCredentialInteractor;
@@ -36,7 +37,7 @@ class HomeController extends GetxController {
}
void _goToLogin() {
Get.offNamed(AppRoutes.LOGIN);
pushAndPop(AppRoutes.LOGIN);
}
void _goToMailbox(GetCredentialViewState credentialViewState) {
@@ -45,6 +46,6 @@ class HomeController extends GetxController {
credentialViewState.userName.userName,
credentialViewState.password.value,
);
Get.offNamed(AppRoutes.SESSION);
pushAndPop(AppRoutes.SESSION);
}
}
@@ -6,6 +6,7 @@ import 'package:tmail_ui_user/features/login/domain/state/authentication_user_st
import 'package:tmail_ui_user/features/login/domain/usecases/authentication_user_interactor.dart';
import 'package:tmail_ui_user/features/login/presentation/state/login_state.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
class LoginController extends GetxController {
@@ -60,7 +61,7 @@ class LoginController extends GetxController {
loginState.value = LoginState(Right(success));
_dynamicUrlInterceptors.changeBaseUrl(_urlText);
_authorizationInterceptors.changeAuthorization(_userNameText, _passwordText);
Get.offNamed(AppRoutes.SESSION);
pushAndPop(AppRoutes.SESSION);
}
void _loginFailureAction(AuthenticationUserFailure failure) {
@@ -16,6 +16,7 @@ import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_b
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/thread/domain/state/mark_as_multiple_email_read_state.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
class MailboxController extends BaseController {
@@ -141,6 +142,6 @@ class MailboxController extends BaseController {
void closeMailboxScreen() {
_deleteCredential();
Get.offAllNamed(AppRoutes.LOGIN);
pushAndPopAll(AppRoutes.LOGIN);
}
}
@@ -3,6 +3,7 @@ import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_i
import 'package:tmail_ui_user/features/session/domain/state/get_session_state.dart';
import 'package:tmail_ui_user/features/session/domain/usecases/get_session_interactor.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
class SessionController extends GetxController {
final GetSessionInteractor _getSessionInteractor;
@@ -29,10 +30,10 @@ class SessionController extends GetxController {
void _goToLogin() {
_deleteCredential();
Get.offNamed(AppRoutes.LOGIN);
pushAndPop(AppRoutes.LOGIN);
}
void _goToMailboxDashBoard(GetSessionSuccess getSessionSuccess) {
Get.offNamed(AppRoutes.MAILBOX_DASHBOARD, arguments: getSessionSuccess.session);
pushAndPop(AppRoutes.MAILBOX_DASHBOARD, arguments: getSessionSuccess.session);
}
}
@@ -392,7 +392,7 @@ class ThreadController extends BaseController {
void composeEmailAction() {
if (canComposeEmail()) {
Get.toNamed(
push(
AppRoutes.COMPOSER,
arguments: ComposerArguments(
session: mailboxDashBoardController.sessionCurrent!,
+24 -2
View File
@@ -276,8 +276,30 @@
"placeholders_order": [],
"placeholders": {}
},
"attachment_download_successfully": "Attachment downloaded successfully",
"@attachment_download_successfully": {
"downloading_file": "Downloading {fileName}",
"@downloading_file": {
"type": "text",
"placeholders_order": [
"fileName"
],
"placeholders": {
"fileName": {}
}
},
"preparing_to_export": "Preparing to export",
"@preparing_to_export": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"cancel": "Cancel",
"@cancel": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"user_cancel_download_file": "User cancel download file",
"@user_cancel_download_file": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
+24 -2
View File
@@ -276,8 +276,30 @@
"placeholders_order": [],
"placeholders": {}
},
"attachment_download_successfully": "Attachment downloaded successfully",
"@attachment_download_successfully": {
"downloading_file": "Downloading {fileName}",
"@downloading_file": {
"type": "text",
"placeholders_order": [
"fileName"
],
"placeholders": {
"fileName": {}
}
},
"preparing_to_export": "Preparing to export",
"@preparing_to_export": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"cancel": "Cancel",
"@cancel": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"user_cancel_download_file": "User cancel download file",
"@user_cancel_download_file": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
+25 -3
View File
@@ -1,5 +1,5 @@
{
"@@last_modified": "2021-09-15T23:44:29.035668",
"@@last_modified": "2021-09-16T14:31:23.463339",
"initializing_data": "Initializing data...",
"@initializing_data": {
"type": "text",
@@ -276,8 +276,30 @@
"placeholders_order": [],
"placeholders": {}
},
"attachment_download_successfully": "Attachment downloaded successfully",
"@attachment_download_successfully": {
"downloading_file": "Downloading {fileName}",
"@downloading_file": {
"type": "text",
"placeholders_order": [
"fileName"
],
"placeholders": {
"fileName": {}
}
},
"preparing_to_export": "Preparing to export",
"@preparing_to_export": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"cancel": "Cancel",
"@cancel": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"user_cancel_download_file": "User cancel download file",
"@user_cancel_download_file": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
+24 -2
View File
@@ -276,8 +276,30 @@
"placeholders_order": [],
"placeholders": {}
},
"attachment_download_successfully": "Attachment downloaded successfully",
"@attachment_download_successfully": {
"downloading_file": "Downloading {fileName}",
"@downloading_file": {
"type": "text",
"placeholders_order": [
"fileName"
],
"placeholders": {
"fileName": {}
}
},
"preparing_to_export": "Preparing to export",
"@preparing_to_export": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"cancel": "Cancel",
"@cancel": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"user_cancel_download_file": "User cancel download file",
"@user_cancel_download_file": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
+24 -2
View File
@@ -276,8 +276,30 @@
"placeholders_order": [],
"placeholders": {}
},
"attachment_download_successfully": "Attachment downloaded successfully",
"@attachment_download_successfully": {
"downloading_file": "Downloading {fileName}",
"@downloading_file": {
"type": "text",
"placeholders_order": [
"fileName"
],
"placeholders": {
"fileName": {}
}
},
"preparing_to_export": "Preparing to export",
"@preparing_to_export": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"cancel": "Cancel",
"@cancel": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"user_cancel_download_file": "User cancel download file",
"@user_cancel_download_file": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
@@ -45,9 +45,13 @@ class NetworkBindings extends Bindings {
void _bindingApi() {
Get.put(DioClient(Get.find<Dio>()));
Get.put(JmapHttpClient.HttpClient(Get.find<Dio>()));
Get.put(DownloadClient(Get.find<DioClient>()));
Get.put(DownloadManager(Get.find<DownloadClient>()));
Get.put(MailboxAPI(Get.find<JmapHttpClient.HttpClient>()));
Get.put(SessionAPI(Get.find<JmapHttpClient.HttpClient>()));
Get.put(ThreadAPI(Get.find<JmapHttpClient.HttpClient>()));
Get.put(EmailAPI(Get.find<JmapHttpClient.HttpClient>()));
Get.put(EmailAPI(
Get.find<JmapHttpClient.HttpClient>(),
Get.find<DownloadManager>()));
}
}
+40 -3
View File
@@ -308,10 +308,47 @@ class AppLocalizations {
);
}
String get attachment_download_successfully {
String downloading_file(String fileName) {
return Intl.message(
'Attachment downloaded successfully',
name: 'attachment_download_successfully',
'Downloading $fileName',
name: 'downloading_file',
args: [fileName]
);
}
String get preparing_to_export {
return Intl.message(
'Preparing to export',
name: 'preparing_to_export'
);
}
String get cancel {
return Intl.message(
'Cancel',
name: 'cancel'
);
}
String get user_cancel_download_file {
return Intl.message(
'User cancel download file',
name: 'user_cancel_download_file'
);
}
String get you_need_to_grant_files_permission_to_download_attachments {
return Intl.message(
'You need to grant files permission to download attachments',
name: 'you_need_to_grant_files_permission_to_download_attachments'
);
}
String count_attachment(int count) {
return Intl.message(
'$count attachments',
name: 'count_attachment',
args: [count]
);
}
}