diff --git a/lib/features/caching/account_cache_client.dart b/lib/features/caching/account_cache_client.dart new file mode 100644 index 000000000..2630dae8e --- /dev/null +++ b/lib/features/caching/account_cache_client.dart @@ -0,0 +1,133 @@ +import 'package:core/utils/app_logger.dart'; +import 'package:hive/hive.dart'; +import 'package:tmail_ui_user/features/caching/config/hive_cache_client.dart'; +import 'package:tmail_ui_user/features/login/data/model/account_cache.dart'; + +class AccountCacheClient extends HiveCacheClient { + + @override + String get tableName => "AccountCache"; + + @override + Future clearAllData() { + return Future.sync(() async { + final boxToken = await openBox(); + boxToken.clear(); + }).catchError((error) { + throw error; + }); + } + + @override + Future deleteItem(String key) { + return Future.sync(() async { + final boxToken = await openBox(); + return boxToken.delete(key); + }).catchError((error) { + throw error; + }); + } + + @override + Future deleteMultipleItem(List listKey) { + return Future.sync(() async { + final boxToken = await openBox(); + return boxToken.deleteAll(listKey); + }).catchError((error) { + throw error; + }); + } + + @override + Future> getAll() { + return Future.sync(() async { + final boxToken = await openBox(); + return boxToken.values.toList(); + }).catchError((error) { + throw error; + }); + } + + @override + Future getItem(String key) { + return Future.sync(() async { + final boxToken = await openBox(); + return boxToken.get(key); + }).catchError((error) { + throw error; + }); + } + + @override + Future insertItem(String key, AccountCache newObject) { + log('AccountCacheClient::insertItem(): $key: $newObject'); + return Future.sync(() async { + final boxToken = await openBox(); + boxToken.put(key, newObject); + }).catchError((error) { + throw error; + }); + } + + @override + Future insertMultipleItem(Map mapObject) { + return Future.sync(() async { + final boxToken = await openBox(); + boxToken.putAll(mapObject); + }).catchError((error) { + throw error; + }); + } + + @override + Future isExistItem(String key) { + return Future.sync(() async { + final boxToken = await openBox(); + return boxToken.containsKey(key); + }).catchError((error) { + throw error; + }); + } + + @override + Future isExistTable() { + return Future.sync(() async { + return await Hive.boxExists(tableName); + }).catchError((error) { + throw error; + }); + } + + @override + Future> openBox() { + return Future.sync(() async { + if (Hive.isBoxOpen(tableName)) { + return Hive.box(tableName); + } + return await Hive.openBox(tableName); + }).catchError((error) { + throw error; + }); + } + + @override + Future updateItem(String key, AccountCache newObject) { + return Future.sync(() async { + final boxToken = await openBox(); + boxToken.put(key, newObject); + }).catchError((error) { + throw error; + }); + } + + @override + Future updateMultipleItem(Map mapObject) { + return Future.sync(() async { + final boxToken = await openBox(); + boxToken.putAll(mapObject); + }).catchError((error) { + throw error; + }); + } + +} \ No newline at end of file diff --git a/lib/features/login/data/datasource_impl/hive_account_datasource_impl.dart b/lib/features/login/data/datasource_impl/hive_account_datasource_impl.dart new file mode 100644 index 000000000..c1f1bd7f5 --- /dev/null +++ b/lib/features/login/data/datasource_impl/hive_account_datasource_impl.dart @@ -0,0 +1,22 @@ +import 'package:core/utils/app_logger.dart'; +import 'package:model/account/account.dart'; +import 'package:tmail_ui_user/features/login/data/datasource/account_datasource.dart'; +import 'package:tmail_ui_user/features/login/data/local/account_cache_manager.dart'; + +class HiveAccountDatasourceImpl extends AccountDatasource { + final AccountCacheManager _accountCacheManager; + + HiveAccountDatasourceImpl(this._accountCacheManager); + + @override + Future getCurrentAccount() { + return _accountCacheManager.getSelectedAccount(); + } + + @override + Future setCurrentAccount(Account newCurrentAccount) { + log('HiveAccountDatasourceImpl::setCurrentAccount(): $newCurrentAccount'); + log('HiveAccountDatasourceImpl::setCurrentAccount(): $_accountCacheManager'); + return _accountCacheManager.setSelectedAccount(newCurrentAccount); + } +} \ No newline at end of file diff --git a/lib/features/login/data/extensions/account_cache_extensions.dart b/lib/features/login/data/extensions/account_cache_extensions.dart new file mode 100644 index 000000000..215d4ee44 --- /dev/null +++ b/lib/features/login/data/extensions/account_cache_extensions.dart @@ -0,0 +1,20 @@ +import 'package:model/account/account.dart'; +import 'package:model/account/authentication_type.dart'; +import 'package:tmail_ui_user/features/login/data/model/account_cache.dart'; + +extension AccountCacheExtension on AccountCache { + AuthenticationType fromAuthenticationTypeString() { + if (authenticationType == 'basic') { + return AuthenticationType.basic; + } else if (authenticationType == 'oidc') { + return AuthenticationType.oidc; + } else { + return AuthenticationType.none; + } + } + + Account toAccount() { + final authenticationType = fromAuthenticationTypeString(); + return Account(id, authenticationType, isSelected: isSelected); + } +} \ No newline at end of file diff --git a/lib/features/login/data/extensions/account_extensions.dart b/lib/features/login/data/extensions/account_extensions.dart new file mode 100644 index 000000000..5ba311f7a --- /dev/null +++ b/lib/features/login/data/extensions/account_extensions.dart @@ -0,0 +1,9 @@ +import 'package:model/account/account.dart'; +import 'package:model/account/authentication_type.dart'; +import 'package:tmail_ui_user/features/login/data/model/account_cache.dart'; + +extension AccountExtensions on Account { + AccountCache toCache() { + return AccountCache(id, authenticationType.asString(), isSelected: isSelected); + } +} \ No newline at end of file diff --git a/lib/features/login/data/local/account_cache_manager.dart b/lib/features/login/data/local/account_cache_manager.dart new file mode 100644 index 000000000..d0cf5086f --- /dev/null +++ b/lib/features/login/data/local/account_cache_manager.dart @@ -0,0 +1,28 @@ +import 'package:core/utils/app_logger.dart'; +import 'package:model/account/account.dart'; +import 'package:tmail_ui_user/features/caching/account_cache_client.dart'; +import 'package:tmail_ui_user/features/login/data/extensions/account_cache_extensions.dart'; +import 'package:tmail_ui_user/features/login/data/extensions/account_extensions.dart'; +import 'package:tmail_ui_user/features/login/domain/exceptions/authentication_exception.dart'; + +class AccountCacheManager { + final AccountCacheClient _accountCacheClient; + + AccountCacheManager(this._accountCacheClient); + + Future getSelectedAccount() async { + try { + final allAccounts = await _accountCacheClient.getAll(); + return allAccounts.firstWhere((account) => account.isSelected) + .toAccount(); + } catch (e) { + logError('AccountCacheManager::getSelectedAccount(): $e'); + throw NotFoundAuthenticatedAccountException(); + } + } + + Future setSelectedAccount(Account account) { + log('AccountCacheManager::setSelectedAccount(): $_accountCacheClient'); + return _accountCacheClient.insertItem(account.id, account.toCache()); + } +} \ No newline at end of file diff --git a/lib/features/login/data/model/account_cache.dart b/lib/features/login/data/model/account_cache.dart new file mode 100644 index 000000000..a5823a4bd --- /dev/null +++ b/lib/features/login/data/model/account_cache.dart @@ -0,0 +1,22 @@ +import 'package:equatable/equatable.dart'; +import 'package:hive/hive.dart'; +import 'package:tmail_ui_user/features/caching/utils/caching_constants.dart'; + +part 'account_cache.g.dart'; + +@HiveType(typeId: CachingConstants.ACCOUNT_HIVE_CACHE_IDENTIFY) +class AccountCache extends HiveObject with EquatableMixin { + @HiveField(0) + final String id; + + @HiveField(1) + final String authenticationType; + + @HiveField(2) + final bool isSelected; + + AccountCache(this.id, this.authenticationType, {required this.isSelected}); + + @override + List get props => [id, authenticationType, isSelected]; +} \ No newline at end of file diff --git a/lib/features/login/data/repository/account_repository_impl.dart b/lib/features/login/data/repository/account_repository_impl.dart new file mode 100644 index 000000000..62070b52c --- /dev/null +++ b/lib/features/login/data/repository/account_repository_impl.dart @@ -0,0 +1,22 @@ +import 'package:core/utils/app_logger.dart'; +import 'package:model/account/account.dart'; +import 'package:tmail_ui_user/features/login/data/datasource/account_datasource.dart'; +import 'package:tmail_ui_user/features/login/domain/repository/account_repository.dart'; + +class AccountRepositoryImpl extends AccountRepository { + + final AccountDatasource _accountDatasource; + + AccountRepositoryImpl(this._accountDatasource); + + @override + Future getCurrentAccount() { + return _accountDatasource.getCurrentAccount(); + } + + @override + Future setCurrentAccount(Account newCurrentAccount) { + log('AccountRepositoryImpl::setCurrentAccount(): $newCurrentAccount'); + return _accountDatasource.setCurrentAccount(newCurrentAccount); + } +} \ No newline at end of file