diff --git a/lib/features/caching/config/hive_cache_config.dart b/lib/features/caching/config/hive_cache_config.dart index 833aaf32f..17cb20dd2 100644 --- a/lib/features/caching/config/hive_cache_config.dart +++ b/lib/features/caching/config/hive_cache_config.dart @@ -7,6 +7,7 @@ import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_cache.dart'; import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_rights_cache.dart'; import 'package:tmail_ui_user/features/mailbox/data/model/state_cache.dart'; import 'package:tmail_ui_user/features/mailbox/data/model/state_type.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/recent_search_cache.dart'; import 'package:tmail_ui_user/features/thread/data/model/email_address_hive_cache.dart'; import 'package:tmail_ui_user/features/thread/data/model/email_cache.dart'; @@ -35,5 +36,6 @@ class HiveCacheConfig { Hive.registerAdapter(StateTypeAdapter()); Hive.registerAdapter(EmailAddressHiveCacheAdapter()); Hive.registerAdapter(EmailCacheAdapter()); + Hive.registerAdapter(RecentSearchCacheAdapter()); } } \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/data/datasource/search_datasource.dart b/lib/features/mailbox_dashboard/data/datasource/search_datasource.dart index ec66fb0c5..3d5c95d20 100644 --- a/lib/features/mailbox_dashboard/data/datasource/search_datasource.dart +++ b/lib/features/mailbox_dashboard/data/datasource/search_datasource.dart @@ -2,4 +2,6 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_sea abstract class SearchDataSource { Future saveRecentSearch(RecentSearch recentSearch); + + Future> getAllRecentSearchLatest({int? limit, String? pattern}); } \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/data/datasource_impl/search_datasource_impl.dart b/lib/features/mailbox_dashboard/data/datasource_impl/search_datasource_impl.dart index 3dc4ff161..e1f28dbad 100644 --- a/lib/features/mailbox_dashboard/data/datasource_impl/search_datasource_impl.dart +++ b/lib/features/mailbox_dashboard/data/datasource_impl/search_datasource_impl.dart @@ -2,6 +2,7 @@ import 'package:tmail_ui_user/features/caching/recent_search_cache_client.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource/search_datasource.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/recent_search_cache.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/extensions/list_recent_search_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart'; class SearchDataSourceImpl extends SearchDataSource { @@ -26,4 +27,34 @@ class SearchDataSourceImpl extends SearchDataSource { throw error; }); } + + @override + Future> getAllRecentSearchLatest({int? limit, String? pattern}) { + return Future.sync(() async { + final listRecentSearchCache = await _recentSearchCacheClient.getAll(); + final listRecentSearch = listRecentSearchCache + .where((recentCache) => _filterRecentSearchCache(recentCache, pattern)) + .map((recentCache) => recentCache.toRecentSearch()) + .toList(); + listRecentSearch.sortByCreationDate(); + + final newLimit = limit ?? 10; + + final newListRecentSearch = listRecentSearch.length > newLimit + ? listRecentSearch.sublist(0, newLimit) + : listRecentSearch; + + return newListRecentSearch; + }).catchError((error) { + throw error; + }); + } + + bool _filterRecentSearchCache(RecentSearchCache recentSearchCache, String? pattern) { + if (pattern == null || pattern.trim().isEmpty) { + return true; + } else { + return recentSearchCache.match(pattern); + } + } } \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/data/model/recent_search_cache.dart b/lib/features/mailbox_dashboard/data/model/recent_search_cache.dart index 676dc2935..12e53b459 100644 --- a/lib/features/mailbox_dashboard/data/model/recent_search_cache.dart +++ b/lib/features/mailbox_dashboard/data/model/recent_search_cache.dart @@ -13,16 +13,26 @@ class RecentSearchCache extends HiveObject with EquatableMixin { final String value; @HiveField(1) - final DateTime creationTime; + final DateTime creationDate; - RecentSearchCache(this.value, this.creationTime); + RecentSearchCache(this.value, this.creationDate); @override - List get props => [value, creationTime]; + List get props => [value, creationDate]; } extension RecentSearchExtension on RecentSearch { RecentSearchCache toRecentSearchCache() { return RecentSearchCache(value, creationDate); } +} + +extension RecentSearchCacheExtension on RecentSearchCache { + RecentSearch toRecentSearch() { + return RecentSearch(value, creationDate); + } + + bool match(String pattern) { + return value.toLowerCase().contains(pattern.toLowerCase()); + } } \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/data/repository/search_repository_impl.dart b/lib/features/mailbox_dashboard/data/repository/search_repository_impl.dart index a30c8bec3..e21240964 100644 --- a/lib/features/mailbox_dashboard/data/repository/search_repository_impl.dart +++ b/lib/features/mailbox_dashboard/data/repository/search_repository_impl.dart @@ -13,4 +13,9 @@ class SearchRepositoryImpl extends SearchRepository { Future saveRecentSearch(RecentSearch recentSearch) { return searchDataSource.saveRecentSearch(recentSearch); } + + @override + Future> getAllRecentSearchLatest({int? limit, String? pattern}) { + return searchDataSource.getAllRecentSearchLatest(limit: limit, pattern: pattern); + } } \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/domain/extensions/list_recent_search_extension.dart b/lib/features/mailbox_dashboard/domain/extensions/list_recent_search_extension.dart new file mode 100644 index 000000000..22a3d204f --- /dev/null +++ b/lib/features/mailbox_dashboard/domain/extensions/list_recent_search_extension.dart @@ -0,0 +1,12 @@ + +import 'package:jmap_dart_client/jmap/core/extensions/date_time_extension.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart'; + +extension ListRecentSearchExtension on List { + + void sortByCreationDate() { + sort((recentSearch1, recentSearch2) { + return recentSearch1.creationDate.compareToSort(recentSearch1.creationDate, false); + }); + } +} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/domain/repository/search_repository.dart b/lib/features/mailbox_dashboard/domain/repository/search_repository.dart index 4dac4a666..1f1fec86e 100644 --- a/lib/features/mailbox_dashboard/domain/repository/search_repository.dart +++ b/lib/features/mailbox_dashboard/domain/repository/search_repository.dart @@ -3,4 +3,6 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_sea abstract class SearchRepository { Future saveRecentSearch(RecentSearch recentSearch); + + Future> getAllRecentSearchLatest({int? limit, String? pattern}); } \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/domain/state/get_all_recent_search_latest_state.dart b/lib/features/mailbox_dashboard/domain/state/get_all_recent_search_latest_state.dart new file mode 100644 index 000000000..2394bc574 --- /dev/null +++ b/lib/features/mailbox_dashboard/domain/state/get_all_recent_search_latest_state.dart @@ -0,0 +1,21 @@ +import 'package:core/core.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart'; + +class GetAllRecentSearchLatestSuccess extends UIState { + + final List listRecentSearch; + + GetAllRecentSearchLatestSuccess(this.listRecentSearch); + + @override + List get props => [listRecentSearch]; +} + +class GetAllRecentSearchLatestFailure extends FeatureFailure { + final dynamic exception; + + GetAllRecentSearchLatestFailure(this.exception); + + @override + List get props => [exception]; +} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/domain/usecases/get_all_recent_search_latest_interactor.dart b/lib/features/mailbox_dashboard/domain/usecases/get_all_recent_search_latest_interactor.dart new file mode 100644 index 000000000..a68059732 --- /dev/null +++ b/lib/features/mailbox_dashboard/domain/usecases/get_all_recent_search_latest_interactor.dart @@ -0,0 +1,22 @@ +import 'dart:core'; + +import 'package:core/core.dart'; +import 'package:dartz/dartz.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/search_repository.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_all_recent_search_latest_state.dart'; + +class GetAllRecentSearchLatestInteractor { + final SearchRepository searchRepository; + + GetAllRecentSearchLatestInteractor(this.searchRepository); + + Future> execute({int? limit, String? pattern}) async { + try { + final listRecent = await searchRepository.getAllRecentSearchLatest(limit: limit, pattern: pattern); + log('GetAllRecentSearchLatestInteractor::execute(): listRecent: ${listRecent.length}'); + return Right(GetAllRecentSearchLatestSuccess(listRecent)); + } catch (exception) { + return Left(GetAllRecentSearchLatestFailure(exception)); + } + } +} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_bindings.dart b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_bindings.dart index 95c05bb67..3b301db7e 100644 --- a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_bindings.dart +++ b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_bindings.dart @@ -19,6 +19,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource/search_ import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource_impl/search_datasource_impl.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/repository/search_repository_impl.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/search_repository.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_all_recent_search_latest_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_user_profile_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_email_drafts_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_recent_search_interactor.dart'; @@ -41,6 +42,7 @@ class MailboxDashBoardBindings extends BaseBindings { Get.find(), Get.find(), Get.find(), + Get.find(), )); } @@ -68,6 +70,7 @@ class MailboxDashBoardBindings extends BaseBindings { Get.lazyPut(() => MoveToMailboxInteractor(Get.find())); Get.lazyPut(() => DeleteEmailPermanentlyInteractor(Get.find())); Get.lazyPut(() => SaveRecentSearchInteractor(Get.find())); + Get.lazyPut(() => GetAllRecentSearchLatestInteractor(Get.find())); } @override diff --git a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart index cde20c69e..cc09e47e2 100644 --- a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart @@ -31,8 +31,10 @@ import 'package:tmail_ui_user/features/email/domain/usecases/delete_email_perman import 'package:tmail_ui_user/features/email/domain/usecases/move_to_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_all_recent_search_latest_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_user_profile_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/remove_email_drafts_state.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_all_recent_search_latest_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_user_profile_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_email_drafts_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_recent_search_interactor.dart'; @@ -61,6 +63,7 @@ class MailboxDashBoardController extends ReloadableController { final MoveToMailboxInteractor _moveToMailboxInteractor; final DeleteEmailPermanentlyInteractor _deleteEmailPermanentlyInteractor; final SaveRecentSearchInteractor _saveRecentSearchInteractor; + final GetAllRecentSearchLatestInteractor _getAllRecentSearchLatestInteractor; final scaffoldKey = GlobalKey(); final selectedMailbox = Rxn(); @@ -90,6 +93,7 @@ class MailboxDashBoardController extends ReloadableController { this._moveToMailboxInteractor, this._deleteEmailPermanentlyInteractor, this._saveRecentSearchInteractor, + this._getAllRecentSearchLatestInteractor, ); @override @@ -402,6 +406,15 @@ class MailboxDashBoardController extends ReloadableController { consumeState(_saveRecentSearchInteractor.execute(recentSearch)); } + Future> getAllRecentSearchAction(String pattern) async { + return await _getAllRecentSearchLatestInteractor.execute(pattern: pattern) + .then((result) => result.fold( + (failure) => [], + (success) => success is GetAllRecentSearchLatestSuccess + ? success.listRecentSearch + : [])); + } + void composeEmailAction() { if (kIsWeb) { if (dashBoardAction.value is! ComposeEmailAction) { diff --git a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart index b38bd7b4b..2c9866eb6 100644 --- a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart +++ b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart @@ -510,7 +510,7 @@ class MailboxDashBoardView extends GetWidget with Ne color: AppColor.colorTextButtonHeaderThread, fontWeight: FontWeight.w500))), getRecentCallback: (pattern) async { - return []; + return controller.getAllRecentSearchAction(pattern); }, itemRecentBuilder: (context, recent) { return RecentSearchItemTileWidget(recent); diff --git a/lib/main.dart b/lib/main.dart index d4119ec9c..ddb127130 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -16,23 +16,25 @@ void main() async { await MainBindings().dependencies(); await HiveCacheConfig().setUp(); await dotenv.load(fileName: 'env.file'); - runApp(TMailApp()); + runApp(const TMailApp()); }); } class TMailApp extends StatelessWidget { + const TMailApp({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return GetMaterialApp( debugShowCheckedModeBanner: false, theme: appTheme(), - supportedLocales: [ + supportedLocales: const [ Locale('en'), Locale('vi'), Locale('ru'), Locale('fr') ], - localizationsDelegates: [ + localizationsDelegates: const [ AppLocalizationsDelegate(), GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, @@ -46,7 +48,7 @@ class TMailApp extends StatelessWidget { } return supportedLocales.first; }, - locale: Get.locale ?? Locale('en'), + locale: Get.locale ?? const Locale('en'), onGenerateTitle: (context) => AppLocalizations.of(context).page_name, defaultTransition: Transition.fade, initialRoute: AppRoutes.HOME,