From c46329774bf30c632d5e022db7f29ab094fca084 Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 8 Sep 2021 15:15:42 +0700 Subject: [PATCH] TF-48 Implement save email address to local storage --- .../data/datasource/composer_datasource.dart | 5 ++ .../composer_datasource_impl.dart | 12 +++ .../local_composer_datasource_impl.dart | 19 +++++ .../local/email_address_database_manager.dart | 81 +++++++++++++++++++ .../repository/composer_repository_impl.dart | 17 ++++ .../repository/composer_repository.dart | 5 ++ .../state/save_email_address_state.dart | 18 +++++ .../save_email_addresses_interactor.dart | 20 +++++ 8 files changed, 177 insertions(+) create mode 100644 lib/features/composer/data/datasource/composer_datasource.dart create mode 100644 lib/features/composer/data/datasource_impl/composer_datasource_impl.dart create mode 100644 lib/features/composer/data/datasource_impl/local_composer_datasource_impl.dart create mode 100644 lib/features/composer/data/local/email_address_database_manager.dart create mode 100644 lib/features/composer/data/repository/composer_repository_impl.dart create mode 100644 lib/features/composer/domain/repository/composer_repository.dart create mode 100644 lib/features/composer/domain/state/save_email_address_state.dart create mode 100644 lib/features/composer/domain/usecases/save_email_addresses_interactor.dart diff --git a/lib/features/composer/data/datasource/composer_datasource.dart b/lib/features/composer/data/datasource/composer_datasource.dart new file mode 100644 index 000000000..5f47a46da --- /dev/null +++ b/lib/features/composer/data/datasource/composer_datasource.dart @@ -0,0 +1,5 @@ +import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; + +abstract class ComposerDataSource { + Future saveEmailAddresses(List listEmailAddress); +} \ No newline at end of file diff --git a/lib/features/composer/data/datasource_impl/composer_datasource_impl.dart b/lib/features/composer/data/datasource_impl/composer_datasource_impl.dart new file mode 100644 index 000000000..a47de7517 --- /dev/null +++ b/lib/features/composer/data/datasource_impl/composer_datasource_impl.dart @@ -0,0 +1,12 @@ +import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; +import 'package:tmail_ui_user/features/composer/data/datasource/composer_datasource.dart'; + +class ComposerDataSourceImpl extends ComposerDataSource { + + ComposerDataSourceImpl(); + + @override + Future saveEmailAddresses(List listEmailAddress) { + throw UnimplementedError(); + } +} \ No newline at end of file diff --git a/lib/features/composer/data/datasource_impl/local_composer_datasource_impl.dart b/lib/features/composer/data/datasource_impl/local_composer_datasource_impl.dart new file mode 100644 index 000000000..ac5ca8330 --- /dev/null +++ b/lib/features/composer/data/datasource_impl/local_composer_datasource_impl.dart @@ -0,0 +1,19 @@ +import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; +import 'package:tmail_ui_user/features/composer/data/datasource/composer_datasource.dart'; +import 'package:tmail_ui_user/features/composer/data/local/email_address_database_manager.dart'; + +class LocalComposerDataSourceImpl extends ComposerDataSource { + + final EmailAddressDatabaseManager emailAddressDatabaseManager; + + LocalComposerDataSourceImpl(this.emailAddressDatabaseManager); + + @override + Future saveEmailAddresses(List listEmailAddress) { + return Future.sync(() async { + return await emailAddressDatabaseManager.insertMultipleData(listEmailAddress); + }).catchError((error) { + throw error; + }); + } +} \ No newline at end of file diff --git a/lib/features/composer/data/local/email_address_database_manager.dart b/lib/features/composer/data/local/email_address_database_manager.dart new file mode 100644 index 000000000..d8dd22484 --- /dev/null +++ b/lib/features/composer/data/local/email_address_database_manager.dart @@ -0,0 +1,81 @@ + +import 'package:core/core.dart'; +import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; +import 'package:model/model.dart'; + +class EmailAddressDatabaseManager implements DatabaseManager { + final DatabaseClient _databaseClient; + + EmailAddressDatabaseManager(this._databaseClient); + + @override + Future deleteData(String key) async { + final res = await _databaseClient.deleteData(EmailAddressTable.TABLE_NAME, EmailAddressTable.EMAIL, key); + return res > 0 ? true : false; + } + + @override + Future getData(String key) async { + final res = await _databaseClient.getData(EmailAddressTable.TABLE_NAME, EmailAddressTable.EMAIL, key); + return res.isNotEmpty ? EmailAddressCache.fromJson(res.first).toEmailAddress() : null; + } + + @override + Future> getListData({String? word, int? limit, String? orderBy}) async { + final res = await _databaseClient.getListData(EmailAddressTable.TABLE_NAME, limit: limit ?? 10, orderBy: orderBy ?? EmailAddressTable.NAME); + return res.isNotEmpty + ? res.map((mapObject) => EmailAddressCache.fromJson(mapObject).toEmailAddress()).toList() + : []; + } + + @override + Future insertData(EmailAddress emailAddress) async { + final res = await _databaseClient.insertData(EmailAddressTable.TABLE_NAME, emailAddress.toEmailAddressCache().toJson()); + return res > 0 ? true : false; + } + + @override + Future updateData(EmailAddress emailAddress) async { + final res = await _databaseClient.updateData( + EmailAddressTable.TABLE_NAME, + EmailAddressTable.EMAIL, + emailAddress.getEmail(), + emailAddress.toEmailAddressCache().toJson()); + return res > 0 ? true : false; + } + + @override + Future insertMultipleData(List listObject) async { + final listEmailAddressNotExist = await Future.wait(listObject + .map((emailAddress) async { + final emailAddressExist = await _databaseClient.getData( + EmailAddressTable.TABLE_NAME, + EmailAddressTable.EMAIL, + emailAddress.email ?? ''); + return emailAddressExist.isEmpty ? emailAddress : null;}) + .toList()); + + listEmailAddressNotExist.removeWhere((element) => element == null); + + final mapObjects = listEmailAddressNotExist + .map((emailAddress) => emailAddress!.toEmailAddressCache().toJson()) + .toList(); + + final res = await _databaseClient.insertMultipleData(EmailAddressTable.TABLE_NAME, mapObjects); + return res.isNotEmpty ? true : false; + } + + @override + Future> getListDataWithCondition(String condition, {String? word, int? limit, String? orderBy}) async { + final sqlQuery = 'SELECT * FROM ${EmailAddressTable.TABLE_NAME} ' + 'WHERE $condition ' + 'ORDER BY ${orderBy ?? EmailAddressTable.NAME} ' + 'LIMIT ${limit ?? 10}'; + + final res = await _databaseClient.getDataBySql(sqlQuery); + + return res.isNotEmpty + ? res.map((mapObject) => EmailAddressCache.fromJson(mapObject).toEmailAddress()).toList() + : []; + } +} \ No newline at end of file diff --git a/lib/features/composer/data/repository/composer_repository_impl.dart b/lib/features/composer/data/repository/composer_repository_impl.dart new file mode 100644 index 000000000..963a8c011 --- /dev/null +++ b/lib/features/composer/data/repository/composer_repository_impl.dart @@ -0,0 +1,17 @@ + +import 'package:core/core.dart'; +import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; +import 'package:tmail_ui_user/features/composer/data/datasource/composer_datasource.dart'; +import 'package:tmail_ui_user/features/composer/domain/repository/composer_repository.dart'; + +class ComposerRepositoryImpl extends ComposerRepository { + + final Map composerDataSources; + + ComposerRepositoryImpl(this.composerDataSources); + + @override + Future saveEmailAddresses(List listEmailAddress) { + return composerDataSources[DataSourceType.local]!.saveEmailAddresses(listEmailAddress); + } +} \ No newline at end of file diff --git a/lib/features/composer/domain/repository/composer_repository.dart b/lib/features/composer/domain/repository/composer_repository.dart new file mode 100644 index 000000000..8313a1334 --- /dev/null +++ b/lib/features/composer/domain/repository/composer_repository.dart @@ -0,0 +1,5 @@ +import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; + +abstract class ComposerRepository { + Future saveEmailAddresses(List listEmailAddress); +} \ No newline at end of file diff --git a/lib/features/composer/domain/state/save_email_address_state.dart b/lib/features/composer/domain/state/save_email_address_state.dart new file mode 100644 index 000000000..242dbb4b7 --- /dev/null +++ b/lib/features/composer/domain/state/save_email_address_state.dart @@ -0,0 +1,18 @@ +import 'package:core/core.dart'; + +class SaveEmailAddressSuccess extends UIState { + + SaveEmailAddressSuccess(); + + @override + List get props => []; +} + +class SaveEmailAddressFailure extends FeatureFailure { + final exception; + + SaveEmailAddressFailure(this.exception); + + @override + List get props => [exception]; +} \ No newline at end of file diff --git a/lib/features/composer/domain/usecases/save_email_addresses_interactor.dart b/lib/features/composer/domain/usecases/save_email_addresses_interactor.dart new file mode 100644 index 000000000..7afd2a225 --- /dev/null +++ b/lib/features/composer/domain/usecases/save_email_addresses_interactor.dart @@ -0,0 +1,20 @@ +import 'package:core/core.dart'; +import 'package:dartz/dartz.dart'; +import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; +import 'package:tmail_ui_user/features/composer/domain/repository/composer_repository.dart'; +import 'package:tmail_ui_user/features/composer/domain/state/save_email_address_state.dart'; + +class SaveEmailAddressesInteractor { + final ComposerRepository composerRepository; + + SaveEmailAddressesInteractor(this.composerRepository); + + Future> execute(List emailAddress) async { + try { + final result = await composerRepository.saveEmailAddresses(emailAddress); + return result ? Right(SaveEmailAddressSuccess()) : Left(SaveEmailAddressFailure(result)); + } catch (e) { + return Left(SaveEmailAddressFailure(e)); + } + } +} \ No newline at end of file