TF-145 Add data layer for getAllEmail in Caching

This commit is contained in:
dab246
2021-10-07 15:02:07 +07:00
committed by Dat H. Pham
parent 3cac5e4e83
commit bfd5901bf4
16 changed files with 524 additions and 22 deletions
@@ -1,5 +1,6 @@
import 'package:hive/hive.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:tmail_ui_user/features/caching/config/hive_cache_client.dart';
import 'package:tmail_ui_user/features/thread/data/model/email_cache.dart';
@@ -118,4 +119,17 @@ class EmailCacheClient extends HiveCacheClient<EmailCache> {
throw error;
});
}
Future<List<EmailCache>> getListEmailCacheByMailboxId(MailboxId mailboxId) {
return Future.sync(() async {
final boxEmail = await openBox();
return boxEmail.values.where((emailCache) {
return emailCache.mailboxIds != null
&& emailCache.mailboxIds!.containsKey(mailboxId.id.value)
&& emailCache.mailboxIds![mailboxId.id.value] == true;
}).toList();
}).catchError((error) {
throw error;
});
}
}
@@ -2,11 +2,15 @@ import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/filter/filter.dart';
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:tmail_ui_user/features/thread/data/model/email_change_response.dart';
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
abstract class ThreadDataSource {
Future<List<Email>> getAllEmail(
Future<EmailResponse> getAllEmail(
AccountId accountId,
{
int? position,
@@ -16,4 +20,17 @@ abstract class ThreadDataSource {
Properties? properties
}
);
Future<EmailChangeResponse> getChanges(
AccountId accountId,
State sinceState,
{
Properties? propertiesCreated,
Properties? propertiesUpdated
}
);
Future<List<Email>> getAllEmailCache({MailboxId? inMailboxId, Set<Comparator>? sort});
Future<void> update({List<Email>? updated, List<Email>? created, List<EmailId>? destroyed});
}
@@ -0,0 +1,63 @@
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/filter/filter.dart';
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart';
import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart';
import 'package:tmail_ui_user/features/thread/data/model/email_change_response.dart';
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
class LocalThreadDataSourceImpl extends ThreadDataSource {
final EmailCacheManager _emailCacheManager;
LocalThreadDataSourceImpl(this._emailCacheManager);
@override
Future<EmailResponse> getAllEmail(
AccountId accountId,
{
int? position,
UnsignedInt? limit,
Set<Comparator>? sort,
Filter? filter,
Properties? properties
}
) {
throw UnimplementedError();
}
@override
Future<EmailChangeResponse> getChanges(
AccountId accountId,
State sinceState,
{
Properties? propertiesCreated,
Properties? propertiesUpdated
}
) {
throw UnimplementedError();
}
@override
Future<List<Email>> getAllEmailCache({MailboxId? inMailboxId, Set<Comparator>? sort}) {
return Future.sync(() async {
return await _emailCacheManager.getAllEmail(inMailboxId: inMailboxId, sort: sort);
}).catchError((error) {
throw error;
});
}
@override
Future<void> update({List<Email>? updated, List<Email>? created, List<EmailId>? destroyed}) {
return Future.sync(() async {
return await _emailCacheManager.update(updated: updated, created: created, destroyed: destroyed);
}).catchError((error) {
throw error;
});
}
}
@@ -2,9 +2,13 @@ import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/filter/filter.dart';
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart';
import 'package:tmail_ui_user/features/thread/data/model/email_change_response.dart';
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
import 'package:tmail_ui_user/features/thread/data/network/thread_api.dart';
class ThreadDataSourceImpl extends ThreadDataSource {
@@ -14,14 +18,17 @@ class ThreadDataSourceImpl extends ThreadDataSource {
ThreadDataSourceImpl(this.threadAPI);
@override
Future<List<Email>> getAllEmail(
Future<EmailResponse> getAllEmail(
AccountId accountId,
{
int? position,
UnsignedInt? limit,
Set<Comparator>? sort,
Filter? filter,
Properties? properties
Properties? properties,
Properties? propertiesCreated,
Properties? propertiesUpdated,
MailboxId? inMailboxId
}
) {
return Future.sync(() async {
@@ -36,4 +43,34 @@ class ThreadDataSourceImpl extends ThreadDataSource {
throw error;
});
}
@override
Future<EmailChangeResponse> getChanges(
AccountId accountId,
State sinceState,
{
Properties? propertiesCreated,
Properties? propertiesUpdated
}
) {
return Future.sync(() async {
return await threadAPI.getChanges(
accountId,
sinceState,
propertiesCreated: propertiesCreated,
propertiesUpdated: propertiesUpdated);
}).catchError((error) {
throw error;
});
}
@override
Future<List<Email>> getAllEmailCache({MailboxId? inMailboxId, Set<Comparator>? sort}) {
throw UnimplementedError();
}
@override
Future<void> update({List<Email>? updated, List<Email>? created, List<EmailId>? destroyed}) {
throw UnimplementedError();
}
}
@@ -0,0 +1,8 @@
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:tmail_ui_user/features/thread/data/model/email_address_hive_cache.dart';
extension EmailAddressHiveCacheExtension on EmailAddressHiveCache {
EmailAddress toEmailAddress() => EmailAddress(name, email);
}
@@ -0,0 +1,34 @@
import 'package:jmap_dart_client/jmap/core/id.dart';
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/core/utc_date.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:tmail_ui_user/features/thread/data/model/email_cache.dart';
import 'package:tmail_ui_user/features/thread/data/extensions/email_address_hive_cache_extension.dart';
extension EmailCacheExtension on EmailCache {
Email toEmail() {
return Email(
EmailId(Id(id)),
keywords: keywords != null
? Map.fromIterables(keywords!.keys.map((value) => KeyWordIdentifier(value)), keywords!.values)
: null,
size: size != null ? UnsignedInt(size!) : null,
receivedAt: receivedAt != null ? UTCDate(receivedAt!) : null,
hasAttachment: hasAttachment,
preview: preview,
subject: subject,
sentAt: sentAt != null ? UTCDate(sentAt!) : null,
from: from?.map((emailAddressCache) => emailAddressCache.toEmailAddress()).toSet(),
to: to?.map((emailAddressCache) => emailAddressCache.toEmailAddress()).toSet(),
cc: cc?.map((emailAddressCache) => emailAddressCache.toEmailAddress()).toSet(),
bcc: bcc?.map((emailAddressCache) => emailAddressCache.toEmailAddress()).toSet(),
replyTo: replyTo?.map((emailAddressCache) => emailAddressCache.toEmailAddress()).toSet(),
mailboxIds: mailboxIds != null
? Map.fromIterables(mailboxIds!.keys.map((value) => MailboxId(Id(value))), mailboxIds!.values)
: null,
);
}
}
@@ -2,12 +2,13 @@ import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:tmail_ui_user/features/thread/data/model/email_cache.dart';
import 'package:tmail_ui_user/features/thread/data/extensions/map_keywords_extension.dart';
import 'package:tmail_ui_user/features/thread/data/extensions/email_address_extension.dart';
import 'package:tmail_ui_user/features/thread/data/extensions/map_mailbox_id_extension.dart';
extension EmailExtension on Email {
EmailCache toEmailCache() {
return EmailCache(
id.toString(),
id.id.value,
keywords: keywords?.toMapString(),
size: size?.value.round(),
receivedAt: receivedAt?.value,
@@ -20,6 +21,7 @@ extension EmailExtension on Email {
cc: cc?.map((emailAddress) => emailAddress.toEmailAddressHiveCache()).toList(),
bcc: bcc?.map((emailAddress) => emailAddress.toEmailAddressHiveCache()).toList(),
replyTo: replyTo?.map((emailAddress) => emailAddress.toEmailAddressHiveCache()).toList(),
mailboxIds: mailboxIds?.toMapString(),
);
}
}
@@ -0,0 +1,11 @@
import 'package:tmail_ui_user/features/thread/data/model/email_cache.dart';
extension ListEmailCacheExtension on List<EmailCache> {
Map<String, EmailCache> toMap() {
return Map<String, EmailCache>.fromIterable(
this,
key: (emailCache) => emailCache.id,
value: (emailCache) => emailCache);
}
}
@@ -0,0 +1,7 @@
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
extension MapMailboxIdExtension on Map<MailboxId, bool> {
Map<String, bool> toMapString() => Map.fromIterables(keys.map((mailboxId) => mailboxId.id.value), values);
}
@@ -0,0 +1,53 @@
import 'package:model/model.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
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/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:jmap_dart_client/jmap/core/sort/comparator.dart';
class EmailCacheManager {
final EmailCacheClient _emailCacheClient;
EmailCacheManager(this._emailCacheClient);
Future<List<Email>> getAllEmail({MailboxId? inMailboxId, Set<Comparator>? sort}) async {
final emailCacheList = inMailboxId != null
? await _emailCacheClient.getListEmailCacheByMailboxId(inMailboxId)
: await _emailCacheClient.getAll();
final emailList = emailCacheList.map((emailCache) => emailCache.toEmail()).toList();
if (sort != null) {
sort.forEach((comparator) {
emailList.sortBy(comparator);
});
}
return emailList;
}
Future<void> update({List<Email>? updated, List<Email>? created, List<EmailId>? destroyed}) async {
final emailCacheExist = await _emailCacheClient.isExistTable();
if (emailCacheExist) {
final updatedCacheEmails = updated
?.map((email) => email.toEmailCache()).toList() ?? <EmailCache>[];
final createdCacheEmails = created
?.map((email) => email.toEmailCache()).toList() ?? <EmailCache>[];
final destroyedCacheEmails = destroyed
?.map((emailId) => emailId.id.value).toList() ?? <String>[];
await Future.wait([
_emailCacheClient.updateMultipleItem(updatedCacheEmails.toMap()),
_emailCacheClient.insertMultipleItem(createdCacheEmails.toMap()),
_emailCacheClient.deleteMultipleItem(destroyedCacheEmails)
]);
} else {
final createdCacheEmails = created
?.map((email) => email.toEmailCache()).toList() ?? <EmailCache>[];
await _emailCacheClient.insertMultipleItem(createdCacheEmails.toMap());
}
}
}
@@ -48,6 +48,9 @@ class EmailCache extends HiveObject with EquatableMixin {
@HiveField(12)
final List<EmailAddressHiveCache>? replyTo;
@HiveField(13)
Map<String, bool>? mailboxIds;
EmailCache(
this.id,
{
@@ -63,6 +66,7 @@ class EmailCache extends HiveObject with EquatableMixin {
this.cc,
this.bcc,
this.replyTo,
this.mailboxIds,
}
);
@@ -80,6 +84,7 @@ class EmailCache extends HiveObject with EquatableMixin {
sentAt,
replyTo,
preview,
hasAttachment
hasAttachment,
mailboxIds,
];
}
@@ -30,13 +30,14 @@ class EmailCacheAdapter extends TypeAdapter<EmailCache> {
cc: (fields[10] as List?)?.cast<EmailAddressHiveCache>(),
bcc: (fields[11] as List?)?.cast<EmailAddressHiveCache>(),
replyTo: (fields[12] as List?)?.cast<EmailAddressHiveCache>(),
mailboxIds: (fields[13] as Map?)?.cast<String, bool>(),
);
}
@override
void write(BinaryWriter writer, EmailCache obj) {
writer
..writeByte(13)
..writeByte(14)
..writeByte(0)
..write(obj.id)
..writeByte(1)
@@ -62,7 +63,9 @@ class EmailCacheAdapter extends TypeAdapter<EmailCache> {
..writeByte(11)
..write(obj.bcc)
..writeByte(12)
..write(obj.replyTo);
..write(obj.replyTo)
..writeByte(13)
..write(obj.mailboxIds);
}
@override
@@ -0,0 +1,47 @@
import 'package:model/model.dart';
import 'package:equatable/equatable.dart';
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
class EmailChangeResponse with EquatableMixin {
final List<Email>? updated;
final List<Email>? created;
final List<EmailId>? destroyed;
final State? newStateEmail;
final State? newStateChanges;
final bool hasMoreChanges;
final Properties? updatedProperties;
EmailChangeResponse({
this.updated,
this.created,
this.destroyed,
this.newStateEmail,
this.newStateChanges,
this.hasMoreChanges = false,
this.updatedProperties,
});
EmailChangeResponse union(EmailChangeResponse other) => EmailChangeResponse(
updated: updated.union(other.updated),
created: created.union(other.created),
destroyed: destroyed.union(other.destroyed),
newStateEmail: other.newStateEmail,
newStateChanges: other.newStateChanges,
hasMoreChanges: other.hasMoreChanges,
updatedProperties: other.updatedProperties,
);
@override
List<Object?> get props => [
updated,
created,
destroyed,
newStateEmail,
newStateChanges,
hasMoreChanges,
updatedProperties
];
}
@@ -6,12 +6,17 @@ import 'package:jmap_dart_client/jmap/core/filter/filter.dart';
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/core/request/reference_path.dart';
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/jmap_request.dart';
import 'package:jmap_dart_client/jmap/mail/email/changes/changes_email_method.dart';
import 'package:jmap_dart_client/jmap/mail/email/changes/changes_email_response.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/email/get/get_email_method.dart';
import 'package:jmap_dart_client/jmap/mail/email/get/get_email_response.dart';
import 'package:jmap_dart_client/jmap/mail/email/query/query_email_method.dart';
import 'package:tmail_ui_user/features/thread/data/model/email_change_response.dart';
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
class ThreadAPI {
@@ -19,7 +24,7 @@ class ThreadAPI {
ThreadAPI(this.httpClient);
Future<List<Email>> getAllEmail(
Future<EmailResponse> getAllEmail(
AccountId accountId,
{
int? position,
@@ -69,6 +74,72 @@ class ThreadAPI {
});
}
return resultList == null ? [] : resultList.list;
return EmailResponse(emailList: resultList?.list, state: resultList?.state);
}
Future<EmailChangeResponse> getChanges(
AccountId accountId,
State sinceState,
{
Properties? propertiesCreated,
Properties? propertiesUpdated
}
) async {
final processingInvocation = ProcessingInvocation();
final jmapRequestBuilder = JmapRequestBuilder(httpClient, processingInvocation);
final changesEmailMethod = ChangesEmailMethod(accountId, sinceState, maxChanges: UnsignedInt(128));
final changesEmailInvocation = jmapRequestBuilder.invocation(changesEmailMethod);
final getMailboxUpdated = GetEmailMethod(accountId)
..addReferenceIds(processingInvocation.createResultReference(
changesEmailInvocation.methodCallId,
ReferencePath.updatedPath));
if (propertiesUpdated != null) {
getMailboxUpdated..addProperties(propertiesUpdated);
}
final getEmailCreated = GetEmailMethod(accountId)
..addReferenceIds(processingInvocation.createResultReference(
changesEmailInvocation.methodCallId,
ReferencePath.createdPath));
if (propertiesCreated != null) {
getEmailCreated..addProperties(propertiesCreated);
}
final getEmailUpdatedInvocation = jmapRequestBuilder.invocation(getMailboxUpdated);
final getEmailCreatedInvocation = jmapRequestBuilder.invocation(getEmailCreated);
final result = await (jmapRequestBuilder
..usings(getEmailCreated.requiredCapabilities))
.build()
.execute();
final resultChanges = result.parse<ChangesEmailResponse>(
changesEmailInvocation.methodCallId,
ChangesEmailResponse.deserialize);
final resultUpdated = result.parse<GetEmailResponse>(
getEmailUpdatedInvocation.methodCallId,
GetEmailResponse.deserialize);
final resultCreated = result.parse<GetEmailResponse>(
getEmailCreatedInvocation.methodCallId,
GetEmailResponse.deserialize);
final listMailboxIdDestroyed = resultChanges?.destroyed.map((id) => EmailId(id)).toList() ?? <EmailId>[];
return EmailChangeResponse(
updated: resultUpdated?.list,
created: resultCreated?.list,
destroyed: listMailboxIdDestroyed,
newStateEmail: resultUpdated?.state,
newStateChanges: resultChanges?.newState,
hasMoreChanges: resultChanges?.hasMoreChanges ?? false,
updatedProperties: propertiesUpdated);
}
}
@@ -1,37 +1,163 @@
import 'package:core/core.dart';
import 'package:model/model.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/filter/filter.dart';
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:tmail_ui_user/features/mailbox/data/datasource/state_datasource.dart';
import 'package:tmail_ui_user/features/mailbox/data/model/state_type.dart';
import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart';
import 'package:tmail_ui_user/features/thread/data/model/email_change_response.dart';
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart';
import 'package:tmail_ui_user/features/mailbox/data/extensions/state_extension.dart';
class ThreadRepositoryImpl extends ThreadRepository {
final ThreadDataSource threadDataSource;
final Map<DataSourceType, ThreadDataSource> mapDataSource;
final StateDataSource stateDataSource;
ThreadRepositoryImpl(this.threadDataSource);
ThreadRepositoryImpl(this.mapDataSource, this.stateDataSource);
@override
Future<List<Email>> getAllEmail(
Stream<EmailResponse> getAllEmail(
AccountId accountId,
{
int? position,
UnsignedInt? limit,
Set<Comparator>? sort,
Filter? filter,
Properties? properties
Properties? propertiesCreated,
Properties? propertiesUpdated,
MailboxId? inMailboxId
}
) {
return threadDataSource.getAllEmail(
accountId,
position: position,
limit: limit,
sort: sort,
filter: filter,
properties: properties
);
) async* {
final localEmailResponse = await Future.wait([
mapDataSource[DataSourceType.local]!.getAllEmailCache(inMailboxId: inMailboxId, sort: sort),
stateDataSource.getState(StateType.email)
]).then((List response) {
return EmailResponse(emailList: response.first, state: response.last);
});
EmailResponse? networkEmailResponse;
if (!localEmailResponse.hasEmails()) {
networkEmailResponse = await mapDataSource[DataSourceType.network]!.getAllEmail(
accountId,
position: position,
limit: limit,
sort: sort,
filter: filter,
properties: propertiesCreated);
yield networkEmailResponse;
} else {
yield localEmailResponse;
}
if (localEmailResponse.hasState()) {
EmailChangeResponse? emailChangeResponse;
bool hasMoreChanges = true;
State? sinceState = localEmailResponse.state!;
while(hasMoreChanges && sinceState != null) {
final changesResponse = await mapDataSource[DataSourceType.network]!.getChanges(
accountId,
sinceState,
propertiesCreated: propertiesCreated,
propertiesUpdated: propertiesUpdated);
hasMoreChanges = changesResponse.hasMoreChanges;
sinceState = changesResponse.newStateChanges;
if (emailChangeResponse != null) {
emailChangeResponse.union(changesResponse);
} else {
emailChangeResponse = changesResponse;
}
}
final totalEmails = networkEmailResponse != null
? networkEmailResponse.emailList
: localEmailResponse.emailList;
final newEmailUpdated = await _combineEmailCache(
emailUpdated: emailChangeResponse?.updated,
updatedProperties: emailChangeResponse?.updatedProperties,
emailCacheList: totalEmails);
final newEmailCreated = networkEmailResponse != null
? networkEmailResponse.emailList
: emailChangeResponse?.created;
await _updateEmailCache(
newCreated: newEmailCreated,
newUpdated: newEmailUpdated,
newDestroyed: emailChangeResponse?.destroyed);
if (emailChangeResponse != null && emailChangeResponse.newStateEmail != null) {
await _updateState(emailChangeResponse.newStateEmail!);
}
} else {
if (networkEmailResponse != null) {
await _updateEmailCache(newCreated: networkEmailResponse.emailList);
if (networkEmailResponse.state != null) {
await _updateState(networkEmailResponse.state!);
}
}
}
final newEmailResponse = await Future.wait([
mapDataSource[DataSourceType.local]!.getAllEmailCache(inMailboxId: inMailboxId, sort: sort),
stateDataSource.getState(StateType.email)
]).then((List response) {
return EmailResponse(emailList: response.first, state: response.last);
});
yield newEmailResponse;
}
Future<List<Email>?> _combineEmailCache({
List<Email>? emailUpdated,
Properties? updatedProperties,
List<Email>? emailCacheList
}) async {
if (emailUpdated != null && emailUpdated.isNotEmpty) {
final newEmailUpdated = emailUpdated.map((email) {
if (updatedProperties == null) {
return email;
} else {
final emailOld = emailCacheList?.findEmail(email.id);
if (emailOld != null) {
return emailOld.combineEmail(email, updatedProperties);
} else {
return email;
}
}
}).toList();
return newEmailUpdated;
}
return emailUpdated;
}
Future<void> _updateEmailCache({
List<Email>? newUpdated,
List<Email>? newCreated,
List<EmailId>? newDestroyed
}) async {
await mapDataSource[DataSourceType.local]!.update(
updated: newUpdated,
created: newCreated,
destroyed: newDestroyed);
}
Future<void> _updateState(State newState) async {
await stateDataSource.saveState(newState.toStateCache(StateType.email));
}
}
@@ -2,9 +2,11 @@
import 'package:core/core.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/caching/caching_manager.dart';
import 'package:tmail_ui_user/features/caching/email_cache_client.dart';
import 'package:tmail_ui_user/features/caching/mailbox_cache_client.dart';
import 'package:tmail_ui_user/features/caching/state_cache_client.dart';
import 'package:tmail_ui_user/features/mailbox/data/local/mailbox_cache_manager.dart';
import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart';
class LocalBindings extends Bindings {
@@ -25,5 +27,7 @@ class LocalBindings extends Bindings {
Get.put(CachingManager(
Get.find<MailboxCacheClient>(),
Get.find<StateCacheClient>()));
Get.put(EmailCacheClient());
Get.put(EmailCacheManager(Get.find<EmailCacheClient>()));
}
}