diff --git a/lib/features/caching/utils/cache_utils.dart b/lib/features/caching/utils/cache_utils.dart new file mode 100644 index 000000000..29e18d241 --- /dev/null +++ b/lib/features/caching/utils/cache_utils.dart @@ -0,0 +1,29 @@ + +class TupleKey { + final List parts; + + TupleKey( + String key1, + [ + String? key2, + String? key3 + ] + ) : parts = [ + key1, + if (key2 != null) key2, + if (key3 != null) key3, + ]; + + const TupleKey.byParts(this.parts); + + TupleKey.fromString(String multiKeyString) : parts = multiKeyString.split('|').toList(); + + @override + String toString() => parts.join('|'); + + @override + bool operator ==(other) => parts.toString() == other.toString(); + + @override + int get hashCode => Object.hashAll(parts); +} \ No newline at end of file diff --git a/lib/features/mailbox/data/datasource/mailbox_datasource.dart b/lib/features/mailbox/data/datasource/mailbox_datasource.dart index 7baabf59d..655eae1ad 100644 --- a/lib/features/mailbox/data/datasource/mailbox_datasource.dart +++ b/lib/features/mailbox/data/datasource/mailbox_datasource.dart @@ -26,7 +26,7 @@ abstract class MailboxDataSource { Future getChanges(Session session, AccountId accountId, State sinceState); - Future update({List? updated, List? created, List? destroyed}); + Future update(AccountId accountId, {List? updated, List? created, List? destroyed}); Future createNewMailbox(Session session, AccountId accountId, CreateNewMailboxRequest newMailboxRequest); diff --git a/lib/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart b/lib/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart index b6eceb883..efadf197a 100644 --- a/lib/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart +++ b/lib/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart @@ -40,9 +40,9 @@ class MailboxCacheDataSourceImpl extends MailboxDataSource { } @override - Future update({List? updated, List? created, List? destroyed}) { + Future update(AccountId accountId, {List? updated, List? created, List? destroyed}) { return Future.sync(() async { - return await _mailboxCacheManager.update(updated: updated, created: created, destroyed: destroyed); + return await _mailboxCacheManager.update(accountId, updated: updated, created: created, destroyed: destroyed); }).catchError(_exceptionThrower.throwException); } diff --git a/lib/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart b/lib/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart index 55ec5594d..18579a91a 100644 --- a/lib/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart +++ b/lib/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart @@ -46,7 +46,7 @@ class MailboxDataSourceImpl extends MailboxDataSource { } @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/mailbox/data/extensions/list_mailbox_cache_extension.dart b/lib/features/mailbox/data/extensions/list_mailbox_cache_extension.dart deleted file mode 100644 index de46791e7..000000000 --- a/lib/features/mailbox/data/extensions/list_mailbox_cache_extension.dart +++ /dev/null @@ -1,8 +0,0 @@ - -import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_cache.dart'; - -extension ListMailboxCacheExtension on List { - Map toMap() { - return { for (var mailboxCache in this) mailboxCache.id : mailboxCache }; - } -} \ No newline at end of file diff --git a/lib/features/mailbox/data/extensions/list_mailbox_extension.dart b/lib/features/mailbox/data/extensions/list_mailbox_extension.dart new file mode 100644 index 000000000..16db6a3e3 --- /dev/null +++ b/lib/features/mailbox/data/extensions/list_mailbox_extension.dart @@ -0,0 +1,17 @@ + +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; +import 'package:model/extensions/account_id_extensions.dart'; +import 'package:model/extensions/mailbox_id_extension.dart'; +import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart'; +import 'package:tmail_ui_user/features/mailbox/data/extensions/mailbox_extension.dart'; +import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_cache.dart'; + +extension ListMailboxExtension on List { + Map toMapCache(AccountId accountId) { + return { + for (var mailbox in this) + TupleKey(mailbox.id!.asString, accountId.asString).toString() : mailbox.toMailboxCache() + }; + } +} \ No newline at end of file diff --git a/lib/features/mailbox/data/extensions/list_mailbox_id_extension.dart b/lib/features/mailbox/data/extensions/list_mailbox_id_extension.dart new file mode 100644 index 000000000..92a5c21f7 --- /dev/null +++ b/lib/features/mailbox/data/extensions/list_mailbox_id_extension.dart @@ -0,0 +1,10 @@ + +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; +import 'package:model/extensions/account_id_extensions.dart'; +import 'package:model/extensions/mailbox_id_extension.dart'; +import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart'; + +extension ListMailboxIdExtension 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/mailbox/data/local/mailbox_cache_manager.dart b/lib/features/mailbox/data/local/mailbox_cache_manager.dart index 87bfcc3f3..44a8d881a 100644 --- a/lib/features/mailbox/data/local/mailbox_cache_manager.dart +++ b/lib/features/mailbox/data/local/mailbox_cache_manager.dart @@ -1,11 +1,11 @@ +import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:tmail_ui_user/features/caching/mailbox_cache_client.dart'; -import 'package:tmail_ui_user/features/mailbox/data/extensions/list_mailbox_cache_extension.dart'; +import 'package:tmail_ui_user/features/mailbox/data/extensions/list_mailbox_extension.dart'; +import 'package:tmail_ui_user/features/mailbox/data/extensions/list_mailbox_id_extension.dart'; import 'package:tmail_ui_user/features/mailbox/data/extensions/mailbox_cache_extension.dart'; -import 'package:tmail_ui_user/features/mailbox/data/extensions/mailbox_extension.dart'; -import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_cache.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/exceptions/spam_report_exception.dart'; class MailboxCacheManager { @@ -20,24 +20,26 @@ class MailboxCacheManager { return mailboxList; } - Future update({List? updated, List? created, List? destroyed}) async { + Future update( + AccountId accountId, { + List? updated, + List? created, + List? destroyed + }) async { final mailboxCacheExist = await _mailboxCacheClient.isExistTable(); if (mailboxCacheExist) { - final updatedCacheMailboxes = updated - ?.map((mailbox) => mailbox.toMailboxCache()).toList() ?? []; - final createdCacheMailboxes = created - ?.map((mailbox) => mailbox.toMailboxCache()).toList() ?? []; - final destroyedCacheMailboxes = destroyed - ?.map((mailboxId) => mailboxId.id.value).toList() ?? []; + final updatedCacheMailboxes = updated?.toMapCache(accountId) ?? {}; + final createdCacheMailboxes = created?.toMapCache(accountId) ?? {}; + final destroyedCacheMailboxes = destroyed?.toCacheKeyList(accountId) ?? []; + await Future.wait([ - _mailboxCacheClient.updateMultipleItem(updatedCacheMailboxes.toMap()), - _mailboxCacheClient.insertMultipleItem(createdCacheMailboxes.toMap()), + _mailboxCacheClient.updateMultipleItem(updatedCacheMailboxes), + _mailboxCacheClient.insertMultipleItem(createdCacheMailboxes), _mailboxCacheClient.deleteMultipleItem(destroyedCacheMailboxes) ]); } else { - final createdCacheMailboxes = created - ?.map((mailbox) => mailbox.toMailboxCache()).toList() ?? []; - await _mailboxCacheClient.insertMultipleItem(createdCacheMailboxes.toMap()); + final createdCacheMailboxes = created?.toMapCache(accountId) ?? {}; + await _mailboxCacheClient.insertMultipleItem(createdCacheMailboxes); } } diff --git a/lib/features/mailbox/data/repository/mailbox_repository_impl.dart b/lib/features/mailbox/data/repository/mailbox_repository_impl.dart index f546cdc6d..2ba1bb61d 100644 --- a/lib/features/mailbox/data/repository/mailbox_repository_impl.dart +++ b/lib/features/mailbox/data/repository/mailbox_repository_impl.dart @@ -64,6 +64,7 @@ class MailboxRepositoryImpl extends MailboxRepository { await Future.wait([ mapDataSource[DataSourceType.local]!.update( + accountId, updated: newMailboxUpdated, created: changesResponse.created, destroyed: changesResponse.destroyed), @@ -75,7 +76,7 @@ class MailboxRepositoryImpl extends MailboxRepository { final mailboxResponse = await mapDataSource[DataSourceType.network]!.getAllMailbox(session, accountId); await Future.wait([ - mapDataSource[DataSourceType.local]!.update(created: mailboxResponse.mailboxes), + mapDataSource[DataSourceType.local]!.update(accountId, created: mailboxResponse.mailboxes), if (mailboxResponse.state != null) stateDataSource.saveState(mailboxResponse.state!.toStateCache(StateType.mailbox)), ]); @@ -135,6 +136,7 @@ class MailboxRepositoryImpl extends MailboxRepository { await Future.wait([ mapDataSource[DataSourceType.local]!.update( + accountId, updated: newMailboxUpdated, created: changesResponse.created, destroyed: changesResponse.destroyed), diff --git a/model/lib/extensions/account_id_extensions.dart b/model/lib/extensions/account_id_extensions.dart new file mode 100644 index 000000000..6337f4590 --- /dev/null +++ b/model/lib/extensions/account_id_extensions.dart @@ -0,0 +1,6 @@ + +import 'package:jmap_dart_client/jmap/account_id.dart'; + +extension AccountIdExtension on AccountId { + String get asString => id.value; +} \ No newline at end of file diff --git a/model/lib/extensions/email_id_extensions.dart b/model/lib/extensions/email_id_extensions.dart new file mode 100644 index 000000000..2841f331a --- /dev/null +++ b/model/lib/extensions/email_id_extensions.dart @@ -0,0 +1,5 @@ +import 'package:jmap_dart_client/jmap/mail/email/email.dart'; + +extension EmailIdExtension on EmailId { + String get asString => id.value; +} \ No newline at end of file diff --git a/model/lib/extensions/mailbox_id_extension.dart b/model/lib/extensions/mailbox_id_extension.dart index 89fee4913..b6e45b152 100644 --- a/model/lib/extensions/mailbox_id_extension.dart +++ b/model/lib/extensions/mailbox_id_extension.dart @@ -23,4 +23,6 @@ extension MailboxIdExtension on MailboxId { generatePath(): true, }); } + + String get asString => id.value; } \ No newline at end of file diff --git a/model/lib/model.dart b/model/lib/model.dart index 98360ed61..02b3a7a4c 100644 --- a/model/lib/model.dart +++ b/model/lib/model.dart @@ -55,6 +55,8 @@ export 'extensions/list_email_header_extension.dart'; export 'extensions/account_extension.dart'; export 'extensions/list_presentation_mailbox_extension.dart'; export 'extensions/list_identity_id_extension.dart'; +export 'extensions/email_id_extensions.dart'; +export 'extensions/account_id_extensions.dart'; // Identity export 'identity/identity_request_dto.dart'; export 'mailbox/expand_mode.dart';