TF-2613 Invoke show warning dialog when add other domain
Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
+98
-21
@@ -8,14 +8,17 @@ import 'package:core/presentation/utils/responsive_utils.dart';
|
|||||||
import 'package:core/utils/app_logger.dart';
|
import 'package:core/utils/app_logger.dart';
|
||||||
import 'package:core/utils/platform_info.dart';
|
import 'package:core/utils/platform_info.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.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';
|
||||||
import 'package:super_tag_editor/tag_editor.dart';
|
import 'package:super_tag_editor/tag_editor.dart';
|
||||||
|
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_mixin.dart';
|
||||||
import 'package:tmail_ui_user/features/base/widget/material_text_icon_button.dart';
|
import 'package:tmail_ui_user/features/base/widget/material_text_icon_button.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/model/suggestion_email_address.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/model/suggestion_email_address.dart';
|
||||||
import 'package:tmail_ui_user/features/contact/presentation/widgets/contact_input_tag_item.dart';
|
import 'package:tmail_ui_user/features/contact/presentation/widgets/contact_input_tag_item.dart';
|
||||||
import 'package:tmail_ui_user/features/contact/presentation/widgets/contact_suggestion_box_item.dart';
|
import 'package:tmail_ui_user/features/contact/presentation/widgets/contact_suggestion_box_item.dart';
|
||||||
|
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
|
||||||
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart';
|
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart';
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
import 'package:tmail_ui_user/main/utils/app_utils.dart';
|
import 'package:tmail_ui_user/main/utils/app_utils.dart';
|
||||||
@@ -32,21 +35,24 @@ class AutocompleteContactTextFieldWithTags extends StatefulWidget {
|
|||||||
final OnSuggestionContactCallbackAction? onSuggestionCallback;
|
final OnSuggestionContactCallbackAction? onSuggestionCallback;
|
||||||
final OnAddListContactCallbackAction? onAddContactCallback;
|
final OnAddListContactCallbackAction? onAddContactCallback;
|
||||||
final OnExceptionAddListContactCallbackAction? onExceptionCallback;
|
final OnExceptionAddListContactCallbackAction? onExceptionCallback;
|
||||||
|
final String serverDomain;
|
||||||
|
|
||||||
const AutocompleteContactTextFieldWithTags(this.listEmailAddress, {
|
const AutocompleteContactTextFieldWithTags({
|
||||||
Key? key,
|
Key? key,
|
||||||
|
required this.listEmailAddress,
|
||||||
|
required this.serverDomain,
|
||||||
this.controller,
|
this.controller,
|
||||||
this.hasAddContactButton = false,
|
this.hasAddContactButton = false,
|
||||||
this.onSuggestionCallback,
|
this.onSuggestionCallback,
|
||||||
this.onAddContactCallback,
|
this.onAddContactCallback,
|
||||||
this.onExceptionCallback
|
this.onExceptionCallback,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<AutocompleteContactTextFieldWithTags> createState() => _AutocompleteContactTextFieldWithTagsState();
|
State<AutocompleteContactTextFieldWithTags> createState() => _AutocompleteContactTextFieldWithTagsState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AutocompleteContactTextFieldWithTagsState extends State<AutocompleteContactTextFieldWithTags> {
|
class _AutocompleteContactTextFieldWithTagsState extends State<AutocompleteContactTextFieldWithTags> with MessageDialogActionMixin {
|
||||||
|
|
||||||
final _responsiveUtils = Get.find<ResponsiveUtils>();
|
final _responsiveUtils = Get.find<ResponsiveUtils>();
|
||||||
final _imagePaths = Get.find<ImagePaths>();
|
final _imagePaths = Get.find<ImagePaths>();
|
||||||
@@ -89,7 +95,6 @@ class _AutocompleteContactTextFieldWithTagsState extends State<AutocompleteConta
|
|||||||
autofocus: false,
|
autofocus: false,
|
||||||
minTextFieldWidth: 20,
|
minTextFieldWidth: 20,
|
||||||
debounceDuration: const Duration(milliseconds: 150),
|
debounceDuration: const Duration(milliseconds: 150),
|
||||||
resetTextOnSubmitted: true,
|
|
||||||
autoScrollToInput: false,
|
autoScrollToInput: false,
|
||||||
suggestionsBoxBackgroundColor: Colors.white,
|
suggestionsBoxBackgroundColor: Colors.white,
|
||||||
suggestionsBoxRadius: 16,
|
suggestionsBoxRadius: 16,
|
||||||
@@ -106,16 +111,14 @@ class _AutocompleteContactTextFieldWithTagsState extends State<AutocompleteConta
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSelectOptionAction: (item) {
|
onSelectOptionAction: (item) => _addEmailAddressToInputFieldAction(
|
||||||
if (!_isDuplicatedRecipient(item.emailAddress.emailAddress)) {
|
context: context,
|
||||||
setState(() => listEmailAddress.add(item.emailAddress));
|
emailAddress: item.emailAddress
|
||||||
}
|
),
|
||||||
},
|
onSubmitted: (value) => _addEmailAddressToInputFieldAction(
|
||||||
onSubmitted: (value) {
|
context: context,
|
||||||
if (!_isDuplicatedRecipient(value)) {
|
emailAddress: EmailAddress(null, value)
|
||||||
setState(() => listEmailAddress.add(EmailAddress(null, value)));
|
),
|
||||||
}
|
|
||||||
},
|
|
||||||
textStyle: const TextStyle(
|
textStyle: const TextStyle(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
@@ -138,9 +141,10 @@ class _AutocompleteContactTextFieldWithTagsState extends State<AutocompleteConta
|
|||||||
}
|
}
|
||||||
),
|
),
|
||||||
onTagChanged: (value) {
|
onTagChanged: (value) {
|
||||||
if (!_isDuplicatedRecipient(value)) {
|
_addEmailAddressToInputFieldAction(
|
||||||
setState(() => listEmailAddress.add(EmailAddress(null, value)));
|
context: context,
|
||||||
}
|
emailAddress: EmailAddress(null, value)
|
||||||
|
);
|
||||||
_gapBetweenTagChangedAndFindSuggestion = Timer(
|
_gapBetweenTagChangedAndFindSuggestion = Timer(
|
||||||
const Duration(seconds: 1),
|
const Duration(seconds: 1),
|
||||||
_handleGapBetweenTagChangedAndFindSuggestion
|
_handleGapBetweenTagChangedAndFindSuggestion
|
||||||
@@ -155,7 +159,9 @@ class _AutocompleteContactTextFieldWithTagsState extends State<AutocompleteConta
|
|||||||
shapeBorder: const RoundedRectangleBorder(
|
shapeBorder: const RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(12))),
|
borderRadius: BorderRadius.all(Radius.circular(12))),
|
||||||
selectedContactCallbackAction: (contact) {
|
selectedContactCallbackAction: (contact) {
|
||||||
setState(() => listEmailAddress.add(contact));
|
_addEmailAddressToInputFieldAction(
|
||||||
|
context: context,
|
||||||
|
emailAddress: contact);
|
||||||
tagEditorState.closeSuggestionBox();
|
tagEditorState.closeSuggestionBox();
|
||||||
tagEditorState.resetTextField();
|
tagEditorState.resetTextField();
|
||||||
},
|
},
|
||||||
@@ -193,6 +199,7 @@ class _AutocompleteContactTextFieldWithTagsState extends State<AutocompleteConta
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool _isDuplicatedRecipient(String inputEmail) {
|
bool _isDuplicatedRecipient(String inputEmail) {
|
||||||
|
log('_AutocompleteContactTextFieldWithTagsState::_isDuplicatedRecipient: inputEmail = $inputEmail');
|
||||||
if (inputEmail.isEmpty) {
|
if (inputEmail.isEmpty) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -281,9 +288,10 @@ class _AutocompleteContactTextFieldWithTagsState extends State<AutocompleteConta
|
|||||||
_hideKeyboardForMobile();
|
_hideKeyboardForMobile();
|
||||||
if (widget.controller?.text.isNotEmpty == true) {
|
if (widget.controller?.text.isNotEmpty == true) {
|
||||||
if (!_isDuplicatedRecipient(widget.controller?.text ?? '')) {
|
if (!_isDuplicatedRecipient(widget.controller?.text ?? '')) {
|
||||||
setState(() {
|
_addEmailAddressToInputFieldAction(
|
||||||
listEmailAddress.add(EmailAddress(null, widget.controller?.text));
|
context: context,
|
||||||
});
|
emailAddress: EmailAddress(null, widget.controller?.text)
|
||||||
|
);
|
||||||
_closeSuggestionBox();
|
_closeSuggestionBox();
|
||||||
} else {
|
} else {
|
||||||
_closeSuggestionBox();
|
_closeSuggestionBox();
|
||||||
@@ -317,4 +325,73 @@ class _AutocompleteContactTextFieldWithTagsState extends State<AutocompleteConta
|
|||||||
FocusScope.of(context).unfocus();
|
FocusScope.of(context).unfocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _addEmailAddressToInputFieldAction({
|
||||||
|
required BuildContext context,
|
||||||
|
required EmailAddress emailAddress
|
||||||
|
}) {
|
||||||
|
if (_isDuplicatedRecipient(emailAddress.emailAddress)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final validateSameDomain = EmailUtils.isSameDomain(
|
||||||
|
emailAddress: emailAddress.emailAddress,
|
||||||
|
serverDomain: widget.serverDomain
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!validateSameDomain) {
|
||||||
|
_showWarningDialogWithExternalDomain(
|
||||||
|
context: context,
|
||||||
|
confirmAction: () {
|
||||||
|
keyToEmailTagEditor.currentState?.resetTextField();
|
||||||
|
setState(() => listEmailAddress.add(emailAddress));
|
||||||
|
},
|
||||||
|
cancelAction: () {
|
||||||
|
keyToEmailTagEditor.currentState?.resetTextField();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
keyToEmailTagEditor.currentState?.resetTextField();
|
||||||
|
setState(() => listEmailAddress.add(emailAddress));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showWarningDialogWithExternalDomain({
|
||||||
|
required BuildContext context,
|
||||||
|
VoidCallback? confirmAction,
|
||||||
|
VoidCallback? cancelAction
|
||||||
|
}) async {
|
||||||
|
await showConfirmDialogAction(
|
||||||
|
context,
|
||||||
|
title: AppLocalizations.of(context).messageWarningDialogForForwardsToOtherDomains,
|
||||||
|
AppLocalizations.of(context).doYouWantToProceed,
|
||||||
|
AppLocalizations.of(context).yes,
|
||||||
|
cancelTitle: AppLocalizations.of(context).no,
|
||||||
|
alignCenter: true,
|
||||||
|
onConfirmAction: confirmAction,
|
||||||
|
onCancelAction: cancelAction,
|
||||||
|
icon: SvgPicture.asset(
|
||||||
|
_imagePaths.icQuotasWarning,
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
colorFilter: AppColor.colorQuotaError.asFilter(),
|
||||||
|
),
|
||||||
|
messageStyle: Theme.of(context).textTheme.labelMedium?.copyWith(
|
||||||
|
fontSize: 17,
|
||||||
|
color: Colors.black
|
||||||
|
),
|
||||||
|
titleStyle: Theme.of(context).textTheme.labelSmall?.copyWith(
|
||||||
|
fontSize: 14,
|
||||||
|
color: AppColor.colorMessageConfirmDialog
|
||||||
|
),
|
||||||
|
actionStyle: Theme.of(context).textTheme.labelMedium?.copyWith(
|
||||||
|
fontSize: 17,
|
||||||
|
color: Colors.white
|
||||||
|
),
|
||||||
|
cancelStyle: Theme.of(context).textTheme.labelMedium?.copyWith(
|
||||||
|
fontSize: 17,
|
||||||
|
color: Colors.black
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,7 @@ import 'package:flutter_svg/flutter_svg.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
|
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
|
||||||
import 'package:tmail_ui_user/features/contact/presentation/widgets/autocomplete_contact_text_field_with_tags.dart';
|
import 'package:tmail_ui_user/features/contact/presentation/widgets/autocomplete_contact_text_field_with_tags.dart';
|
||||||
|
import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.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';
|
||||||
import 'package:tmail_ui_user/features/manage_account/presentation/forward/widgets/forward_header_widget.dart';
|
import 'package:tmail_ui_user/features/manage_account/presentation/forward/widgets/forward_header_widget.dart';
|
||||||
import 'package:tmail_ui_user/features/manage_account/presentation/forward/widgets/list_email_forward_widget.dart';
|
import 'package:tmail_ui_user/features/manage_account/presentation/forward/widgets/list_email_forward_widget.dart';
|
||||||
@@ -124,7 +125,8 @@ class ForwardView extends GetWidget<ForwardController> with AppLoaderMixin {
|
|||||||
|
|
||||||
Widget _buildAddRecipientsFormWidget(BuildContext context) {
|
Widget _buildAddRecipientsFormWidget(BuildContext context) {
|
||||||
return AutocompleteContactTextFieldWithTags(
|
return AutocompleteContactTextFieldWithTags(
|
||||||
controller.recipientController.listRecipients,
|
listEmailAddress: controller.recipientController.listRecipients,
|
||||||
|
serverDomain: controller.accountDashBoardController.sessionCurrent?.serverDomain ?? '',
|
||||||
controller: controller.recipientController.inputRecipientController,
|
controller: controller.recipientController.inputRecipientController,
|
||||||
onSuggestionCallback: controller.recipientController.getAutoCompleteSuggestion,
|
onSuggestionCallback: controller.recipientController.getAutoCompleteSuggestion,
|
||||||
hasAddContactButton: true,
|
hasAddContactButton: true,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"@@last_modified": "2024-02-22T09:16:33.644962",
|
"@@last_modified": "2024-02-29T10:18:57.883345",
|
||||||
"initializing_data": "Initializing data...",
|
"initializing_data": "Initializing data...",
|
||||||
"@initializing_data": {
|
"@initializing_data": {
|
||||||
"type": "text",
|
"type": "text",
|
||||||
@@ -3635,5 +3635,17 @@
|
|||||||
"type": "text",
|
"type": "text",
|
||||||
"placeholders_order": [],
|
"placeholders_order": [],
|
||||||
"placeholders": {}
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"doYouWantToProceed": "Do you want to proceed?",
|
||||||
|
"@doYouWantToProceed": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders_order": [],
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"messageWarningDialogForForwardsToOtherDomains": "You are redirecting emails to another domain. This could be a security threat or considered illegal data extraction.",
|
||||||
|
"@messageWarningDialogForForwardsToOtherDomains": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders_order": [],
|
||||||
|
"placeholders": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3787,4 +3787,17 @@ class AppLocalizations {
|
|||||||
name: 'loadMore',
|
name: 'loadMore',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get doYouWantToProceed {
|
||||||
|
return Intl.message(
|
||||||
|
'Do you want to proceed?',
|
||||||
|
name: 'doYouWantToProceed');
|
||||||
|
}
|
||||||
|
|
||||||
|
String get messageWarningDialogForForwardsToOtherDomains {
|
||||||
|
return Intl.message(
|
||||||
|
'You are redirecting emails to another domain. This could be a security threat or considered illegal data extraction.',
|
||||||
|
name: 'messageWarningDialogForForwardsToOtherDomains'
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user