TF-3767 Clean up recent searches whenever re-login and exceeds limit

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2025-06-11 12:59:13 +07:00
committed by Dat H. Pham
parent a02435c9f5
commit 6fef6190e0
13 changed files with 136 additions and 61 deletions
@@ -1,4 +1,5 @@
import 'package:core/utils/app_logger.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:model/extensions/account_id_extensions.dart';
@@ -18,16 +19,27 @@ class RecentSearchCacheManager {
RecentSearchCacheManager(this._recentSearchCacheClient);
Future<void> clean(RecentSearchCleanupRule cleanupRule) async {
final listRecentSearchCache = await _recentSearchCacheClient.getAll();
listRecentSearchCache.sortByCreationDate();
final nestedKey = TupleKey(
cleanupRule.accountId.asString,
cleanupRule.userName.value,
).encodeKey;
if (listRecentSearchCache.length > cleanupRule.storageLimit) {
final newListKeyRecent = listRecentSearchCache
.sublist(cleanupRule.storageLimit)
.map((recent) => recent.value)
.toList();
await _recentSearchCacheClient.deleteMultipleItem(newListKeyRecent);
}
final listRecentSearchCache = await _recentSearchCacheClient
.getListByNestedKey(nestedKey);
listRecentSearchCache.sortByCreationDate();
if (listRecentSearchCache.length > cleanupRule.storageLimit) {
final newListKeyRecent = listRecentSearchCache
.sublist(cleanupRule.storageLimit)
.map((recent) => recent.toRecentSearch().generateTupleKey(
cleanupRule.accountId,
cleanupRule.userName,
))
.toList();
log('RecentSearchCacheManager::clean: list recent to delete $newListKeyRecent');
await _recentSearchCacheClient.deleteMultipleItem(newListKeyRecent);
}
}
Future<void> saveRecentSearch(
@@ -76,6 +88,10 @@ class RecentSearchCacheManager {
? listRecentSearch.sublist(0, newLimit)
: listRecentSearch;
for (var recentSearch in newListRecentSearch) {
log('RecentSearchCacheManager::getAllLatest: Recent search: ${recentSearch.toString()}');
}
return newListRecentSearch;
}
@@ -1,13 +1,19 @@
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:tmail_ui_user/features/cleanup/domain/model/cleanup_rule.dart';
class RecentSearchCleanupRule extends CleanupRule {
final int storageLimit;
final AccountId accountId;
final UserName userName;
RecentSearchCleanupRule(
{this.storageLimit = 10}
this.accountId,
this.userName,
{this.storageLimit = 10}
) : super();
@override
List<Object?> get props => [storageLimit];
List<Object?> get props => [accountId, userName, storageLimit];
}
@@ -1,6 +1,8 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
class CleanupRecentSearchCacheLoading extends LoadingState {}
class CleanupRecentSearchCacheSuccess extends UIState {}
class CleanupRecentSearchCacheFailure extends FeatureFailure {
@@ -1,4 +1,5 @@
import 'package:core/core.dart';
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:dartz/dartz.dart';
import 'package:tmail_ui_user/features/cleanup/domain/model/recent_search_cleanup_rule.dart';
import 'package:tmail_ui_user/features/cleanup/domain/repository/cleanup_repository.dart';
@@ -9,13 +10,13 @@ class CleanupRecentSearchCacheInteractor {
CleanupRecentSearchCacheInteractor(this.cleanupRepository);
Future<Either<Failure, Success>> execute(RecentSearchCleanupRule cleanupRule) async {
Stream<Either<Failure, Success>> execute(RecentSearchCleanupRule cleanupRule) async* {
try {
yield Right<Failure, Success>(CleanupRecentSearchCacheLoading());
await cleanupRepository.cleanRecentSearchCache(cleanupRule);
log('CleanupRecentSearchCacheInteractor::execute(): SUCCESS');
return Right<Failure, Success>(CleanupRecentSearchCacheSuccess());
yield Right<Failure, Success>(CleanupRecentSearchCacheSuccess());
} catch (e) {
return Left(CleanupRecentSearchCacheFailure(e));
yield Left(CleanupRecentSearchCacheFailure(e));
}
}
}
@@ -0,0 +1,53 @@
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/base/interactors_bindings.dart';
import 'package:tmail_ui_user/features/cleanup/data/datasource/cleanup_datasource.dart';
import 'package:tmail_ui_user/features/cleanup/data/datasource_impl/cleanup_datasource_impl.dart';
import 'package:tmail_ui_user/features/cleanup/data/local/recent_login_url_cache_manager.dart';
import 'package:tmail_ui_user/features/cleanup/data/local/recent_login_username_cache_manager.dart';
import 'package:tmail_ui_user/features/cleanup/data/local/recent_search_cache_manager.dart';
import 'package:tmail_ui_user/features/cleanup/data/repository/cleanup_repository_impl.dart';
import 'package:tmail_ui_user/features/cleanup/domain/repository/cleanup_repository.dart';
import 'package:tmail_ui_user/features/cleanup/domain/usecases/cleanup_email_cache_interactor.dart';
import 'package:tmail_ui_user/features/cleanup/domain/usecases/cleanup_recent_login_url_cache_interactor.dart';
import 'package:tmail_ui_user/features/cleanup/domain/usecases/cleanup_recent_login_username_interactor.dart';
import 'package:tmail_ui_user/features/cleanup/domain/usecases/cleanup_recent_search_cache_interactor.dart';
import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart';
import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart';
class CleanupBindings extends InteractorsBindings {
@override
void bindingsDataSource() {
Get.lazyPut<CleanupDataSource>(() => Get.find<CleanupDataSourceImpl>());
}
@override
void bindingsDataSourceImpl() {
Get.lazyPut(() => CleanupDataSourceImpl(
Get.find<EmailCacheManager>(),
Get.find<RecentSearchCacheManager>(),
Get.find<RecentLoginUrlCacheManager>(),
Get.find<RecentLoginUsernameCacheManager>(),
Get.find<CacheExceptionThrower>(),
));
}
@override
void bindingsInteractor() {
Get.lazyPut(() => CleanupEmailCacheInteractor(Get.find<CleanupRepository>()));
Get.lazyPut(() => CleanupRecentSearchCacheInteractor(Get.find<CleanupRepository>()));
Get.lazyPut(() => CleanupRecentLoginUrlCacheInteractor(Get.find<CleanupRepository>()));
Get.lazyPut(() => CleanupRecentLoginUsernameCacheInteractor(Get.find<CleanupRepository>()));
}
@override
void bindingsRepository() {
Get.lazyPut<CleanupRepository>(() => Get.find<CleanupRepositoryImpl>());
}
@override
void bindingsRepositoryImpl() {
Get.lazyPut(() => CleanupRepositoryImpl(Get.find<CleanupDataSource>()));
}
}