diff --git a/lib/features/identity_creator/presentation/identity_creator_controller.dart b/lib/features/identity_creator/presentation/identity_creator_controller.dart index 3db2f56fe..b24dea4a4 100644 --- a/lib/features/identity_creator/presentation/identity_creator_controller.dart +++ b/lib/features/identity_creator/presentation/identity_creator_controller.dart @@ -47,6 +47,7 @@ import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_id import 'package:tmail_ui_user/features/manage_account/presentation/extensions/identity_extension.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/identity_action_type.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/utils/identity_utils.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/model/public_assets_in_identity_arguments.dart'; import 'package:tmail_ui_user/features/public_asset/presentation/model/public_asset_arguments.dart'; import 'package:tmail_ui_user/features/public_asset/presentation/public_asset_bindings.dart'; import 'package:tmail_ui_user/features/public_asset/presentation/public_asset_controller.dart'; @@ -377,6 +378,12 @@ class IdentityCreatorController extends BaseController { final sortOrder = isDefaultIdentitySupported.isTrue ? UnsignedInt(isDefaultIdentity.value ? 0 : 100) : null; + + final publicAssetsInIdentityArguments = PublicAssetsInIdentityArguments( + htmlSignature: signatureHtmlText ?? '', + preExistingPublicAssetIds: List.from(publicAssetController?.preExistingPublicAssetIds ?? []), + newlyPickedPublicAssetIds: List.from(publicAssetController?.newlyPickedPublicAssetIds ?? []), + ); final newIdentity = Identity( name: _nameIdentity, @@ -392,12 +399,14 @@ class IdentityCreatorController extends BaseController { final identityRequest = CreateNewIdentityRequest( generateCreateId, newIdentity, + publicAssetsInIdentityArguments: publicAssetsInIdentityArguments, isDefaultIdentity: isDefaultIdentity.value); popBack(result: identityRequest); } else { final identityRequest = EditIdentityRequest( identityId: identity!.id!, identityRequest: newIdentity.toIdentityRequest(), + publicAssetsInIdentityArguments: publicAssetsInIdentityArguments, isDefaultIdentity: isDefaultIdentity.value); popBack(result: identityRequest); } diff --git a/lib/features/manage_account/domain/model/create_new_default_identity_request.dart b/lib/features/manage_account/domain/model/create_new_default_identity_request.dart index 52b32b724..1bc1b8b52 100644 --- a/lib/features/manage_account/domain/model/create_new_default_identity_request.dart +++ b/lib/features/manage_account/domain/model/create_new_default_identity_request.dart @@ -10,12 +10,12 @@ class CreateNewDefaultIdentityRequest extends CreateNewIdentityRequest { super.creationId, super.newIdentity, { - this.oldDefaultIdentityIds + this.oldDefaultIdentityIds, + super.publicAssetsInIdentityArguments, }); @override List get props => [ - super.creationId, - super.newIdentity, + ...super.props, oldDefaultIdentityIds]; } \ No newline at end of file diff --git a/lib/features/manage_account/domain/model/create_new_identity_request.dart b/lib/features/manage_account/domain/model/create_new_identity_request.dart index a765e229d..771f9fd88 100644 --- a/lib/features/manage_account/domain/model/create_new_identity_request.dart +++ b/lib/features/manage_account/domain/model/create_new_identity_request.dart @@ -2,20 +2,23 @@ import 'package:equatable/equatable.dart'; import 'package:jmap_dart_client/jmap/core/id.dart'; import 'package:jmap_dart_client/jmap/identities/identity.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/model/public_assets_in_identity_arguments.dart'; class CreateNewIdentityRequest with EquatableMixin { final Identity newIdentity; final Id creationId; final bool isDefaultIdentity; + final PublicAssetsInIdentityArguments? publicAssetsInIdentityArguments; CreateNewIdentityRequest( this.creationId, this.newIdentity, { - this.isDefaultIdentity = false + this.isDefaultIdentity = false, + this.publicAssetsInIdentityArguments, }); @override - List get props => [creationId, newIdentity, isDefaultIdentity]; + List get props => [creationId, newIdentity, isDefaultIdentity, publicAssetsInIdentityArguments]; } \ No newline at end of file diff --git a/lib/features/manage_account/domain/model/edit_default_identity_request.dart b/lib/features/manage_account/domain/model/edit_default_identity_request.dart index 5db324a18..82f64636f 100644 --- a/lib/features/manage_account/domain/model/edit_default_identity_request.dart +++ b/lib/features/manage_account/domain/model/edit_default_identity_request.dart @@ -10,14 +10,13 @@ class EditDefaultIdentityRequest extends EditIdentityRequest { required super.identityId, required super.identityRequest, required super.isDefaultIdentity, - this.oldDefaultIdentityIds + this.oldDefaultIdentityIds, + super.publicAssetsInIdentityArguments }); @override List get props => [ - super.identityId, - super.identityRequest, - super.isDefaultIdentity, + ...super.props, oldDefaultIdentityIds ]; } \ No newline at end of file diff --git a/lib/features/manage_account/domain/model/edit_identity_request.dart b/lib/features/manage_account/domain/model/edit_identity_request.dart index 4309d3960..1ef5b272e 100644 --- a/lib/features/manage_account/domain/model/edit_identity_request.dart +++ b/lib/features/manage_account/domain/model/edit_identity_request.dart @@ -2,23 +2,27 @@ import 'package:equatable/equatable.dart'; import 'package:jmap_dart_client/jmap/identities/identity.dart'; import 'package:model/model.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/model/public_assets_in_identity_arguments.dart'; class EditIdentityRequest with EquatableMixin { final IdentityRequestDto identityRequest; final IdentityId identityId; final bool isDefaultIdentity; + final PublicAssetsInIdentityArguments? publicAssetsInIdentityArguments; EditIdentityRequest({ required this.identityId, required this.identityRequest, - this.isDefaultIdentity = false + this.isDefaultIdentity = false, + this.publicAssetsInIdentityArguments }); @override List get props => [ identityId, identityRequest, - isDefaultIdentity + isDefaultIdentity, + publicAssetsInIdentityArguments ]; } \ No newline at end of file diff --git a/lib/features/manage_account/domain/state/create_new_default_identity_state.dart b/lib/features/manage_account/domain/state/create_new_default_identity_state.dart index 3d6c67522..d9b4ac620 100644 --- a/lib/features/manage_account/domain/state/create_new_default_identity_state.dart +++ b/lib/features/manage_account/domain/state/create_new_default_identity_state.dart @@ -1,16 +1,20 @@ import 'package:core/core.dart'; import 'package:jmap_dart_client/jmap/identities/identity.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/model/public_assets_in_identity_arguments.dart'; class CreateNewDefaultIdentityLoading extends UIState {} class CreateNewDefaultIdentitySuccess extends UIState { final Identity newIdentity; + final PublicAssetsInIdentityArguments? publicAssetsInIdentityArguments; - CreateNewDefaultIdentitySuccess(this.newIdentity); + CreateNewDefaultIdentitySuccess( + this.newIdentity, + {this.publicAssetsInIdentityArguments}); @override - List get props => [newIdentity]; + List get props => [newIdentity, publicAssetsInIdentityArguments]; } class CreateNewDefaultIdentityFailure extends FeatureFailure { diff --git a/lib/features/manage_account/domain/state/create_new_identity_state.dart b/lib/features/manage_account/domain/state/create_new_identity_state.dart index 612f91efa..f4ee4fe15 100644 --- a/lib/features/manage_account/domain/state/create_new_identity_state.dart +++ b/lib/features/manage_account/domain/state/create_new_identity_state.dart @@ -1,16 +1,20 @@ import 'package:core/core.dart'; import 'package:jmap_dart_client/jmap/identities/identity.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/model/public_assets_in_identity_arguments.dart'; class CreateNewIdentityLoading extends UIState {} class CreateNewIdentitySuccess extends UIState { final Identity newIdentity; + final PublicAssetsInIdentityArguments? publicAssetsInIdentityArguments; - CreateNewIdentitySuccess(this.newIdentity); + CreateNewIdentitySuccess( + this.newIdentity, + {this.publicAssetsInIdentityArguments}); @override - List get props => [newIdentity]; + List get props => [newIdentity, publicAssetsInIdentityArguments]; } class CreateNewIdentityFailure extends FeatureFailure { diff --git a/lib/features/manage_account/domain/state/edit_default_identity_state.dart b/lib/features/manage_account/domain/state/edit_default_identity_state.dart index 99e61284c..2ff80c326 100644 --- a/lib/features/manage_account/domain/state/edit_default_identity_state.dart +++ b/lib/features/manage_account/domain/state/edit_default_identity_state.dart @@ -4,7 +4,11 @@ import 'package:tmail_ui_user/features/manage_account/domain/state/edit_identity class EditDefaultIdentityLoading extends UIState {} -class EditDefaultIdentitySuccess extends EditIdentitySuccess {} +class EditDefaultIdentitySuccess extends EditIdentitySuccess { + EditDefaultIdentitySuccess( + super.identityId, + {super.publicAssetsInIdentityArguments}); +} class EditDefaultIdentityFailure extends FeatureFailure { diff --git a/lib/features/manage_account/domain/state/edit_identity_state.dart b/lib/features/manage_account/domain/state/edit_identity_state.dart index 8d403ad4c..1c123288e 100644 --- a/lib/features/manage_account/domain/state/edit_identity_state.dart +++ b/lib/features/manage_account/domain/state/edit_identity_state.dart @@ -1,9 +1,21 @@ import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/success.dart'; +import 'package:jmap_dart_client/jmap/identities/identity.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/model/public_assets_in_identity_arguments.dart'; class EditIdentityLoading extends UIState {} -class EditIdentitySuccess extends UIState {} +class EditIdentitySuccess extends UIState { + final IdentityId identityId; + final PublicAssetsInIdentityArguments? publicAssetsInIdentityArguments; + + EditIdentitySuccess( + this.identityId, + {this.publicAssetsInIdentityArguments}); + + @override + List get props => [identityId, publicAssetsInIdentityArguments]; +} class EditIdentityFailure extends FeatureFailure { diff --git a/lib/features/manage_account/domain/usecases/create_new_default_identity_interactor.dart b/lib/features/manage_account/domain/usecases/create_new_default_identity_interactor.dart index a4a5101cc..5a31906fd 100644 --- a/lib/features/manage_account/domain/usecases/create_new_default_identity_interactor.dart +++ b/lib/features/manage_account/domain/usecases/create_new_default_identity_interactor.dart @@ -33,7 +33,9 @@ class CreateNewDefaultIdentityInteractor { final defaultRequest = _createNewIdentityDefault(identityRequest, listDefaultIdentities); final newIdentity = await _identityRepository.createNewIdentity(session, accountId, defaultRequest); - yield Right(CreateNewDefaultIdentitySuccess(newIdentity)); + yield Right(CreateNewDefaultIdentitySuccess( + newIdentity, + publicAssetsInIdentityArguments: identityRequest.publicAssetsInIdentityArguments)); } catch (exception) { yield Left(CreateNewDefaultIdentityFailure(exception)); } diff --git a/lib/features/manage_account/domain/usecases/create_new_identity_interactor.dart b/lib/features/manage_account/domain/usecases/create_new_identity_interactor.dart index 8f9803090..e1beafd50 100644 --- a/lib/features/manage_account/domain/usecases/create_new_identity_interactor.dart +++ b/lib/features/manage_account/domain/usecases/create_new_identity_interactor.dart @@ -21,7 +21,9 @@ class CreateNewIdentityInteractor { try { yield Right(CreateNewIdentityLoading()); final newIdentity = await _identityRepository.createNewIdentity(session, accountId, identityRequest); - yield Right(CreateNewIdentitySuccess(newIdentity)); + yield Right(CreateNewIdentitySuccess( + newIdentity, + publicAssetsInIdentityArguments: identityRequest.publicAssetsInIdentityArguments)); } catch (exception) { yield Left(CreateNewIdentityFailure(exception)); } diff --git a/lib/features/manage_account/domain/usecases/edit_default_identity_interactor.dart b/lib/features/manage_account/domain/usecases/edit_default_identity_interactor.dart index 97c4c26e4..725624d2d 100644 --- a/lib/features/manage_account/domain/usecases/edit_default_identity_interactor.dart +++ b/lib/features/manage_account/domain/usecases/edit_default_identity_interactor.dart @@ -41,7 +41,11 @@ class EditDefaultIdentityInteractor { .toList()); final result = await _identityRepository.editIdentity(session, accountId, editDefaultRequest); - yield result ? Right(EditDefaultIdentitySuccess()) : Left(EditDefaultIdentityFailure(null)); + yield result + ? Right(EditDefaultIdentitySuccess( + editDefaultRequest.identityId, + publicAssetsInIdentityArguments: editDefaultRequest.publicAssetsInIdentityArguments)) + : Left(EditDefaultIdentityFailure(null)); } catch (exception) { yield Left(EditDefaultIdentityFailure(exception)); } diff --git a/lib/features/manage_account/domain/usecases/edit_identity_interactor.dart b/lib/features/manage_account/domain/usecases/edit_identity_interactor.dart index 494fc87f0..c4d9216ef 100644 --- a/lib/features/manage_account/domain/usecases/edit_identity_interactor.dart +++ b/lib/features/manage_account/domain/usecases/edit_identity_interactor.dart @@ -22,7 +22,11 @@ class EditIdentityInteractor { try { yield Right(EditIdentityLoading()); final result = await _identityRepository.editIdentity(session, accountId, editIdentityRequest); - yield result ? Right(EditIdentitySuccess()) : Left(EditIdentityFailure(null)); + yield result + ? Right(EditIdentitySuccess( + editIdentityRequest.identityId, + publicAssetsInIdentityArguments: editIdentityRequest.publicAssetsInIdentityArguments)) + : Left(EditIdentityFailure(null)); } catch (exception) { yield Left(EditIdentityFailure(exception)); } diff --git a/lib/features/manage_account/presentation/profiles/identities/identities_controller.dart b/lib/features/manage_account/presentation/profiles/identities/identities_controller.dart index e3854efe1..a68f3bde8 100644 --- a/lib/features/manage_account/presentation/profiles/identities/identities_controller.dart +++ b/lib/features/manage_account/presentation/profiles/identities/identities_controller.dart @@ -3,11 +3,13 @@ import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/success.dart'; import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart'; +import 'package:core/utils/app_logger.dart'; import 'package:core/utils/platform_info.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:jmap_dart_client/jmap/identities/identity.dart'; import 'package:tmail_ui_user/features/base/base_controller.dart'; @@ -31,6 +33,11 @@ import 'package:tmail_ui_user/features/manage_account/presentation/extensions/id import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/identity_action_type.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/widgets/delete_identity_dialog_builder.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/model/public_assets_in_identity_arguments.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/usecase/clean_up_public_assets_interactor.dart'; +import 'package:tmail_ui_user/features/public_asset/presentation/clean_up_public_assets_interactor_bindings.dart'; +import 'package:tmail_ui_user/main/bindings/network/binding_tag.dart'; +import 'package:tmail_ui_user/main/error/capability_validator.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/routes/app_routes.dart'; import 'package:tmail_ui_user/main/routes/dialog_router.dart'; @@ -99,6 +106,7 @@ class IdentitiesController extends BaseController { final session = accountDashBoardController.sessionCurrent; if (accountId != null && session != null) { _getAllIdentities(session, accountId); + _injectCleanUpPublicAssetsInteractorBindings(session, accountId); } }); } @@ -177,6 +185,11 @@ class IdentitiesController extends BaseController { AppLocalizations.of(currentContext!).you_have_created_a_new_identity); } + _cleanUpPublicAssets( + success.newIdentity.id, + IdentityActionType.create, + success.publicAssetsInIdentityArguments); + _refreshAllIdentities(); } @@ -187,6 +200,11 @@ class IdentitiesController extends BaseController { AppLocalizations.of(currentContext!).you_have_created_a_new_default_identity); } + _cleanUpPublicAssets( + success.newIdentity.id, + IdentityActionType.create, + success.publicAssetsInIdentityArguments); + _refreshAllIdentities(); } @@ -287,8 +305,52 @@ class IdentitiesController extends BaseController { AppLocalizations.of(currentContext!).you_are_changed_your_identity_successfully); } + _cleanUpPublicAssets( + success.identityId, + IdentityActionType.edit, + success.publicAssetsInIdentityArguments); + _refreshAllIdentities(); } bool get isSignatureShow => identitySelected.value != null; + + void _injectCleanUpPublicAssetsInteractorBindings(Session? session, AccountId? accountId) { + try { + requireCapability(session!, accountId!, [CapabilityIdentifier.jmapPublicAsset]); + CleanUpPublicAssetsInteractorBindings().dependencies(); + } catch(e) { + logError('$runtimeType::injectCleanUpPublicAssetsInteractorBindings(): exception: $e'); + } + } + + void _cleanUpPublicAssets( + IdentityId? identityId, + IdentityActionType? identityActionType, + PublicAssetsInIdentityArguments? publicAssetsInIdentityArguments) { + final session = accountDashBoardController.sessionCurrent; + final accountId = accountDashBoardController.accountId.value; + + if (session == null + || accountId == null + || identityId == null + || identityActionType == null + || publicAssetsInIdentityArguments == null) return; + + final cleanUpPublicAssetsInteractor = getBinding( + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + if (cleanUpPublicAssetsInteractor == null) return; + consumeState(cleanUpPublicAssetsInteractor.execute( + session, + accountId, + identityId: identityId, + identityActionType: identityActionType, + publicAssetsInIdentityArguments: publicAssetsInIdentityArguments)); + } + + @override + void onClose() { + CleanUpPublicAssetsInteractorBindings().close(); + super.onClose(); + } } \ No newline at end of file diff --git a/lib/features/public_asset/data/network/public_asset_api.dart b/lib/features/public_asset/data/network/public_asset_api.dart index a533645d8..c26deb454 100644 --- a/lib/features/public_asset/data/network/public_asset_api.dart +++ b/lib/features/public_asset/data/network/public_asset_api.dart @@ -128,7 +128,7 @@ class PublicAssetApi { final notUpdatedPublicAssetIds = response.parse( invocation.methodCallId, SetPublicAssetResponse.deserialize - )?.updated; + )?.notUpdated; if (notUpdatedPublicAssetIds?.isNotEmpty == true) { throw const CannotUpdatePublicAssetException(); diff --git a/lib/features/public_asset/domain/extensions/public_asset_extension.dart b/lib/features/public_asset/domain/extensions/public_asset_extension.dart new file mode 100644 index 000000000..1af10d4e6 --- /dev/null +++ b/lib/features/public_asset/domain/extensions/public_asset_extension.dart @@ -0,0 +1,26 @@ +import 'package:jmap_dart_client/jmap/identities/identity.dart'; +import 'package:jmap_dart_client/jmap/mail/extensions/public_asset/public_asset.dart'; + +extension PublicAssetExtension on PublicAsset { + PublicAsset withRemovedIdentityId(IdentityId toBeRemovedIdentityId) { + return PublicAsset( + id: id, + publicURI: publicURI, + size: size, + contentType: contentType, + blobId: blobId, + identityIds: identityIds?..remove(toBeRemovedIdentityId), + ); + } + + PublicAsset withAddedIdentityId(IdentityId toBeAddedIdentityId) { + return PublicAsset( + id: id, + publicURI: publicURI, + size: size, + contentType: contentType, + blobId: blobId, + identityIds: identityIds?..addAll({toBeAddedIdentityId: true}), + ); + } +} \ No newline at end of file diff --git a/lib/features/public_asset/domain/model/public_assets_in_identity_arguments.dart b/lib/features/public_asset/domain/model/public_assets_in_identity_arguments.dart new file mode 100644 index 000000000..00d13607d --- /dev/null +++ b/lib/features/public_asset/domain/model/public_assets_in_identity_arguments.dart @@ -0,0 +1,21 @@ +import 'package:equatable/equatable.dart'; +import 'package:tmail_ui_user/features/public_asset/presentation/public_asset_controller.dart'; + +class PublicAssetsInIdentityArguments with EquatableMixin { + final String htmlSignature; + final List preExistingPublicAssetIds; + final List newlyPickedPublicAssetIds; + + PublicAssetsInIdentityArguments({ + required this.htmlSignature, + required this.preExistingPublicAssetIds, + required this.newlyPickedPublicAssetIds, + }); + + @override + List get props => [ + htmlSignature, + preExistingPublicAssetIds, + newlyPickedPublicAssetIds, + ]; +} \ No newline at end of file diff --git a/lib/features/public_asset/domain/state/add_identity_to_public_assets_state.dart b/lib/features/public_asset/domain/state/add_identity_to_public_assets_state.dart new file mode 100644 index 000000000..156063d91 --- /dev/null +++ b/lib/features/public_asset/domain/state/add_identity_to_public_assets_state.dart @@ -0,0 +1,10 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; + +class AddingIdentityToPublicAssetsState extends LoadingState {} + +class AddIdentityToPublicAssetsSuccessState extends UIState {} + +class AddIdentityToPublicAssetsFailureState extends FeatureFailure { + AddIdentityToPublicAssetsFailureState({super.exception}); +} \ No newline at end of file diff --git a/lib/features/public_asset/domain/state/clean_up_public_assets_state.dart b/lib/features/public_asset/domain/state/clean_up_public_assets_state.dart new file mode 100644 index 000000000..2a216ed22 --- /dev/null +++ b/lib/features/public_asset/domain/state/clean_up_public_assets_state.dart @@ -0,0 +1,10 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; + +class CleaningUpPublicAssetsState extends LoadingState {} + +class CleanUpPublicAssetsSuccessState extends UIState {} + +class CleanUpPublicAssetsFailureState extends FeatureFailure { + CleanUpPublicAssetsFailureState({super.exception}); +} \ No newline at end of file diff --git a/lib/features/public_asset/domain/state/remove_identity_from_public_assets_state.dart b/lib/features/public_asset/domain/state/remove_identity_from_public_assets_state.dart new file mode 100644 index 000000000..c55d9001b --- /dev/null +++ b/lib/features/public_asset/domain/state/remove_identity_from_public_assets_state.dart @@ -0,0 +1,14 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; + +class RemovingIdentityFromPublicAssetsState extends LoadingState {} + +class RemoveIdentityFromPublicAssetsSuccessState extends UIState {} + +class RemoveIdentityFromPublicAssetsFailureState extends FeatureFailure { + RemoveIdentityFromPublicAssetsFailureState({super.exception}); +} + +class NotFoundAnyPublicAssetsFailureState extends FeatureFailure { + NotFoundAnyPublicAssetsFailureState({super.exception}); +} \ No newline at end of file diff --git a/lib/features/public_asset/domain/usecase/add_identity_to_public_assets_interactor.dart b/lib/features/public_asset/domain/usecase/add_identity_to_public_assets_interactor.dart new file mode 100644 index 000000000..e3b052183 --- /dev/null +++ b/lib/features/public_asset/domain/usecase/add_identity_to_public_assets_interactor.dart @@ -0,0 +1,50 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/core/session/session.dart'; +import 'package:jmap_dart_client/jmap/identities/identity.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/extensions/public_asset_extension.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/repository/public_asset_repository.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/state/add_identity_to_public_assets_state.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/state/remove_identity_from_public_assets_state.dart'; +import 'package:tmail_ui_user/features/public_asset/presentation/public_asset_controller.dart'; + +class AddIdentityToPublicAssetsInteractor { + AddIdentityToPublicAssetsInteractor(this._publicAssetRepository); + + final PublicAssetRepository _publicAssetRepository; + + Stream> execute( + Session session, + AccountId accountId, + { + required IdentityId identityId, + required List publicAssetIds + } + ) async* { + try { + yield Right(AddingIdentityToPublicAssetsState()); + final publicAssets = await _publicAssetRepository.getPublicAssetsFromIds( + session, + accountId, + publicAssetIds: publicAssetIds + ); + if (publicAssets.isEmpty) { + yield Left(NotFoundAnyPublicAssetsFailureState()); + } else { + final publicAssetsWithCurrentIdentity = publicAssets + .map((publicAsset) => publicAsset.withAddedIdentityId(identityId)) + .toList(); + await _publicAssetRepository.updatePublicAssets( + session, + accountId, + publicAssets: publicAssetsWithCurrentIdentity + ); + yield Right(AddIdentityToPublicAssetsSuccessState()); + } + } catch (exception) { + yield Left(AddIdentityToPublicAssetsFailureState(exception: exception)); + } + } +} \ No newline at end of file diff --git a/lib/features/public_asset/domain/usecase/clean_up_public_assets_interactor.dart b/lib/features/public_asset/domain/usecase/clean_up_public_assets_interactor.dart new file mode 100644 index 000000000..3894cb4a8 --- /dev/null +++ b/lib/features/public_asset/domain/usecase/clean_up_public_assets_interactor.dart @@ -0,0 +1,124 @@ +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/session/session.dart'; +import 'package:jmap_dart_client/jmap/identities/identity.dart'; +import 'package:model/extensions/list_extension.dart'; +import 'package:rxdart/rxdart.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/model/identity_action_type.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/extensions/string_to_public_asset_extension.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/model/public_assets_in_identity_arguments.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/state/clean_up_public_assets_state.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/usecase/add_identity_to_public_assets_interactor.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/usecase/delete_public_assets_interactor.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/usecase/remove_identity_from_public_assets_interactor.dart'; +import 'package:tmail_ui_user/features/public_asset/presentation/public_asset_controller.dart'; + +class CleanUpPublicAssetsInteractor { + CleanUpPublicAssetsInteractor( + this.removeIdentityFromPublicAssetsInteractor, + this.deletePublicAssetsInteractor, + this.addIdentityToPublicAssetsInteractor); + + final RemoveIdentityFromPublicAssetsInteractor removeIdentityFromPublicAssetsInteractor; + final DeletePublicAssetsInteractor deletePublicAssetsInteractor; + final AddIdentityToPublicAssetsInteractor addIdentityToPublicAssetsInteractor; + + Stream> execute( + Session session, + AccountId accountId, + { + required IdentityId identityId, + required IdentityActionType identityActionType, + required PublicAssetsInIdentityArguments publicAssetsInIdentityArguments, + } + ) async* { + try { + yield Right(CleaningUpPublicAssetsState()); + + final publicAssetIds = _filterPublicAssetsIdsForCleanUp( + identityId, + identityActionType, + publicAssetsInIdentityArguments); + + await Rx.merge>([ + if (publicAssetIds.publicAssetsIdsToBeDereferenced.isNotEmpty) + removeIdentityFromPublicAssetsInteractor.execute( + session, + accountId, + identityId: identityId, + publicAssetIds: publicAssetIds.publicAssetsIdsToBeDereferenced), + if (publicAssetIds.publicAssetsIdsToBeDestroyed.isNotEmpty) + deletePublicAssetsInteractor.execute( + session, + accountId, + publicAssetIds: publicAssetIds.publicAssetsIdsToBeDestroyed), + if (publicAssetIds.publicAssetsIdsToBeReferenced.isNotEmpty) + addIdentityToPublicAssetsInteractor.execute( + session, + accountId, + identityId: identityId, + publicAssetIds: publicAssetIds.publicAssetsIdsToBeReferenced), + ]).last; + + yield Right(CleanUpPublicAssetsSuccessState()); + + } catch (exception) { + logError('CleanUpPublicAssetsInteractor::execute():error: $exception'); + yield Left(CleanUpPublicAssetsFailureState(exception: exception)); + } + } + + ({ + List publicAssetsIdsToBeDestroyed, + List publicAssetsIdsToBeReferenced, + List publicAssetsIdsToBeDereferenced, + }) _filterPublicAssetsIdsForCleanUp( + IdentityId identityId, + IdentityActionType identityActionType, + PublicAssetsInIdentityArguments publicAssetsInIdentityArguments, + ) { + final htmlSignature = publicAssetsInIdentityArguments.htmlSignature; + final publicAssetIdsInSignature = htmlSignature.publicAssetIdsFromHtmlContent; + log('CleanUpPublicAssetsInteractor::publicAssetIdsInSignature: $publicAssetIdsInSignature'); + final preExistingPublicAssetIds = publicAssetsInIdentityArguments.preExistingPublicAssetIds; + log('CleanUpPublicAssetsInteractor::preExistingPublicAssetIds: $preExistingPublicAssetIds'); + final newlyPickedPublicAssetIds = publicAssetsInIdentityArguments.newlyPickedPublicAssetIds; + log('CleanUpPublicAssetsInteractor::newlyPickedPublicAssetIds: $newlyPickedPublicAssetIds'); + + final deletedPreExistingPublicAssetIds = List.from(preExistingPublicAssetIds); + final notIncludedNewlyPickedPublicAssetIds = List.from(newlyPickedPublicAssetIds); + final pastedPublicAssetIds = []; + final newPublicAssetsIdsInSignature = []; + + for (var id in publicAssetIdsInSignature) { + deletedPreExistingPublicAssetIds.remove(id); + notIncludedNewlyPickedPublicAssetIds.remove(id); + + if (preExistingPublicAssetIds.notContains(id) + && newlyPickedPublicAssetIds.notContains(id) + ) { + pastedPublicAssetIds.add(id); + } + + if (identityActionType == IdentityActionType.create + && newlyPickedPublicAssetIds.contains(id) + ) { + newPublicAssetsIdsInSignature.add(id); + } + } + + log('CleanUpPublicAssetsInteractor::deletedpreExistingPublicAssetIds: $deletedPreExistingPublicAssetIds'); + log('CleanUpPublicAssetsInteractor::notIncludednewlyPickedPublicAssetIds: $notIncludedNewlyPickedPublicAssetIds'); + log('CleanUpPublicAssetsInteractor::pastedPublicAssetIds: $pastedPublicAssetIds'); + log('CleanUpPublicAssetsInteractor::newPublicAssetsIdsInSignature: $newPublicAssetsIdsInSignature'); + + return ( + publicAssetsIdsToBeDestroyed: notIncludedNewlyPickedPublicAssetIds, + publicAssetsIdsToBeReferenced: pastedPublicAssetIds + newPublicAssetsIdsInSignature, + publicAssetsIdsToBeDereferenced: deletedPreExistingPublicAssetIds, + ); + } +} \ No newline at end of file diff --git a/lib/features/public_asset/domain/usecase/remove_identity_from_public_assets_interactor.dart b/lib/features/public_asset/domain/usecase/remove_identity_from_public_assets_interactor.dart new file mode 100644 index 000000000..99a095d73 --- /dev/null +++ b/lib/features/public_asset/domain/usecase/remove_identity_from_public_assets_interactor.dart @@ -0,0 +1,49 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/core/session/session.dart'; +import 'package:jmap_dart_client/jmap/identities/identity.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/extensions/public_asset_extension.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/repository/public_asset_repository.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/state/remove_identity_from_public_assets_state.dart'; +import 'package:tmail_ui_user/features/public_asset/presentation/public_asset_controller.dart'; + +class RemoveIdentityFromPublicAssetsInteractor { + RemoveIdentityFromPublicAssetsInteractor(this._publicAssetRepository); + + final PublicAssetRepository _publicAssetRepository; + + Stream> execute( + Session session, + AccountId accountId, + { + required IdentityId identityId, + required List publicAssetIds + } + ) async* { + try { + yield Right(RemovingIdentityFromPublicAssetsState()); + final publicAssets = await _publicAssetRepository.getPublicAssetsFromIds( + session, + accountId, + publicAssetIds: publicAssetIds + ); + if (publicAssets.isEmpty) { + yield Left(NotFoundAnyPublicAssetsFailureState()); + } else { + final publicAssetsWithCurrentIdentity = publicAssets + .map((publicAsset) => publicAsset.withRemovedIdentityId(identityId)) + .toList(); + await _publicAssetRepository.updatePublicAssets( + session, + accountId, + publicAssets: publicAssetsWithCurrentIdentity + ); + yield Right(RemoveIdentityFromPublicAssetsSuccessState()); + } + } catch (exception) { + yield Left(RemoveIdentityFromPublicAssetsFailureState(exception: exception)); + } + } +} \ No newline at end of file diff --git a/lib/features/public_asset/presentation/clean_up_public_assets_interactor_bindings.dart b/lib/features/public_asset/presentation/clean_up_public_assets_interactor_bindings.dart new file mode 100644 index 000000000..15b7a0974 --- /dev/null +++ b/lib/features/public_asset/presentation/clean_up_public_assets_interactor_bindings.dart @@ -0,0 +1,97 @@ +import 'package:get/get.dart'; +import 'package:jmap_dart_client/http/http_client.dart'; +import 'package:tmail_ui_user/features/base/interactors_bindings.dart'; +import 'package:tmail_ui_user/features/public_asset/data/datasource/public_asset_datasource.dart'; +import 'package:tmail_ui_user/features/public_asset/data/datasource_impl/remote_public_asset_datasource_impl.dart'; +import 'package:tmail_ui_user/features/public_asset/data/network/public_asset_api.dart'; +import 'package:tmail_ui_user/features/public_asset/data/repository/public_asset_repository_impl.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/repository/public_asset_repository.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/usecase/add_identity_to_public_assets_interactor.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/usecase/clean_up_public_assets_interactor.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/usecase/delete_public_assets_interactor.dart'; +import 'package:tmail_ui_user/features/public_asset/domain/usecase/remove_identity_from_public_assets_interactor.dart'; +import 'package:tmail_ui_user/main/bindings/network/binding_tag.dart'; +import 'package:tmail_ui_user/main/exceptions/remote_exception_thrower.dart'; +import 'package:uuid/uuid.dart'; + +class CleanUpPublicAssetsInteractorBindings extends InteractorsBindings { + @override + void dependencies() { + Get.lazyPut( + () => PublicAssetApi(Get.find(), Get.find()), + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + + super.dependencies(); + } + + @override + void bindingsDataSource() { + Get.lazyPut( + () => Get.find( + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag), + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + } + + @override + void bindingsDataSourceImpl() { + Get.lazyPut( + () => RemotePublicAssetDatasourceImpl( + Get.find( + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag), + Get.find()), + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + } + + @override + void bindingsInteractor() { + Get.lazyPut( + () => CleanUpPublicAssetsInteractor( + Get.find( + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag), + Get.find( + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag), + Get.find( + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag)), + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + Get.lazyPut( + () => RemoveIdentityFromPublicAssetsInteractor(Get.find( + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag)), + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + Get.lazyPut( + () => DeletePublicAssetsInteractor(Get.find( + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag)), + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + Get.lazyPut( + () => AddIdentityToPublicAssetsInteractor(Get.find( + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag)), + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + } + + @override + void bindingsRepository() { + Get.lazyPut( + () => Get.find( + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag), + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + } + + @override + void bindingsRepositoryImpl() { + Get.lazyPut( + () => PublicAssetRepositoryImpl(Get.find( + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag)), + tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + } + + void close() { + Get.delete(tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + Get.delete(tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + Get.delete(tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + Get.delete(tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + Get.delete(tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + Get.delete(tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + Get.delete(tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + Get.delete(tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + Get.delete(tag: BindingTag.cleanUpPublicAssetsInteractorBindingsTag); + } +} \ No newline at end of file diff --git a/model/lib/extensions/list_extension.dart b/model/lib/extensions/list_extension.dart index 9ab054a1e..97d522031 100644 --- a/model/lib/extensions/list_extension.dart +++ b/model/lib/extensions/list_extension.dart @@ -7,4 +7,6 @@ extension ListExtension on List? { } return this; } + + bool notContains(T value) => this?.contains(value) != true; } \ No newline at end of file