TF-3040 Create public_asset feature

This commit is contained in:
DatDang
2024-08-07 11:17:59 +07:00
committed by Dat H. Pham
parent 34b7bf78c3
commit 0656fd9390
6 changed files with 349 additions and 0 deletions
@@ -0,0 +1,36 @@
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:jmap_dart_client/jmap/mail/extensions/public_asset/public_asset.dart';
abstract class PublicAssetDatasource {
const PublicAssetDatasource();
Future<List<PublicAsset>> getPublicAssetFromIds(
Session session,
AccountId accountId,
{required List<Id> publicAssetIds}
);
Future<PublicAsset> createPublicAsset(
Session session,
AccountId accountId,
{
required Id blobId,
required IdentityId? identityId
}
);
Future<void> deletePublicAssets(
Session session,
AccountId accountId,
{required List<Id> publicAssetIds}
);
Future<void> updatePublicAssets(
Session session,
AccountId accountId,
{required List<PublicAsset> publicAssets}
);
}
@@ -0,0 +1,70 @@
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:jmap_dart_client/jmap/mail/extensions/public_asset/public_asset.dart';
import 'package:tmail_ui_user/features/public_asset/data/datasource/public_asset_datasource.dart';
import 'package:tmail_ui_user/features/public_asset/data/network/public_asset_api.dart';
import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart';
class RemotePublicAssetDatasourceImpl implements PublicAssetDatasource {
const RemotePublicAssetDatasourceImpl(this._publicAssetApi, this._exceptionThrower);
final PublicAssetApi _publicAssetApi;
final ExceptionThrower _exceptionThrower;
@override
Future<PublicAsset> createPublicAsset(
Session session,
AccountId accountId,
{
required Id blobId,
required IdentityId? identityId
}
) => Future.sync(() async {
return await _publicAssetApi.createPublicAsset(
session,
accountId,
blobId: blobId,
identityId: identityId);
}).catchError(_exceptionThrower.throwException);
@override
Future<void> deletePublicAssets(
Session session,
AccountId accountId,
{required List<Id> publicAssetIds}
) => Future.sync(() async {
return await _publicAssetApi.destroyPublicAssets(
session,
accountId,
publicAssetIds: publicAssetIds
);
}).catchError(_exceptionThrower.throwException);
@override
Future<List<PublicAsset>> getPublicAssetFromIds(
Session session,
AccountId accountId,
{required List<Id> publicAssetIds}
) => Future.sync(() async {
return await _publicAssetApi.getPublicAssets(
session,
accountId,
publicAssetIds: publicAssetIds
);
}).catchError(_exceptionThrower.throwException);
@override
Future<void> updatePublicAssets(
Session session,
AccountId accountId,
{required List<PublicAsset> publicAssets}
) => Future.sync(() async {
return await _publicAssetApi.updatePublicAssets(
session,
accountId,
publicAssets: publicAssets
);
}).catchError(_exceptionThrower.throwException);
}
@@ -0,0 +1,137 @@
import 'package:jmap_dart_client/http/converter/identities/public_asset_identities_converter.dart';
import 'package:jmap_dart_client/http/http_client.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/id.dart';
import 'package:jmap_dart_client/jmap/core/patch_object.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:jmap_dart_client/jmap/jmap_request.dart';
import 'package:jmap_dart_client/jmap/mail/extensions/public_asset/get/get_public_asset_method.dart';
import 'package:jmap_dart_client/jmap/mail/extensions/public_asset/get/get_public_asset_response.dart';
import 'package:jmap_dart_client/jmap/mail/extensions/public_asset/public_asset.dart';
import 'package:jmap_dart_client/jmap/mail/extensions/public_asset/set/set_public_asset_method.dart';
import 'package:jmap_dart_client/jmap/mail/extensions/public_asset/set/set_public_asset_response.dart';
import 'package:tmail_ui_user/features/public_asset/domain/exceptions/public_asset_exceptions.dart';
import 'package:uuid/uuid.dart';
class PublicAssetApi {
const PublicAssetApi(this._httpClient, this._uuid);
final HttpClient _httpClient;
final Uuid _uuid;
MapEntry<Id, PatchObject> _toPatchObjectMapEntry(PublicAsset publicAsset) {
final patchObject = PatchObject({
PatchObject.identityIdsProperty: const PublicAssetIdentitiesConverter()
.toJson(publicAsset.identityIds!),
});
return MapEntry(publicAsset.id!, patchObject);
}
Future<List<PublicAsset>> getPublicAssets(
Session session,
AccountId accountId,
{required List<Id> publicAssetIds}
) async {
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
final method = GetPublicAssetMethod(accountId);
method.addIds(publicAssetIds.toSet());
final invocation = requestBuilder.invocation(method);
final response = await (requestBuilder..usings(method.requiredCapabilities))
.build()
.execute();
final publicAssets = response.parse<GetPublicAssetResponse>(
invocation.methodCallId,
GetPublicAssetResponse.deserialize
)?.list ?? [];
return publicAssets;
}
Future<PublicAsset> createPublicAsset(
Session session,
AccountId accountId,
{
required Id blobId,
required IdentityId? identityId
}
) async {
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
final method = SetPublicAssetMethod(accountId);
final generateCreateId = Id(_uuid.v1());
method.addCreate(
generateCreateId,
PublicAsset(
blobId: blobId,
identityIds: identityId != null ? {identityId: true} : {}
)
);
final invocation = requestBuilder.invocation(method);
final response = await (requestBuilder..usings(method.requiredCapabilities))
.build()
.execute();
final publicAsset = response.parse<SetPublicAssetResponse>(
invocation.methodCallId,
SetPublicAssetResponse.deserialize
)?.created?[generateCreateId];
if (publicAsset == null) {
throw const CannotCreatePublicAssetException();
}
return publicAsset;
}
Future<void> destroyPublicAssets(
Session session,
AccountId accountId,
{required List<Id> publicAssetIds}
) async {
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
final method = SetPublicAssetMethod(accountId);
method.addDestroy(publicAssetIds.toSet());
final invocation = requestBuilder.invocation(method);
final response = await (requestBuilder..usings(method.requiredCapabilities))
.build()
.execute();
final notDestroyedPublicAssetIds = response.parse<SetPublicAssetResponse>(
invocation.methodCallId,
SetPublicAssetResponse.deserialize
)?.notDestroyed;
if (notDestroyedPublicAssetIds?.isNotEmpty == true) {
throw const CannotDestroyPublicAssetException();
}
}
Future<void> updatePublicAssets(
Session session,
AccountId accountId,
{required List<PublicAsset> publicAssets}
) async {
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
final method = SetPublicAssetMethod(accountId);
method.addUpdates(
Map.fromEntries(
publicAssets
.where((publicAsset) => publicAsset.id != null && publicAsset.identityIds != null)
.map(_toPatchObjectMapEntry)
)
);
final invocation = requestBuilder.invocation(method);
final response = await (requestBuilder..usings(method.requiredCapabilities))
.build()
.execute();
final notUpdatedPublicAssetIds = response.parse<SetPublicAssetResponse>(
invocation.methodCallId,
SetPublicAssetResponse.deserialize
)?.updated;
if (notUpdatedPublicAssetIds?.isNotEmpty == true) {
throw const CannotUpdatePublicAssetException();
}
}
}
@@ -0,0 +1,57 @@
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:jmap_dart_client/jmap/mail/extensions/public_asset/public_asset.dart';
import 'package:tmail_ui_user/features/public_asset/data/datasource/public_asset_datasource.dart';
import 'package:tmail_ui_user/features/public_asset/domain/repository/public_asset_repository.dart';
class PublicAssetRepositoryImpl implements PublicAssetRepository {
const PublicAssetRepositoryImpl(this._publicAssetDatasource);
final PublicAssetDatasource _publicAssetDatasource;
@override
Future<List<PublicAsset>> getPublicAssetsFromIds(
Session session,
AccountId accountId,
{required List<Id> publicAssetIds}
) => _publicAssetDatasource.getPublicAssetFromIds(
session,
accountId,
publicAssetIds: publicAssetIds);
@override
Future<void> deletePublicAssets(
Session session,
AccountId accountId,
{required List<Id> publicAssetIds}
) => _publicAssetDatasource.deletePublicAssets(
session,
accountId,
publicAssetIds: publicAssetIds);
@override
Future<PublicAsset> createPublicAsset(
Session session,
AccountId accountId,
{
required Id blobId,
required IdentityId? identityId
}
) => _publicAssetDatasource.createPublicAsset(
session,
accountId,
blobId: blobId,
identityId: identityId);
@override
Future<void> updatePublicAssets(
Session session,
AccountId accountId,
{required List<PublicAsset> publicAssets}
) => _publicAssetDatasource.updatePublicAssets(
session,
accountId,
publicAssets: publicAssets);
}
@@ -0,0 +1,15 @@
class UnsupportedCapabilityException implements Exception {
const UnsupportedCapabilityException();
}
class CannotCreatePublicAssetException implements Exception {
const CannotCreatePublicAssetException();
}
class CannotDestroyPublicAssetException implements Exception {
const CannotDestroyPublicAssetException();
}
class CannotUpdatePublicAssetException implements Exception {
const CannotUpdatePublicAssetException();
}
@@ -0,0 +1,34 @@
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:jmap_dart_client/jmap/mail/extensions/public_asset/public_asset.dart';
abstract class PublicAssetRepository {
Future<List<PublicAsset>> getPublicAssetsFromIds(
Session session,
AccountId accountId,
{required List<Id> publicAssetIds}
);
Future<PublicAsset> createPublicAsset(
Session session,
AccountId accountId,
{
required Id blobId,
required IdentityId? identityId
}
);
Future<void> deletePublicAssets(
Session session,
AccountId accountId,
{required List<Id> publicAssetIds}
);
Future<void> updatePublicAssets(
Session session,
AccountId accountId,
{required List<PublicAsset> publicAssets}
);
}