TF-2666 Apply new UI for edit recipient card on mobile
Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:core/presentation/utils/theme_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/model/email_address_action_type.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
typedef OnClickEmailAddressAction = void Function(EmailAddressActionType actionType);
|
||||
|
||||
class EmailAddressActionWidget extends StatelessWidget {
|
||||
final ImagePaths imagePaths;
|
||||
final EmailAddressActionType actionType;
|
||||
final OnClickEmailAddressAction onClick;
|
||||
|
||||
const EmailAddressActionWidget({
|
||||
super.key,
|
||||
required this.imagePaths,
|
||||
required this.actionType,
|
||||
required this.onClick,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
type: MaterialType.transparency,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: InkWell(
|
||||
onTap: () => onClick(actionType),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 36,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 14),
|
||||
child: Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
actionType.getContextMenuIcon(imagePaths),
|
||||
width: 20,
|
||||
height: 20,
|
||||
colorFilter: AppColor.steelGrayA540.asFilter(),
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
const SizedBox(width: 22),
|
||||
Expanded(
|
||||
child: Text(
|
||||
actionType.getContextMenuTitle(AppLocalizations.of(context)),
|
||||
style: ThemeUtils.textStyleInter400.copyWith(
|
||||
fontSize: 14,
|
||||
height: 21.01 / 14,
|
||||
letterSpacing: -0.15,
|
||||
color: AppColor.gray424244.withOpacity(0.9),
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import 'package:core/utils/platform_info.dart';
|
||||
import 'package:core/utils/string_convert.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||
import 'package:model/email/prefix_email_address.dart';
|
||||
import 'package:model/extensions/email_address_extension.dart';
|
||||
@@ -77,6 +78,7 @@ class RecipientComposerWidget extends StatefulWidget {
|
||||
final bool isTestingForWeb;
|
||||
final int minInputLengthAutocomplete;
|
||||
final String? composerId;
|
||||
final VoidCallback? onClearFocusAction;
|
||||
|
||||
const RecipientComposerWidget({
|
||||
super.key,
|
||||
@@ -110,6 +112,7 @@ class RecipientComposerWidget extends StatefulWidget {
|
||||
this.onEnableAllRecipientsInputAction,
|
||||
this.focusNodeKeyboard,
|
||||
this.onEditRecipientAction,
|
||||
this.onClearFocusAction,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -118,6 +121,8 @@ class RecipientComposerWidget extends StatefulWidget {
|
||||
|
||||
class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
|
||||
|
||||
final _responsiveUtils = Get.find<ResponsiveUtils>();
|
||||
|
||||
Timer? _gapBetweenTagChangedAndFindSuggestion;
|
||||
bool _lastTagFocused = false;
|
||||
bool _isDragging = false;
|
||||
@@ -224,9 +229,11 @@ class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
|
||||
isCollapsed: _isCollapse,
|
||||
isLatestTagFocused: _lastTagFocused,
|
||||
maxWidth: widget.maxWidth,
|
||||
isMobile: _responsiveUtils.isMobile(context),
|
||||
onDeleteTagAction: (emailAddress) => _handleDeleteTagAction.call(emailAddress, stateSetter),
|
||||
onShowFullAction: widget.onShowFullListEmailAddressAction,
|
||||
onEditRecipientAction: widget.onEditRecipientAction,
|
||||
onClearFocusAction: widget.onClearFocusAction,
|
||||
);
|
||||
},
|
||||
onTagChanged: (value) => _handleOnTagChangeAction.call(value, stateSetter),
|
||||
@@ -317,9 +324,11 @@ class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
|
||||
isCollapsed: _isCollapse,
|
||||
isLatestTagFocused: _lastTagFocused,
|
||||
maxWidth: widget.maxWidth,
|
||||
isMobile: _responsiveUtils.isMobile(context),
|
||||
onDeleteTagAction: (emailAddress) => _handleDeleteTagAction.call(emailAddress, stateSetter),
|
||||
onShowFullAction: widget.onShowFullListEmailAddressAction,
|
||||
onEditRecipientAction: widget.onEditRecipientAction,
|
||||
onClearFocusAction: widget.onClearFocusAction,
|
||||
);
|
||||
},
|
||||
onTagChanged: (value) => _handleOnTagChangeAction.call(value, stateSetter),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:core/presentation/views/text/rich_text_builder.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||
@@ -50,7 +49,6 @@ class RecipientSuggestionItemWidget extends StatelessWidget {
|
||||
child: Padding(
|
||||
padding: RecipientSuggestionItemWidgetStyle.labelPadding,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
AvatarSuggestionItemWidget(emailAddress: emailAddress),
|
||||
const SizedBox(width: 8),
|
||||
@@ -58,18 +56,22 @@ class RecipientSuggestionItemWidget extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
RichTextWidget(
|
||||
textOrigin: emailAddress.asString(),
|
||||
wordSearched: suggestionValid ?? '',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
),
|
||||
if (emailAddress.displayName.isNotEmpty)
|
||||
RichTextBuilder(
|
||||
RichTextWidget(
|
||||
textOrigin: emailAddress.emailAddress,
|
||||
wordToStyle: suggestionValid ?? '',
|
||||
styleOrigin: RecipientSuggestionItemWidgetStyle.labelTextStyle,
|
||||
styleWord: RecipientSuggestionItemWidgetStyle.labelHighlightTextStyle,
|
||||
wordSearched: suggestionValid ?? '',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
styleTextOrigin: RecipientSuggestionItemWidgetStyle.labelTextStyle,
|
||||
styleWordSearched: RecipientSuggestionItemWidgetStyle.labelHighlightTextStyle,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -98,7 +100,6 @@ class RecipientSuggestionItemWidget extends StatelessWidget {
|
||||
child: Padding(
|
||||
padding: RecipientSuggestionItemWidgetStyle.labelPadding,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
AvatarSuggestionItemWidget(emailAddress: emailAddress),
|
||||
const SizedBox(width: 8),
|
||||
@@ -106,18 +107,22 @@ class RecipientSuggestionItemWidget extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
RichTextWidget(
|
||||
textOrigin: emailAddress.asString(),
|
||||
wordSearched: suggestionValid ?? '',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
),
|
||||
if (emailAddress.displayName.isNotEmpty)
|
||||
RichTextBuilder(
|
||||
RichTextWidget(
|
||||
textOrigin: emailAddress.emailAddress,
|
||||
wordToStyle: suggestionValid ?? '',
|
||||
styleOrigin: RecipientSuggestionItemWidgetStyle.labelTextStyle,
|
||||
styleWord: RecipientSuggestionItemWidgetStyle.labelHighlightTextStyle,
|
||||
wordSearched: suggestionValid ?? '',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
styleTextOrigin: RecipientSuggestionItemWidgetStyle.labelTextStyle,
|
||||
styleWordSearched: RecipientSuggestionItemWidgetStyle.labelHighlightTextStyle,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -36,6 +36,8 @@ class RecipientTagItemWidget extends StatelessWidget {
|
||||
final OnEditRecipientAction? onEditRecipientAction;
|
||||
final bool isTestingForWeb;
|
||||
final String? composerId;
|
||||
final bool isMobile;
|
||||
final VoidCallback? onClearFocusAction;
|
||||
|
||||
const RecipientTagItemWidget({
|
||||
super.key,
|
||||
@@ -49,28 +51,39 @@ class RecipientTagItemWidget extends StatelessWidget {
|
||||
this.isCollapsed = false,
|
||||
this.isLatestTagFocused = false,
|
||||
this.isLatestEmail = false,
|
||||
this.isMobile = false,
|
||||
this.onShowFullAction,
|
||||
this.onDeleteTagAction,
|
||||
this.onEditRecipientAction,
|
||||
this.maxWidth,
|
||||
this.composerId,
|
||||
this.onClearFocusAction,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final overlayWidth = isMobile ? 227.0 : 361.0;
|
||||
Widget tagWidget = CardWithSmartInteractionOverlayView(
|
||||
overlayWidth: overlayWidth,
|
||||
menuBuilder: (onClose) => EditRecipientsView(
|
||||
emailAddress: currentEmailAddress,
|
||||
imagePaths: imagePaths,
|
||||
onCopyAction: () => _onEditRecipientAction(
|
||||
context,
|
||||
EmailAddressActionType.copy,
|
||||
),
|
||||
isMobile: isMobile,
|
||||
width: overlayWidth,
|
||||
onCopyAction: () {
|
||||
if (isMobile) {
|
||||
onClose();
|
||||
}
|
||||
_onEditRecipientAction(
|
||||
context,
|
||||
EmailAddressActionType.copy,
|
||||
);
|
||||
},
|
||||
onEditAction: () {
|
||||
onClose();
|
||||
_onEditRecipientAction(
|
||||
context,
|
||||
EmailAddressActionType.modify,
|
||||
EmailAddressActionType.edit,
|
||||
);
|
||||
},
|
||||
onCreateRuleAction: () {
|
||||
@@ -82,6 +95,7 @@ class RecipientTagItemWidget extends StatelessWidget {
|
||||
},
|
||||
onCloseAction: onClose,
|
||||
),
|
||||
onClearFocusAction: onClearFocusAction,
|
||||
child: Chip(
|
||||
labelPadding: EdgeInsetsDirectional.symmetric(
|
||||
horizontal: 4,
|
||||
|
||||
Reference in New Issue
Block a user