Skip to content

Commit 1582106

Browse files
committed
TF-3358 Sort list local email draft by time
Signed-off-by: dab246 <[email protected]>
1 parent 4a5c529 commit 1582106

18 files changed

+78
-129
lines changed

lib/features/composer/presentation/composer_controller.dart

Lines changed: 12 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,6 @@ import 'package:tmail_ui_user/features/email/domain/usecases/transform_html_emai
8686
import 'package:tmail_ui_user/features/email/presentation/extensions/presentation_email_extension.dart';
8787
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
8888
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
89-
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_composer_cache_by_id_on_web_interactor.dart';
90-
import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart';
9189
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
9290
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart';
9391
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/remove_local_email_draft_extension.dart';
@@ -223,17 +221,14 @@ class ComposerController extends BaseController
223221
ButtonState _saveToDraftButtonState = ButtonState.enabled;
224222
ButtonState _sendButtonState = ButtonState.enabled;
225223
ButtonState printDraftButtonState = ButtonState.enabled;
226-
int? _savedEmailDraftHash;
224+
int? savedEmailDraftHash;
227225
bool restoringSignatureButton = false;
228226
bool synchronizeInitDraftHash = false;
229227
GlobalKey? responsiveContainerKey;
230228
EmailActionType? currentEmailActionType;
231229
EmailActionType? savedActionType;
232230
int minInputLengthAutocomplete = AppConfig.defaultMinInputLengthAutocomplete;
233231

234-
@visibleForTesting
235-
int? get savedEmailDraftHash => _savedEmailDraftHash;
236-
237232
GetEmailContentInteractor get getEmailContentInteractor => _getEmailContentInteractor;
238233

239234
GetServerSettingInteractor get getServerSettingInteractor => _getServerSettingInteractor;
@@ -300,7 +295,7 @@ class ComposerController extends BaseController
300295
void onClose() {
301296
_textEditorWeb = null;
302297
savedActionType = null;
303-
_savedEmailDraftHash = null;
298+
savedEmailDraftHash = null;
304299
currentEmailActionType = null;
305300
emailIdEditing = null;
306301
maxWithEditor = null;
@@ -447,19 +442,7 @@ class ComposerController extends BaseController
447442
});
448443
}
449444

450-
Future<void> _saveLocalEmailDraftAction() async {
451-
autoCreateEmailTag();
452-
453-
final createEmailRequest = await _generateCreateEmailRequestToSaveAsCache();
454-
if (createEmailRequest == null) return;
455-
456-
await _saveLocalEmailDraftInteractor.execute(
457-
createEmailRequest,
458-
mailboxDashBoardController.accountId.value!,
459-
mailboxDashBoardController.sessionCurrent!.username);
460-
}
461-
462-
Uri? _getUploadUriFromSession(Session session, AccountId accountId) {
445+
Uri? getUploadUriFromSession(Session session, AccountId accountId) {
463446
try {
464447
return session.getUploadUri(accountId, jmapUrl: dynamicUrlInterceptors.jmapUrl);
465448
} catch (e) {
@@ -468,63 +451,6 @@ class ComposerController extends BaseController
468451
}
469452
}
470453

471-
Future<CreateEmailRequest?> _generateCreateEmailRequestToSaveAsCache() async {
472-
final arguments = composerArguments.value;
473-
final session = mailboxDashBoardController.sessionCurrent;
474-
final accountId = mailboxDashBoardController.accountId.value;
475-
476-
if (arguments == null || session == null || accountId == null) {
477-
log('ComposerController::_generateCreateEmailRequest: SESSION or ACCOUNT_ID or ARGUMENTS is NULL');
478-
return null;
479-
}
480-
481-
String emailContent = await getContentInEditor();
482-
if (currentEmailActionType == EmailActionType.compose) {
483-
emailContent = await _composerRepository.removeCollapsedExpandedSignatureEffect(
484-
emailContent: emailContent,
485-
);
486-
}
487-
final uploadUri = _getUploadUriFromSession(session, accountId);
488-
489-
final composerIndex = composerId != null
490-
? mailboxDashBoardController.composerManager.getComposerIndex(composerId!)
491-
: null;
492-
493-
return CreateEmailRequest(
494-
session: session,
495-
accountId: accountId,
496-
emailActionType: arguments.emailActionType,
497-
subject: subjectEmail.value ?? '',
498-
emailContent: emailContent,
499-
fromSender: arguments.presentationEmail?.from ?? {},
500-
toRecipients: listToEmailAddress.toSet(),
501-
ccRecipients: listCcEmailAddress.toSet(),
502-
bccRecipients: listBccEmailAddress.toSet(),
503-
replyToRecipients: listReplyToEmailAddress.toSet(),
504-
hasRequestReadReceipt: hasRequestReadReceipt.value,
505-
isMarkAsImportant: isMarkAsImportant.value,
506-
identity: identitySelected.value,
507-
attachments: uploadController.attachmentsUploaded,
508-
inlineAttachments: uploadController.mapInlineAttachments,
509-
outboxMailboxId: getOutboxMailboxIdForComposer(),
510-
sentMailboxId: getSentMailboxIdForComposer(),
511-
draftsMailboxId: getDraftMailboxIdForComposer(),
512-
draftsEmailId: getDraftEmailId(),
513-
answerForwardEmailId: arguments.presentationEmail?.id,
514-
unsubscribeEmailId: arguments.previousEmailId,
515-
messageId: arguments.messageId,
516-
references: arguments.references,
517-
emailSendingQueue: arguments.sendingEmail,
518-
displayMode: screenDisplayMode.value,
519-
uploadUri: uploadUri,
520-
composerIndex: composerIndex,
521-
composerId: composerId,
522-
savedDraftHash: arguments.savedDraftHash ?? _savedEmailDraftHash,
523-
savedActionType: savedActionType ?? currentEmailActionType,
524-
savedEmailDraftId: emailIdEditing,
525-
);
526-
}
527-
528454
void _scrollControllerEmailAddressListener() {
529455
if (toEmailAddressController.text.isNotEmpty) {
530456
keyToEmailTagEditor.currentState?.closeSuggestionBox();
@@ -1101,8 +1027,8 @@ class ComposerController extends BaseController
11011027

11021028
Future<bool> _validateEmailChange() async {
11031029
final newDraftHash = await _hashDraftEmail();
1104-
log('ComposerController::_validateEmailChange:newDraftHash = $newDraftHash | _savedEmailDraftHash = $_savedEmailDraftHash');
1105-
return _savedEmailDraftHash != newDraftHash;
1030+
log('ComposerController::_validateEmailChange:newDraftHash = $newDraftHash | savedEmailDraftHash = $savedEmailDraftHash');
1031+
return savedEmailDraftHash != newDraftHash;
11061032
}
11071033

11081034
Future<int> _hashDraftEmail() async {
@@ -1113,7 +1039,7 @@ class ComposerController extends BaseController
11131039
);
11141040
if (emailIdEditing != null &&
11151041
savedActionType == EmailActionType.compose &&
1116-
currentEmailActionType == EmailActionType.reopenComposerBrowser) {
1042+
currentEmailActionType == EmailActionType.composeFromLocalEmailDraft) {
11171043
emailContent = await _composerRepository.removeStyleLazyLoadDisplayInlineImages(
11181044
emailContent: emailContent,
11191045
);
@@ -1138,7 +1064,7 @@ class ComposerController extends BaseController
11381064
}
11391065

11401066
Future<void> _updateSavedEmailDraftHash() async {
1141-
_savedEmailDraftHash = await _hashDraftEmail();
1067+
savedEmailDraftHash = await _hashDraftEmail();
11421068
}
11431069

11441070
Future<void> initEmailDraftHash() async {
@@ -1148,13 +1074,13 @@ class ComposerController extends BaseController
11481074

11491075
if (currentEmailActionType == EmailActionType.compose ||
11501076
currentEmailActionType == EmailActionType.editDraft) {
1151-
_savedEmailDraftHash = currentDraftHash;
1152-
} else if (currentEmailActionType == EmailActionType.reopenComposerBrowser) {
1153-
_savedEmailDraftHash = oldSavedDraftHash;
1077+
savedEmailDraftHash = currentDraftHash;
1078+
} else if (currentEmailActionType == EmailActionType.composeFromLocalEmailDraft) {
1079+
savedEmailDraftHash = oldSavedDraftHash;
11541080
}
1155-
log('ComposerController::initEmailDraftHash:oldSavedDraftHash = $oldSavedDraftHash | currentDraftHash = $currentDraftHash | _savedEmailDraftHash = $_savedEmailDraftHash');
1081+
log('ComposerController::initEmailDraftHash:oldSavedDraftHash = $oldSavedDraftHash | currentDraftHash = $currentDraftHash | savedEmailDraftHash = $savedEmailDraftHash');
11561082

1157-
isEmailChanged.value = currentDraftHash != _savedEmailDraftHash;
1083+
isEmailChanged.value = currentDraftHash != savedEmailDraftHash;
11581084
}
11591085

11601086
void handleClickSaveAsDraftsButton(BuildContext context) async {

lib/features/composer/presentation/extensions/create_email_request_extension.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import 'package:model/email/mail_priority_header.dart';
1414
import 'package:model/extensions/account_id_extensions.dart';
1515
import 'package:model/extensions/email_address_extension.dart';
1616
import 'package:model/extensions/email_extension.dart';
17+
import 'package:model/extensions/email_id_extensions.dart';
1718
import 'package:model/extensions/session_extension.dart';
1819
import 'package:model/mailbox/presentation_mailbox.dart';
1920
import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart';
@@ -223,6 +224,9 @@ extension CreateEmailRequestExtension on CreateEmailRequest {
223224
isMarkAsImportant: isMarkAsImportant,
224225
displayMode: displayMode.name,
225226
composerIndex: composerIndex,
227+
draftHash: savedDraftHash,
228+
actionType: savedActionType?.name,
229+
draftEmailId: savedEmailDraftId?.asString,
226230
);
227231
}
228232
}

lib/features/composer/presentation/extensions/handle_local_email_draft_extension.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ extension HandleLocalEmailDraftExtension on ComposerController {
5151
uploadUri: uploadUri,
5252
composerIndex: composerIndex,
5353
composerId: composerId,
54+
savedDraftHash: arguments.savedDraftHash ?? savedEmailDraftHash,
55+
savedActionType: savedActionType ?? currentEmailActionType,
56+
savedEmailDraftId: emailIdEditing,
5457
);
5558
}
5659

lib/features/composer/presentation/extensions/setup_email_attachments_extension.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ extension SetupEmailAttachmentsExtension on ComposerController {
3535
attachments = arguments.attachments;
3636
inlineImages = arguments.inlineImages;
3737
break;
38-
case EmailActionType.reopenComposerBrowser:
38+
case EmailActionType.composeFromLocalEmailDraft:
3939
attachments = arguments.attachments;
4040
inlineImages = arguments.inlineImages;
4141
break;

lib/features/composer/presentation/extensions/setup_email_content_extension.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ extension SetupEmailContentExtension on ComposerController {
162162
}
163163
}
164164
break;
165-
case EmailActionType.reopenComposerBrowser:
165+
case EmailActionType.composeFromLocalEmailDraft:
166166
final inlineImages = arguments.inlineImages ?? [];
167167
final content = arguments.emailContents ?? '';
168168
final displayMode = arguments.displayMode;

lib/features/composer/presentation/extensions/setup_email_important_flag_extension.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ extension SetupEmailImportantFlagExtension on ComposerController {
1111
case EmailActionType.editDraft:
1212
isMarkAsImportant.value = arguments.presentationEmail?.isMarkAsImportant ?? false;
1313
break;
14-
case EmailActionType.reopenComposerBrowser:
14+
case EmailActionType.composeFromLocalEmailDraft:
1515
isMarkAsImportant.value = arguments.isMarkAsImportant ?? false;
1616
break;
1717
default:

lib/features/composer/presentation/extensions/setup_email_other_components_extension.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ extension SetupEmailOtherComponentsExtension on ComposerController {
1313
case EmailActionType.editSendingEmail:
1414
emailIdEditing = arguments.sendingEmail?.presentationEmail.id;
1515
break;
16-
case EmailActionType.reopenComposerBrowser:
16+
case EmailActionType.composeFromLocalEmailDraft:
1717
screenDisplayMode.value = arguments.displayMode;
1818
break;
1919
default:

lib/features/composer/presentation/extensions/setup_email_recipients_extension.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ extension SetupEmailRecipientsExtension on ComposerController {
1111
switch(currentEmailActionType) {
1212
case EmailActionType.editAsNewEmail:
1313
case EmailActionType.editDraft:
14-
case EmailActionType.reopenComposerBrowser:
14+
case EmailActionType.composeFromLocalEmailDraft:
1515
initEmailAddress(
1616
presentationEmail: arguments.presentationEmail!,
1717
actionType: currentEmailActionType!,

lib/features/composer/presentation/extensions/setup_email_request_read_receipt_flag_extension.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import 'package:tmail_ui_user/features/server_settings/domain/state/get_server_s
88
extension SetupEmailRequestReadReceiptFlagExtension on ComposerController {
99

1010
void setupEmailRequestReadReceiptFlag(ComposerArguments arguments) {
11-
if (currentEmailActionType == EmailActionType.reopenComposerBrowser) {
11+
if (currentEmailActionType == EmailActionType.composeFromLocalEmailDraft) {
1212
hasRequestReadReceipt.value = arguments.hasRequestReadReceipt ?? false;
1313
} else if (currentEmailActionType != EmailActionType.editDraft) {
1414
getServerSetting();

lib/features/composer/presentation/extensions/setup_email_subject_extension.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ extension SetupEmailSubjectExtension on ComposerController {
1717
case EmailActionType.replyToList:
1818
case EmailActionType.replyAll:
1919
case EmailActionType.forward:
20-
case EmailActionType.reopenComposerBrowser:
20+
case EmailActionType.composeFromLocalEmailDraft:
2121
subject = arguments.presentationEmail!.getEmailTitle().trim();
2222
break;
2323
case EmailActionType.editSendingEmail:

lib/features/composer/presentation/extensions/setup_selected_identity_extension.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ extension SetupSelectedIdentityExtension on ComposerController {
3030
) ?? listFromIdentities.first;
3131

3232
if (currentEmailActionType == EmailActionType.editDraft ||
33-
currentEmailActionType == EmailActionType.reopenComposerBrowser &&
33+
currentEmailActionType == EmailActionType.composeFromLocalEmailDraft &&
3434
savedActionType == EmailActionType.editDraft) {
3535
identitySelected.value = currentIdentity;
3636
} else if (currentEmailActionType == EmailActionType.editAsNewEmail) {

lib/features/composer/presentation/manager/composer_manager.dart

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,39 +23,30 @@ class ComposerManager extends GetxController {
2323

2424
ComposerTimer? _composerTimer;
2525

26-
void addComposer(ComposerArguments composerArguments) {
27-
final id = DateTime.now().millisecondsSinceEpoch.toString();
26+
void addComposer(ComposerArguments composerArguments, {bool isSynchronous = true}) {
27+
final id = composerArguments.composerId
28+
?? DateTime.now().millisecondsSinceEpoch.toString();
2829
log('ComposerManager::addComposer:Id = $id');
29-
ComposerBindings(composerId: id, composerArguments: composerArguments).dependencies();
30+
ComposerBindings(
31+
composerId: id,
32+
composerArguments: composerArguments,
33+
).dependencies();
3034

3135
composers[id] = ComposerView(key: Key(id), composerId: id);
3236
composerIdsQueue.add(id);
3337

34-
_arrangeComposerIfNeeded();
35-
36-
_initializeTimerIfNeeded();
38+
if (isSynchronous) {
39+
_arrangeComposerIfNeeded();
40+
_initializeTimerIfNeeded();
41+
}
3742
}
3843

3944
void addListComposer(List<ComposerArguments> listArguments) {
4045
for (var argument in listArguments) {
41-
final composerId = argument.composerId;
42-
43-
if (composerId == null) continue;
44-
45-
ComposerBindings(
46-
composerId: composerId,
47-
composerArguments: argument,
48-
).dependencies();
49-
50-
composers[composerId] = ComposerView(
51-
key: Key(composerId),
52-
composerId: composerId,
53-
);
54-
composerIdsQueue.add(composerId);
46+
addComposer(argument, isSynchronous: false);
5547
}
5648

5749
_arrangeComposerIfNeeded();
58-
5950
_initializeTimerIfNeeded();
6051
}
6152

lib/features/email/presentation/model/composer_arguments.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
44
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
55
import 'package:model/model.dart';
66
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
7-
87
import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart';
9-
import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/local_email_draft.dart';
108
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/presentation_local_email_draft.dart';
119
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
1210
import 'package:tmail_ui_user/features/sending_queue/presentation/model/sending_email_action_type.dart';

lib/features/mailbox_dashboard/data/model/local_email_draft.dart

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
import 'package:equatable/equatable.dart';
22
import 'package:hive/hive.dart';
33
import 'package:tmail_ui_user/features/caching/utils/caching_constants.dart';
4-
import 'package:jmap_dart_client/http/converter/email_id_nullable_converter.dart';
5-
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
6-
import 'package:json_annotation/json_annotation.dart';
7-
import 'package:model/email/email_action_type.dart';
8-
import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart';
94

105
part 'local_email_draft.g.dart';
116

lib/features/mailbox_dashboard/presentation/extensions/local_email_draft_extension.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
import 'dart:convert';
33

44
import 'package:collection/collection.dart';
5+
import 'package:jmap_dart_client/jmap/core/id.dart';
56
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
7+
import 'package:model/email/email_action_type.dart';
68
import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart';
79
import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/local_email_draft.dart';
810
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/presentation_local_email_draft.dart';
@@ -20,6 +22,11 @@ extension LocalEmailDraftExtension on LocalEmailDraft {
2022
(type) => type.name == displayMode,
2123
) ?? ScreenDisplayMode.normal,
2224
composerIndex: composerIndex,
25+
draftHash: draftHash,
26+
actionType: EmailActionType.values.firstWhereOrNull(
27+
(type) => type.name == actionType,
28+
),
29+
draftEmailId: draftEmailId != null ? EmailId(Id(draftEmailId!)) : null,
2330
);
2431
}
2532
}

lib/features/mailbox_dashboard/presentation/extensions/restore_local_email_draft_extension.dart

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,11 @@ extension RestoreLocalEmailDraftExtension on MailboxDashBoardController {
3333
final listPresentationLocalEmailDraft = localEmailDrafts
3434
.map((localEmailDraft) => localEmailDraft.toPresentation())
3535
.toList();
36-
final listLocalEmailDraftSortByIndex = listPresentationLocalEmailDraft
37-
..sort((a, b) => (a.composerIndex ?? 0).compareTo(b.composerIndex ?? 0));
3836

39-
showLocalEmailDraftListDialog(listLocalEmailDraftSortByIndex);
37+
final listLocalEmailDraftSortByTime = listPresentationLocalEmailDraft
38+
..sort((a, b) => b.savedTime.compareTo(a.savedTime));
39+
40+
showLocalEmailDraftListDialog(listLocalEmailDraftSortByTime);
4041
}
4142

4243
void showLocalEmailDraftListDialog(List<PresentationLocalEmailDraft> presentationLocalEmailDrafts) {
@@ -64,7 +65,11 @@ extension RestoreLocalEmailDraftExtension on MailboxDashBoardController {
6465
void _restoreAllLocalEmailDrafts(List<PresentationLocalEmailDraft> localDrafts) {
6566
popBack();
6667

67-
final listComposerArguments = localDrafts
68+
69+
final listLocalEmailDraftSortByIndex = localDrafts
70+
..sort((a, b) => (a.composerIndex ?? 0).compareTo(b.composerIndex ?? 0));
71+
72+
final listComposerArguments = listLocalEmailDraftSortByIndex
6873
.map(ComposerArguments.fromLocalEmailDraft)
6974
.toList();
7075

0 commit comments

Comments
 (0)