TF-561 Fix edit identity

This commit is contained in:
dab246
2022-05-16 18:46:27 +07:00
committed by Dat H. Pham
parent 29a5649a84
commit 0d40f765e6
18 changed files with 333 additions and 117 deletions
@@ -2,28 +2,53 @@ import 'package:get/get.dart';
import 'package:tmail_ui_user/features/base/base_bindings.dart'; import 'package:tmail_ui_user/features/base/base_bindings.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_controller.dart'; import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_controller.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/data/datasource/manage_account_datasource.dart';
import 'package:tmail_ui_user/features/manage_account/data/datasource_impl/manage_account_datasource_impl.dart';
import 'package:tmail_ui_user/features/manage_account/data/network/manage_account_api.dart';
import 'package:tmail_ui_user/features/manage_account/data/repository/manage_account_repository_impl.dart';
import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart';
import 'package:jmap_dart_client/http/http_client.dart' as jmap_http_client;
class IdentityCreatorBindings extends BaseBindings { class IdentityCreatorBindings extends BaseBindings {
@override @override
void bindingsController() { void dependencies() {
Get.lazyPut(() => IdentityCreatorController(Get.find<VerifyNameInteractor>())); Get.lazyPut(() => ManageAccountAPI(Get.find<jmap_http_client.HttpClient>()));
super.dependencies();
} }
@override @override
void bindingsDataSource() {} void bindingsController() {
Get.lazyPut(() => IdentityCreatorController(
Get.find<VerifyNameInteractor>(),
Get.find<GetAllIdentitiesInteractor>(),
));
}
@override @override
void bindingsDataSourceImpl() {} void bindingsDataSource() {
Get.lazyPut<ManageAccountDataSource>(() => Get.find<ManageAccountDataSourceImpl>());
}
@override
void bindingsDataSourceImpl() {
Get.lazyPut(() => ManageAccountDataSourceImpl(Get.find<ManageAccountAPI>()));
}
@override @override
void bindingsInteractor() { void bindingsInteractor() {
Get.lazyPut(() => VerifyNameInteractor()); Get.lazyPut(() => VerifyNameInteractor());
Get.lazyPut(() => GetAllIdentitiesInteractor(Get.find<ManageAccountRepository>()));
} }
@override @override
void bindingsRepository() {} void bindingsRepository() {
Get.lazyPut<ManageAccountRepository>(() => Get.find<ManageAccountRepositoryImpl>());
}
@override @override
void bindingsRepositoryImpl() {} void bindingsRepositoryImpl() {
Get.lazyPut(() => ManageAccountRepositoryImpl(Get.find<ManageAccountDataSource>()));
}
} }
@@ -4,6 +4,7 @@ import 'package:flutter/cupertino.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:html_editor_enhanced/html_editor.dart'; import 'package:html_editor_enhanced/html_editor.dart';
import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart'; import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/model.dart'; import 'package:model/model.dart';
@@ -14,12 +15,15 @@ import 'package:tmail_ui_user/features/mailbox_creator/domain/model/verification
import 'package:tmail_ui_user/features/mailbox_creator/domain/state/verify_name_view_state.dart'; import 'package:tmail_ui_user/features/mailbox_creator/domain/state/verify_name_view_state.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_creator/presentation/extensions/validator_failure_extension.dart'; import 'package:tmail_ui_user/features/mailbox_creator/presentation/extensions/validator_failure_extension.dart';
import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_identities_state.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/identity_action_type.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/identity_action_type.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart';
class IdentityCreatorController extends BaseController { class IdentityCreatorController extends BaseController {
final VerifyNameInteractor _verifyNameInteractor; final VerifyNameInteractor _verifyNameInteractor;
final GetAllIdentitiesInteractor _getAllIdentitiesInteractor;
final noneEmailAddress = EmailAddress(null, 'None'); final noneEmailAddress = EmailAddress(null, 'None');
final signatureType = SignatureType.plainText.obs; final signatureType = SignatureType.plainText.obs;
@@ -29,6 +33,7 @@ class IdentityCreatorController extends BaseController {
final emailOfIdentity = Rxn<EmailAddress>(); final emailOfIdentity = Rxn<EmailAddress>();
final replyToOfIdentity = Rxn<EmailAddress>(); final replyToOfIdentity = Rxn<EmailAddress>();
final bccOfIdentity = Rxn<EmailAddress>(); final bccOfIdentity = Rxn<EmailAddress>();
final actionType = IdentityActionType.create.obs;
final HtmlEditorController signatureHtmlEditorController = HtmlEditorController(processNewLineAsBr: true); final HtmlEditorController signatureHtmlEditorController = HtmlEditorController(processNewLineAsBr: true);
final TextEditingController signaturePlainEditorController = TextEditingController(); final TextEditingController signaturePlainEditorController = TextEditingController();
@@ -37,7 +42,6 @@ class IdentityCreatorController extends BaseController {
AccountId? accountId; AccountId? accountId;
UserProfile? userProfile; UserProfile? userProfile;
IdentityActionType? actionType;
Identity? identity; Identity? identity;
String? _nameIdentity; String? _nameIdentity;
String? _contentHtmlEditor; String? _contentHtmlEditor;
@@ -51,15 +55,17 @@ class IdentityCreatorController extends BaseController {
String? get contentHtmlEditor => _contentHtmlEditor; String? get contentHtmlEditor => _contentHtmlEditor;
IdentityCreatorController(this._verifyNameInteractor); IdentityCreatorController(
this._verifyNameInteractor,
this._getAllIdentitiesInteractor
);
@override @override
void onReady() { void onReady() {
_getArguments(); _getArguments();
if (actionType == IdentityActionType.edit && identity != null) { _getAllIdentities();
if (actionType.value == IdentityActionType.edit && identity != null) {
_setUpValueFromIdentity(); _setUpValueFromIdentity();
} else {
_setDefaultValueForIdentity();
} }
super.onReady(); super.onReady();
} }
@@ -74,6 +80,18 @@ class IdentityCreatorController extends BaseController {
@override @override
void onDone() { void onDone() {
viewState.value.fold(
(failure) {
if (failure is GetAllIdentitiesFailure) {
_getALlIdentitiesFailure(failure);
}
},
(success) {
if (success is GetAllIdentitiesSuccess) {
_getALlIdentitiesSuccess(success);
}
}
);
} }
@override @override
@@ -84,55 +102,15 @@ class IdentityCreatorController extends BaseController {
if (arguments is IdentityCreatorArguments) { if (arguments is IdentityCreatorArguments) {
accountId = arguments.accountId; accountId = arguments.accountId;
userProfile = arguments.userProfile; userProfile = arguments.userProfile;
actionType = arguments.actionType; actionType.value = arguments.actionType;
identity = arguments.identity; identity = arguments.identity;
} }
} }
void _setDefaultValueForIdentity() {
listEmailAddressOfReplyTo.add(noneEmailAddress);
bccOfIdentity.value = noneEmailAddress;
replyToOfIdentity.value = noneEmailAddress;
if (userProfile != null && userProfile?.email.isNotEmpty == true) {
final userEmailAddress = EmailAddress(null, userProfile!.email);
listEmailAddressDefault.add(userEmailAddress);
listEmailAddressOfReplyTo.add(userEmailAddress);
emailOfIdentity.value = userEmailAddress;
}
}
void _setUpValueFromIdentity() { void _setUpValueFromIdentity() {
Set<EmailAddress> listEmailAddress = {};
listEmailAddress.add(noneEmailAddress);
_nameIdentity = identity?.name ?? ''; _nameIdentity = identity?.name ?? '';
inputNameIdentityController.text = identity?.name ?? ''; inputNameIdentityController.text = identity?.name ?? '';
if (identity?.replyTo?.isNotEmpty == true) {
replyToOfIdentity.value = identity!.replyTo!.first;
listEmailAddress.add(identity!.replyTo!.first);
} else {
replyToOfIdentity.value = noneEmailAddress;
}
if (identity?.bcc?.isNotEmpty == true) {
bccOfIdentity.value = identity!.bcc!.first;
listEmailAddress.add(identity!.bcc!.first);
} else {
bccOfIdentity.value = noneEmailAddress;
}
if (identity?.email?.isNotEmpty == true) {
emailOfIdentity.value = EmailAddress(null, identity?.email!);
listEmailAddress.add(EmailAddress(null, identity?.email!));
}
listEmailAddressOfReplyTo.value = listEmailAddress.toList();
listEmailAddressDefault.value = listEmailAddress
.where((emailAddress) => emailAddress != noneEmailAddress)
.toList();
if (identity?.textSignature?.value.isNotEmpty == true) { if (identity?.textSignature?.value.isNotEmpty == true) {
signaturePlainEditorController.text = identity?.textSignature?.value ?? ''; signaturePlainEditorController.text = identity?.textSignature?.value ?? '';
} }
@@ -143,6 +121,72 @@ class IdentityCreatorController extends BaseController {
} }
} }
void _getAllIdentities() {
if (accountId != null) {
consumeState(_getAllIdentitiesInteractor.execute(
accountId!,
properties: Properties({'email'})
));
}
}
void _getALlIdentitiesSuccess(GetAllIdentitiesSuccess success) {
if (success.identities?.isNotEmpty == true) {
listEmailAddressDefault.value = success.identities
!.map((identity) => identity.toEmailAddressNoName())
.toSet()
.toList();
listEmailAddressOfReplyTo.add(noneEmailAddress);
listEmailAddressOfReplyTo.addAll(listEmailAddressDefault);
_setUpAllFieldEmailAddress();
} else {
_setDefaultEmailAddressList();
}
}
void _getALlIdentitiesFailure(GetAllIdentitiesFailure failure) {
_setDefaultEmailAddressList();
}
void _setDefaultEmailAddressList() {
listEmailAddressOfReplyTo.add(noneEmailAddress);
if (userProfile != null && userProfile?.email.isNotEmpty == true) {
final userEmailAddress = EmailAddress(null, userProfile!.email);
listEmailAddressDefault.add(userEmailAddress);
listEmailAddressOfReplyTo.addAll(listEmailAddressDefault);
}
_setUpAllFieldEmailAddress();
}
void _setUpAllFieldEmailAddress() {
if (actionType.value == IdentityActionType.edit && identity != null) {
replyToOfIdentity.value = identity?.replyTo?.isNotEmpty == true
? identity!.replyTo!.first
: noneEmailAddress;
bccOfIdentity.value = identity?.bcc?.isNotEmpty == true
? identity!.bcc!.first
: noneEmailAddress;
if (identity?.email?.isNotEmpty == true) {
emailOfIdentity.value = EmailAddress(null, identity?.email!);
} else {
emailOfIdentity.value = listEmailAddressDefault.isNotEmpty
? listEmailAddressDefault.first
: null;
}
} else {
replyToOfIdentity.value = noneEmailAddress;
bccOfIdentity.value = noneEmailAddress;
emailOfIdentity.value = listEmailAddressDefault.isNotEmpty
? listEmailAddressDefault.first
: null;
}
}
void selectSignatureType(SignatureType newSignatureType) { void selectSignatureType(SignatureType newSignatureType) {
signatureType.value = newSignatureType; signatureType.value = newSignatureType;
} }
@@ -6,6 +6,7 @@ import 'package:html_editor_enhanced/html_editor.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_controller.dart'; import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_controller.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/model/signature_type.dart'; import 'package:tmail_ui_user/features/identity_creator/presentation/model/signature_type.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_drop_list_field_builder.dart'; import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_drop_list_field_builder.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_field_no_editable_builder.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_input_field_builder.dart'; import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_input_field_builder.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/identity_action_type.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/identity_action_type.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -105,8 +106,13 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Padding( Padding(
padding: const EdgeInsets.only(left: 24, top: 24), padding: const EdgeInsets.only(left: 24, top: 24),
child: Text(AppLocalizations.of(context).new_identity.inCaps, child: Obx(() => Text(controller.actionType.value == IdentityActionType.create
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 24, color: Colors.black))), ? AppLocalizations.of(context).new_identity.inCaps
: AppLocalizations.of(context).edit_identity.inCaps,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 24,
color: Colors.black)))),
const SizedBox(height: 8), const SizedBox(height: 8),
Expanded(child: SingleChildScrollView( Expanded(child: SingleChildScrollView(
physics: const ClampingScrollPhysics(), physics: const ClampingScrollPhysics(),
@@ -115,8 +121,6 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
child: Column(children: [ child: Column(children: [
Row(crossAxisAlignment: CrossAxisAlignment.start, children: [ Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
Expanded(child: Obx(() => (IdentityInputFieldBuilder( Expanded(child: Obx(() => (IdentityInputFieldBuilder(
context,
_responsiveUtils,
AppLocalizations.of(context).name, AppLocalizations.of(context).name,
controller.errorNameIdentity.value, controller.errorNameIdentity.value,
editingController: controller.inputNameIdentityController, editingController: controller.inputNameIdentityController,
@@ -125,14 +129,23 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
..addOnChangeInputNameAction((value) => controller.updateNameIdentity(context, value))) ..addOnChangeInputNameAction((value) => controller.updateNameIdentity(context, value)))
.build())), .build())),
const SizedBox(width: 24), const SizedBox(width: 24),
Expanded(child: Obx(() => (IdentityDropListFieldBuilder( Expanded(child: Obx(() {
_imagePaths, if (controller.actionType.value == IdentityActionType.create) {
return (IdentityDropListFieldBuilder(
_imagePaths,
AppLocalizations.of(context).email.inCaps,
controller.emailOfIdentity.value,
controller.listEmailAddressDefault)
..addOnSelectEmailAddressDropListAction((emailAddress) =>
controller.updateEmailOfIdentity(emailAddress))
).build();
} else {
return IdentityFieldNoEditableBuilder(
AppLocalizations.of(context).email.inCaps, AppLocalizations.of(context).email.inCaps,
controller.emailOfIdentity.value, controller.emailOfIdentity.value
controller.listEmailAddressDefault) ).build();
..addOnSelectEmailAddressDropListAction((emailAddress) => }
controller.updateEmailOfIdentity(emailAddress))) })),
.build())),
]), ]),
const SizedBox(height: 24), const SizedBox(height: 24),
Row(crossAxisAlignment: CrossAxisAlignment.start, children: [ Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
@@ -265,12 +278,14 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
radius: 10, radius: 10,
onTap: () => controller.closeView(context)), onTap: () => controller.closeView(context)),
const SizedBox(width: 12), const SizedBox(width: 12),
buildTextButton( Obx(() => buildTextButton(
AppLocalizations.of(context).create, controller.actionType.value == IdentityActionType.create
? AppLocalizations.of(context).create
: AppLocalizations.of(context).save,
width: 128, width: 128,
height: 44, height: 44,
radius: 10, radius: 10,
onTap: () => controller.createNewIdentity(context)), onTap: () => controller.createNewIdentity(context))),
] ]
), ),
) )
@@ -299,8 +314,6 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
padding: const EdgeInsets.all(24.0), padding: const EdgeInsets.all(24.0),
child: Column(children: [ child: Column(children: [
Obx(() => (IdentityInputFieldBuilder( Obx(() => (IdentityInputFieldBuilder(
context,
_responsiveUtils,
AppLocalizations.of(context).name, AppLocalizations.of(context).name,
controller.errorNameIdentity.value, controller.errorNameIdentity.value,
editingController: controller.inputNameIdentityController, editingController: controller.inputNameIdentityController,
@@ -309,14 +322,23 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
..addOnChangeInputNameAction((value) => controller.updateNameIdentity(context, value))) ..addOnChangeInputNameAction((value) => controller.updateNameIdentity(context, value)))
.build()), .build()),
const SizedBox(height: 24), const SizedBox(height: 24),
Obx(() => (IdentityDropListFieldBuilder( Obx(() {
_imagePaths, if (controller.actionType.value == IdentityActionType.create) {
return (IdentityDropListFieldBuilder(
_imagePaths,
AppLocalizations.of(context).email.inCaps,
controller.emailOfIdentity.value,
controller.listEmailAddressDefault)
..addOnSelectEmailAddressDropListAction((emailAddress) =>
controller.updateEmailOfIdentity(emailAddress))
).build();
} else {
return IdentityFieldNoEditableBuilder(
AppLocalizations.of(context).email.inCaps, AppLocalizations.of(context).email.inCaps,
controller.emailOfIdentity.value, controller.emailOfIdentity.value
controller.listEmailAddressDefault) ).build();
..addOnSelectEmailAddressDropListAction((emailAddress) => }
controller.updateEmailOfIdentity(emailAddress))) }),
.build()),
const SizedBox(height: 24), const SizedBox(height: 24),
Obx(() => (IdentityDropListFieldBuilder( Obx(() => (IdentityDropListFieldBuilder(
_imagePaths, _imagePaths,
@@ -446,7 +468,7 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
const SizedBox(width: 12), const SizedBox(width: 12),
Expanded( Expanded(
child: Obx(() => buildTextButton( child: Obx(() => buildTextButton(
controller.actionType == IdentityActionType.create controller.actionType.value == IdentityActionType.create
? AppLocalizations.of(context).create ? AppLocalizations.of(context).create
: AppLocalizations.of(context).save, : AppLocalizations.of(context).save,
width: 128, width: 128,
@@ -0,0 +1,41 @@
import 'package:core/core.dart';
import 'package:flutter/material.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
class IdentityFieldNoEditableBuilder {
final String _label;
final EmailAddress? _emailAddressSelected;
IdentityFieldNoEditableBuilder(this._label, this._emailAddressSelected);
Widget build() {
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(_label, style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
color: AppColor.colorContentEmail)),
const SizedBox(height: 8),
Container(
height: 44,
alignment: Alignment.center,
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(color: AppColor.colorInputBorderCreateMailbox, width: 0.5),
color: AppColor.colorInputBackgroundCreateMailbox),
child: Text(
_emailAddressSelected?.email ?? '',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
color: AppColor.colorInputBorderCreateMailbox),
maxLines: 1,
overflow: BuildUtils.isWeb ? null : TextOverflow.ellipsis,
)
),
]);
}
}
@@ -7,8 +7,6 @@ typedef OnChangeInputNameAction = Function(String? value);
class IdentityInputFieldBuilder { class IdentityInputFieldBuilder {
final BuildContext _context;
final ResponsiveUtils _responsiveUtils;
final String _label; final String _label;
final String? _error; final String? _error;
final TextEditingController? editingController; final TextEditingController? editingController;
@@ -19,8 +17,6 @@ class IdentityInputFieldBuilder {
OnChangeInputNameAction? onChangeInputNameAction; OnChangeInputNameAction? onChangeInputNameAction;
IdentityInputFieldBuilder( IdentityInputFieldBuilder(
this._context,
this._responsiveUtils,
this._label, this._label,
this._error, { this._error, {
this.isMandatory = false, this.isMandatory = false,
@@ -48,8 +44,8 @@ class IdentityInputFieldBuilder {
..textStyle(const TextStyle(color: Colors.black, fontSize: 16)) ..textStyle(const TextStyle(color: Colors.black, fontSize: 16))
..keyboardType(inputType ?? TextInputType.text) ..keyboardType(inputType ?? TextInputType.text)
..textDecoration((IdentityInputDecorationBuilder() ..textDecoration((IdentityInputDecorationBuilder()
..setContentPadding(EdgeInsets.symmetric( ..setContentPadding(const EdgeInsets.symmetric(
vertical: _responsiveUtils.isDesktop(_context) ? 16 : 12, vertical: BuildUtils.isWeb ? 16 : 12,
horizontal: 12)) horizontal: 12))
..setErrorText(_error)) ..setErrorText(_error))
.build())) .build()))
@@ -1,15 +1,16 @@
import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart'; import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_identity_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_identity_request.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/edit_identity_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/edit_identity_request.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/identities_response.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/identities_response.dart';
abstract class ManageAccountDataSource { abstract class ManageAccountDataSource {
Future<IdentitiesResponse> getAllIdentities(AccountId accountId); Future<IdentitiesResponse> getAllIdentities(AccountId accountId, {Properties? properties});
Future<Identity> createNewIdentity(AccountId accountId, CreateNewIdentityRequest identityRequest); Future<Identity> createNewIdentity(AccountId accountId, CreateNewIdentityRequest identityRequest);
Future<bool> deleteIdentity(AccountId accountId, IdentityId identityId); Future<bool> deleteIdentity(AccountId accountId, IdentityId identityId);
Future<Identity> editIdentity(AccountId accountId, EditIdentityRequest identityRequest); Future<bool> editIdentity(AccountId accountId, EditIdentityRequest editIdentityRequest);
} }
@@ -1,4 +1,5 @@
import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart'; import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:tmail_ui_user/features/manage_account/data/datasource/manage_account_datasource.dart'; import 'package:tmail_ui_user/features/manage_account/data/datasource/manage_account_datasource.dart';
import 'package:tmail_ui_user/features/manage_account/data/network/manage_account_api.dart'; import 'package:tmail_ui_user/features/manage_account/data/network/manage_account_api.dart';
@@ -13,9 +14,9 @@ class ManageAccountDataSourceImpl extends ManageAccountDataSource {
ManageAccountDataSourceImpl(this.manageAccountAPI); ManageAccountDataSourceImpl(this.manageAccountAPI);
@override @override
Future<IdentitiesResponse> getAllIdentities(AccountId accountId) { Future<IdentitiesResponse> getAllIdentities(AccountId accountId, {Properties? properties}) {
return Future.sync(() async { return Future.sync(() async {
return await manageAccountAPI.getAllIdentities(accountId); return await manageAccountAPI.getAllIdentities(accountId, properties: properties);
}).catchError((error) { }).catchError((error) {
throw error; throw error;
}); });
@@ -40,9 +41,9 @@ class ManageAccountDataSourceImpl extends ManageAccountDataSource {
} }
@override @override
Future<Identity> editIdentity(AccountId accountId, EditIdentityRequest identityRequest) { Future<bool> editIdentity(AccountId accountId, EditIdentityRequest editIdentityRequest) {
return Future.sync(() async { return Future.sync(() async {
return await manageAccountAPI.editIdentity(accountId, identityRequest); return await manageAccountAPI.editIdentity(accountId, editIdentityRequest);
}).catchError((error) { }).catchError((error) {
throw error; throw error;
}); });
@@ -3,6 +3,7 @@ import 'dart:async';
import 'package:jmap_dart_client/http/http_client.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/account_id.dart';
import 'package:jmap_dart_client/jmap/core/patch_object.dart'; import 'package:jmap_dart_client/jmap/core/patch_object.dart';
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/identities/get/get_identity_method.dart'; import 'package:jmap_dart_client/jmap/identities/get/get_identity_method.dart';
import 'package:jmap_dart_client/jmap/identities/get/get_identity_response.dart'; import 'package:jmap_dart_client/jmap/identities/get/get_identity_response.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart'; import 'package:jmap_dart_client/jmap/identities/identity.dart';
@@ -19,10 +20,13 @@ class ManageAccountAPI {
ManageAccountAPI(this._httpClient); ManageAccountAPI(this._httpClient);
Future<IdentitiesResponse> getAllIdentities(AccountId accountId) async { Future<IdentitiesResponse> getAllIdentities(AccountId accountId, {Properties? properties}) async {
final processingInvocation = ProcessingInvocation(); final processingInvocation = ProcessingInvocation();
final jmapRequestBuilder = JmapRequestBuilder(_httpClient, processingInvocation); final jmapRequestBuilder = JmapRequestBuilder(_httpClient, processingInvocation);
final getIdentityMethod = GetIdentityMethod(accountId); final getIdentityMethod = GetIdentityMethod(accountId);
if (properties != null) {
getIdentityMethod.addProperties(properties);
}
final queryInvocation = jmapRequestBuilder.invocation(getIdentityMethod); final queryInvocation = jmapRequestBuilder.invocation(getIdentityMethod);
final result = await (jmapRequestBuilder final result = await (jmapRequestBuilder
@@ -85,10 +89,10 @@ class ManageAccountAPI {
}); });
} }
Future<Identity> editIdentity(AccountId accountId, EditIdentityRequest identityRequest) async { Future<bool> editIdentity(AccountId accountId, EditIdentityRequest editIdentityRequest) async {
final setIdentityMethod = SetIdentityMethod(accountId) final setIdentityMethod = SetIdentityMethod(accountId)
..addUpdates({ ..addUpdates({
identityRequest.identityId.id : PatchObject({}) editIdentityRequest.identityId.id : PatchObject(editIdentityRequest.identityRequest.toJson())
}); });
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation()); final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
@@ -105,7 +109,7 @@ class ManageAccountAPI {
SetIdentityResponse.deserialize); SetIdentityResponse.deserialize);
return Future.sync(() async { return Future.sync(() async {
return setIdentityResponse!.updated![identityRequest.identityId]!; return setIdentityResponse?.updated?.containsKey(editIdentityRequest.identityId.id) == true;
}).catchError((error) { }).catchError((error) {
throw error; throw error;
}); });
@@ -1,4 +1,5 @@
import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart'; import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:tmail_ui_user/features/manage_account/data/datasource/manage_account_datasource.dart'; import 'package:tmail_ui_user/features/manage_account/data/datasource/manage_account_datasource.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_identity_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_identity_request.dart';
@@ -13,8 +14,8 @@ class ManageAccountRepositoryImpl extends ManageAccountRepository {
ManageAccountRepositoryImpl(this.dataSource); ManageAccountRepositoryImpl(this.dataSource);
@override @override
Future<IdentitiesResponse> getAllIdentities(AccountId accountId) { Future<IdentitiesResponse> getAllIdentities(AccountId accountId, {Properties? properties}) {
return dataSource.getAllIdentities(accountId); return dataSource.getAllIdentities(accountId, properties: properties);
} }
@override @override
@@ -28,7 +29,7 @@ class ManageAccountRepositoryImpl extends ManageAccountRepository {
} }
@override @override
Future<Identity> editIdentity(AccountId accountId, EditIdentityRequest identityRequest) { Future<bool> editIdentity(AccountId accountId, EditIdentityRequest editIdentityRequest) {
return dataSource.editIdentity(accountId, identityRequest); return dataSource.editIdentity(accountId, editIdentityRequest);
} }
} }
@@ -1,14 +1,15 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart'; import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:model/model.dart';
class EditIdentityRequest with EquatableMixin { class EditIdentityRequest with EquatableMixin {
final Identity newIdentity; final IdentityRequestDto identityRequest;
final IdentityId identityId; final IdentityId identityId;
EditIdentityRequest(this.identityId, this.newIdentity); EditIdentityRequest({required this.identityId, required this.identityRequest});
@override @override
List<Object?> get props => [identityId, newIdentity]; List<Object?> get props => [identityId, identityRequest];
} }
@@ -1,15 +1,16 @@
import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart'; import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_identity_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_identity_request.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/edit_identity_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/edit_identity_request.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/identities_response.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/identities_response.dart';
abstract class ManageAccountRepository { abstract class ManageAccountRepository {
Future<IdentitiesResponse> getAllIdentities(AccountId accountId); Future<IdentitiesResponse> getAllIdentities(AccountId accountId, {Properties? properties});
Future<Identity> createNewIdentity(AccountId accountId, CreateNewIdentityRequest identityRequest); Future<Identity> createNewIdentity(AccountId accountId, CreateNewIdentityRequest identityRequest);
Future<bool> deleteIdentity(AccountId accountId, IdentityId identityId); Future<bool> deleteIdentity(AccountId accountId, IdentityId identityId);
Future<Identity> editIdentity(AccountId accountId, EditIdentityRequest identityRequest); Future<bool> editIdentity(AccountId accountId, EditIdentityRequest editIdentityRequest);
} }
@@ -1,14 +1,11 @@
import 'package:core/core.dart'; import 'package:core/core.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
class EditIdentitySuccess extends UIState { class EditIdentitySuccess extends UIState {
final Identity newIdentity; EditIdentitySuccess();
EditIdentitySuccess(this.newIdentity);
@override @override
List<Object?> get props => [newIdentity]; List<Object?> get props => [];
} }
class EditIdentityFailure extends FeatureFailure { class EditIdentityFailure extends FeatureFailure {
@@ -12,10 +12,13 @@ class EditIdentityInteractor {
EditIdentityInteractor(this.manageAccountRepository); EditIdentityInteractor(this.manageAccountRepository);
Stream<Either<Failure, Success>> execute(AccountId accountId, EditIdentityRequest identityRequest) async* { Stream<Either<Failure, Success>> execute(
AccountId accountId,
EditIdentityRequest editIdentityRequest
) async* {
try { try {
final newIdentity = await manageAccountRepository.editIdentity(accountId, identityRequest); final result = await manageAccountRepository.editIdentity(accountId, editIdentityRequest);
yield Right(EditIdentitySuccess(newIdentity)); yield result ? Right(EditIdentitySuccess()) : Left(EditIdentityFailure(null));
} catch (exception) { } catch (exception) {
yield Left(EditIdentityFailure(exception)); yield Left(EditIdentityFailure(exception));
} }
@@ -3,6 +3,7 @@ import 'dart:core';
import 'package:core/core.dart'; import 'package:core/core.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart'; import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart';
import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_identities_state.dart'; import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_identities_state.dart';
@@ -11,10 +12,10 @@ class GetAllIdentitiesInteractor {
GetAllIdentitiesInteractor(this.manageAccountRepository); GetAllIdentitiesInteractor(this.manageAccountRepository);
Stream<Either<Failure, Success>> execute(AccountId accountId) async* { Stream<Either<Failure, Success>> execute(AccountId accountId, {Properties? properties}) async* {
try { try {
yield Right<Failure, Success>(LoadingState()); yield Right<Failure, Success>(LoadingState());
final identitiesResponse = await manageAccountRepository.getAllIdentities(accountId); final identitiesResponse = await manageAccountRepository.getAllIdentities(accountId, properties: properties);
yield Right(GetAllIdentitiesSuccess(identitiesResponse.identities, identitiesResponse.state)); yield Right(GetAllIdentitiesSuccess(identitiesResponse.identities, identitiesResponse.state));
} catch (exception) { } catch (exception) {
yield Left(GetAllIdentitiesFailure(exception)); yield Left(GetAllIdentitiesFailure(exception));
@@ -1,12 +1,13 @@
import 'package:core/core.dart'; import 'package:core/core.dart';
import 'package:model/model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/account_id.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/id.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart'; import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:model/extensions/identity_extension.dart';
import 'package:model/extensions/list_identities_extension.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart'; import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/model/identity_creator_arguments.dart'; import 'package:tmail_ui_user/features/identity_creator/presentation/model/identity_creator_arguments.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_identity_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_identity_request.dart';
@@ -296,16 +297,23 @@ class IdentitiesController extends BaseController {
identity: identity, identity: identity,
actionType: IdentityActionType.edit)); actionType: IdentityActionType.edit));
log('IdentitiesController::goToEditIdentity(): $newIdentity'); if (newIdentity is Identity) {
_editIdentityAction(accountId, newIdentity); log('IdentitiesController::goToEditIdentity(): $newIdentity');
_editIdentityAction(accountId, EditIdentityRequest(
identityId: identity.id!,
identityRequest: newIdentity.toIdentityRequest()
));
}
} }
} }
void _editIdentityAction(AccountId accountId, EditIdentityRequest identityRequest) async { void _editIdentityAction(AccountId accountId, EditIdentityRequest editIdentityRequest) async {
consumeState(_editIdentityInteractor.execute(accountId, identityRequest)); log('IdentitiesController::_editIdentityAction(): $editIdentityRequest');
consumeState(_editIdentityInteractor.execute(accountId, editIdentityRequest));
} }
void _editIdentitySuccess(EditIdentitySuccess success) { void _editIdentitySuccess(EditIdentitySuccess success) {
log('IdentitiesController::_editIdentitySuccess(): $success');
if (currentOverlayContext != null && currentContext != null) { if (currentOverlayContext != null && currentContext != null) {
_appToast.showToastWithIcon( _appToast.showToastWithIcon(
currentOverlayContext!, currentOverlayContext!,
@@ -0,0 +1,15 @@
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/identity/identity_request_dto.dart';
extension IdentityExtension on Identity {
EmailAddress toEmailAddressNoName() => EmailAddress(null, email);
IdentityRequestDto toIdentityRequest() => IdentityRequestDto(
name: name,
replyTo: replyTo,
bcc: bcc,
textSignature: textSignature,
htmlSignature: htmlSignature);
}
@@ -0,0 +1,51 @@
import 'package:equatable/equatable.dart';
import 'package:jmap_dart_client/http/converter/identities/identity_id_nullable_converter.dart';
import 'package:jmap_dart_client/http/converter/identities/signature_nullable_converter.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:json_annotation/json_annotation.dart';
part 'identity_request_dto.g.dart';
@IdentityIdNullableConverter()
@SignatureNullableConverter()
@JsonSerializable()
class IdentityRequestDto with EquatableMixin {
@JsonKey(includeIfNull: false)
final String? name;
@JsonKey(includeIfNull: false)
final Set<EmailAddress>? bcc;
@JsonKey(includeIfNull: false)
final Set<EmailAddress>? replyTo;
@JsonKey(includeIfNull: false)
final Signature? textSignature;
@JsonKey(includeIfNull: false)
final Signature? htmlSignature;
IdentityRequestDto({
this.name,
this.bcc,
this.replyTo,
this.textSignature,
this.htmlSignature,
});
factory IdentityRequestDto.fromJson(Map<String, dynamic> json) => _$IdentityRequestDtoFromJson(json);
Map<String, dynamic> toJson() => _$IdentityRequestDtoToJson(this);
@override
List<Object?> get props => [
name,
bcc,
replyTo,
textSignature,
htmlSignature,
];
}
+4
View File
@@ -56,6 +56,7 @@ export 'extensions/list_attachment_extension.dart';
export 'extensions/list_presentation_email_extension.dart'; export 'extensions/list_presentation_email_extension.dart';
export 'extensions/list_email_content_extension.dart'; export 'extensions/list_email_content_extension.dart';
export 'extensions/list_identities_extension.dart'; export 'extensions/list_identities_extension.dart';
export 'extensions/identity_extension.dart';
// Download // Download
export 'download/download_task_id.dart'; export 'download/download_task_id.dart';
@@ -71,3 +72,6 @@ export 'upload/upload_response.dart';
// AutoComplete // AutoComplete
export 'autocomplete/auto_complete_pattern.dart'; export 'autocomplete/auto_complete_pattern.dart';
// Identity
export 'identity/identity_request_dto.dart';