TF-3082 Restore identity from cache
This commit is contained in:
@@ -7,4 +7,10 @@ abstract class IdentityCreatorDataSource {
|
||||
AccountId accountId,
|
||||
UserName userName,
|
||||
{required IdentityCache identityCache});
|
||||
|
||||
Future<IdentityCache> getIdentityCacheOnWeb(
|
||||
AccountId accountId,
|
||||
UserName userName);
|
||||
|
||||
Future<void> removeIdentityCacheOnWeb();
|
||||
}
|
||||
+27
@@ -1,5 +1,7 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:core/domain/exceptions/web_session_exception.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';
|
||||
@@ -31,6 +33,31 @@ class LocalIdentityCreatorDataSourceImpl implements IdentityCreatorDataSource {
|
||||
window.sessionStorage.addAll(entries);
|
||||
}).catchError(_exceptionThrower.throwException);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<IdentityCache> getIdentityCacheOnWeb(
|
||||
AccountId accountId,
|
||||
UserName userName
|
||||
) async {
|
||||
return Future.sync(() {
|
||||
final cacheKey = _generateTupleKey(accountId, userName);
|
||||
final result = window.sessionStorage.entries.firstWhereOrNull(
|
||||
(entry) => entry.key == cacheKey);
|
||||
if (result != null) {
|
||||
return IdentityCacheModel.fromJson(jsonDecode(result.value));
|
||||
} else {
|
||||
throw NotFoundInWebSessionException();
|
||||
}
|
||||
}).catchError(_exceptionThrower.throwException);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> removeIdentityCacheOnWeb() async {
|
||||
return Future.sync(() {
|
||||
window.sessionStorage.removeWhere(
|
||||
(key, value) => key.startsWith(LocalIdentityCreatorDataSourceImpl.sessionStorageKeyword));
|
||||
}).catchError(_exceptionThrower.throwException);
|
||||
}
|
||||
|
||||
String _generateTupleKey(AccountId accountId, UserName userName) {
|
||||
return TupleKey(
|
||||
|
||||
@@ -18,4 +18,16 @@ class IdentityCreatorRepositoryImpl implements IdentityCreatorRepository {
|
||||
accountId,
|
||||
userName,
|
||||
identityCache: identityCache);
|
||||
|
||||
@override
|
||||
Future<IdentityCache> getIdentityCacheOnWeb(
|
||||
AccountId accountId,
|
||||
UserName userName
|
||||
) => _identityCreatorDataSource.getIdentityCacheOnWeb(
|
||||
accountId,
|
||||
userName);
|
||||
|
||||
@override
|
||||
Future<void> removeIdentityCacheOnWeb()
|
||||
=> _identityCreatorDataSource.removeIdentityCacheOnWeb();
|
||||
}
|
||||
@@ -7,4 +7,10 @@ abstract class IdentityCreatorRepository {
|
||||
AccountId accountId,
|
||||
UserName userName,
|
||||
{required IdentityCache identityCache});
|
||||
|
||||
Future<IdentityCache> getIdentityCacheOnWeb(
|
||||
AccountId accountId,
|
||||
UserName userName);
|
||||
|
||||
Future<void> removeIdentityCacheOnWeb();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
import 'package:tmail_ui_user/features/identity_creator/domain/model/identity_cache.dart';
|
||||
|
||||
class GettingIdentityCacheOnWeb extends LoadingState {}
|
||||
|
||||
class GetIdentityCacheOnWebSuccess extends UIState {
|
||||
GetIdentityCacheOnWebSuccess(this.identityCache);
|
||||
|
||||
final IdentityCache? identityCache;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [identityCache];
|
||||
}
|
||||
|
||||
class GetIdentityCacheOnWebFailure extends FeatureFailure {
|
||||
GetIdentityCacheOnWebFailure({super.exception});
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
|
||||
class RemovingIdentityCacheOnWeb extends LoadingState {}
|
||||
|
||||
class RemoveIdentityCacheOnWebSuccess extends UIState {}
|
||||
|
||||
class RemoveIdentityCacheOnWebFailure extends FeatureFailure {
|
||||
RemoveIdentityCacheOnWebFailure({super.exception});
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
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/identity_creator/domain/repository/identity_creator_repository.dart';
|
||||
import 'package:tmail_ui_user/features/identity_creator/domain/state/get_identity_cache_on_web_state.dart';
|
||||
|
||||
class GetIdentityCacheOnWebInteractor {
|
||||
GetIdentityCacheOnWebInteractor(this._identityCreatorRepository);
|
||||
|
||||
final IdentityCreatorRepository _identityCreatorRepository;
|
||||
|
||||
Stream<Either<Failure, Success>> execute(
|
||||
AccountId accountId,
|
||||
UserName userName
|
||||
) async* {
|
||||
try {
|
||||
yield Right(GettingIdentityCacheOnWeb());
|
||||
final result = await _identityCreatorRepository.getIdentityCacheOnWeb(
|
||||
accountId,
|
||||
userName);
|
||||
|
||||
yield Right(GetIdentityCacheOnWebSuccess(result));
|
||||
} catch (exception) {
|
||||
logError("$runtimeType::execute: $exception");
|
||||
yield Left(GetIdentityCacheOnWebFailure(exception: exception));
|
||||
}
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:tmail_ui_user/features/identity_creator/domain/repository/identity_creator_repository.dart';
|
||||
import 'package:tmail_ui_user/features/identity_creator/domain/state/remove_identity_cache_on_web_state.dart';
|
||||
|
||||
class RemoveIdentityCacheOnWebInteractor {
|
||||
RemoveIdentityCacheOnWebInteractor(this._identityCreatorRepository);
|
||||
|
||||
final IdentityCreatorRepository _identityCreatorRepository;
|
||||
|
||||
Stream<Either<Failure, Success>> execute() async* {
|
||||
try {
|
||||
yield Right(RemovingIdentityCacheOnWeb());
|
||||
await _identityCreatorRepository.removeIdentityCacheOnWeb();
|
||||
|
||||
yield Right(RemoveIdentityCacheOnWebSuccess());
|
||||
} catch (exception) {
|
||||
logError("$runtimeType::execute: $exception");
|
||||
yield Left(RemoveIdentityCacheOnWebFailure(exception: exception));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -352,43 +352,31 @@ class IdentityCreatorController extends BaseController with DragDropFileMixin im
|
||||
listEmailAddressOfReplyTo.value = listEmailAddressOfReplyTo.toSet().toList();
|
||||
listEmailAddressDefault.value = listEmailAddressDefault.toSet().toList();
|
||||
|
||||
if (actionType.value == IdentityActionType.edit && identity != null) {
|
||||
if (identity?.replyTo?.isNotEmpty == true) {
|
||||
try {
|
||||
replyToOfIdentity.value = listEmailAddressOfReplyTo
|
||||
.firstWhere((emailAddress) => emailAddress == identity?.replyTo!.first);
|
||||
} catch(e) {
|
||||
replyToOfIdentity.value = noneEmailAddress;
|
||||
}
|
||||
} else {
|
||||
if (identity?.replyTo?.isNotEmpty == true) {
|
||||
replyToOfIdentity.value = listEmailAddressOfReplyTo
|
||||
.firstWhereOrNull((emailAddress) => emailAddress == identity!.replyTo!.first);
|
||||
|
||||
if (replyToOfIdentity.value == null && identity!.replyTo!.first == noneEmailAddress) {
|
||||
replyToOfIdentity.value = noneEmailAddress;
|
||||
}
|
||||
|
||||
if (identity?.bcc?.isNotEmpty == true) {
|
||||
bccOfIdentity.value = identity?.bcc!.first;
|
||||
inputBccIdentityController.text = identity?.bcc!.first.emailAddress ?? '';
|
||||
} else {
|
||||
bccOfIdentity.value = null;
|
||||
}
|
||||
|
||||
if (identity?.email?.isNotEmpty == true) {
|
||||
try {
|
||||
emailOfIdentity.value = listEmailAddressDefault
|
||||
.firstWhere((emailAddress) => emailAddress.email == identity?.email);
|
||||
} catch(e) {
|
||||
emailOfIdentity.value = null;
|
||||
}
|
||||
} else {
|
||||
emailOfIdentity.value = listEmailAddressDefault.isNotEmpty
|
||||
? listEmailAddressDefault.first
|
||||
: null;
|
||||
}
|
||||
} else if (actionType.value == IdentityActionType.edit) {
|
||||
replyToOfIdentity.value = noneEmailAddress;
|
||||
} else {
|
||||
replyToOfIdentity.value = null;
|
||||
}
|
||||
|
||||
if (identity?.bcc?.isNotEmpty == true) {
|
||||
bccOfIdentity.value = identity!.bcc!.first;
|
||||
inputBccIdentityController.text = identity!.bcc!.first.emailAddress;
|
||||
} else {
|
||||
bccOfIdentity.value = null;
|
||||
emailOfIdentity.value = listEmailAddressDefault.isNotEmpty
|
||||
? listEmailAddressDefault.first
|
||||
: null;
|
||||
}
|
||||
|
||||
if (identity?.email?.isNotEmpty == true) {
|
||||
emailOfIdentity.value = listEmailAddressDefault
|
||||
.firstWhereOrNull((emailAddress) => emailAddress.email == identity!.email);
|
||||
} else {
|
||||
emailOfIdentity.value = listEmailAddressDefault.firstOrNull;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -486,16 +474,19 @@ class IdentityCreatorController extends BaseController with DragDropFileMixin im
|
||||
Future<({
|
||||
Identity identity,
|
||||
PublicAssetsInIdentityArguments publicAssetsInIdentityArguments
|
||||
})> _generateIdentityAndPublicAssetArguments() async {
|
||||
})> _generateIdentityAndPublicAssetArguments({bool forCache = false}) async {
|
||||
final signatureHtmlText = PlatformInfo.isWeb
|
||||
? contentHtmlEditor
|
||||
: await _getSignatureHtmlText();
|
||||
final bccAddress = bccOfIdentity.value != null && bccOfIdentity.value != noneEmailAddress
|
||||
? {bccOfIdentity.value!}
|
||||
: <EmailAddress>{};
|
||||
final replyToAddress = replyToOfIdentity.value != null && replyToOfIdentity.value != noneEmailAddress
|
||||
? {replyToOfIdentity.value!}
|
||||
: <EmailAddress>{};
|
||||
Set<EmailAddress> replyToAddress;
|
||||
if (replyToOfIdentity.value != null && (replyToOfIdentity.value != noneEmailAddress || forCache)) {
|
||||
replyToAddress = {replyToOfIdentity.value!};
|
||||
} else {
|
||||
replyToAddress = {};
|
||||
}
|
||||
|
||||
final sortOrder = isDefaultIdentitySupported.isTrue
|
||||
? UnsignedInt(isDefaultIdentity.value ? 0 : 100)
|
||||
@@ -924,7 +915,8 @@ class IdentityCreatorController extends BaseController with DragDropFileMixin im
|
||||
|
||||
Future<void> _saveIdentityCacheOnWebAction() async {
|
||||
if (accountId != null && session?.username != null) {
|
||||
final cacheArguments = await _generateIdentityAndPublicAssetArguments();
|
||||
final cacheArguments = await _generateIdentityAndPublicAssetArguments(
|
||||
forCache: true);
|
||||
final identityCache = IdentityCache(
|
||||
identity: cacheArguments.identity,
|
||||
identityActionType: actionType.value,
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/base/interactors_bindings.dart';
|
||||
import 'package:tmail_ui_user/features/identity_creator/data/datasource/identity_creator_data_source.dart';
|
||||
import 'package:tmail_ui_user/features/identity_creator/data/datasource_impl/local_identity_creator_data_source_impl.dart';
|
||||
import 'package:tmail_ui_user/features/identity_creator/data/repository/identity_creator_repository_impl.dart';
|
||||
import 'package:tmail_ui_user/features/identity_creator/domain/repository/identity_creator_repository.dart';
|
||||
import 'package:tmail_ui_user/features/identity_creator/domain/usecase/get_identity_cache_on_web_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/identity_creator/domain/usecase/remove_identity_cache_on_web_interactor.dart';
|
||||
import 'package:tmail_ui_user/main/bindings/network/binding_tag.dart';
|
||||
import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart';
|
||||
|
||||
class RestoreIdentityCacheInteractorBindings extends InteractorsBindings {
|
||||
static const _tag = BindingTag.restoreIdentityCacheInteractorBindingsTag;
|
||||
|
||||
@override
|
||||
void bindingsDataSource() {
|
||||
Get.lazyPut<IdentityCreatorDataSource>(
|
||||
() => Get.find<LocalIdentityCreatorDataSourceImpl>(tag: _tag),
|
||||
tag: _tag);
|
||||
}
|
||||
|
||||
@override
|
||||
void bindingsDataSourceImpl() {
|
||||
Get.lazyPut(
|
||||
() => LocalIdentityCreatorDataSourceImpl(
|
||||
Get.find<CacheExceptionThrower>()),
|
||||
tag: _tag);
|
||||
}
|
||||
|
||||
@override
|
||||
void bindingsInteractor() {
|
||||
Get.lazyPut(
|
||||
() => GetIdentityCacheOnWebInteractor(
|
||||
Get.find<IdentityCreatorRepository>(tag: _tag)),
|
||||
tag: _tag);
|
||||
Get.lazyPut(
|
||||
() => RemoveIdentityCacheOnWebInteractor(
|
||||
Get.find<IdentityCreatorRepository>(tag: _tag)),
|
||||
tag: _tag);
|
||||
}
|
||||
|
||||
@override
|
||||
void bindingsRepository() {
|
||||
Get.lazyPut<IdentityCreatorRepository>(
|
||||
() => Get.find<IdentityCreatorRepositoryImpl>(tag: _tag),
|
||||
tag: _tag);
|
||||
}
|
||||
|
||||
@override
|
||||
void bindingsRepositoryImpl() {
|
||||
Get.lazyPut(
|
||||
() => IdentityCreatorRepositoryImpl(
|
||||
Get.find<IdentityCreatorDataSource>(tag: _tag)),
|
||||
tag: _tag);
|
||||
}
|
||||
|
||||
void close() {
|
||||
Get.delete<GetIdentityCacheOnWebInteractor>(tag: _tag);
|
||||
Get.delete<RemoveIdentityCacheOnWebInteractor>(tag: _tag);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user