diff --git a/lib/features/thread/data/datasource/thread_datasource.dart b/lib/features/thread/data/datasource/thread_datasource.dart index d85dd6e62..5b89125e7 100644 --- a/lib/features/thread/data/datasource/thread_datasource.dart +++ b/lib/features/thread/data/datasource/thread_datasource.dart @@ -38,7 +38,7 @@ abstract class ThreadDataSource { Future> getAllEmailCache({MailboxId? inMailboxId, Set? sort, FilterMessageOption? filterOption, UnsignedInt? limit}); - Future update({List? updated, List? created, List? destroyed}); + Future update(AccountId accountId, {List? updated, List? created, List? destroyed}); Future> emptyTrashFolder( Session session, diff --git a/lib/features/thread/data/datasource_impl/local_thread_datasource_impl.dart b/lib/features/thread/data/datasource_impl/local_thread_datasource_impl.dart index 44f285845..45598400c 100644 --- a/lib/features/thread/data/datasource_impl/local_thread_datasource_impl.dart +++ b/lib/features/thread/data/datasource_impl/local_thread_datasource_impl.dart @@ -68,13 +68,15 @@ class LocalThreadDataSourceImpl extends ThreadDataSource { } @override - Future update({ + Future update( + AccountId accountId, { List? updated, List? created, List? destroyed }) { return Future.sync(() async { return await _emailCacheManager.update( + accountId, updated: updated, created: created, destroyed: destroyed); diff --git a/lib/features/thread/data/datasource_impl/thread_datasource_impl.dart b/lib/features/thread/data/datasource_impl/thread_datasource_impl.dart index cb0b55918..60a45157b 100644 --- a/lib/features/thread/data/datasource_impl/thread_datasource_impl.dart +++ b/lib/features/thread/data/datasource_impl/thread_datasource_impl.dart @@ -79,7 +79,7 @@ class ThreadDataSourceImpl extends ThreadDataSource { } @override - Future update({List? updated, List? created, List? destroyed}) { + Future update(AccountId accountId, {List? updated, List? created, List? destroyed}) { throw UnimplementedError(); } diff --git a/lib/features/thread/data/extensions/list_email_extension.dart b/lib/features/thread/data/extensions/list_email_extension.dart new file mode 100644 index 000000000..c1669b6be --- /dev/null +++ b/lib/features/thread/data/extensions/list_email_extension.dart @@ -0,0 +1,17 @@ + +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/mail/email/email.dart'; +import 'package:model/extensions/account_id_extensions.dart'; +import 'package:model/extensions/email_id_extensions.dart'; +import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart'; +import 'package:tmail_ui_user/features/thread/data/extensions/email_extension.dart'; +import 'package:tmail_ui_user/features/thread/data/model/email_cache.dart'; + +extension ListEmailExtension on List { + Map toMapCache(AccountId accountId) { + return { + for (var email in this) + TupleKey(email.id!.asString, accountId.asString).toString() : email.toEmailCache() + }; + } +} \ No newline at end of file diff --git a/lib/features/thread/data/extensions/list_email_id_extension.dart b/lib/features/thread/data/extensions/list_email_id_extension.dart new file mode 100644 index 000000000..7cd80b7a0 --- /dev/null +++ b/lib/features/thread/data/extensions/list_email_id_extension.dart @@ -0,0 +1,10 @@ + +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/mail/email/email.dart'; +import 'package:model/extensions/account_id_extensions.dart'; +import 'package:model/extensions/email_id_extensions.dart'; +import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart'; + +extension ListEmailIdExtension on List { + List toCacheKeyList(AccountId accountId) => map((id) => TupleKey(id.asString, accountId.asString).toString()).toList(); +} \ No newline at end of file diff --git a/lib/features/thread/data/local/email_cache_manager.dart b/lib/features/thread/data/local/email_cache_manager.dart index 0fb9a004b..3e54bd65b 100644 --- a/lib/features/thread/data/local/email_cache_manager.dart +++ b/lib/features/thread/data/local/email_cache_manager.dart @@ -1,4 +1,4 @@ -import 'package:core/core.dart'; +import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/core/unsigned_int.dart'; import 'package:model/model.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; @@ -6,9 +6,8 @@ import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:tmail_ui_user/features/caching/email_cache_client.dart'; import 'package:tmail_ui_user/features/cleanup/domain/model/email_cleanup_rule.dart'; import 'package:tmail_ui_user/features/thread/data/extensions/email_cache_extension.dart'; -import 'package:tmail_ui_user/features/thread/data/extensions/email_extension.dart'; -import 'package:tmail_ui_user/features/thread/data/extensions/list_email_cache_extension.dart'; -import 'package:tmail_ui_user/features/thread/data/model/email_cache.dart'; +import 'package:tmail_ui_user/features/thread/data/extensions/list_email_extension.dart'; +import 'package:tmail_ui_user/features/thread/data/extensions/list_email_id_extension.dart'; import 'package:jmap_dart_client/jmap/core/sort/comparator.dart'; import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart'; @@ -43,28 +42,26 @@ class EmailCacheManager { return emailList; } - Future update({List? updated, List? created, List? destroyed}) async { + Future update( + AccountId accountId, { + List? updated, + List? created, + List? destroyed + }) async { final emailCacheExist = await _emailCacheClient.isExistTable(); - log('EmailCacheManager::update(): emailCacheExist: $emailCacheExist'); if (emailCacheExist) { - final updatedCacheEmails = updated - ?.map((email) => email.toEmailCache()).toList() ?? []; - final createdCacheEmails = created - ?.map((email) => email.toEmailCache()).toList() ?? []; - final destroyedCacheEmails = destroyed - ?.map((emailId) => emailId.id.value).toList() ?? []; - - log('EmailCacheManager::update(): destroyedCacheEmails: ${destroyedCacheEmails.length}'); + final updatedCacheEmails = updated?.toMapCache(accountId) ?? {}; + final createdCacheEmails = created?.toMapCache(accountId) ?? {}; + final destroyedCacheEmails = destroyed?.toCacheKeyList(accountId) ?? []; await Future.wait([ - _emailCacheClient.updateMultipleItem(updatedCacheEmails.toMap()), - _emailCacheClient.insertMultipleItem(createdCacheEmails.toMap()), + _emailCacheClient.updateMultipleItem(updatedCacheEmails), + _emailCacheClient.insertMultipleItem(createdCacheEmails), _emailCacheClient.deleteMultipleItem(destroyedCacheEmails) ]); } else { - final createdCacheEmails = created - ?.map((email) => email.toEmailCache()).toList() ?? []; - await _emailCacheClient.insertMultipleItem(createdCacheEmails.toMap()); + final createdCacheEmails = created?.toMapCache(accountId) ?? {}; + await _emailCacheClient.insertMultipleItem(createdCacheEmails); } } diff --git a/lib/features/thread/data/repository/thread_repository_impl.dart b/lib/features/thread/data/repository/thread_repository_impl.dart index f9829d27f..84ae00814 100644 --- a/lib/features/thread/data/repository/thread_repository_impl.dart +++ b/lib/features/thread/data/repository/thread_repository_impl.dart @@ -81,7 +81,7 @@ class ThreadRepositoryImpl extends ThreadRepository { } if (networkEmailResponse != null) { - await _updateEmailCache(newCreated: networkEmailResponse.emailList); + await _updateEmailCache(accountId, newCreated: networkEmailResponse.emailList); } if (localEmailResponse.hasState()) { @@ -138,7 +138,7 @@ class ThreadRepositoryImpl extends ThreadRepository { filter: filter ?? EmailFilterCondition(inMailbox: mailboxId), properties: propertiesCreated, ); - await _updateEmailCache(newCreated: networkEmailResponse.emailList); + await _updateEmailCache(accountId, newCreated: networkEmailResponse.emailList); return networkEmailResponse; } @@ -176,12 +176,14 @@ class ThreadRepositoryImpl extends ThreadRepository { } } - Future _updateEmailCache({ + Future _updateEmailCache( + AccountId accountId, { List? newUpdated, List? newCreated, List? newDestroyed }) async { await mapDataSource[DataSourceType.local]!.update( + accountId, updated: newUpdated, created: newCreated, destroyed: newDestroyed); @@ -240,7 +242,7 @@ class ThreadRepositoryImpl extends ThreadRepository { @override Stream loadMoreEmails(GetEmailRequest emailRequest) async* { final response = await _getAllEmailsWithoutLastEmailId(emailRequest); - await _updateEmailCache(newCreated: response.emailList); + await _updateEmailCache(emailRequest.accountId, newCreated: response.emailList); yield response; } @@ -290,7 +292,7 @@ class ThreadRepositoryImpl extends ThreadRepository { accountId, trashMailboxId, (listEmailIdDeleted) async { - await _updateEmailCache(newDestroyed: listEmailIdDeleted); + await _updateEmailCache(accountId, newDestroyed: listEmailIdDeleted); }, ); } @@ -342,6 +344,7 @@ class ThreadRepositoryImpl extends ThreadRepository { 'destroyed = ${emailChangeResponse.destroyed?.length}'); await _updateEmailCache( + accountId, newCreated: emailChangeResponse.created, newUpdated: newEmailUpdated, newDestroyed: emailChangeResponse.destroyed);