TF-1715 Load emails in favorite folder without filters

This commit is contained in:
dab246
2025-10-30 11:57:22 +07:00
committed by Dat H. Pham
parent d85e691d98
commit e5e1d02ae9
7 changed files with 124 additions and 33 deletions
@@ -134,6 +134,7 @@ class MailboxController extends BaseMailboxController
WebSocketQueueHandler? _webSocketQueueHandler;
final _openMailboxEventController = StreamController<OpenMailboxViewEvent>();
StreamSubscription? _openMailboxEventStreamSubscription;
final mailboxListScrollController = ScrollController();
PresentationMailbox? get selectedMailbox => mailboxDashBoardController.selectedMailbox.value;
@@ -177,10 +178,13 @@ class MailboxController extends BaseMailboxController
@override
void onReady() {
_openMailboxEventController.stream.debounceTime(const Duration(milliseconds: 500)).listen((event) {
if (!event.buildContext.mounted) return;
_handleOpenMailbox(event.buildContext, event.presentationMailbox);
});
_openMailboxEventStreamSubscription = _openMailboxEventController
.stream
.debounceTime(const Duration(milliseconds: 500))
.listen((event) {
if (!event.buildContext.mounted) return;
_handleOpenMailbox(event.buildContext, event.presentationMailbox);
});
_initCollapseMailboxCategories();
mailboxListScrollController.addListener(_mailboxListScrollControllerListener);
super.onReady();
@@ -188,6 +192,8 @@ class MailboxController extends BaseMailboxController
@override
void onClose() {
_openMailboxEventStreamSubscription?.cancel();
_openMailboxEventStreamSubscription = null;
_openMailboxEventController.close();
mailboxListScrollController.dispose();
_webSocketQueueHandler?.dispose();
@@ -314,12 +314,14 @@ class ThreadRepositoryImpl extends ThreadRepository {
@override
Stream<EmailsResponse> loadMoreEmails(GetEmailRequest emailRequest) async* {
final response = await _getAllEmailsWithoutLastEmailId(emailRequest);
await _updateEmailCache(
emailRequest.accountId,
emailRequest.session.username,
newCreated: response.emailList,
newDestroyed: response.notFoundEmailIds,
);
if (emailRequest.useCache) {
await _updateEmailCache(
emailRequest.accountId,
emailRequest.session.username,
newCreated: response.emailList,
newDestroyed: response.notFoundEmailIds,
);
}
yield response;
}
@@ -498,4 +500,27 @@ class ThreadRepositoryImpl extends ThreadRepository {
accountId,
session,
);
@override
Stream<EmailsResponse> loadAllEmailInFolderWithoutCache({
required Session session,
required AccountId accountId,
UnsignedInt? limit,
int? position,
Set<Comparator>? sort,
EmailFilter? emailFilter,
Properties? propertiesCreated,
}) async* {
final networkDataSource = mapDataSource[DataSourceType.network]!;
final emailResponse = await networkDataSource.getAllEmail(
session,
accountId,
limit: limit,
position: position,
sort: sort,
filter: emailFilter?.filter,
properties: propertiesCreated,
);
yield emailResponse;
}
}
@@ -18,6 +18,7 @@ class GetEmailRequest with EquatableMixin {
final FilterMessageOption? filterOption;
final Properties? properties;
final EmailId? lastEmailId;
final bool useCache;
GetEmailRequest(
this.session,
@@ -30,6 +31,7 @@ class GetEmailRequest with EquatableMixin {
this.filterOption,
this.properties,
this.lastEmailId,
this.useCache = true,
}
);
@@ -43,6 +45,7 @@ class GetEmailRequest with EquatableMixin {
filter,
properties,
lastEmailId,
filterOption
filterOption,
useCache,
];
}
@@ -24,6 +24,7 @@ abstract class ThreadRepository {
AccountId accountId,
{
UnsignedInt? limit,
int? position,
Set<Comparator>? sort,
EmailFilter? emailFilter,
Properties? propertiesCreated,
@@ -32,6 +33,16 @@ abstract class ThreadRepository {
}
);
Stream<EmailsResponse> loadAllEmailInFolderWithoutCache({
required Session session,
required AccountId accountId,
UnsignedInt? limit,
int? position,
Set<Comparator>? sort,
EmailFilter? emailFilter,
Properties? propertiesCreated,
});
Stream<EmailsResponse> refreshChanges(
Session session,
AccountId accountId,
@@ -27,13 +27,14 @@ class GetEmailsInMailboxInteractor {
Properties? propertiesCreated,
Properties? propertiesUpdated,
bool getLatestChanges = true,
bool useCache = true,
}
) async* {
try {
yield Right<Failure, Success>(GetAllEmailLoading());
yield* threadRepository
.getAllEmail(
if (useCache) {
yield* threadRepository.getAllEmail(
session,
accountId,
limit: limit,
@@ -41,11 +42,24 @@ class GetEmailsInMailboxInteractor {
emailFilter: emailFilter,
propertiesCreated: propertiesCreated,
propertiesUpdated: propertiesUpdated,
getLatestChanges: getLatestChanges)
.map((emailResponse) => _toGetEmailState(
getLatestChanges: getLatestChanges,
).map((emailResponse) => _toGetEmailState(
emailResponse: emailResponse,
currentMailboxId: emailFilter?.mailboxId
currentMailboxId: emailFilter?.mailboxId,
));
} else {
yield* threadRepository.loadAllEmailInFolderWithoutCache(
session: session,
accountId: accountId,
limit: limit,
sort: sort,
emailFilter: emailFilter,
propertiesCreated: propertiesCreated,
).map((emailResponse) => _toGetEmailState(
emailResponse: emailResponse,
currentMailboxId: emailFilter?.mailboxId,
));
}
} catch (e) {
yield Left(GetAllEmailFailure(e));
}
@@ -9,6 +9,7 @@ import 'package:dartz/dartz.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/filter/filter.dart' show Filter;
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
@@ -165,7 +166,6 @@ class ThreadController extends BaseController with EmailActionController {
@override
void handleSuccessViewState(Success success) {
super.handleSuccessViewState(success);
if (success is GetAllEmailSuccess) {
_getAllEmailSuccess(success);
} else if (success is LoadMoreEmailsSuccess) {
@@ -192,12 +192,13 @@ class ThreadController extends BaseController with EmailActionController {
_openEmailWithoutMailboxFromLocationBar(success.email);
}
}
} else {
super.handleSuccessViewState(success);
}
}
@override
void handleFailureViewState(Failure failure) {
super.handleFailureViewState(failure);
if (failure is SearchEmailFailure) {
mailboxDashBoardController.updateRefreshAllEmailState(Left(RefreshAllEmailFailure()));
canSearchMore = false;
@@ -215,6 +216,8 @@ class ThreadController extends BaseController with EmailActionController {
} else if (failure is GetAllEmailFailure || failure is CleanAndGetAllEmailFailure) {
mailboxDashBoardController.updateRefreshAllEmailState(Left(RefreshAllEmailFailure()));
canLoadMore = true;
} else {
super.handleFailureViewState(failure);
}
}
@@ -503,7 +506,8 @@ class ThreadController extends BaseController with EmailActionController {
void _getAllEmailSuccess(GetAllEmailSuccess success) {
mailboxDashBoardController.updateRefreshAllEmailState(Right(RefreshAllEmailSuccess()));
if (success.currentMailboxId != selectedMailboxId) {
if (success.currentMailboxId != selectedMailboxId &&
selectedMailboxId?.isNotFavoriteMailboxId == true) {
log('ThreadController::_getAllEmailSuccess: GetAllForMailboxId = ${success.currentMailboxId?.asString} | SELECTED_MAILBOX_ID = ${selectedMailboxId?.asString} | SELECTED_MAILBOX_NAME = ${selectedMailbox?.name?.name}');
return;
}
@@ -543,7 +547,8 @@ class ThreadController extends BaseController with EmailActionController {
}
void _refreshChangesAllEmailSuccess(RefreshChangesAllEmailSuccess success) {
if (success.currentMailboxId != selectedMailboxId) {
if (success.currentMailboxId != selectedMailboxId &&
selectedMailboxId?.isNotFavoriteMailboxId == true) {
log('ThreadController::_refreshChangesAllEmailSuccess: RefreshedMailboxId = ${success.currentMailboxId?.asString} | SELECTED_MAILBOX_ID = ${selectedMailboxId?.asString} | SELECTED_MAILBOX_NAME = ${selectedMailbox?.name?.name}');
return;
}
@@ -579,23 +584,49 @@ class ThreadController extends BaseController with EmailActionController {
_accountId!,
limit: ThreadConstants.defaultLimit,
sort: EmailSortOrderType.mostRecent.getSortOrder().toNullable(),
emailFilter: EmailFilter(
filter: getFilterCondition(mailboxIdSelected: selectedMailboxId),
filterOption: mailboxDashBoardController.filterMessageOption.value,
mailboxId: selectedMailboxId
),
emailFilter: _getEmailFilterForLoadMailbox(),
propertiesCreated: EmailUtils.getPropertiesForEmailGetMethod(_session!, _accountId!),
propertiesUpdated: EmailUtils.getPropertiesForEmailChangeMethod(
_session!,
_accountId!,
),
getLatestChanges: getLatestChanges,
useCache: selectedMailboxId?.isNotFavoriteMailboxId == true,
));
} else {
consumeState(Stream.value(Left(GetAllEmailFailure(NotFoundSessionException()))));
}
}
EmailFilter _getEmailFilterForLoadMailbox({PresentationEmail? oldestEmail}) {
if (selectedMailboxId?.isNotFavoriteMailboxId != true) {
return EmailFilter(
filter: _getFilterConditionForLoadMailbox(oldestEmail: oldestEmail),
filterOption: mailboxDashBoardController.filterMessageOption.value,
);
} else {
return EmailFilter(
filter: _getFilterConditionForLoadMailbox(oldestEmail: oldestEmail),
filterOption: mailboxDashBoardController.filterMessageOption.value,
mailboxId: selectedMailboxId,
);
}
}
Filter _getFilterConditionForLoadMailbox({PresentationEmail? oldestEmail}) {
if (selectedMailboxId?.isNotFavoriteMailboxId != true) {
return EmailFilterCondition(
hasKeyword: KeyWordIdentifier.emailFlagged.value,
before: oldestEmail?.receivedAt,
);
} else {
return getFilterCondition(
mailboxIdSelected: selectedMailboxId,
oldestEmail: oldestEmail,
);
}
}
EmailFilterCondition getFilterCondition({PresentationEmail? oldestEmail, MailboxId? mailboxIdSelected}) {
switch(mailboxDashBoardController.filterMessageOption.value) {
case FilterMessageOption.all:
@@ -741,11 +772,7 @@ class ThreadController extends BaseController with EmailActionController {
_session!,
_accountId!,
),
emailFilter: EmailFilter(
filter: getFilterCondition(mailboxIdSelected: selectedMailboxId),
filterOption: mailboxDashBoardController.filterMessageOption.value,
mailboxId: selectedMailboxId,
),
emailFilter: _getEmailFilterForLoadMailbox(),
).last;
refreshState.fold(
@@ -788,16 +815,17 @@ class ThreadController extends BaseController with EmailActionController {
limit: ThreadConstants.defaultLimit,
sort: EmailSortOrderType.mostRecent.getSortOrder().toNullable(),
filterOption: mailboxDashBoardController.filterMessageOption.value,
filter: getFilterCondition(oldestEmail: oldestEmail, mailboxIdSelected: selectedMailboxId),
filter: _getFilterConditionForLoadMailbox(oldestEmail: oldestEmail),
properties: EmailUtils.getPropertiesForEmailGetMethod(_session!, _accountId!),
lastEmailId: oldestEmail?.id
lastEmailId: oldestEmail?.id,
useCache: selectedMailboxId?.isNotFavoriteMailboxId == true,
)
));
}
}
bool _validatePresentationEmail(PresentationEmail email) {
return _belongToCurrentMailboxId(email)
return (_belongToCurrentMailboxId(email) || selectedMailboxId?.isNotFavoriteMailboxId != true)
&& _notDuplicatedInCurrentList(email);
}
@@ -3,6 +3,7 @@ import 'package:jmap_dart_client/jmap/core/reference_id.dart';
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/extensions/keyword_identifier_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
extension MailboxIdExtension on MailboxId {
String generatePath() {
@@ -31,4 +32,7 @@ extension MailboxIdExtension on MailboxId {
}
String get asString => id.value;
bool get isNotFavoriteMailboxId =>
this != PresentationMailbox.favoriteFolder.id;
}