Support RTL mode for alignment composer
(cherry picked from commit 4146fd960c379973c83eb4e0ea35680a98f4bc41)
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:core/presentation/extensions/color_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/utils/direction_utils.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:filesize/filesize.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
@@ -8,7 +13,6 @@ import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
|
||||
import 'package:tmail_ui_user/features/upload/presentation/model/upload_file_state.dart';
|
||||
import 'package:tmail_ui_user/features/upload/presentation/model/upload_file_status.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
import 'package:tmail_ui_user/main/utils/app_utils.dart';
|
||||
|
||||
typedef OnDeleteAttachmentAction = void Function(UploadFileState fileState);
|
||||
|
||||
@@ -18,7 +22,7 @@ class AttachmentFileComposerBuilder extends StatelessWidget with AppLoaderMixin
|
||||
|
||||
final UploadFileState fileState;
|
||||
final double? maxWidth;
|
||||
final EdgeInsets? itemMargin;
|
||||
final EdgeInsetsGeometry? itemMargin;
|
||||
final OnDeleteAttachmentAction? onDeleteAttachmentAction;
|
||||
final Widget? buttonAction;
|
||||
|
||||
@@ -52,10 +56,9 @@ class AttachmentFileComposerBuilder extends StatelessWidget with AppLoaderMixin
|
||||
hoverColor: AppColor.primaryColor,
|
||||
onTap: () {},
|
||||
leading: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: AppUtils.isDirectionRTL(context) ? 0 : 8,
|
||||
right: AppUtils.isDirectionRTL(context) ? 8 : 0,
|
||||
bottom: BuildUtils.isWeb ? 6 : 14
|
||||
padding: const EdgeInsetsDirectional.only(
|
||||
start: 8,
|
||||
bottom: PlatformInfo.isWeb ? 6 : 14
|
||||
),
|
||||
child: SvgPicture.asset(
|
||||
fileState.getIcon(_imagePaths),
|
||||
@@ -65,14 +68,11 @@ class AttachmentFileComposerBuilder extends StatelessWidget with AppLoaderMixin
|
||||
),
|
||||
title: Transform(
|
||||
transform: Matrix4.translationValues(
|
||||
AppUtils.isDirectionRTL(context) ? 0.0 : BuildUtils.isWeb ? 0.0 : -8.0,
|
||||
BuildUtils.isWeb ? -8.0 : -10.0,
|
||||
0.0),
|
||||
DirectionUtils.isDirectionRTLByLanguage(context) ? 0.0 : (PlatformInfo.isWeb ? 0.0 : -8.0),
|
||||
PlatformInfo.isWeb ? -8.0 : -10.0,
|
||||
0.0),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
right: AppUtils.isDirectionRTL(context) ? 0 : BuildUtils.isWeb ? 20 : 16,
|
||||
left: AppUtils.isDirectionRTL(context) ? BuildUtils.isWeb ? 20 : 16 : 0
|
||||
),
|
||||
padding: const EdgeInsetsDirectional.only(end: PlatformInfo.isWeb ? 20 : 16),
|
||||
child: Text(
|
||||
fileState.fileName,
|
||||
maxLines: 1,
|
||||
@@ -88,9 +88,9 @@ class AttachmentFileComposerBuilder extends StatelessWidget with AppLoaderMixin
|
||||
subtitle: fileState.fileSize != 0
|
||||
? Transform(
|
||||
transform: Matrix4.translationValues(
|
||||
AppUtils.isDirectionRTL(context) ? 0.0 : BuildUtils.isWeb ? 0.0 : -8.0,
|
||||
BuildUtils.isWeb ? -8.0 : -10.0,
|
||||
0.0),
|
||||
DirectionUtils.isDirectionRTLByLanguage(context) ? 0.0 : PlatformInfo.isWeb ? 0.0 : -8.0,
|
||||
PlatformInfo.isWeb ? -8.0 : -10.0,
|
||||
0.0),
|
||||
child: Text(
|
||||
filesize(fileState.fileSize),
|
||||
maxLines: 1,
|
||||
@@ -102,35 +102,20 @@ class AttachmentFileComposerBuilder extends StatelessWidget with AppLoaderMixin
|
||||
color: AppColor.colorContentEmail)))
|
||||
: null,
|
||||
),
|
||||
if (AppUtils.isDirectionRTL(context))
|
||||
Positioned(
|
||||
left: BuildUtils.isWeb ? -5 : -12,
|
||||
top: BuildUtils.isWeb ? -5 : -12,
|
||||
child: buildIconWeb(
|
||||
icon: SvgPicture.asset(_imagePaths.icDeleteAttachment, fit: BoxFit.fill),
|
||||
tooltip: AppLocalizations.of(context).delete,
|
||||
onTap: () {
|
||||
if (onDeleteAttachmentAction != null) {
|
||||
onDeleteAttachmentAction!.call(fileState);
|
||||
}
|
||||
PositionedDirectional(
|
||||
end: PlatformInfo.isWeb ? -5 : -12,
|
||||
top: PlatformInfo.isWeb ? -5 : -12,
|
||||
child: buildIconWeb(
|
||||
icon: SvgPicture.asset(_imagePaths.icDeleteAttachment, fit: BoxFit.fill),
|
||||
tooltip: AppLocalizations.of(context).delete,
|
||||
onTap: () {
|
||||
if (onDeleteAttachmentAction != null) {
|
||||
onDeleteAttachmentAction!.call(fileState);
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
else
|
||||
Positioned(
|
||||
right: BuildUtils.isWeb ? -5 : -12,
|
||||
top: BuildUtils.isWeb ? -5 : -12,
|
||||
child: buildIconWeb(
|
||||
icon: SvgPicture.asset(_imagePaths.icDeleteAttachment, fit: BoxFit.fill),
|
||||
tooltip: AppLocalizations.of(context).delete,
|
||||
onTap: () {
|
||||
if (onDeleteAttachmentAction != null) {
|
||||
onDeleteAttachmentAction!.call(fileState);
|
||||
}
|
||||
}
|
||||
)
|
||||
),
|
||||
Align(alignment: Alignment.bottomCenter, child: _progressLoading),
|
||||
),
|
||||
Align(alignment: AlignmentDirectional.bottomCenter, child: _progressLoading),
|
||||
]),
|
||||
)
|
||||
);
|
||||
|
||||
@@ -13,6 +13,7 @@ import 'package:model/model.dart';
|
||||
import 'package:super_tag_editor/tag_editor.dart';
|
||||
import 'package:super_tag_editor/widgets/rich_text_widget.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/prefix_email_address_extension.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/styles/composer_style.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/widgets/suggestion_email_address.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
import 'package:tmail_ui_user/main/utils/app_constants.dart';
|
||||
@@ -30,6 +31,7 @@ class EmailAddressInputBuilder {
|
||||
static const _suggestionBoxRadius = 20.0;
|
||||
final BuildContext _context;
|
||||
final ImagePaths _imagePaths;
|
||||
final ResponsiveUtils _responsiveUtils;
|
||||
final ExpandMode expandMode;
|
||||
final PrefixEmailAddress _prefixEmailAddress;
|
||||
final List<PrefixEmailAddress> _listEmailAddressType;
|
||||
@@ -77,13 +79,14 @@ class EmailAddressInputBuilder {
|
||||
_onFocusEmailAddressChangeAction = onFocusEmailAddressChangeAction;
|
||||
}
|
||||
|
||||
void addOnFocusNextAddressAction(OnFocusNextAddressAction onFocusNextAddressAction) {
|
||||
void addOnFocusNextAddressAction(OnFocusNextAddressAction? onFocusNextAddressAction) {
|
||||
_onFocusNextAddressAction = onFocusNextAddressAction;
|
||||
}
|
||||
|
||||
EmailAddressInputBuilder(
|
||||
this._context,
|
||||
this._imagePaths,
|
||||
this._responsiveUtils,
|
||||
this._prefixEmailAddress,
|
||||
this.listEmailAddress,
|
||||
this._listEmailAddressType,
|
||||
@@ -99,41 +102,55 @@ class EmailAddressInputBuilder {
|
||||
);
|
||||
|
||||
Widget build() {
|
||||
return Row(
|
||||
children: [
|
||||
Text('${_prefixEmailAddress.asName(_context)}:',
|
||||
style: const TextStyle(fontSize: 15, color: AppColor.colorHintEmailAddressInput)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: Padding(
|
||||
padding: EdgeInsets.only(right: _listEmailAddressType.length == 2 ? 8 : 8),
|
||||
child: _buildTagEditor())),
|
||||
if (_prefixEmailAddress == PrefixEmailAddress.to)
|
||||
Row(children: [
|
||||
if (!_listEmailAddressType.contains(PrefixEmailAddress.cc))
|
||||
buildTextIcon(AppLocalizations.of(_context).cc_email_address_prefix,
|
||||
padding: const EdgeInsets.all(5),
|
||||
textStyle: const TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.normal,
|
||||
decoration: TextDecoration.underline,
|
||||
color: AppColor.lineItemListColor),
|
||||
onTap: () => _onAddEmailAddressTypeAction?.call(PrefixEmailAddress.cc)),
|
||||
if (!_listEmailAddressType.contains(PrefixEmailAddress.bcc))
|
||||
buildTextIcon(AppLocalizations.of(_context).bcc_email_address_prefix,
|
||||
return Padding(
|
||||
padding: _prefixEmailAddress == PrefixEmailAddress.to
|
||||
? ComposerStyle.getToAddressPadding(_context, _responsiveUtils)
|
||||
: ComposerStyle.getCcBccAddressPadding(_context, _responsiveUtils),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'${_prefixEmailAddress.asName(_context)}:',
|
||||
style: const TextStyle(
|
||||
fontSize: 15,
|
||||
color: AppColor.colorHintEmailAddressInput
|
||||
)
|
||||
),
|
||||
SizedBox(width: ComposerStyle.getSpace(_context, _responsiveUtils)),
|
||||
Expanded(child: _buildTagEditor()),
|
||||
SizedBox(width: ComposerStyle.getSpace(_context, _responsiveUtils)),
|
||||
if (_prefixEmailAddress == PrefixEmailAddress.to)
|
||||
Row(children: [
|
||||
if (!_listEmailAddressType.contains(PrefixEmailAddress.cc))
|
||||
buildTextIcon(AppLocalizations.of(_context).cc_email_address_prefix,
|
||||
padding: const EdgeInsets.all(5),
|
||||
textStyle: const TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.normal,
|
||||
decoration: TextDecoration.underline,
|
||||
color: AppColor.lineItemListColor),
|
||||
onTap: () => _onAddEmailAddressTypeAction?.call(PrefixEmailAddress.bcc)),
|
||||
const SizedBox(width: 10),
|
||||
]),
|
||||
if (_prefixEmailAddress != PrefixEmailAddress.to)
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(_imagePaths.icCloseComposer, fit: BoxFit.fill),
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.normal,
|
||||
decoration: TextDecoration.underline,
|
||||
color: AppColor.lineItemListColor),
|
||||
onTap: () => _onAddEmailAddressTypeAction?.call(PrefixEmailAddress.cc)),
|
||||
if (!_listEmailAddressType.contains(PrefixEmailAddress.bcc))
|
||||
buildTextIcon(AppLocalizations.of(_context).bcc_email_address_prefix,
|
||||
padding: const EdgeInsets.all(5),
|
||||
textStyle: const TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.normal,
|
||||
decoration: TextDecoration.underline,
|
||||
color: AppColor.lineItemListColor),
|
||||
onTap: () => _onAddEmailAddressTypeAction?.call(PrefixEmailAddress.bcc)),
|
||||
])
|
||||
else
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(
|
||||
_imagePaths.icCloseComposer,
|
||||
width: 28,
|
||||
height: 28,
|
||||
fit: BoxFit.fill
|
||||
),
|
||||
iconPadding: EdgeInsets.zero,
|
||||
onTap: () => _onDeleteEmailAddressTypeAction?.call(_prefixEmailAddress))
|
||||
]
|
||||
]
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,8 +36,8 @@ class ToolbarRichTextWebBuilder extends StatelessWidget with RichTextButtonMixin
|
||||
final opacity = codeViewEnabled ? 0.5 : 1.0;
|
||||
|
||||
return Container(
|
||||
padding: padding ?? const EdgeInsets.only(left: 20, top: 8, bottom: 8),
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: padding ?? const EdgeInsetsDirectional.only(start: 20, top: 8, bottom: 8),
|
||||
alignment: AlignmentDirectional.centerStart,
|
||||
child: Wrap(
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
runSpacing: 8,
|
||||
@@ -93,7 +93,7 @@ class ToolbarRichTextWebBuilder extends StatelessWidget with RichTextButtonMixin
|
||||
supportSelectionIcon: true)),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 4.0),
|
||||
padding: const EdgeInsetsDirectional.only(end: 4.0),
|
||||
child: AbsorbPointer(
|
||||
absorbing: codeViewEnabled,
|
||||
child: buildWrapIconStyleText(
|
||||
@@ -106,7 +106,7 @@ class ToolbarRichTextWebBuilder extends StatelessWidget with RichTextButtonMixin
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 4.0),
|
||||
padding: const EdgeInsetsDirectional.only(end: 4.0),
|
||||
child: AbsorbPointer(
|
||||
absorbing: codeViewEnabled,
|
||||
child: buildWrapIconStyleText(
|
||||
@@ -121,7 +121,7 @@ class ToolbarRichTextWebBuilder extends StatelessWidget with RichTextButtonMixin
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 4.0),
|
||||
padding: const EdgeInsetsDirectional.only(end: 4.0),
|
||||
child: buildWrapIconStyleText(
|
||||
hasDropdown: false,
|
||||
padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 5),
|
||||
@@ -166,7 +166,7 @@ class ToolbarRichTextWebBuilder extends StatelessWidget with RichTextButtonMixin
|
||||
])),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 4.0),
|
||||
padding: const EdgeInsetsDirectional.only(end: 4.0),
|
||||
child: AbsorbPointer(
|
||||
absorbing: codeViewEnabled,
|
||||
child: PopupMenuOverlayWidget(
|
||||
@@ -190,7 +190,7 @@ class ToolbarRichTextWebBuilder extends StatelessWidget with RichTextButtonMixin
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 4.0),
|
||||
padding: const EdgeInsetsDirectional.only(end: 4.0),
|
||||
child: AbsorbPointer(
|
||||
absorbing: codeViewEnabled,
|
||||
child: PopupMenuOverlayWidget(
|
||||
|
||||
Reference in New Issue
Block a user