TF-2613 Handle display forward warning icon in recipient item
Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
@@ -71,10 +71,10 @@ class EmailUtils {
|
||||
|
||||
static bool isSameDomain({
|
||||
required String emailAddress,
|
||||
required String serverDomain
|
||||
required String internalDomain
|
||||
}) {
|
||||
log('EmailUtils::isSameDomain: emailAddress = $emailAddress | serverDomain = $serverDomain');
|
||||
log('EmailUtils::isSameDomain: emailAddress = $emailAddress | internalDomain = $internalDomain');
|
||||
return GetUtils.isEmail(emailAddress) &&
|
||||
emailAddress.split('@').last.toLowerCase() == serverDomain.toLowerCase();
|
||||
emailAddress.split('@').last.toLowerCase() == internalDomain.toLowerCase();
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:core/presentation/extensions/uri_extension.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:jmap_dart_client/http/converter/state_converter.dart';
|
||||
import 'package:jmap_dart_client/http/converter/user_name_converter.dart';
|
||||
@@ -46,12 +47,17 @@ extension SessionExtensions on Session {
|
||||
}
|
||||
}
|
||||
|
||||
String get serverDomain {
|
||||
if (GetUtils.isEmail(username.value)) {
|
||||
return username.value.split('@').last;
|
||||
} else if (GetUtils.isEmail(personalAccount.name.value)) {
|
||||
return personalAccount.name.value.split('@').last;
|
||||
} else {
|
||||
String get internalDomain {
|
||||
try {
|
||||
if (GetUtils.isEmail(username.value)) {
|
||||
return username.value.split('@').last;
|
||||
} else if (GetUtils.isEmail(personalAccount.name.value)) {
|
||||
return personalAccount.name.value.split('@').last;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
} catch (e) {
|
||||
logError('SessionExtensions::internalDomain: Exception: $e');
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,10 +177,10 @@ class ForwardController extends BaseController {
|
||||
|
||||
bool get _isExistRecipientSameServerDomain =>
|
||||
listRecipientForward.any((recipient) {
|
||||
final serverDomain = accountDashBoardController.sessionCurrent?.serverDomain ?? '';
|
||||
final internalDomain = accountDashBoardController.sessionCurrent?.internalDomain ?? '';
|
||||
final isSameDomain = EmailUtils.isSameDomain(
|
||||
emailAddress: recipient.emailAddress.emailAddress,
|
||||
serverDomain: serverDomain
|
||||
internalDomain: internalDomain
|
||||
);
|
||||
return !isSameDomain;
|
||||
});
|
||||
|
||||
@@ -126,7 +126,7 @@ class ForwardView extends GetWidget<ForwardController> with AppLoaderMixin {
|
||||
Widget _buildAddRecipientsFormWidget(BuildContext context) {
|
||||
return AutocompleteContactTextFieldWithTags(
|
||||
listEmailAddress: controller.recipientController.listRecipients,
|
||||
serverDomain: controller.accountDashBoardController.sessionCurrent?.serverDomain ?? '',
|
||||
internalDomain: controller.accountDashBoardController.sessionCurrent?.internalDomain ?? '',
|
||||
controller: controller.recipientController.inputRecipientController,
|
||||
onSuggestionCallback: controller.recipientController.getAutoCompleteSuggestion,
|
||||
hasAddContactButton: true,
|
||||
|
||||
+3
-3
@@ -35,12 +35,12 @@ class AutocompleteContactTextFieldWithTags extends StatefulWidget {
|
||||
final OnSuggestionContactCallbackAction? onSuggestionCallback;
|
||||
final OnAddListContactCallbackAction? onAddContactCallback;
|
||||
final OnExceptionAddListContactCallbackAction? onExceptionCallback;
|
||||
final String serverDomain;
|
||||
final String internalDomain;
|
||||
|
||||
const AutocompleteContactTextFieldWithTags({
|
||||
Key? key,
|
||||
required this.listEmailAddress,
|
||||
required this.serverDomain,
|
||||
required this.internalDomain,
|
||||
this.controller,
|
||||
this.hasAddContactButton = false,
|
||||
this.onSuggestionCallback,
|
||||
@@ -336,7 +336,7 @@ class _AutocompleteContactTextFieldWithTagsState extends State<AutocompleteConta
|
||||
|
||||
final validateSameDomain = EmailUtils.isSameDomain(
|
||||
emailAddress: emailAddress.emailAddress,
|
||||
serverDomain: widget.serverDomain
|
||||
internalDomain: widget.internalDomain
|
||||
);
|
||||
|
||||
if (!validateSameDomain) {
|
||||
|
||||
+50
-16
@@ -3,6 +3,7 @@ import 'package:core/presentation/extensions/string_extension.dart';
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:core/presentation/utils/style_utils.dart';
|
||||
import 'package:core/presentation/views/button/icon_button_web.dart';
|
||||
import 'package:core/presentation/views/button/tmail_button_widget.dart';
|
||||
import 'package:core/presentation/views/image/avatar_builder.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -10,7 +11,9 @@ import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:model/extensions/email_address_extension.dart';
|
||||
import 'package:model/mailbox/select_mode.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/recipient_forward.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
typedef OnSelectRecipientCallbackAction = Function(RecipientForward recipientForward);
|
||||
typedef OnDeleteRecipientCallbackAction = Function(RecipientForward recipientForward);
|
||||
@@ -19,11 +22,16 @@ class EmailForwardItemWidget extends StatelessWidget {
|
||||
|
||||
final RecipientForward recipientForward;
|
||||
final SelectMode selectionMode;
|
||||
final String internalDomain;
|
||||
final OnSelectRecipientCallbackAction? onSelectRecipientCallback;
|
||||
final OnDeleteRecipientCallbackAction? onDeleteRecipientCallback;
|
||||
|
||||
const EmailForwardItemWidget(this.recipientForward, {
|
||||
final ImagePaths _imagePaths = Get.find<ImagePaths>();
|
||||
|
||||
EmailForwardItemWidget({
|
||||
Key? key,
|
||||
required this.recipientForward,
|
||||
required this.internalDomain,
|
||||
this.selectionMode = SelectMode.INACTIVE,
|
||||
this.onSelectRecipientCallback,
|
||||
this.onDeleteRecipientCallback,
|
||||
@@ -31,8 +39,6 @@ class EmailForwardItemWidget extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final imagePaths = Get.find<ImagePaths>();
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 4),
|
||||
child: Material(
|
||||
@@ -53,23 +59,51 @@ class EmailForwardItemWidget extends StatelessWidget {
|
||||
recipientForward.selectMode == SelectMode.ACTIVE ? 12 : 0))
|
||||
),
|
||||
child: Row(children: [
|
||||
_buildAvatarIcon(imagePaths),
|
||||
_buildAvatarIcon(_imagePaths),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
recipientForward.emailAddress.asString(),
|
||||
overflow: CommonTextStyle.defaultTextOverFlow,
|
||||
softWrap: CommonTextStyle.defaultSoftWrap,
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Colors.black
|
||||
if (EmailUtils.isSameDomain(
|
||||
emailAddress: recipientForward.emailAddress.emailAddress,
|
||||
internalDomain: internalDomain))
|
||||
Text(
|
||||
recipientForward.emailAddress.asString(),
|
||||
overflow: CommonTextStyle.defaultTextOverFlow,
|
||||
softWrap: CommonTextStyle.defaultSoftWrap,
|
||||
maxLines: 1,
|
||||
style: Theme.of(context).textTheme.labelSmall?.copyWith(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Colors.black
|
||||
)
|
||||
)
|
||||
),
|
||||
else
|
||||
Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: Text(
|
||||
recipientForward.emailAddress.asString(),
|
||||
overflow: CommonTextStyle.defaultTextOverFlow,
|
||||
softWrap: CommonTextStyle.defaultSoftWrap,
|
||||
maxLines: 1,
|
||||
style: Theme.of(context).textTheme.labelSmall?.copyWith(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Colors.black
|
||||
)
|
||||
),
|
||||
),
|
||||
TMailButtonWidget.fromIcon(
|
||||
icon: _imagePaths.icInfoCircleOutline,
|
||||
iconColor: AppColor.colorQuotaError,
|
||||
iconSize: 20,
|
||||
backgroundColor: Colors.transparent,
|
||||
padding: const EdgeInsets.all(3),
|
||||
tooltipMessage: AppLocalizations.of(context).externalDomain,
|
||||
)
|
||||
],
|
||||
),
|
||||
if (recipientForward.emailAddress.displayName.isNotEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4),
|
||||
@@ -92,7 +126,7 @@ class EmailForwardItemWidget extends StatelessWidget {
|
||||
buildIconWeb(
|
||||
iconSize: 30,
|
||||
splashRadius: 20,
|
||||
icon: SvgPicture.asset(imagePaths.icDeleteRecipient),
|
||||
icon: SvgPicture.asset(_imagePaths.icDeleteRecipient),
|
||||
onTap: () => onDeleteRecipientCallback?.call(recipientForward)
|
||||
)
|
||||
]),
|
||||
|
||||
+3
-2
@@ -5,6 +5,7 @@ import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:model/extensions/email_address_extension.dart';
|
||||
import 'package:model/mailbox/select_mode.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/widgets/email_forward_item_widget.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart';
|
||||
@@ -34,10 +35,10 @@ class ListEmailForwardsWidget extends GetWidget<ForwardController> {
|
||||
primary: false,
|
||||
itemCount: controller.listRecipientForward.length,
|
||||
padding: EdgeInsets.zero,
|
||||
itemExtent: 75,
|
||||
itemBuilder: (context, index) {
|
||||
return EmailForwardItemWidget(
|
||||
controller.listRecipientForward[index],
|
||||
recipientForward: controller.listRecipientForward[index],
|
||||
internalDomain: controller.accountDashBoardController.sessionCurrent?.internalDomain ?? '',
|
||||
selectionMode: controller.selectionMode.value,
|
||||
onSelectRecipientCallback: controller.selectRecipientForward,
|
||||
onDeleteRecipientCallback: (recipientForward) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"@@last_modified": "2024-02-29T10:18:57.883345",
|
||||
"@@last_modified": "2024-02-29T11:49:16.217272",
|
||||
"initializing_data": "Initializing data...",
|
||||
"@initializing_data": {
|
||||
"type": "text",
|
||||
@@ -3647,5 +3647,11 @@
|
||||
"type": "text",
|
||||
"placeholders_order": [],
|
||||
"placeholders": {}
|
||||
},
|
||||
"externalDomain": "External domain",
|
||||
"@externalDomain": {
|
||||
"type": "text",
|
||||
"placeholders_order": [],
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
@@ -3800,4 +3800,10 @@ class AppLocalizations {
|
||||
name: 'messageWarningDialogForForwardsToOtherDomains'
|
||||
);
|
||||
}
|
||||
|
||||
String get externalDomain {
|
||||
return Intl.message(
|
||||
'External domain',
|
||||
name: 'externalDomain');
|
||||
}
|
||||
}
|
||||
@@ -5,27 +5,27 @@ void main() {
|
||||
group('EmailUtils', () {
|
||||
test('isSameDomain should return true when email is from the same domain as server', () {
|
||||
String emailAddress = 'user@example.com';
|
||||
String serverDomain = 'example.com';
|
||||
String internalDomain = 'example.com';
|
||||
|
||||
bool result = EmailUtils.isSameDomain(emailAddress: emailAddress, serverDomain: serverDomain);
|
||||
bool result = EmailUtils.isSameDomain(emailAddress: emailAddress, internalDomain: internalDomain);
|
||||
|
||||
expect(result, true);
|
||||
});
|
||||
|
||||
test('isSameDomain should return false when email is not from the same domain as server', () {
|
||||
String emailAddress = 'user@example.com';
|
||||
String serverDomain = 'example2.com';
|
||||
String internalDomain = 'example2.com';
|
||||
|
||||
bool result = EmailUtils.isSameDomain(emailAddress: emailAddress, serverDomain: serverDomain);
|
||||
bool result = EmailUtils.isSameDomain(emailAddress: emailAddress, internalDomain: internalDomain);
|
||||
|
||||
expect(result, false);
|
||||
});
|
||||
|
||||
test('isSameDomain should return false when email is invalid', () {
|
||||
String emailAddress = 'invalid_email';
|
||||
String serverDomain = 'example.com';
|
||||
String internalDomain = 'example.com';
|
||||
|
||||
bool result = EmailUtils.isSameDomain(emailAddress: emailAddress, serverDomain: serverDomain);
|
||||
bool result = EmailUtils.isSameDomain(emailAddress: emailAddress, internalDomain: internalDomain);
|
||||
|
||||
expect(result, false);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/account/account.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/state.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/user_name.dart';
|
||||
import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.dart';
|
||||
|
||||
void main() {
|
||||
group('get internal domain in session test', () {
|
||||
test('When username is valid email, internalDomain should be returns the domain', () {
|
||||
final Session session = Session(
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
UserName('example@example.com'),
|
||||
Uri.parse('http://domain.com/jmap'),
|
||||
Uri.parse('http://domain.com/download/{accountId}/{blobId}/?type={type}&name={name}'),
|
||||
Uri.parse('http://domain.com/upload/{accountId}'),
|
||||
Uri.parse('http://domain.com/eventSource?types={types}&closeAfter={closeafter}&ping={ping}'),
|
||||
State('2c9f1b12-b35a-43e6-9af2-0106fb53a943')
|
||||
);
|
||||
|
||||
String result = session.internalDomain;
|
||||
|
||||
expect(result, equals('example.com'));
|
||||
});
|
||||
|
||||
test('When personal account name is valid email, internalDomain should be returns the domain', () {
|
||||
final Session session = Session(
|
||||
{},
|
||||
{
|
||||
AccountId(Id('29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6')): Account(AccountName('example@example.com'), true, false, {})
|
||||
},
|
||||
{},
|
||||
UserName('example'),
|
||||
Uri.parse('http://domain.com/jmap'),
|
||||
Uri.parse('http://domain.com/download/{accountId}/{blobId}/?type={type}&name={name}'),
|
||||
Uri.parse('http://domain.com/upload/{accountId}'),
|
||||
Uri.parse('http://domain.com/eventSource?types={types}&closeAfter={closeafter}&ping={ping}'),
|
||||
State('2c9f1b12-b35a-43e6-9af2-0106fb53a943')
|
||||
);
|
||||
|
||||
String result = session.internalDomain;
|
||||
|
||||
expect(result, equals('example.com'));
|
||||
});
|
||||
|
||||
test('When neither username nor personal account name is valid email, internalDomain should be returns an empty string', () {
|
||||
final Session session = Session(
|
||||
{},
|
||||
{
|
||||
AccountId(Id('29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6')): Account(AccountName('example'), true, false, {})
|
||||
},
|
||||
{},
|
||||
UserName('example'),
|
||||
Uri.parse('http://domain.com/jmap'),
|
||||
Uri.parse('http://domain.com/download/{accountId}/{blobId}/?type={type}&name={name}'),
|
||||
Uri.parse('http://domain.com/upload/{accountId}'),
|
||||
Uri.parse('http://domain.com/eventSource?types={types}&closeAfter={closeafter}&ping={ping}'),
|
||||
State('2c9f1b12-b35a-43e6-9af2-0106fb53a943')
|
||||
);
|
||||
|
||||
String result = session.internalDomain;
|
||||
|
||||
expect(result, equals(''));
|
||||
});
|
||||
|
||||
test('When personalAccount throw an exception, internalDomain should be returns an empty string', () {
|
||||
final Session session = Session(
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
UserName('example'),
|
||||
Uri.parse('http://domain.com/jmap'),
|
||||
Uri.parse('http://domain.com/download/{accountId}/{blobId}/?type={type}&name={name}'),
|
||||
Uri.parse('http://domain.com/upload/{accountId}'),
|
||||
Uri.parse('http://domain.com/eventSource?types={types}&closeAfter={closeafter}&ping={ping}'),
|
||||
State('2c9f1b12-b35a-43e6-9af2-0106fb53a943')
|
||||
);
|
||||
|
||||
final result = session.internalDomain;
|
||||
|
||||
expect(result, equals(''));
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user