Support RTL mode for alignment composer

(cherry picked from commit 4146fd960c379973c83eb4e0ea35680a98f4bc41)
This commit is contained in:
dab246
2023-06-15 03:30:55 +07:00
committed by Dat H. Pham
parent 5c3833b72f
commit bf9e9b012b
12 changed files with 1225 additions and 1461 deletions
@@ -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(