TF-831: implement Add a new recipient in forwarding

This commit is contained in:
ManhNTX
2022-08-20 20:45:27 +07:00
committed by Dat H. Pham
parent 04b530a4b9
commit 3c85f1d5ed
29 changed files with 615 additions and 536 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
SERVER_URL=https://gateway.upn.integration-open-paas.org SERVER_URL=http://localhost
DOMAIN_REDIRECT_URL=http://localhost:3000 DOMAIN_REDIRECT_URL=http://localhost:3000
WEB_OIDC_CLIENT_ID=teammail-web WEB_OIDC_CLIENT_ID=teammail-web
-2
View File
@@ -1,6 +1,4 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:forward/forward/converter/forward_id_coverter.dart';
import 'package:jmap_dart_client/http/converter/id_converter.dart';
import 'package:jmap_dart_client/jmap/core/id.dart'; import 'package:jmap_dart_client/jmap/core/id.dart';
enum ForwardIdType { enum ForwardIdType {
@@ -12,7 +12,7 @@ import 'package:tmail_ui_user/features/composer/domain/repository/contact_reposi
import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_interactor.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_with_device_contact_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_with_device_contact_interactor.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/get_device_contact_suggestions_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/get_device_contact_suggestions_interactor.dart';
import 'package:tmail_ui_user/features/mails_forward_creator/presentation/emails_forward_creator_controller.dart'; import 'package:tmail_ui_user/features/emails_forward_creator/presentation/emails_forward_creator_controller.dart';
class EmailsForwardCreatorBindings extends BaseBindings { class EmailsForwardCreatorBindings extends BaseBindings {
@@ -1,6 +1,7 @@
import 'package:core/utils/app_logger.dart'; import 'package:core/utils/app_logger.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.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/session/session.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart';
@@ -11,7 +12,8 @@ import 'package:tmail_ui_user/features/composer/domain/model/contact_suggestion_
import 'package:tmail_ui_user/features/composer/domain/state/get_autocomplete_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/get_autocomplete_state.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_interactor.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_with_device_contact_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_with_device_contact_interactor.dart';
import 'package:tmail_ui_user/features/mails_forward_creator/presentation/model/mails_forward_creator_arguments.dart'; import 'package:tmail_ui_user/features/emails_forward_creator/presentation/model/mails_forward_creator_arguments.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/forward/forward_controller.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/session_extension.dart'; import 'package:tmail_ui_user/features/composer/presentation/extensions/session_extension.dart';
@@ -19,18 +21,19 @@ class EmailsForwardCreatorController extends BaseController {
final inputEmailForwardController = TextEditingController(); final inputEmailForwardController = TextEditingController();
final ContactSuggestionSource _contactSuggestionSource = ContactSuggestionSource.tMailContact; final ContactSuggestionSource _contactSuggestionSource = ContactSuggestionSource.tMailContact;
final _forwardController = Get.find<ForwardController>();
late AccountId _accountId; late AccountId _accountId;
late Session? _session; late Session? _session;
late GetAutoCompleteWithDeviceContactInteractor _getAutoCompleteWithDeviceContactInteractor; late GetAutoCompleteWithDeviceContactInteractor _getAutoCompleteWithDeviceContactInteractor;
late GetAutoCompleteInteractor _getAutoCompleteInteractor; late GetAutoCompleteInteractor _getAutoCompleteInteractor;
final listEmailForwards = <EmailAddress>[].obs; final listEmailForwards = RxSet<EmailAddress>();
EmailsForwardCreatorController( EmailsForwardCreatorController(
this._getAutoCompleteWithDeviceContactInteractor, this._getAutoCompleteWithDeviceContactInteractor,
this._getAutoCompleteInteractor, this._getAutoCompleteInteractor,
); );
@override @override
void onReady() { void onReady() {
@@ -91,14 +94,33 @@ class EmailsForwardCreatorController extends BaseController {
inputEmailForwardController.clear(); inputEmailForwardController.clear();
} }
void _clearListEmailForwards() {
listEmailForwards.clear();
}
void closeView(BuildContext context) { void closeView(BuildContext context) {
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
popBack(); if(kIsWeb) {
_clearListEmailForwards();
_forwardController.accountDashBoardController.emailsForwardCreatorIsActive.toggle();
} else {
popBack();
}
} }
void addEmailForwards(BuildContext context) { void addEmailForwards(BuildContext context) {
inputEmailForwardController.clear();
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
popBack(result: listEmailForwards.toList()); if(inputEmailForwardController.text.trim().isNotEmpty) {
listEmailForwards.add(EmailAddress(null, inputEmailForwardController.text.trim()));
}
inputEmailForwardController.clear();
if(kIsWeb) {
_forwardController.accountDashBoardController.emailsForwardCreatorIsActive.toggle();
_forwardController.handleAddRecipients(listEmailForwards.toList());
_clearListEmailForwards();
} else {
popBack(result: listEmailForwards.toList());
}
} }
} }
@@ -0,0 +1,203 @@
import 'package:core/core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/model.dart';
import 'package:tmail_ui_user/features/emails_forward_creator/presentation/emails_forward_creator_controller.dart';
import 'package:tmail_ui_user/features/emails_forward_creator/presentation/widgets/email_forward_creator_item_widget.dart';
import 'package:tmail_ui_user/features/emails_forward_creator/presentation/widgets/emails_forward_input_with_drop_list_field_builder.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class EmailsForwardCreatorView extends GetWidget<EmailsForwardCreatorController> {
final _imagePaths = Get.find<ImagePaths>();
final _responsiveUtils = Get.find<ResponsiveUtils>();
EmailsForwardCreatorView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ResponsiveWidget(
responsiveUtils: _responsiveUtils,
mobile: Scaffold(
backgroundColor: Colors.black38,
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: SafeArea(
child: Align(
alignment: Alignment.bottomCenter,
child: Card(
color: Colors.transparent,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
)),
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
)),
width: double.infinity,
height: _responsiveUtils.getSizeScreenHeight(context) - 70,
child: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16)),
child: _buildEmailForwardCreatorList(context)
)
)
)
),
),
)
),
tablet: Scaffold(
backgroundColor: Colors.black38,
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Align(alignment: Alignment.bottomCenter, child: Card(
color: Colors.transparent,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
)),
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
)),
width: double.infinity,
height: _responsiveUtils.getSizeScreenHeight(context) * 0.7,
child: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16)),
child: _buildEmailForwardCreatorList(context)
)
)
)),
)
),
desktop: Scaffold(
backgroundColor: Colors.black38,
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Align(alignment: Alignment.center, child: Card(
color: Colors.transparent,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(16))),
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(16))),
width: _responsiveUtils.getSizeScreenWidth(context) * 0.6,
height: _responsiveUtils.getSizeScreenHeight(context) * 0.7,
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(16)),
child: _buildEmailForwardCreatorList(context)
)
)
)
),
)
)
);
}
Widget _buildEmailForwardCreatorList(BuildContext context) {
return Stack(
children: [
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Container(
padding: const EdgeInsets.only(top: 16),
alignment: Alignment.center,
child: Text(
AppLocalizations.of(context).addRecipients,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.black))),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: (EmailsForwardInputWithDropListFieldBuilder(
AppLocalizations.of(context).recipientsLabel,
controller.inputEmailForwardController)
..addOnSelectedSuggestionAction((newEmailAddress) {
controller.addToListEmailForwards(newEmailAddress);
controller.clearAll();
})
..addOnSummitedCallbackAction((pattern) {
if (pattern != null && pattern.trim().isNotEmpty) {
controller.addToListEmailForwards(EmailAddress(null, pattern.trim()));
controller.clearAll();
}
})
..addOnSuggestionCallbackAction((pattern) {
if (pattern != null) {
controller.getAutoCompleteSuggestion(word: pattern.trim());
}
}))
.build(),
),
Expanded(
child: Obx(() => ListView.builder(
itemCount: controller.listEmailForwards.length,
itemBuilder: (BuildContext context, int index) {
final item = controller.listEmailForwards.toList()[index];
return EmailForwardCreatorItemWidget(
emailForward: item.emailAddress,
onDelete: () {
controller.listEmailForwards.remove(item);
}
);
},
)),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
child: _buildButtonAddNewEmailsForward(context),
),
]),
Positioned(top: 8, right: 8,
child: buildIconWeb(
icon: SvgPicture.asset(
_imagePaths.icCloseMailbox,
fit: BoxFit.fill),
tooltip: AppLocalizations.of(context).close,
onTap: () => controller.closeView(context)))
],
);
}
Widget _buildButtonAddNewEmailsForward(BuildContext context) {
return (ButtonBuilder(_imagePaths.icAddEmailForward)
..key(const Key('button_add_emails_forward_creator'))
..decoration(BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: AppColor.colorTextButton))
..paddingIcon(const EdgeInsets.only(right: 8))
..iconColor(Colors.white)
..size(20)
..radiusSplash(10)
..padding(const EdgeInsets.symmetric(vertical: 12))
..textStyle(const TextStyle(
fontSize: 17,
color: Colors.white,
fontWeight: FontWeight.w500,
))
..onPressActionClick(() => controller.addEmailForwards(context))
..text(
AppLocalizations.of(context).addRecipients,
isVertical: false,
))
.build();
}
}
@@ -4,7 +4,6 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
class EmailForwardCreatorItemWidget extends StatelessWidget { class EmailForwardCreatorItemWidget extends StatelessWidget {
final _responsiveUtils = Get.find<ResponsiveUtils>();
final _imagePaths = Get.find<ImagePaths>(); final _imagePaths = Get.find<ImagePaths>();
final VoidCallback onDelete; final VoidCallback onDelete;
final String emailForward; final String emailForward;
@@ -18,19 +17,25 @@ class EmailForwardCreatorItemWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
padding: EdgeInsets.only( padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
top: 15,
bottom: 15,
left: _responsiveUtils.isMobile(context) ? 16 : 24,
right: _responsiveUtils.isMobile(context) ? 0 : 24),
color: Colors.white, color: Colors.white,
child: Row(crossAxisAlignment: CrossAxisAlignment.center, children: [ child: Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
Text(emailForward, CircleAvatar(
backgroundColor: AppColor.colorTextButton,
radius: 16,
child: Text(emailForward[0].toUpperCase(),
style: const TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.w500))),
const SizedBox(width: 10),
Expanded(child: Text(emailForward,
overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap,
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: Colors.black)), color: Colors.black))),
const Spacer(),
buildIconWeb( buildIconWeb(
icon: SvgPicture.asset( icon: SvgPicture.asset(
_imagePaths.icDeleteEmailAddress, _imagePaths.icDeleteEmailAddress,
@@ -3,13 +3,12 @@ import 'package:core/core.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart'; import 'package:flutter_typeahead/flutter_typeahead.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:tmail_ui_user/features/mails_forward_creator/presentation/widgets/emails_forward_input_decoration_builder.dart'; import 'package:tmail_ui_user/features/emails_forward_creator/presentation/widgets/emails_forward_input_decoration_builder.dart';
typedef OnSelectedSuggestionAction = Function(EmailAddress emailAddress); typedef OnSelectedSuggestionAction = Function(EmailAddress emailAddress);
typedef OnSuggestionCallbackAction = Function(String? pattern); typedef OnSuggestionCallbackAction = Function(String? pattern);
typedef OnSummitedCallbackAction = Function(String? pattern); typedef OnSummitedCallbackAction = Function(String? pattern);
class EmailsForwardInputWithDropListFieldBuilder { class EmailsForwardInputWithDropListFieldBuilder {
final String hintText; final String hintText;
@@ -1,313 +0,0 @@
import 'package:core/core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/model.dart';
import 'package:tmail_ui_user/features/mails_forward_creator/presentation/emails_forward_creator_controller.dart';
import 'package:tmail_ui_user/features/mails_forward_creator/presentation/widgets/email_forward_creator_item_widget.dart';
import 'package:tmail_ui_user/features/mails_forward_creator/presentation/widgets/emails_forward_input_with_drop_list_field_builder.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class EmailsForwardCreatorView extends GetWidget<EmailsForwardCreatorController> {
final _imagePaths = Get.find<ImagePaths>();
final _responsiveUtils = Get.find<ResponsiveUtils>();
EmailsForwardCreatorView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ResponsiveWidget(
responsiveUtils: _responsiveUtils,
mobile: Scaffold(
backgroundColor: Colors.black38,
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: SafeArea(
child: Align(
alignment: Alignment.bottomCenter,
child: Card(
color: Colors.transparent,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
)),
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
)),
width: double.infinity,
height: _responsiveUtils.getSizeScreenHeight(context) - 70,
child: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16)),
child: _buildRulesFilterFormOnMobile(context)
)
)
)
),
),
)
),
tablet: Scaffold(
backgroundColor: Colors.black38,
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Align(alignment: Alignment.bottomCenter, child: Card(
color: Colors.transparent,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
)),
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
)),
width: double.infinity,
height: _responsiveUtils.getSizeScreenHeight(context) * 0.7,
child: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16)),
child: _buildRulesFilterFormOnTablet(context)
)
)
)),
)
),
desktop: Scaffold(
backgroundColor: Colors.black38,
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Align(alignment: Alignment.center, child: Card(
color: Colors.transparent,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(16))),
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(16))),
width: _responsiveUtils.getSizeScreenWidth(context) * 0.6,
height: _responsiveUtils.getSizeScreenHeight(context) * 0.7,
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(16)),
child: _buildRulesFilterFormOnDesktop(context)
)
)
)
),
)
)
);
}
Widget _buildRulesFilterFormOnDesktop(BuildContext context) {
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Align(
alignment: Alignment.centerRight,
child: buildIconWeb(
icon: SvgPicture.asset(
_imagePaths.icCloseMailbox,
fit: BoxFit.fill),
tooltip: AppLocalizations.of(context).close,
onTap: () => controller.closeView(context)),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: (EmailsForwardInputWithDropListFieldBuilder(
AppLocalizations.of(context).emailForwardLabel,
controller.inputEmailForwardController)
..addOnSelectedSuggestionAction((newEmailAddress) {
controller.addToListEmailForwards(newEmailAddress);
controller.clearAll();
})
..addOnSummitedCallbackAction((pattern) {
if (pattern != null && pattern.trim().isNotEmpty) {
controller.addToListEmailForwards(EmailAddress(null, pattern.trim()));
controller.clearAll();
}
})
..addOnSuggestionCallbackAction((pattern) {
if (pattern != null) {
controller.getAutoCompleteSuggestion(word: pattern.trim());
}
}))
.build(),
),
Expanded(
child: Obx(() => ListView.builder(
itemCount: controller.listEmailForwards.length,
itemBuilder: (BuildContext context, int index) {
final item = controller.listEmailForwards[index];
return EmailForwardCreatorItemWidget(
emailForward: item.emailAddress,
onDelete: () {
controller.listEmailForwards.removeAt(index);
}
);
},
)),
),
]);
}
Widget _buildRulesFilterFormOnTablet(BuildContext context) {
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Align(
alignment: Alignment.centerRight,
child: buildIconWeb(
icon: SvgPicture.asset(
_imagePaths.icCloseMailbox,
fit: BoxFit.fill),
tooltip: AppLocalizations.of(context).close,
onTap: () => controller.closeView(context)),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: (EmailsForwardInputWithDropListFieldBuilder(
AppLocalizations.of(context).emailForwardLabel,
controller.inputEmailForwardController)
..addOnSelectedSuggestionAction((newEmailAddress) {
controller.addToListEmailForwards(newEmailAddress);
controller.clearAll();
})
..addOnSummitedCallbackAction((pattern) {
if (pattern != null && pattern.trim().isNotEmpty) {
controller.addToListEmailForwards(EmailAddress(null, pattern.trim()));
controller.clearAll();
}
})
..addOnSuggestionCallbackAction((pattern) {
if (pattern != null) {
controller.getAutoCompleteSuggestion(word: pattern.trim());
}
}))
.build(),
),
Expanded(
child: Obx(() => ListView.builder(
itemCount: controller.listEmailForwards.length,
itemBuilder: (BuildContext context, int index) {
final item = controller.listEmailForwards[index];
return EmailForwardCreatorItemWidget(
emailForward: item.emailAddress,
onDelete: () {
controller.listEmailForwards.removeAt(index);
}
);
},
)),
),
]);
}
Widget _buildRulesFilterFormOnMobile(BuildContext context) {
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Align(
alignment: Alignment.centerRight,
child: buildIconWeb(
icon: SvgPicture.asset(
_imagePaths.icCloseMailbox,
fit: BoxFit.fill),
tooltip: AppLocalizations.of(context).close,
onTap: () => controller.closeView(context)),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: (EmailsForwardInputWithDropListFieldBuilder(
AppLocalizations.of(context).emailForwardLabel,
controller.inputEmailForwardController)
..addOnSelectedSuggestionAction((newEmailAddress) {
controller.addToListEmailForwards(newEmailAddress);
controller.clearAll();
})
..addOnSummitedCallbackAction((pattern) {
if (pattern != null && pattern.trim().isNotEmpty) {
controller.addToListEmailForwards(EmailAddress(null, pattern.trim()));
controller.clearAll();
}
})
..addOnSuggestionCallbackAction((pattern) {
if (pattern != null) {
controller.getAutoCompleteSuggestion(word: pattern.trim());
}
}))
.build(),
),
Expanded(
child: Obx(() => ListView.builder(
itemCount: controller.listEmailForwards.length,
itemBuilder: (BuildContext context, int index) {
final item = controller.listEmailForwards[index];
return EmailForwardCreatorItemWidget(
emailForward: item.emailAddress,
onDelete: () {
controller.listEmailForwards.removeAt(index);
}
);
},
)),
),
]);
}
Widget _buildButtonAddNewEmailsForward(BuildContext context) {
if (!_responsiveUtils.isMobile(context)) {
return (ButtonBuilder(_imagePaths.icAddEmailForward)
..key(const Key('button_add_emails_forward_creator'))
..decoration(BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: AppColor.colorTextButton))
..paddingIcon(const EdgeInsets.only(right: 8))
..iconColor(Colors.white)
..maxWidth(130)
..size(20)
..radiusSplash(10)
..padding(const EdgeInsets.symmetric(vertical: 12))
..textStyle(const TextStyle(
fontSize: 17,
color: Colors.white,
fontWeight: FontWeight.w500,
))
..onPressActionClick(() => controller.addEmailForwards(context))
..text(
AppLocalizations.of(context).addEmailForward,
isVertical: false,
))
.build();
} else {
return (ButtonBuilder(_imagePaths.icAddEmailForward)
..key(const Key('button_add_emails_forward_creator'))
..decoration(BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: AppColor.colorTextButton))
..paddingIcon(const EdgeInsets.only(right: 8))
..iconColor(Colors.white)
..size(20)
..radiusSplash(10)
..padding(const EdgeInsets.symmetric(vertical: 12))
..textStyle(const TextStyle(
fontSize: 17,
color: Colors.white,
fontWeight: FontWeight.w500,
))
..onPressActionClick(() => controller.addEmailForwards(context))
..text(
AppLocalizations.of(context).addEmailForward,
isVertical: false,
))
.build();
}
}
}
@@ -6,6 +6,7 @@ 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/vacation/vacation_response.dart'; import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart';
import 'package:rule_filter/rule_filter/tmail_rule.dart'; import 'package:rule_filter/rule_filter/tmail_rule.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/add_recipients_in_forwarding_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/create_new_identity_request.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/delete_email_rule_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/delete_email_rule_request.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_email_rule_filter_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_email_rule_filter_request.dart';
@@ -40,4 +41,7 @@ abstract class ManageAccountDataSource {
Future<List<VacationResponse>> updateVacation(AccountId accountId, VacationResponse vacationResponse); Future<List<VacationResponse>> updateVacation(AccountId accountId, VacationResponse vacationResponse);
Future<TMailForward> deleteRecipientInForwarding(AccountId accountId, DeleteRecipientInForwardingRequest deleteRequest); Future<TMailForward> deleteRecipientInForwarding(AccountId accountId, DeleteRecipientInForwardingRequest deleteRequest);
Future<TMailForward> addRecipientsInForwarding(AccountId accountId, AddRecipientInForwardingRequest addRequest);
} }
@@ -9,6 +9,7 @@ import 'package:rule_filter/rule_filter/tmail_rule.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/local/language_cache_manager.dart'; import 'package:tmail_ui_user/features/manage_account/data/local/language_cache_manager.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';
import 'package:tmail_ui_user/features/manage_account/domain/model/add_recipients_in_forwarding_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/create_new_identity_request.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/delete_email_rule_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/delete_email_rule_request.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_email_rule_filter_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_email_rule_filter_request.dart';
@@ -145,4 +146,13 @@ class ManageAccountDataSourceImpl extends ManageAccountDataSource {
throw error; throw error;
}); });
} }
@override
Future<TMailForward> addRecipientsInForwarding(AccountId accountId, AddRecipientInForwardingRequest addRequest) {
return Future.sync(() async {
return await manageAccountAPI.updateForward(accountId, addRequest.newTMailForward);
}).catchError((error) {
throw error;
});
}
} }
@@ -7,6 +7,7 @@ import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart'; import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart';
import 'package:rule_filter/rule_filter/tmail_rule.dart'; import 'package:rule_filter/rule_filter/tmail_rule.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/add_recipients_in_forwarding_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/create_new_identity_request.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/delete_email_rule_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/delete_email_rule_request.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_email_rule_filter_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_email_rule_filter_request.dart';
@@ -88,7 +89,7 @@ class ManageAccountRepositoryImpl extends ManageAccountRepository {
} }
@override @override
Future<TMailForward> updateForward(AccountId accountId, TMailForward forward) { Future<TMailForward> addRecipientsInForwarding(AccountId accountId, AddRecipientInForwardingRequest addRequest) {
return dataSource.updateForward(accountId, forward); return dataSource.addRecipientsInForwarding(accountId, addRequest);
} }
} }
@@ -0,0 +1,23 @@
import 'package:equatable/equatable.dart';
import 'package:forward/forward/tmail_forward.dart';
class AddRecipientInForwardingRequest with EquatableMixin {
final TMailForward currentForward;
final Set<String> listRecipientAdded;
AddRecipientInForwardingRequest({
required this.currentForward,
required this.listRecipientAdded,
});
TMailForward get newTMailForward {
final newListRecipients = currentForward.forwards
.where((recipient) => !listRecipientAdded.contains(recipient))
.toSet();
newListRecipients.addAll(listRecipientAdded);
return currentForward.copyWith(forwards: newListRecipients);
}
@override
List<Object?> get props => [currentForward, listRecipientAdded];
}
@@ -6,6 +6,7 @@ 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/vacation/vacation_response.dart'; import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart';
import 'package:rule_filter/rule_filter/tmail_rule.dart'; import 'package:rule_filter/rule_filter/tmail_rule.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/add_recipients_in_forwarding_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/create_new_identity_request.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/delete_email_rule_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/delete_email_rule_request.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_email_rule_filter_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_email_rule_filter_request.dart';
@@ -40,4 +41,6 @@ abstract class ManageAccountRepository {
Future<List<VacationResponse>> updateVacation(AccountId accountId, VacationResponse vacationResponse); Future<List<VacationResponse>> updateVacation(AccountId accountId, VacationResponse vacationResponse);
Future<TMailForward> deleteRecipientInForwarding(AccountId accountId, DeleteRecipientInForwardingRequest deleteRequest); Future<TMailForward> deleteRecipientInForwarding(AccountId accountId, DeleteRecipientInForwardingRequest deleteRequest);
Future<TMailForward> addRecipientsInForwarding(AccountId accountId, AddRecipientInForwardingRequest addRequest);
} }
@@ -0,0 +1,21 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:forward/forward/tmail_forward.dart';
class AddRecipientsInForwardingSuccess extends UIState {
final TMailForward forward;
AddRecipientsInForwardingSuccess(this.forward);
@override
List<Object?> get props => [forward];
}
class AddRecipientsInForwardingFailure extends FeatureFailure {
final dynamic exception;
AddRecipientsInForwardingFailure(this.exception);
@override
List<Object> get props => [exception];
}
@@ -0,0 +1,28 @@
import 'dart:core';
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:tmail_ui_user/features/manage_account/domain/model/add_recipients_in_forwarding_request.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/add_recipient_in_forwarding_state.dart';
class AddRecipientsInForwardingInteractor {
final ManageAccountRepository manageAccountRepository;
AddRecipientsInForwardingInteractor(this.manageAccountRepository);
Stream<Either<Failure, Success>> execute(
AccountId accountId,
AddRecipientInForwardingRequest addRequest,
) async* {
try {
yield Right<Failure, Success>(LoadingState());
final result = await manageAccountRepository.addRecipientsInForwarding(accountId, addRequest);
yield Right<Failure, Success>(AddRecipientsInForwardingSuccess(result));
} catch (exception) {
yield Left<Failure, Success>(AddRecipientsInForwardingFailure(exception));
}
}
}
@@ -1,6 +1,7 @@
import 'package:get/get.dart'; 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/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/usecases/add_recipients_in_forwarding_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/delete_recipient_in_forwarding_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/delete_recipient_in_forwarding_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_forward_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_forward_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/forward/forward_controller.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/forward/forward_controller.dart';
@@ -12,6 +13,7 @@ class ForwardBindings extends BaseBindings {
Get.lazyPut(() => ForwardController( Get.lazyPut(() => ForwardController(
Get.find<GetForwardInteractor>(), Get.find<GetForwardInteractor>(),
Get.find<DeleteRecipientInForwardingInteractor>(), Get.find<DeleteRecipientInForwardingInteractor>(),
Get.find<AddRecipientsInForwardingInteractor>(),
)); ));
} }
@@ -25,6 +27,7 @@ class ForwardBindings extends BaseBindings {
void bindingsInteractor() { void bindingsInteractor() {
Get.lazyPut(() => GetForwardInteractor(Get.find<ManageAccountRepository>())); Get.lazyPut(() => GetForwardInteractor(Get.find<ManageAccountRepository>()));
Get.lazyPut(() => DeleteRecipientInForwardingInteractor(Get.find<ManageAccountRepository>())); Get.lazyPut(() => DeleteRecipientInForwardingInteractor(Get.find<ManageAccountRepository>()));
Get.lazyPut(() => AddRecipientsInForwardingInteractor(Get.find<ManageAccountRepository>()));
} }
@override @override
@@ -4,19 +4,24 @@ import 'package:core/presentation/utils/app_toast.dart';
import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart'; import 'package:core/presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart';
import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart'; import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart';
import 'package:flutter/foundation.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:forward/forward/tmail_forward.dart'; import 'package:forward/forward/tmail_forward.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:model/extensions/email_address_extension.dart';
import 'package:model/mailbox/select_mode.dart'; import 'package:model/mailbox/select_mode.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart'; import 'package:pointer_interceptor/pointer_interceptor.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/emails_forward_creator/presentation/emails_forward_creator_binding.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/add_recipients_in_forwarding_request.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/delete_recipient_in_forwarding_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/delete_recipient_in_forwarding_request.dart';
import 'package:tmail_ui_user/features/manage_account/domain/state/add_recipient_in_forwarding_state.dart';
import 'package:tmail_ui_user/features/manage_account/domain/state/delete_recipient_in_forwarding_state.dart'; import 'package:tmail_ui_user/features/manage_account/domain/state/delete_recipient_in_forwarding_state.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:tmail_ui_user/features/base/base_controller.dart'; import 'package:tmail_ui_user/features/emails_forward_creator/presentation/model/mails_forward_creator_arguments.dart';
import 'package:tmail_ui_user/features/mails_forward_creator/presentation/model/mails_forward_creator_arguments.dart';
import 'package:tmail_ui_user/features/manage_account/domain/state/get_forward_state.dart'; import 'package:tmail_ui_user/features/manage_account/domain/state/get_forward_state.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/add_recipients_in_forwarding_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/delete_recipient_in_forwarding_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/delete_recipient_in_forwarding_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_forward_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_forward_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/tmail_forward_extension.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/extensions/tmail_forward_extension.dart';
@@ -30,8 +35,9 @@ class ForwardController extends BaseController {
final GetForwardInteractor _getForwardInteractor; final GetForwardInteractor _getForwardInteractor;
final DeleteRecipientInForwardingInteractor _deleteRecipientInForwardingInteractor; final DeleteRecipientInForwardingInteractor _deleteRecipientInForwardingInteractor;
final AddRecipientsInForwardingInteractor _addRecipientsInForwardingInteractor;
final _accountDashBoardController = Get.find<ManageAccountDashBoardController>(); final accountDashBoardController = Get.find<ManageAccountDashBoardController>();
final _responsiveUtils = Get.find<ResponsiveUtils>(); final _responsiveUtils = Get.find<ResponsiveUtils>();
final _imagePaths = Get.find<ImagePaths>(); final _imagePaths = Get.find<ImagePaths>();
final _appToast = Get.find<AppToast>(); final _appToast = Get.find<AppToast>();
@@ -41,9 +47,12 @@ class ForwardController extends BaseController {
TMailForward? currentForward; TMailForward? currentForward;
final listForwards = <String>[].obs;
ForwardController( ForwardController(
this._getForwardInteractor, this._getForwardInteractor,
this._deleteRecipientInForwardingInteractor, this._deleteRecipientInForwardingInteractor,
this._addRecipientsInForwardingInteractor,
); );
@override @override
@@ -60,6 +69,8 @@ class ForwardController extends BaseController {
listRecipientForward.value = currentForward!.listRecipientForward; listRecipientForward.value = currentForward!.listRecipientForward;
} else if (success is DeleteRecipientInForwardingSuccess) { } else if (success is DeleteRecipientInForwardingSuccess) {
_handleDeleteRecipientSuccess(success); _handleDeleteRecipientSuccess(success);
} else if (success is AddRecipientsInForwardingSuccess) {
_handleAddRecipientsSuccess(success);
} }
}); });
} }
@@ -74,7 +85,7 @@ class ForwardController extends BaseController {
} }
void _getForward() { void _getForward() {
consumeState(_getForwardInteractor.execute(_accountDashBoardController.accountId.value!)); consumeState(_getForwardInteractor.execute(accountDashBoardController.accountId.value!));
} }
void deleteRecipients(BuildContext context, String emailAddress) { void deleteRecipients(BuildContext context, String emailAddress) {
@@ -116,7 +127,7 @@ class ForwardController extends BaseController {
void _handleDeleteRecipientAction(Set<String> listRecipients) { void _handleDeleteRecipientAction(Set<String> listRecipients) {
popBack(); popBack();
final accountId = _accountDashBoardController.accountId.value; final accountId = accountDashBoardController.accountId.value;
if (accountId != null && currentForward != null) { if (accountId != null && currentForward != null) {
consumeState(_deleteRecipientInForwardingInteractor.execute( consumeState(_deleteRecipientInForwardingInteractor.execute(
accountId, accountId,
@@ -217,19 +228,48 @@ class ForwardController extends BaseController {
} }
void goToAddEmailsForward() async { void goToAddEmailsForward() async {
final accountId = _accountDashBoardController.accountId.value; final accountId = accountDashBoardController.accountId.value;
if (accountId != null) { if (accountId != null) {
final listEmail = await push( if(kIsWeb) {
AppRoutes.EMAILS_FORWARD_CREATOR, _openMailsForwardCreatorOverlay();
arguments: MailsForwardCreatorArguments(accountId, _accountDashBoardController.sessionCurrent.value)); } else {
final listEmail = await push(
AppRoutes.EMAILS_FORWARD_CREATOR,
arguments: MailsForwardCreatorArguments(accountId, accountDashBoardController.sessionCurrent.value));
if (listEmail is List<EmailAddress>) { if (listEmail is List<EmailAddress>) {
_addEmailsForward(listEmail); handleAddRecipients(listEmail);
}
} }
} }
} }
void _addEmailsForward(List<EmailAddress> listEmailAddress) { void _openMailsForwardCreatorOverlay() {
EmailsForwardCreatorBindings().dependencies();
accountDashBoardController.emailsForwardCreatorIsActive.toggle();
}
void handleAddRecipients(List<EmailAddress> listEmailAddress) {
final accountId = accountDashBoardController.accountId.value;
final listRecipients = listEmailAddress.map((e) => e.emailAddress).toSet();
if (accountId != null && currentForward != null) {
consumeState(_addRecipientsInForwardingInteractor.execute(
accountId,
AddRecipientInForwardingRequest(
currentForward: currentForward!,
listRecipientAdded: listRecipients)));
}
}
void _handleAddRecipientsSuccess(AddRecipientsInForwardingSuccess success) {
if (currentOverlayContext != null && currentContext != null) {
_appToast.showToastWithIcon(
currentOverlayContext!,
message: AppLocalizations.of(currentContext!).toastMessageAddRecipientsSuccessfully,
icon: _imagePaths.icSelected);
}
currentForward = success.forward;
listRecipientForward.value = currentForward!.listRecipientForward;
} }
} }
@@ -42,49 +42,49 @@ class ForwardHeaderWidget extends StatelessWidget {
Widget _buildButtonAddNewEmailsForward(BuildContext context) { Widget _buildButtonAddNewEmailsForward(BuildContext context) {
if (!responsiveUtils.isMobile(context)) { if (!responsiveUtils.isMobile(context)) {
return (ButtonBuilder(imagePaths.icAddEmailForward) return (ButtonBuilder(imagePaths.icAddEmailForward)
..key(const Key('button_add_emails_forward')) ..key(const Key('button_add_emails_forward'))
..decoration(BoxDecoration( ..decoration(BoxDecoration(
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
color: AppColor.colorTextButton)) color: AppColor.colorTextButton))
..paddingIcon(const EdgeInsets.only(right: 8)) ..paddingIcon(const EdgeInsets.only(right: 8))
..iconColor(Colors.white) ..iconColor(Colors.white)
..maxWidth(130) ..maxWidth(170)
..size(20) ..size(20)
..radiusSplash(10) ..radiusSplash(10)
..padding(const EdgeInsets.symmetric(vertical: 12)) ..padding(const EdgeInsets.symmetric(vertical: 12))
..textStyle(const TextStyle( ..textStyle(const TextStyle(
fontSize: 17, fontSize: 17,
color: Colors.white, color: Colors.white,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
)) ))
..onPressActionClick(() => addEmailForward.call()) ..onPressActionClick(() => addEmailForward.call())
..text( ..text(
AppLocalizations.of(context).addEmailForward, AppLocalizations.of(context).addRecipients,
isVertical: false, isVertical: false,
)) ))
.build(); .build();
} else { } else {
return (ButtonBuilder(imagePaths.icAddEmailForward) return (ButtonBuilder(imagePaths.icAddEmailForward)
..key(const Key('button_add_emails_forward')) ..key(const Key('button_add_emails_forward'))
..decoration(BoxDecoration( ..decoration(BoxDecoration(
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
color: AppColor.colorTextButton)) color: AppColor.colorTextButton))
..paddingIcon(const EdgeInsets.only(right: 8)) ..paddingIcon(const EdgeInsets.only(right: 8))
..iconColor(Colors.white) ..iconColor(Colors.white)
..size(20) ..size(20)
..radiusSplash(10) ..radiusSplash(10)
..padding(const EdgeInsets.symmetric(vertical: 12)) ..padding(const EdgeInsets.symmetric(vertical: 12))
..textStyle(const TextStyle( ..textStyle(const TextStyle(
fontSize: 17, fontSize: 17,
color: Colors.white, color: Colors.white,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
)) ))
..onPressActionClick(() => addEmailForward.call()) ..onPressActionClick(() => addEmailForward.call())
..text( ..text(
AppLocalizations.of(context).addEmailForward, AppLocalizations.of(context).addRecipients,
isVertical: false, isVertical: false,
)) ))
.build(); .build();
} }
} }
} }
@@ -44,7 +44,7 @@ class ListEmailForwardsWidget extends GetWidget<ForwardController> {
: const EdgeInsets.symmetric(vertical: 13, horizontal: 24), : const EdgeInsets.symmetric(vertical: 13, horizontal: 24),
child: Row(children: [ child: Row(children: [
Expanded(child: Text( Expanded(child: Text(
AppLocalizations.of(context).headerEmailsForward, AppLocalizations.of(context).headerRecipients,
overflow: CommonTextStyle.defaultTextOverFlow, overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap, softWrap: CommonTextStyle.defaultSoftWrap,
style: const TextStyle( style: const TextStyle(
@@ -45,6 +45,8 @@ class ManageAccountDashBoardController extends ReloadableController {
final sessionCurrent = Rxn<Session>(); final sessionCurrent = Rxn<Session>();
final vacationResponse = Rxn<VacationResponse>(); final vacationResponse = Rxn<VacationResponse>();
final emailsForwardCreatorIsActive = false.obs;
ManageAccountDashBoardController( ManageAccountDashBoardController(
LogoutOidcInteractor logoutOidcInteractor, LogoutOidcInteractor logoutOidcInteractor,
DeleteAuthorityOidcInteractor deleteAuthorityOidcInteractor, DeleteAuthorityOidcInteractor deleteAuthorityOidcInteractor,
@@ -3,6 +3,7 @@ import 'package:core/core.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:tmail_ui_user/features/emails_forward_creator/presentation/emails_forward_creator_view.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mixin/user_setting_popup_menu_mixin.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mixin/user_setting_popup_menu_mixin.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart';
@@ -33,136 +34,144 @@ class ManageAccountDashBoardView extends GetWidget<ManageAccountDashBoardControl
}); });
} }
return Scaffold( return Obx(
key: controller.menuDrawerKey, () => Stack(
backgroundColor: Colors.white, children: [
drawer: ResponsiveWidget( Scaffold(
responsiveUtils: _responsiveUtils, key: controller.menuDrawerKey,
mobile: SizedBox(child: ManageAccountMenuView(), width: ResponsiveUtils.defaultSizeDrawer), backgroundColor: Colors.white,
desktop: const SizedBox.shrink() drawer: ResponsiveWidget(
), responsiveUtils: _responsiveUtils,
drawerEnableOpenDragGesture: !_responsiveUtils.isDesktop(context), mobile: SizedBox(child: ManageAccountMenuView(), width: ResponsiveUtils.defaultSizeDrawer),
body: GestureDetector( desktop: const SizedBox.shrink()
onTap: () => FocusScope.of(context).unfocus(), ),
child: ResponsiveWidget( drawerEnableOpenDragGesture: !_responsiveUtils.isDesktop(context),
responsiveUtils: _responsiveUtils, body: GestureDetector(
desktop: Column(children: [ onTap: () => FocusScope.of(context).unfocus(),
Row(children: [ child: ResponsiveWidget(
Container(width: 256, color: Colors.white, responsiveUtils: _responsiveUtils,
padding: const EdgeInsets.only(top: 25, bottom: 25, left: 32), desktop: Column(children: [
child: Row(children: [ Row(children: [
(SloganBuilder(arrangedByHorizontal: true) Container(width: 256, color: Colors.white,
..setSloganText(AppLocalizations.of(context).app_name) padding: const EdgeInsets.only(top: 25, bottom: 25, left: 32),
..setSloganTextAlign(TextAlign.center) child: Row(children: [
..setSloganTextStyle(const TextStyle(color: Colors.black, fontSize: 20, fontWeight: FontWeight.bold)) (SloganBuilder(arrangedByHorizontal: true)
..setSizeLogo(24) ..setSloganText(AppLocalizations.of(context).app_name)
..addOnTapCallback(() => controller.backToMailboxDashBoard(context)) ..setSloganTextAlign(TextAlign.center)
..setLogo(_imagePaths.icLogoTMail)) ..setSloganTextStyle(const TextStyle(color: Colors.black, fontSize: 20, fontWeight: FontWeight.bold))
.build(), ..setSizeLogo(24)
Obx(() { ..addOnTapCallback(() => controller.backToMailboxDashBoard(context))
if (controller.appInformation.value != null) { ..setLogo(_imagePaths.icLogoTMail))
return Padding(padding: const EdgeInsets.only(top: 6), .build(),
child: Text( Obx(() {
'v.${controller.appInformation.value!.version}', if (controller.appInformation.value != null) {
textAlign: TextAlign.center, return Padding(padding: const EdgeInsets.only(top: 6),
style: const TextStyle(fontSize: 13, color: AppColor.colorContentEmail, fontWeight: FontWeight.w500), child: Text(
)); 'v.${controller.appInformation.value!.version}',
} else { textAlign: TextAlign.center,
return const SizedBox.shrink(); style: const TextStyle(fontSize: 13, color: AppColor.colorContentEmail, fontWeight: FontWeight.w500),
} ));
}), } else {
]) return const SizedBox.shrink();
), }
Expanded(child: Padding( }),
padding: const EdgeInsets.only(right: 10, top: 16, bottom: 10, left: 48), ])
child: _buildRightHeader(context))) ),
]), Expanded(child: Padding(
Expanded(child: Row( padding: const EdgeInsets.only(right: 10, top: 16, bottom: 10, left: 48),
crossAxisAlignment: CrossAxisAlignment.start, child: _buildRightHeader(context)))
children: [
SizedBox(child: ManageAccountMenuView(), width: _responsiveUtils.defaultSizeMenu),
Expanded(child: Container(
color: AppColor.colorBgDesktop,
child: Column(children: [
Obx(() {
if (controller.vacationResponse.value?.vacationResponderIsValid == true) {
return VacationNotificationMessageWidget(
margin: const EdgeInsets.only(
top: 16,
left: BuildUtils.isWeb ? 24 : 16,
right: BuildUtils.isWeb ? 24 : 16),
vacationResponse: controller.vacationResponse.value!,
action: () => controller.disableVacationResponder());
} else if ((controller.vacationResponse.value?.vacationResponderIsWaiting == true
|| controller.vacationResponse.value?.vacationResponderIsStopped == true)
&& controller.accountMenuItemSelected.value == AccountMenuItem.vacation) {
return VacationNotificationMessageWidget(
margin: const EdgeInsets.only(
top: 16,
left: BuildUtils.isWeb ? 24 : 16,
right: BuildUtils.isWeb ? 24 : 16),
vacationResponse: controller.vacationResponse.value!,
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
backgroundColor: Colors.yellow,
fontWeight: FontWeight.normal,
leadingIcon: const Padding(
padding: EdgeInsets.only(right: 16),
child: Icon(Icons.timer, size: 20),
));
} else {
return const SizedBox.shrink();
}
}),
Expanded(child: _viewDisplayedOfAccountMenuItem())
]), ]),
)) Expanded(child: Row(
], crossAxisAlignment: CrossAxisAlignment.start,
)) children: [
]), SizedBox(child: ManageAccountMenuView(), width: _responsiveUtils.defaultSizeMenu),
mobile: SafeArea( Expanded(child: Container(
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ color: AppColor.colorBgDesktop,
Padding( child: Column(children: [
padding: !BuildUtils.isWeb && _responsiveUtils.isPortraitMobile(context) Obx(() {
? const EdgeInsets.only(left: 4, right: 8) if (controller.vacationResponse.value?.vacationResponderIsValid == true) {
: const EdgeInsets.only(top: 16, left: 24, right: 32), return VacationNotificationMessageWidget(
child: _buildAppbar(context)), margin: const EdgeInsets.only(
Obx(() { top: 16,
if (controller.vacationResponse.value?.vacationResponderIsValid == true) { left: BuildUtils.isWeb ? 24 : 16,
return VacationNotificationMessageWidget( right: BuildUtils.isWeb ? 24 : 16),
margin: const EdgeInsets.only( vacationResponse: controller.vacationResponse.value!,
left: BuildUtils.isWeb ? 24 : 16, action: () => controller.disableVacationResponder());
right: BuildUtils.isWeb ? 24 : 16, } else if ((controller.vacationResponse.value?.vacationResponderIsWaiting == true
top: BuildUtils.isWeb ? 16 : 0), || controller.vacationResponse.value?.vacationResponderIsStopped == true)
vacationResponse: controller.vacationResponse.value!, && controller.accountMenuItemSelected.value == AccountMenuItem.vacation) {
action: () => controller.disableVacationResponder()); return VacationNotificationMessageWidget(
} else if ((controller.vacationResponse.value?.vacationResponderIsWaiting == true margin: const EdgeInsets.only(
|| controller.vacationResponse.value?.vacationResponderIsStopped == true) top: 16,
&& controller.accountMenuItemSelected.value == AccountMenuItem.vacation) { left: BuildUtils.isWeb ? 24 : 16,
return VacationNotificationMessageWidget( right: BuildUtils.isWeb ? 24 : 16),
margin: const EdgeInsets.only( vacationResponse: controller.vacationResponse.value!,
left: BuildUtils.isWeb ? 24 : 16, padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
right: BuildUtils.isWeb ? 24 : 16, backgroundColor: Colors.yellow,
top: BuildUtils.isWeb ? 16 : 0), fontWeight: FontWeight.normal,
vacationResponse: controller.vacationResponse.value!, leadingIcon: const Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16), padding: EdgeInsets.only(right: 16),
fontWeight: FontWeight.normal, child: Icon(Icons.timer, size: 20),
backgroundColor: Colors.yellow, ));
leadingIcon: const Padding( } else {
padding: EdgeInsets.only(right: 16), return const SizedBox.shrink();
child: Icon(Icons.timer, size: 20), }
)); }),
} else { Expanded(child: _viewDisplayedOfAccountMenuItem())
return const SizedBox.shrink(); ]),
} ))
}), ],
Expanded(child: Padding( ))
padding: !BuildUtils.isWeb && _responsiveUtils.isPortraitMobile(context) ]),
? const EdgeInsets.only(left: 8) mobile: SafeArea(
: const EdgeInsets.only(left: 24), child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
child: _viewDisplayedOfAccountMenuItem())) Padding(
]) padding: !BuildUtils.isWeb && _responsiveUtils.isPortraitMobile(context)
) ? const EdgeInsets.only(left: 4, right: 8)
), : const EdgeInsets.only(top: 16, left: 24, right: 32),
child: _buildAppbar(context)),
Obx(() {
if (controller.vacationResponse.value?.vacationResponderIsValid == true) {
return VacationNotificationMessageWidget(
margin: const EdgeInsets.only(
left: BuildUtils.isWeb ? 24 : 16,
right: BuildUtils.isWeb ? 24 : 16,
top: BuildUtils.isWeb ? 16 : 0),
vacationResponse: controller.vacationResponse.value!,
action: () => controller.disableVacationResponder());
} else if ((controller.vacationResponse.value?.vacationResponderIsWaiting == true
|| controller.vacationResponse.value?.vacationResponderIsStopped == true)
&& controller.accountMenuItemSelected.value == AccountMenuItem.vacation) {
return VacationNotificationMessageWidget(
margin: const EdgeInsets.only(
left: BuildUtils.isWeb ? 24 : 16,
right: BuildUtils.isWeb ? 24 : 16,
top: BuildUtils.isWeb ? 16 : 0),
vacationResponse: controller.vacationResponse.value!,
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
fontWeight: FontWeight.normal,
backgroundColor: Colors.yellow,
leadingIcon: const Padding(
padding: EdgeInsets.only(right: 16),
child: Icon(Icons.timer, size: 20),
));
} else {
return const SizedBox.shrink();
}
}),
Expanded(child: Padding(
padding: !BuildUtils.isWeb && _responsiveUtils.isPortraitMobile(context)
? const EdgeInsets.only(left: 8)
: const EdgeInsets.only(left: 24),
child: _viewDisplayedOfAccountMenuItem()))
])
)
),
),
),
if(controller.emailsForwardCreatorIsActive.isTrue)
EmailsForwardCreatorView(),
] ,
), ),
); );
} }
+19 -1
View File
@@ -1,5 +1,5 @@
{ {
"@@last_modified": "2022-08-19T13:28:03.023650", "@@last_modified": "2022-08-20T20:59:54.192845",
"initializing_data": "Initializing data...", "initializing_data": "Initializing data...",
"@initializing_data": { "@initializing_data": {
"type": "text", "type": "text",
@@ -2065,5 +2065,23 @@
"type": "text", "type": "text",
"placeholders_order": [], "placeholders_order": [],
"placeholders": {} "placeholders": {}
},
"addEmailForward": "Add Email",
"@addEmailForward": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"emailForwardLabel": "Name or Email address",
"@emailForwardLabel": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"toastMessageAddRecipientsSuccessfully": "The emails has been added from the recipient list.",
"@toastMessageAddRecipientsSuccessfully": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
} }
} }
+14 -8
View File
@@ -1946,10 +1946,10 @@ class AppLocalizations {
name: 'yourFilterHasBeenUpdated'); name: 'yourFilterHasBeenUpdated');
} }
String get headerEmailsForward { String get headerRecipients {
return Intl.message( return Intl.message(
'Emails forward', 'Recipients',
name: 'headerEmailsForward', name: 'headerRecipients',
); );
} }
@@ -2134,17 +2134,23 @@ class AppLocalizations {
); );
} }
String get addEmailForward { String get addRecipients {
return Intl.message( return Intl.message(
'Add Email', 'Add Recipients',
name: 'addEmailForward', name: 'addRecipients',
); );
} }
String get emailForwardLabel { String get recipientsLabel {
return Intl.message( return Intl.message(
'Name or Email address', 'Name or Email address',
name: 'emailForwardLabel', name: 'recipientsLabel',
); );
} }
String get toastMessageAddRecipientsSuccessfully {
return Intl.message(
'The emails has been added from the recipient list.',
name: 'toastMessageAddRecipientsSuccessfully');
}
} }
+2 -2
View File
@@ -9,8 +9,8 @@ import 'package:tmail_ui_user/features/home/presentation/home_bindings.dart';
import 'package:tmail_ui_user/features/home/presentation/home_view.dart'; import 'package:tmail_ui_user/features/home/presentation/home_view.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_bindings.dart'; import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_bindings.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_view.dart' deferred as identity_creator; import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_view.dart' deferred as identity_creator;
import 'package:tmail_ui_user/features/mails_forward_creator/presentation/emails_forward_creator_binding.dart'; import 'package:tmail_ui_user/features/emails_forward_creator/presentation/emails_forward_creator_binding.dart';
import 'package:tmail_ui_user/features/mails_forward_creator/presentation/emails_forward_creator_view.dart' deferred as emails_forward_creator; import 'package:tmail_ui_user/features/emails_forward_creator/presentation/emails_forward_creator_view.dart' deferred as emails_forward_creator;
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/rules_filter_creator_bindings.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/rules_filter_creator_bindings.dart';
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/rules_filter_creator_view.dart' deferred as rules_filter_creator; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/rules_filter_creator_view.dart' deferred as rules_filter_creator;
import 'package:tmail_ui_user/features/login/presentation/login_bindings.dart'; import 'package:tmail_ui_user/features/login/presentation/login_bindings.dart';
+1
View File
@@ -12,4 +12,5 @@ abstract class AppRoutes {
static const MANAGE_ACCOUNT = '$MAILBOX_DASHBOARD/manage_account'; static const MANAGE_ACCOUNT = '$MAILBOX_DASHBOARD/manage_account';
static const IDENTITY_CREATOR = '$MANAGE_ACCOUNT/identity_creator'; static const IDENTITY_CREATOR = '$MANAGE_ACCOUNT/identity_creator';
static const RULES_FILTER_CREATOR = '$MANAGE_ACCOUNT/rules_filter_creator'; static const RULES_FILTER_CREATOR = '$MANAGE_ACCOUNT/rules_filter_creator';
static const EMAILS_FORWARD_CREATOR = '$MANAGE_ACCOUNT/emails_forward_creator';
} }
@@ -1,8 +1,7 @@
// Mocks generated by Mockito 5.2.0 from annotations // Mocks generated by Mockito 5.0.17 from annotations
// in tmail_ui_user/test/features/thread/domain/usecases/get_emails_in_mailbox_interactor_test.dart. // in tmail_ui_user/test/features/thread/domain/usecases/get_emails_in_mailbox_interactor_test.dart.
// Do not manually edit this file. // Do not manually edit this file.
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i3; import 'dart:async' as _i3;
import 'package:jmap_dart_client/jmap/account_id.dart' as _i5; import 'package:jmap_dart_client/jmap/account_id.dart' as _i5;
@@ -25,7 +24,6 @@ import 'package:tmail_ui_user/features/thread/domain/model/get_email_request.dar
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart' import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart'
as _i2; as _i2;
// ignore_for_file: type=lint
// ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_redundant_argument_values
// ignore_for_file: avoid_setters_without_getters // ignore_for_file: avoid_setters_without_getters
// ignore_for_file: comment_references // ignore_for_file: comment_references
@@ -1,8 +1,7 @@
// Mocks generated by Mockito 5.2.0 from annotations // Mocks generated by Mockito 5.0.17 from annotations
// in tmail_ui_user/test/features/thread/domain/usecases/refresh_changes_emails_in_mailbox_interactor_test.dart. // in tmail_ui_user/test/features/thread/domain/usecases/refresh_changes_emails_in_mailbox_interactor_test.dart.
// Do not manually edit this file. // Do not manually edit this file.
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i3; import 'dart:async' as _i3;
import 'package:jmap_dart_client/jmap/account_id.dart' as _i5; import 'package:jmap_dart_client/jmap/account_id.dart' as _i5;
@@ -25,7 +24,6 @@ import 'package:tmail_ui_user/features/thread/domain/model/get_email_request.dar
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart' import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart'
as _i2; as _i2;
// ignore_for_file: type=lint
// ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_redundant_argument_values
// ignore_for_file: avoid_setters_without_getters // ignore_for_file: avoid_setters_without_getters
// ignore_for_file: comment_references // ignore_for_file: comment_references