TF-3410 Use TextTheme apply almost text style for text widget

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2025-03-10 02:18:34 +07:00
committed by Dat H. Pham
parent efe1c801c1
commit a258dec4ee
87 changed files with 1774 additions and 1776 deletions
-3
View File
@@ -1,3 +0,0 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9 0.5C9.55229 0.5 10 0.947716 10 1.5L10 8H16.5C17.0523 8 17.5 8.44772 17.5 9C17.5 9.55228 17.0523 10 16.5 10H10L10 16.5001C10 17.0524 9.55229 17.5001 9 17.5001C8.44772 17.5001 8 17.0524 8 16.5001L7.999 10H1.5C0.947715 10 0.5 9.55228 0.5 9C0.5 8.44772 0.947715 8 1.5 8H7.999L8 1.5C8 0.947716 8.44772 0.5 9 0.5Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 439 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41Z" fill="#55687D"/>
</svg>

After

Width:  |  Height:  |  Size: 240 B

+6 -6
View File
@@ -292,10 +292,10 @@ packages:
dependency: transitive
description:
name: ffi
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.1.3"
file:
dependency: transitive
description:
@@ -1273,18 +1273,18 @@ packages:
dependency: transitive
description:
name: win32
sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c"
sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4
url: "https://pub.dev"
source: hosted
version: "4.1.4"
version: "5.5.1"
win32_registry:
dependency: transitive
description:
name: win32_registry
sha256: "1c52f994bdccb77103a6231ad4ea331a244dbcef5d1f37d8462f713143b0bfae"
sha256: "723b7f851e5724c55409bb3d5a32b203b3afe8587eaf5dafb93a5fed8ecda0d6"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
version: "1.1.4"
xdg_directories:
dependency: transitive
description:
@@ -111,7 +111,6 @@ extension AppColor on Color {
static const colorBorderIdentityInfo = Color(0xFFE7E8EC);
static const colorBgMailboxSelected = Color(0x99E4E8EC);
static const colorLoading = Color(0x2999A2AD);
static const colorActionButtonHover = Color(0xFFA2AAB3);
static const colorBgMenuItemDropDownSelected = Color(0x80DEE2E7);
static const colorButtonCancelDialog = Color(0x0D000000);
static const colorShadowComposerButton = Color(0x99007AFF);
@@ -245,7 +244,7 @@ extension AppColor on Color {
static const blue400 = Color(0xFF80BDFF);
static const m3Tertiary = Color(0xFF8C9CAF);
static const m3Neutral70 = Color(0xFFAEAAAE);
static const colorF3F6F9 = Color(0xFFF3F6F9);
static const grayBackgroundColor = Color(0xFFF3F6F9);
static const m3SurfaceBackground = Color(0xFF1C1B1F);
static const mapGradientColor = [
@@ -38,4 +38,6 @@ extension StringExtension on String {
return '';
}
}
String get firstCharacterToUpperCase => isNotEmpty ? this[0].toUpperCase() : '';
}
@@ -141,7 +141,6 @@ class ImagePaths {
String get icSwitchOff => _getImagePath('ic_switch_off.svg');
String get icClock => _getImagePath('ic_clock.svg');
String get icCalendar => _getImagePath('ic_calendar.svg');
String get icAddEmailForward => _getImagePath('ic_add_email_forwards.svg');
String get icChevronDownOutline => _getImagePath('ic_chevron_down_outline.svg');
String get icUndo => _getImagePath('ic_undo.svg');
String get icDownloadAttachment => _getImagePath('ic_download_attachment.svg');
@@ -227,6 +226,7 @@ class ImagePaths {
String get icSubaddressingAllow => _getImagePath('ic_subaddressing_allow.svg');
String get icSubaddressingDisallow => _getImagePath('ic_subaddressing_disallow.svg');
String get icMarkAsImportant => _getImagePath('ic_mark_as_important.svg');
String get icCloseDialog => _getImagePath('ic_close_dialog.svg');
String _getImagePath(String imageName) {
return AssetsPaths.images + imageName;
+111 -2
View File
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class ThemeUtils {
ThemeUtils._();
static ThemeData get appTheme {
return ThemeData(
@@ -23,11 +24,119 @@ class ThemeUtils {
static TextTheme get _textTheme {
return const TextTheme(
bodyMedium: TextStyle(color: AppColor.baseTextColor),
bodySmall: TextStyle(color: AppColor.baseTextColor),
bodyLarge: TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.w500,
letterSpacing: -0.15,
fontSize: 17,
height: 24 / 17,
),
bodyMedium: TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.w500,
letterSpacing: 0.25,
),
bodySmall: TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.w400,
letterSpacing: 0.0,
fontSize: 13,
height: 16 / 13
),
labelLarge: TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.w500,
letterSpacing: 0.1,
),
labelSmall: TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.w500,
letterSpacing: 0.5,
),
displayLarge: TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.w700,
),
displayMedium: TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.w600,
letterSpacing: 0.4,
),
displaySmall: TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.w600,
letterSpacing: 0.4,
),
headlineMedium: TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.w600,
),
headlineSmall: TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.w600,
letterSpacing: 0.4,
),
headlineLarge: TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.w600,
fontSize: 32,
),
titleLarge: TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.w600,
letterSpacing: 0.0,
fontSize: 22,
height: 28 / 22,
),
titleMedium: TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.w500,
letterSpacing: 0.15,
),
titleSmall: TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.w500,
letterSpacing: 0.1,
),
);
}
static TextStyle textStyleBodyBody1({Color? color, FontWeight? fontWeight}) => TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: fontWeight ?? FontWeight.w500,
letterSpacing: 0.0,
fontSize: 16,
height: 20 / 16,
color: color,
);
static TextStyle textStyleBodyBody2({Color? color, FontWeight? fontWeight}) => TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: fontWeight ?? FontWeight.w400,
letterSpacing: 0.0,
fontSize: 15,
height: 20 / 15,
color: color,
);
static TextStyle textStyleBodyBody3({Color? color, FontWeight? fontWeight}) => TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: fontWeight ?? FontWeight.w400,
letterSpacing: 0.0,
fontSize: 14,
height: 18 / 14,
color: color,
);
static TextStyle textStyleHeadingH6({Color? color, FontWeight? fontWeight}) => TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: fontWeight ?? FontWeight.w700,
letterSpacing: 0.0,
fontSize: 20,
height: 24 / 20,
color: color,
);
static TextSelectionThemeData get _textSelectionTheme {
return const TextSelectionThemeData(
cursorColor: AppColor.primaryColor,
@@ -66,7 +66,10 @@ class ConfirmationDialogActionSheetBuilder {
child: Text(
_messageText ?? '',
textAlign: TextAlign.center,
style: _styleMessage ?? const TextStyle(fontSize: 14, color: AppColor.colorMessageConfirmDialog)),
style: _styleMessage ?? Theme.of(context).textTheme.bodyLarge?.copyWith(
color: AppColor.steelGrayA540,
),
),
onPressed: () => {},
),
)
@@ -79,7 +82,9 @@ class ConfirmationDialogActionSheetBuilder {
cursor: PlatformInfo.isWeb ? WidgetStateMouseCursor.clickable : MouseCursor.defer,
child: CupertinoActionSheetAction(
child: RichText(text: TextSpan(
style: _styleMessage ?? const TextStyle(fontSize: 14, color: AppColor.colorMessageConfirmDialog),
style: _styleMessage ?? Theme.of(context).textTheme.bodyLarge?.copyWith(
color: AppColor.steelGrayA540,
),
children: listTextSpan
)),
onPressed: () => {},
@@ -93,7 +98,9 @@ class ConfirmationDialogActionSheetBuilder {
child: CupertinoActionSheetAction(
child: Text(
_confirmText ?? '',
style: _styleConfirmButton ?? const TextStyle(fontWeight: FontWeight.w500, fontSize: 20, color: AppColor.colorActionDeleteConfirmDialog)),
style: _styleConfirmButton ?? Theme.of(context).textTheme.bodyLarge?.copyWith(
color: AppColor.steelGray600,
)),
onPressed: () => _onConfirmActionClick?.call(),
),
)
@@ -104,7 +111,9 @@ class ConfirmationDialogActionSheetBuilder {
child: CupertinoActionSheetAction(
child: Text(
_cancelText ?? '',
style: _styleCancelButton ?? const TextStyle(fontWeight: FontWeight.w500, fontSize: 20, color: AppColor.colorActionCancelDialog)),
style: _styleCancelButton ?? Theme.of(context).textTheme.bodyLarge?.copyWith(
color: Colors.white,
)),
onPressed: () => _onCancelActionClick?.call(),
),
),
@@ -8,17 +8,19 @@ class ConfirmDialogButton extends StatelessWidget {
final Color backgroundColor;
final EdgeInsetsGeometry? padding;
final int? maxLines;
final TextStyle textStyle;
final TextStyle? textStyle;
final Color? textColor;
final VoidCallback? onTapAction;
const ConfirmDialogButton({
super.key,
required this.label,
required this.textStyle,
required this.backgroundColor,
this.textStyle,
this.borderRadius,
this.padding,
this.maxLines,
this.textColor,
this.onTapAction
});
@@ -45,7 +47,9 @@ class ConfirmDialogButton extends StatelessWidget {
textAlign: TextAlign.center,
maxLines: maxLines,
overflow: TextOverflow.ellipsis,
style: textStyle
style: textStyle ?? Theme.of(context).textTheme.bodyLarge?.copyWith(
color: textColor,
)
),
),
),
@@ -1,5 +1,6 @@
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/views/button/tmail_button_widget.dart';
import 'package:core/presentation/views/dialog/confirm_dialog_button.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
@@ -8,354 +9,436 @@ typedef OnConfirmButtonAction = void Function();
typedef OnCancelButtonAction = void Function();
typedef OnCloseButtonAction = void Function();
class ConfirmDialogBuilder {
final ImagePaths _imagePath;
Key? _key;
String _title = '';
String _textContent = '';
String _confirmText = '';
String _cancelText = '';
Widget? _iconWidget;
Widget? _additionalWidgetContent;
Color? _colorCancelButton;
Color? _colorConfirmButton;
TextStyle? _styleTextCancelButton;
TextStyle? _styleTextConfirmButton;
TextStyle? _styleTitle;
TextStyle? _styleContent;
double? _radiusButton;
EdgeInsetsGeometry? _paddingTitle;
EdgeInsets? _paddingContent;
EdgeInsetsGeometry? _paddingButton;
EdgeInsets? _marginButton;
EdgeInsets? _outsideDialogPadding;
EdgeInsetsGeometry? _marginIcon;
EdgeInsets? _margin;
double? _widthDialog;
final double maxWith;
Alignment? _alignment;
Color? _backgroundColor;
class ConfirmationDialogBuilder extends StatelessWidget {
final ImagePaths imagePath;
final String title;
final String textContent;
final String confirmText;
final String cancelText;
final Widget? iconWidget;
final Widget? additionalWidgetContent;
final Color? colorCancelButton;
final Color? colorConfirmButton;
final TextStyle? styleTextCancelButton;
final TextStyle? styleTextConfirmButton;
final TextStyle? styleTitle;
final TextStyle? styleContent;
final double? radiusButton;
final EdgeInsetsGeometry? paddingTitle;
final EdgeInsetsGeometry? paddingContent;
final EdgeInsetsGeometry? paddingButton;
final EdgeInsetsGeometry? marginButton;
final EdgeInsets? outsideDialogPadding;
final EdgeInsetsGeometry? marginIcon;
final EdgeInsetsGeometry? margin;
final double? widthDialog;
final double maxWidth;
final Alignment? alignment;
final Color? backgroundColor;
final bool showAsBottomSheet;
final List<TextSpan>? listTextSpan;
final int? titleActionButtonMaxLines;
final bool isArrangeActionButtonsVertical;
final bool useIconAsBasicLogo;
final OnConfirmButtonAction? onConfirmButtonAction;
final OnCancelButtonAction? onCancelButtonAction;
final OnCloseButtonAction? onCloseButtonAction;
OnConfirmButtonAction? _onConfirmButtonAction;
OnCancelButtonAction? _onCancelButtonAction;
OnCloseButtonAction? _onCloseButtonAction;
const ConfirmationDialogBuilder({
super.key,
required this.imagePath,
this.title = '',
this.textContent = '',
this.confirmText = '',
this.cancelText = '',
this.iconWidget,
this.additionalWidgetContent,
this.colorCancelButton,
this.colorConfirmButton,
this.styleTextCancelButton,
this.styleTextConfirmButton,
this.styleTitle,
this.styleContent,
this.radiusButton,
this.paddingTitle,
this.paddingContent,
this.paddingButton,
this.marginButton,
this.outsideDialogPadding,
this.marginIcon,
this.margin,
this.widthDialog,
this.maxWidth = double.infinity,
this.alignment,
this.backgroundColor,
this.showAsBottomSheet = false,
this.listTextSpan,
this.titleActionButtonMaxLines,
this.isArrangeActionButtonsVertical = false,
this.useIconAsBasicLogo = false,
this.onConfirmButtonAction,
this.onCancelButtonAction,
this.onCloseButtonAction,
});
ConfirmDialogBuilder(
this._imagePath,
{
this.showAsBottomSheet = false,
this.listTextSpan,
this.maxWith = double.infinity,
this.titleActionButtonMaxLines,
this.isArrangeActionButtonsVertical = false,
this.useIconAsBasicLogo = false,
@override
Widget build(BuildContext context) {
return showAsBottomSheet
? _BodyContent(
imagePath: imagePath,
title: title,
textContent: textContent,
confirmText: confirmText,
cancelText: cancelText,
iconWidget: iconWidget,
additionalWidgetContent: additionalWidgetContent,
colorCancelButton: colorCancelButton,
colorConfirmButton: colorConfirmButton,
styleTextCancelButton: styleTextCancelButton,
styleTextConfirmButton: styleTextConfirmButton,
styleTitle: styleTitle,
styleContent: styleContent,
radiusButton: radiusButton,
paddingTitle: paddingTitle,
paddingContent: paddingContent,
paddingButton: paddingButton,
marginButton: marginButton,
marginIcon: marginIcon,
margin: margin,
widthDialog: widthDialog,
maxWidth: maxWidth,
listTextSpan: listTextSpan,
titleActionButtonMaxLines: titleActionButtonMaxLines,
isArrangeActionButtonsVertical: isArrangeActionButtonsVertical,
useIconAsBasicLogo: useIconAsBasicLogo,
onConfirmButtonAction: onConfirmButtonAction,
onCancelButtonAction: onCancelButtonAction,
onCloseButtonAction: onCloseButtonAction,
)
: Dialog(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(18))),
insetPadding: outsideDialogPadding,
alignment: alignment ?? Alignment.center,
backgroundColor: backgroundColor,
child: _BodyContent(
imagePath: imagePath,
title: title,
textContent: textContent,
confirmText: confirmText,
cancelText: cancelText,
iconWidget: iconWidget,
additionalWidgetContent: additionalWidgetContent,
colorCancelButton: colorCancelButton,
colorConfirmButton: colorConfirmButton,
styleTextCancelButton: styleTextCancelButton,
styleTextConfirmButton: styleTextConfirmButton,
styleTitle: styleTitle,
styleContent: styleContent,
radiusButton: radiusButton,
paddingTitle: paddingTitle,
paddingContent: paddingContent,
paddingButton: paddingButton,
marginButton: marginButton,
marginIcon: marginIcon,
margin: margin,
widthDialog: widthDialog,
maxWidth: maxWidth,
listTextSpan: listTextSpan,
titleActionButtonMaxLines: titleActionButtonMaxLines,
isArrangeActionButtonsVertical: isArrangeActionButtonsVertical,
useIconAsBasicLogo: useIconAsBasicLogo,
onConfirmButtonAction: onConfirmButtonAction,
onCancelButtonAction: onCancelButtonAction,
onCloseButtonAction: onCloseButtonAction,
),
);
}
}
class _BodyContent extends StatelessWidget {
final ImagePaths imagePath;
final String title;
final String textContent;
final String confirmText;
final String cancelText;
final Widget? iconWidget;
final Widget? additionalWidgetContent;
final Color? colorCancelButton;
final Color? colorConfirmButton;
final TextStyle? styleTextCancelButton;
final TextStyle? styleTextConfirmButton;
final TextStyle? styleTitle;
final TextStyle? styleContent;
final double? radiusButton;
final EdgeInsetsGeometry? paddingTitle;
final EdgeInsetsGeometry? paddingContent;
final EdgeInsetsGeometry? paddingButton;
final EdgeInsetsGeometry? marginButton;
final EdgeInsetsGeometry? marginIcon;
final EdgeInsetsGeometry? margin;
final double? widthDialog;
final double maxWidth;
final List<TextSpan>? listTextSpan;
final int? titleActionButtonMaxLines;
final bool isArrangeActionButtonsVertical;
final bool useIconAsBasicLogo;
final OnConfirmButtonAction? onConfirmButtonAction;
final OnCancelButtonAction? onCancelButtonAction;
final OnCloseButtonAction? onCloseButtonAction;
const _BodyContent({
required this.imagePath,
required this.title,
required this.textContent,
required this.confirmText,
required this.cancelText,
this.iconWidget,
this.additionalWidgetContent,
this.colorCancelButton,
this.colorConfirmButton,
this.styleTextCancelButton,
this.styleTextConfirmButton,
this.styleTitle,
this.styleContent,
this.radiusButton,
this.paddingTitle,
this.paddingContent,
this.paddingButton,
this.marginButton,
this.marginIcon,
this.margin,
this.widthDialog,
required this.maxWidth,
this.listTextSpan,
this.titleActionButtonMaxLines,
required this.isArrangeActionButtonsVertical,
required this.useIconAsBasicLogo,
this.onConfirmButtonAction,
this.onCancelButtonAction,
this.onCloseButtonAction,
});
@override
Widget build(BuildContext context) {
return Container(
width: widthDialog ?? 400,
constraints: BoxConstraints(maxWidth: maxWidth),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(18)),
),
margin: margin,
padding: const EdgeInsetsDirectional.only(
top: 11,
end: 11,
start: 16,
bottom: 24,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
_buildCloseButton(),
_buildIcon(),
_buildTitle(context),
_buildContent(context),
_buildAdditionalContent(),
_buildActionButtons(context),
].where((widget) => widget != const SizedBox.shrink()).toList(),
),
);
}
Widget _buildCloseButton() {
return onCloseButtonAction != null
? Align(
alignment: AlignmentDirectional.topEnd,
child: TMailButtonWidget.fromIcon(
icon: imagePath.icCloseDialog,
iconSize: 29,
iconColor: AppColor.steelGrayA540,
padding: const EdgeInsets.all(5),
backgroundColor: Colors.transparent,
onTapActionCallback: onCloseButtonAction,
),
)
: const SizedBox(height: 24);
}
Widget _buildIcon() {
if (useIconAsBasicLogo) {
return Padding(
padding: const EdgeInsets.all(20),
child: SvgPicture.asset(
imagePath.icTMailLogo,
fit: BoxFit.fill,
width: 50,
height: 50,
),
);
} else if (iconWidget != null) {
return Container(
margin: marginIcon ?? EdgeInsets.zero,
alignment: Alignment.center,
child: iconWidget,
);
}
);
void key(Key key) {
_key = key;
return const SizedBox.shrink();
}
void title(String title) {
_title = title;
Widget _buildTitle(BuildContext context) {
return title.trim().isNotEmpty
? Padding(
padding: paddingTitle ??
const EdgeInsetsDirectional.only(top: 16, end: 5),
child: Center(
child: Text(
title,
textAlign: TextAlign.center,
style: styleTitle ??
Theme.of(context).textTheme.titleLarge?.copyWith(
color: AppColor.m3SurfaceBackground,
),
),
),
)
: const SizedBox.shrink();
}
void content(String content) {
_textContent = content;
Widget _buildContent(BuildContext context) {
if (textContent.trim().isNotEmpty) {
return Padding(
padding:
paddingContent ?? const EdgeInsetsDirectional.only(top: 16, end: 5),
child: Center(
child: Text(
textContent,
textAlign: TextAlign.center,
style: styleContent ??
Theme.of(context).textTheme.bodyLarge?.copyWith(
color: AppColor.steelGrayA540,
),
),
),
);
} else if (listTextSpan != null) {
return Padding(
padding:
paddingContent ?? const EdgeInsetsDirectional.only(top: 16, end: 5),
child: Center(
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: styleContent ??
Theme.of(context).textTheme.bodyLarge?.copyWith(
color: AppColor.steelGrayA540,
),
children: listTextSpan,
),
),
),
);
}
return const SizedBox.shrink();
}
void addWidgetContent(Widget? icon) {
_additionalWidgetContent = icon;
Widget _buildAdditionalContent() {
return additionalWidgetContent != null
? Padding(
padding: const EdgeInsetsDirectional.only(top: 16, end: 5),
child: additionalWidgetContent!,
)
: const SizedBox.shrink();
}
void addIcon(Widget? icon) {
_iconWidget = icon;
}
void colorCancelButton(Color? color) {
_colorCancelButton = color;
}
void colorConfirmButton(Color? color) {
_colorConfirmButton = color;
}
void styleTextCancelButton(TextStyle? style) {
_styleTextCancelButton = style;
}
void styleTextConfirmButton(TextStyle? style) {
_styleTextConfirmButton = style;
}
void styleTitle(TextStyle? style) {
_styleTitle = style;
}
void styleContent(TextStyle? style) {
_styleContent = style;
}
void radiusButton(double? radius) {
_radiusButton = radius;
}
void paddingTitle(EdgeInsetsGeometry? value) {
_paddingTitle = value;
}
void paddingContent(EdgeInsets? value) {
_paddingContent = value;
}
void paddingButton(EdgeInsetsGeometry? value) {
_paddingButton = value;
}
void marginButton(EdgeInsets? value) {
_marginButton = value;
}
void marginIcon(EdgeInsetsGeometry? value) {
_marginIcon = value;
}
void margin(EdgeInsets? value) {
_margin = value;
}
void widthDialog(double? value) {
_widthDialog = value;
}
void alignment(Alignment? alignment) {
_alignment = alignment;
}
void outsideDialogPadding(EdgeInsets? value) {
_outsideDialogPadding = value;
}
void backgroundColor(Color value) {
_backgroundColor = value;
}
void onConfirmButtonAction(String confirmText, OnConfirmButtonAction? onConfirmButtonAction) {
_confirmText = confirmText;
_onConfirmButtonAction = onConfirmButtonAction;
}
void onCancelButtonAction(String cancelText, OnCancelButtonAction? onCancelButtonAction) {
_cancelText = cancelText;
_onCancelButtonAction = onCancelButtonAction;
}
void onCloseButtonAction(OnCloseButtonAction? onCloseButtonAction) {
_onCloseButtonAction = onCloseButtonAction;
}
Widget build() {
if (showAsBottomSheet) {
return _bodyContent();
Widget _buildActionButtons(BuildContext context) {
if (isArrangeActionButtonsVertical) {
return Padding(
padding: marginButton ??
const EdgeInsetsDirectional.only(start: 15, end: 20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (cancelText.isNotEmpty)
Padding(
padding: const EdgeInsetsDirectional.only(top: 16),
child: _buildButton(
context,
cancelText,
onCancelButtonAction,
colorCancelButton,
styleTextCancelButton,
),
),
if (confirmText.isNotEmpty)
Padding(
padding: const EdgeInsetsDirectional.only(top: 16),
child: _buildButton(
context,
confirmText,
onConfirmButtonAction,
colorConfirmButton,
styleTextConfirmButton,
),
),
],
),
);
} else {
return Dialog(
key: _key,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(18))),
insetPadding: _outsideDialogPadding,
alignment: _alignment ?? Alignment.center,
backgroundColor: _backgroundColor,
child: _bodyContent(),
return Padding(
padding: marginButton ??
const EdgeInsetsDirectional.only(top: 16, start: 15, end: 20),
child: Row(
children: [
if (cancelText.isNotEmpty)
Expanded(
child: _buildButton(
context,
cancelText,
onCancelButtonAction,
colorCancelButton,
styleTextCancelButton,
),
),
if (confirmText.isNotEmpty && cancelText.isNotEmpty)
const SizedBox(width: 16),
if (confirmText.isNotEmpty)
Expanded(
child: _buildButton(
context,
confirmText,
onConfirmButtonAction,
colorConfirmButton,
styleTextConfirmButton,
),
),
],
),
);
}
}
Widget _bodyContent() {
return Container(
width: _widthDialog ?? 400,
constraints: BoxConstraints(maxWidth: maxWith),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(18)),
),
margin: _margin,
padding: const EdgeInsetsDirectional.only(
top: 8,
end: 8,
start: 16,
bottom: 24,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (_onCloseButtonAction != null)
Align(
alignment: AlignmentDirectional.topEnd,
child: TMailButtonWidget.fromIcon(
icon: _imagePath.icCancel,
iconSize: 24,
iconColor: AppColor.steelGrayA540,
padding: const EdgeInsets.all(5),
backgroundColor: Colors.transparent,
onTapActionCallback: _onCloseButtonAction,
),
)
else
const SizedBox(height: 24),
if (useIconAsBasicLogo)
SvgPicture.asset(
_imagePath.icTMailLogo,
fit: BoxFit.fill,
width: 70,
height: 70,
)
else if (_iconWidget != null)
Container(
margin: _marginIcon ?? EdgeInsets.zero,
alignment: Alignment.center,
child: _iconWidget,
),
if (_title.isNotEmpty)
Padding(
padding: _paddingTitle
?? const EdgeInsetsDirectional.only(top: 16, end: 8,),
child: Center(
child: Text(
_title,
textAlign: TextAlign.center,
style: _styleTitle ?? const TextStyle(
fontSize: 22.0,
color: AppColor.m3SurfaceBackground,
fontWeight: FontWeight.w600,
)
)
)
),
if (_textContent.isNotEmpty)
Padding(
padding: _paddingContent
?? const EdgeInsetsDirectional.only(top: 16, end: 8,),
child: Center(
child: Text(
_textContent,
textAlign: TextAlign.center,
style: _styleContent ?? const TextStyle(
fontSize: 17.0,
color: AppColor.steelGrayA540,
fontWeight: FontWeight.w500,
),
),
),
)
else if (listTextSpan != null)
Padding(
padding: _paddingContent ??
const EdgeInsetsDirectional.only(top: 16, end: 8,),
child: Center(
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: _styleContent ?? const TextStyle(
fontSize: 17.0,
color: AppColor.steelGrayA540,
fontWeight: FontWeight.w500,
),
children: listTextSpan,
),
),
),
),
if (_additionalWidgetContent != null)
Padding(
padding:const EdgeInsetsDirectional.only(top: 16, end: 8,),
child: _additionalWidgetContent,
),
if (isArrangeActionButtonsVertical)
...[
if (_cancelText.isNotEmpty)
Padding(
padding: const EdgeInsetsDirectional.only(top: 16, end: 8,),
child: ConfirmDialogButton(
label: _cancelText,
backgroundColor: _colorCancelButton ?? AppColor.blue700,
borderRadius: _radiusButton,
textStyle: _styleTextCancelButton ?? const TextStyle(
fontSize: 17,
height: 24 / 17,
fontWeight: FontWeight.w500,
color: Colors.white,
),
padding: _paddingButton,
maxLines: titleActionButtonMaxLines,
onTapAction: _onCancelButtonAction),
),
if (_confirmText.isNotEmpty)
Padding(
padding: const EdgeInsetsDirectional.only(top: 16, end: 8),
child: ConfirmDialogButton(
label: _confirmText,
backgroundColor: _colorConfirmButton ?? AppColor.colorF3F6F9,
borderRadius: _radiusButton,
textStyle: _styleTextConfirmButton ?? const TextStyle(
fontSize: 17,
height: 24 / 17,
fontWeight: FontWeight.w500,
color: AppColor.steelGray600,
),
padding: _paddingButton,
maxLines: titleActionButtonMaxLines,
onTapAction: _onConfirmButtonAction),
),
]
else
Padding(
padding: _marginButton
?? const EdgeInsetsDirectional.only(top: 16, end: 8),
child: Row(
children: [
if (_cancelText.isNotEmpty)
Expanded(child: ConfirmDialogButton(
label: _cancelText,
backgroundColor: _colorCancelButton ?? AppColor.blue700,
borderRadius: _radiusButton,
textStyle: _styleTextCancelButton ?? const TextStyle(
fontSize: 17,
height: 24 / 17,
fontWeight: FontWeight.w500,
color: Colors.white,
),
padding: _paddingButton,
maxLines: titleActionButtonMaxLines,
onTapAction: _onCancelButtonAction,
)),
if (_confirmText.isNotEmpty && _cancelText.isNotEmpty)
const SizedBox(width: 16),
if (_confirmText.isNotEmpty)
Expanded(child: ConfirmDialogButton(
label: _confirmText,
backgroundColor: _colorConfirmButton ?? AppColor.colorF3F6F9,
borderRadius: _radiusButton,
textStyle: _styleTextConfirmButton ?? const TextStyle(
fontSize: 17,
height: 24 / 17,
fontWeight: FontWeight.w500,
color: AppColor.steelGray600,
),
padding: _paddingButton,
maxLines: titleActionButtonMaxLines,
onTapAction: _onConfirmButtonAction,
))
],
),
)
],
),
Widget _buildButton(
BuildContext context,
String label,
VoidCallback? onTapAction,
Color? bgColor,
TextStyle? textStyle,
) {
return ConfirmDialogButton(
label: label,
backgroundColor: bgColor ??
(onTapAction == onConfirmButtonAction
? AppColor.grayBackgroundColor
: AppColor.blue700),
borderRadius: radiusButton,
textStyle: textStyle,
padding: paddingButton,
textColor: onTapAction == onConfirmButtonAction
? AppColor.steelGray600
: Colors.white,
maxLines: titleActionButtonMaxLines,
onTapAction: onTapAction,
);
}
}
+1 -1
View File
@@ -126,7 +126,7 @@ class HtmlUtils {
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
${useDefaultFont && PlatformInfo.isMobile
? '<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">'
? '<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">'
: ''}
<style>
${useDefaultFont ? '''
+7 -7
View File
@@ -285,10 +285,10 @@ packages:
dependency: transitive
description:
name: ffi
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.1.3"
file:
dependency: transitive
description:
@@ -1207,21 +1207,21 @@ packages:
source: hosted
version: "2.4.0"
win32:
dependency: transitive
dependency: "direct main"
description:
name: win32
sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c"
sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4
url: "https://pub.dev"
source: hosted
version: "4.1.4"
version: "5.5.1"
win32_registry:
dependency: transitive
description:
name: win32_registry
sha256: "1c52f994bdccb77103a6231ad4ea331a244dbcef5d1f37d8462f713143b0bfae"
sha256: "723b7f851e5724c55409bb3d5a32b203b3afe8587eaf5dafb93a5fed8ecda0d6"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
version: "1.1.4"
xdg_directories:
dependency: transitive
description:
+2
View File
@@ -93,6 +93,8 @@ dependencies:
debounce_throttle: 2.0.0
win32: 5.5.1
dev_dependencies:
flutter_test:
sdk: flutter
+13 -8
View File
@@ -436,14 +436,19 @@ abstract class BaseMailboxController extends BaseController {
} else {
Get.dialog(
PointerInterceptor(
child: (ConfirmDialogBuilder(imagePaths, useIconAsBasicLogo: true)
..key(const Key('confirm_dialog_delete_mailbox'))
..title(AppLocalizations.of(context).deleteFolders)
..content(AppLocalizations.of(context).message_confirmation_dialog_delete_folder(presentationMailbox.getDisplayName(context)))
..onCloseButtonAction(() => popBack())
..onConfirmButtonAction(AppLocalizations.of(context).delete, () => onDeleteMailboxAction(presentationMailbox))
..onCancelButtonAction(AppLocalizations.of(context).cancel, () => popBack())
).build()),
child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_delete_mailbox'),
imagePath: imagePaths,
useIconAsBasicLogo: true,
title: AppLocalizations.of(context).deleteFolders,
textContent: AppLocalizations.of(context).message_confirmation_dialog_delete_folder(presentationMailbox.getDisplayName(context)),
confirmText: AppLocalizations.of(context).delete,
cancelText: AppLocalizations.of(context).cancel,
onConfirmButtonAction: () => onDeleteMailboxAction(presentationMailbox),
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
),
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
);
}
+5 -9
View File
@@ -1,4 +1,5 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_mixin.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -19,19 +20,14 @@ mixin LogoutMixin implements MessageDialogActionMixin {
alignCenter: true,
outsideDismissible: false,
titleActionButtonMaxLines: 1,
messageStyle: const TextStyle(
color: AppColor.colorTextBody,
fontSize: 15,
fontWeight: FontWeight.w400,
),
messageStyle: ThemeUtils.textStyleBodyBody2(color: AppColor.steelGray400),
listTextSpan: [
TextSpan(text: AppLocalizations.of(context).messageConfirmationLogout),
TextSpan(
text: ' $userAddress',
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: AppColor.colorTextBody,
fontSize: 15,
fontWeight: FontWeight.bold,
style: ThemeUtils.textStyleBodyBody2(
color: AppColor.steelGray400,
fontWeight: FontWeight.w700,
),
),
const TextSpan(text: '?'),
@@ -77,27 +77,32 @@ mixin MailboxActionHandlerMixin {
.show();
} else {
Get.dialog(
PointerInterceptor(child: (ConfirmDialogBuilder(imagePaths, useIconAsBasicLogo: true)
..key(const Key('confirm_dialog_empty_trash'))
..title(AppLocalizations.of(context).emptyTrash)
..content(AppLocalizations.of(context).empty_trash_dialog_message)
..onCloseButtonAction(popBack)
..onConfirmButtonAction(AppLocalizations.of(context).delete, () {
popBack();
if (mailbox.countTotalEmails > 0) {
dashboardController.emptyTrashFolderAction(
trashFolderId: mailbox.id,
totalEmails: mailbox.countTotalEmails,
);
} else {
appToast.showToastWarningMessage(
context,
AppLocalizations.of(context).noEmailInYourCurrentFolder
);
}
})
..onCancelButtonAction(AppLocalizations.of(context).cancel, popBack))
.build()
PointerInterceptor(
child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_empty_trash'),
imagePath: imagePaths,
title: AppLocalizations.of(context).emptyTrash,
textContent: AppLocalizations.of(context).empty_trash_dialog_message,
confirmText: AppLocalizations.of(context).delete,
cancelText: AppLocalizations.of(context).cancel,
useIconAsBasicLogo: true,
onCloseButtonAction: popBack,
onConfirmButtonAction: () {
popBack();
if (mailbox.countTotalEmails > 0) {
dashboardController.emptyTrashFolderAction(
trashFolderId: mailbox.id,
totalEmails: mailbox.countTotalEmails
);
} else {
appToast.showToastWarningMessage(
context,
AppLocalizations.of(context).noEmailInYourCurrentFolder
);
}
},
onCancelButtonAction: popBack,
),
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
);
@@ -135,24 +140,30 @@ mixin MailboxActionHandlerMixin {
.show();
} else {
Get.dialog(
PointerInterceptor(child: (ConfirmDialogBuilder(imagePaths, useIconAsBasicLogo: true)
..key(const Key('confirm_dialog_empty_spam'))
..title(AppLocalizations.of(context).emptySpamFolder)
..content(AppLocalizations.of(context).emptySpamMessageDialog)
..onCloseButtonAction(popBack)
..onConfirmButtonAction(AppLocalizations.of(context).delete_all, () {
popBack();
if (mailbox.countTotalEmails > 0) {
dashboardController.emptySpamFolderAction(spamFolderId: mailbox.id, totalEmails: mailbox.countTotalEmails);
} else {
appToast.showToastWarningMessage(
context,
AppLocalizations.of(context).noEmailInYourCurrentFolder
);
}
})
..onCancelButtonAction(AppLocalizations.of(context).cancel, popBack)
).build()),
PointerInterceptor(
child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_empty_spam'),
imagePath: imagePaths,
title: AppLocalizations.of(context).emptySpamFolder,
textContent: AppLocalizations.of(context).emptySpamMessageDialog,
confirmText: AppLocalizations.of(context).delete_all,
cancelText: AppLocalizations.of(context).cancel,
useIconAsBasicLogo: true,
onCloseButtonAction: popBack,
onConfirmButtonAction: () {
popBack();
if (mailbox.countTotalEmails > 0) {
dashboardController.emptySpamFolderAction(spamFolderId: mailbox.id, totalEmails: mailbox.countTotalEmails);
} else {
appToast.showToastWarningMessage(
context,
AppLocalizations.of(context).noEmailInYourCurrentFolder
);
}
},
onCancelButtonAction: popBack,
),
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
);
}
@@ -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/responsive_utils.dart';
import 'package:core/presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart';
import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
@@ -46,51 +51,40 @@ mixin MessageDialogActionMixin {
if (alignCenter) {
final childWidget = PointerInterceptor(
child: (ConfirmDialogBuilder(
imagePaths,
listTextSpan: listTextSpan,
titleActionButtonMaxLines: titleActionButtonMaxLines,
isArrangeActionButtonsVertical: isArrangeActionButtonsVertical,
useIconAsBasicLogo: useIconAsBasicLogo,
)
..key(key)
..title(title ?? '')
..content(message)
..addIcon(icon)
..colorConfirmButton(actionButtonColor ?? AppColor.blue700)
..colorCancelButton(cancelButtonColor ?? AppColor.colorF3F6F9)
..radiusButton(12)
..styleTitle(titleStyle)
..styleContent(messageStyle)
..styleTextCancelButton(cancelStyle ?? const TextStyle(
fontSize: 17,
height: 24 / 17,
fontWeight: FontWeight.w500,
color: AppColor.steelGray600,
))
..styleTextConfirmButton(actionStyle ?? const TextStyle(
fontSize: 17,
height: 24 / 17,
fontWeight: FontWeight.w500,
color: Colors.white,
))
..onConfirmButtonAction(actionName, () {
child: ConfirmationDialogBuilder(
key: key,
imagePath: imagePaths,
listTextSpan: listTextSpan,
titleActionButtonMaxLines: titleActionButtonMaxLines,
isArrangeActionButtonsVertical: isArrangeActionButtonsVertical,
useIconAsBasicLogo: useIconAsBasicLogo,
title: title ?? '',
textContent: message,
confirmText: actionName,
cancelText: hasCancelButton ? cancelTitle ?? AppLocalizations.of(context).cancel : '',
iconWidget: icon,
colorCancelButton: cancelButtonColor,
colorConfirmButton: actionButtonColor,
styleTextCancelButton: cancelStyle,
styleTextConfirmButton: actionStyle,
styleTitle: titleStyle,
styleContent: messageStyle,
paddingButton: paddingButton,
marginIcon: marginIcon,
onConfirmButtonAction: () {
if (autoPerformPopBack) {
popBack();
}
onConfirmAction?.call();
})
..onCancelButtonAction(
hasCancelButton ? cancelTitle ?? AppLocalizations.of(context).cancel : '',
() {
if (autoPerformPopBack) {
popBack();
}
onCancelAction?.call();
}
)
..onCloseButtonAction(onCloseButtonAction)
).build()
},
onCancelButtonAction: () {
if (autoPerformPopBack) {
popBack();
}
onCancelAction?.call();
},
onCloseButtonAction: onCloseButtonAction,
),
);
return await Get.dialog(
usePopScope && PlatformInfo.isMobile
@@ -102,53 +96,41 @@ mixin MessageDialogActionMixin {
} else {
if (responsiveUtils.isMobile(context)) {
final childWidget = PointerInterceptor(
child: (ConfirmDialogBuilder(
imagePaths,
showAsBottomSheet: true,
listTextSpan: listTextSpan,
maxWith: responsiveUtils.getSizeScreenShortestSide(context) - 16,
titleActionButtonMaxLines: titleActionButtonMaxLines,
isArrangeActionButtonsVertical: isArrangeActionButtonsVertical,
useIconAsBasicLogo: useIconAsBasicLogo,
)
..key(key)
..title(title ?? '')
..content(message)
..addIcon(icon)
..widthDialog(responsiveUtils.getSizeScreenWidth(context))
..colorConfirmButton(actionButtonColor ?? AppColor.blue700)
..colorCancelButton(cancelButtonColor ?? AppColor.colorF3F6F9)
..styleTitle(titleStyle)
..styleContent(messageStyle)
..styleTextCancelButton(cancelStyle ?? const TextStyle(
fontSize: 17,
height: 24 / 17,
fontWeight: FontWeight.w500,
color: AppColor.steelGray600,
))
..styleTextConfirmButton(actionStyle ?? const TextStyle(
fontSize: 17,
height: 24 / 17,
fontWeight: FontWeight.w500,
color: Colors.white,
))
..onConfirmButtonAction(actionName, () {
child: ConfirmationDialogBuilder(
key: key,
imagePath: imagePaths,
showAsBottomSheet: true,
listTextSpan: listTextSpan,
maxWidth: responsiveUtils.getSizeScreenShortestSide(context) - 16,
titleActionButtonMaxLines: titleActionButtonMaxLines,
isArrangeActionButtonsVertical: isArrangeActionButtonsVertical,
textContent: message,
title: title ?? '',
iconWidget: icon,
widthDialog: responsiveUtils.getSizeScreenWidth(context),
colorConfirmButton: actionButtonColor,
colorCancelButton: cancelButtonColor,
styleContent: messageStyle,
styleTitle: titleStyle,
styleTextCancelButton: cancelStyle,
styleTextConfirmButton: actionStyle,
confirmText: actionName,
cancelText: hasCancelButton ? cancelTitle ?? AppLocalizations.of(context).cancel : '',
useIconAsBasicLogo: useIconAsBasicLogo,
onConfirmButtonAction: () {
if (autoPerformPopBack) {
popBack();
}
onConfirmAction?.call();
})
..onCancelButtonAction(
hasCancelButton ? cancelTitle ?? AppLocalizations.of(context).cancel : '',
() {
if (autoPerformPopBack) {
popBack();
}
onCancelAction?.call();
}
)
..onCloseButtonAction(onCloseButtonAction ?? () => popBack())
).build()
},
onCancelButtonAction: () {
if (autoPerformPopBack) {
popBack();
}
onCancelAction?.call();
},
onCloseButtonAction: onCloseButtonAction ?? popBack
),
);
if (showAsBottomSheet) {
return await Get.bottomSheet(
@@ -166,7 +148,7 @@ mixin MessageDialogActionMixin {
} else {
return (ConfirmationDialogActionSheetBuilder(context, listTextSpan: listTextSpan)
..messageText(message)
..styleConfirmButton(const TextStyle(fontSize: 20, fontWeight: FontWeight.normal, color: Colors.black))
..styleConfirmButton(actionStyle)
..styleMessage(messageStyle)
..styleCancelButton(cancelStyle)
..onCancelAction(
@@ -187,50 +169,39 @@ mixin MessageDialogActionMixin {
}
} else {
final childWidget = PointerInterceptor(
child: (ConfirmDialogBuilder(
imagePaths,
listTextSpan: listTextSpan,
titleActionButtonMaxLines: titleActionButtonMaxLines,
isArrangeActionButtonsVertical: isArrangeActionButtonsVertical,
useIconAsBasicLogo: useIconAsBasicLogo,
)
..key(key)
..title(title ?? '')
..content(message)
..addIcon(icon)
..colorConfirmButton(actionButtonColor ?? AppColor.blue700)
..colorCancelButton(cancelButtonColor ?? AppColor.colorF3F6F9)
..styleTitle(titleStyle)
..styleContent(messageStyle)
..styleTextCancelButton(cancelStyle ?? const TextStyle(
fontSize: 17,
height: 24 / 17,
fontWeight: FontWeight.w500,
color: AppColor.steelGray600,
))
..styleTextConfirmButton(actionStyle ?? const TextStyle(
fontSize: 17,
height: 24 / 17,
fontWeight: FontWeight.w500,
color: Colors.white,
))
..onConfirmButtonAction(actionName, () {
child: ConfirmationDialogBuilder(
key: key,
imagePath: imagePaths,
listTextSpan: listTextSpan,
titleActionButtonMaxLines: titleActionButtonMaxLines,
isArrangeActionButtonsVertical: isArrangeActionButtonsVertical,
useIconAsBasicLogo: useIconAsBasicLogo,
title: title ?? '',
textContent: message,
iconWidget: icon,
colorConfirmButton: actionButtonColor,
colorCancelButton: cancelButtonColor,
styleContent: messageStyle,
styleTitle: titleStyle,
styleTextCancelButton: cancelStyle,
styleTextConfirmButton: actionStyle,
confirmText: actionName,
cancelText: hasCancelButton ? cancelTitle ?? AppLocalizations.of(context).cancel : '',
onConfirmButtonAction: () {
if (autoPerformPopBack) {
popBack();
}
onConfirmAction?.call();
})
..onCancelButtonAction(
hasCancelButton ? cancelTitle ?? AppLocalizations.of(context).cancel : '',
() {
if (autoPerformPopBack) {
popBack();
}
onCancelAction?.call();
}
)
..onCloseButtonAction(onCloseButtonAction ?? () => popBack())
).build()
},
onCancelButtonAction: () {
if (autoPerformPopBack) {
popBack();
} else {
onCancelAction?.call();
}
},
onCloseButtonAction: onCloseButtonAction ?? popBack,
),
);
return await Get.dialog(
usePopScope && PlatformInfo.isMobile
@@ -42,10 +42,8 @@ class _ApplicationVersionWidgetState extends State<ApplicationVersionWidget> {
child: Text(
'${widget.title ?? 'v.'}${snapshot.data}',
textAlign: TextAlign.center,
style: widget.textStyle ?? Theme.of(context).textTheme.labelMedium?.copyWith(
fontSize: 13,
color: AppColor.colorContentEmail,
fontWeight: FontWeight.w500
style: widget.textStyle ?? Theme.of(context).textTheme.bodySmall?.copyWith(
color: AppColor.steelGray400,
),
),
);
@@ -1187,18 +1187,6 @@ class ComposerController extends BaseController
height: 40,
colorFilter: AppColor.colorBackgroundQuotasWarning.asFilter(),
),
messageStyle: Theme.of(context).textTheme.labelMedium?.copyWith(
fontSize: 14,
color: AppColor.colorTextBody
),
actionStyle: Theme.of(context).textTheme.labelMedium?.copyWith(
fontSize: 17,
color: Colors.white
),
cancelStyle: Theme.of(context).textTheme.labelMedium?.copyWith(
fontSize: 17,
color: Colors.black
)
);
}
@@ -2264,23 +2252,6 @@ class ComposerController extends BaseController
height: 40,
colorFilter: AppColor.colorBackgroundQuotasWarning.asFilter(),
),
titleStyle: Theme.of(context).textTheme.labelLarge?.copyWith(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black
),
messageStyle: Theme.of(context).textTheme.labelMedium?.copyWith(
fontSize: 14,
color: AppColor.colorTextBody
),
actionStyle: Theme.of(context).textTheme.labelMedium?.copyWith(
fontSize: 17,
color: Colors.white
),
cancelStyle: Theme.of(context).textTheme.labelMedium?.copyWith(
fontSize: 17,
color: Colors.black
)
);
}
@@ -2482,18 +2453,6 @@ class ComposerController extends BaseController
height: 40,
colorFilter: AppColor.colorBackgroundQuotasWarning.asFilter(),
),
messageStyle: Theme.of(context).textTheme.labelMedium?.copyWith(
fontSize: 14,
color: AppColor.colorTextBody
),
actionStyle: Theme.of(context).textTheme.labelMedium?.copyWith(
fontSize: 17,
color: Colors.white
),
cancelStyle: Theme.of(context).textTheme.labelMedium?.copyWith(
fontSize: 17,
color: Colors.black
)
);
}
@@ -85,7 +85,7 @@ extension ComposerPrintDraftExtension on ComposerController {
child: PrintDraftDialogView(
emailPrint: DraftEmailPrint(
appName: appLocalizations.app_name,
userName: mailboxDashBoardController.userEmail,
userName: mailboxDashBoardController.getOwnEmailAddress(),
attachments: uploadController.allAttachmentsUploaded,
emailContent: emailContent,
fromPrefix: appLocalizations.from_email_address_prefix,
@@ -1,5 +1,7 @@
import 'package:core/presentation/constants/constants_ui.dart';
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/features/composer/presentation/styles/composer_style.dart';
@@ -30,15 +32,19 @@ class RecipientComposerWidgetStyle {
static const EdgeInsetsGeometry enableRecipientButtonMargin = EdgeInsetsDirectional.only(top: 10);
static const TextStyle prefixButtonTextStyle = TextStyle(
fontFamily: ConstantsUI.fontApp,
fontSize: 15,
fontWeight: FontWeight.normal,
fontWeight: FontWeight.w400,
height: 24 / 15,
letterSpacing: -0.01,
decoration: TextDecoration.underline,
decorationColor: AppColor.m3Neutral70,
color: AppColor.m3Neutral70,
);
static const TextStyle inputTextStyle = TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.black
static final TextStyle inputTextStyle = ThemeUtils.textStyleBodyBody1(
color: AppColor.m3SurfaceBackground,
);
static final TextStyle prefixLabelTextStyle = ThemeUtils.textStyleBodyBody1(
color: AppColor.m3Tertiary,
);
}
@@ -1,5 +1,6 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:flutter/material.dart';
class SubjectComposerWidgetStyle {
@@ -8,9 +9,10 @@ class SubjectComposerWidgetStyle {
static const Color cursorColor = AppColor.primaryColor;
static const Color borderColor = AppColor.colorLineComposer;
static const TextStyle inputTextStyle = TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.w500
static final TextStyle labelTextStyle = ThemeUtils.textStyleBodyBody1(
color: AppColor.m3Tertiary,
);
static final TextStyle inputTextStyle = ThemeUtils.textStyleBodyBody1(
color: AppColor.m3SurfaceBackground,
);
}
@@ -1,8 +1,11 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
class FromComposerDropDownWidgetStyle {
FromComposerDropDownWidgetStyle._();
static const double space = 8.0;
static const double dropdownItemSpace = 12.0;
static const double avatarSize = 48.0;
@@ -90,4 +93,7 @@ class FromComposerDropDownWidgetStyle {
fontWeight: FontWeight.w500,
color: AppColor.colorLabelComposer
);
static final TextStyle prefixLabelTextStyle = ThemeUtils.textStyleBodyBody1(
color: AppColor.m3Tertiary,
);
}
@@ -147,11 +147,7 @@ class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
child: Text(
'${widget.prefix.asName(context)}:',
key: Key('prefix_${widget.prefix.name}_recipient_composer_widget'),
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 16,
fontWeight: FontWeight.w500,
color: AppColor.m3Tertiary,
),
style: RecipientComposerWidgetStyle.prefixLabelTextStyle,
),
),
const SizedBox(width: RecipientComposerWidgetStyle.space),
@@ -147,7 +147,7 @@ class RecipientTagItemWidget extends StatelessWidget {
if (isLatestTagFocused && isLatestEmail) {
return AppColor.colorItemRecipientSelected;
} else if (EmailUtils.isEmailAddressValid(currentEmailAddress.emailAddress)) {
return AppColor.colorF3F6F9;
return AppColor.grayBackgroundColor;
} else {
return Colors.white;
}
@@ -1,4 +1,3 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/views/text/text_field_builder.dart';
import 'package:core/utils/direction_utils.dart';
import 'package:flutter/material.dart';
@@ -39,11 +38,7 @@ class SubjectComposerWidget extends StatelessWidget {
children: [
Text(
'${AppLocalizations.of(context).subject_email}:',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 16,
fontWeight: FontWeight.w500,
color: AppColor.m3Tertiary,
),
style: SubjectComposerWidgetStyle.labelTextStyle,
),
const SizedBox(width:SubjectComposerWidgetStyle.space),
Expanded(
@@ -55,11 +55,7 @@ class FromComposerDropDownWidget extends StatelessWidget {
padding: FromComposerDropDownWidgetStyle.prefixPadding,
child: Text(
'${PrefixEmailAddress.from.asName(context)}:',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 16,
fontWeight: FontWeight.w500,
color: AppColor.m3Tertiary,
),
style: FromComposerDropDownWidgetStyle.prefixLabelTextStyle,
),
),
const SizedBox(width: FromComposerDropDownWidgetStyle.space),
@@ -1492,15 +1492,18 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
.show();
} else {
Get.dialog(
PointerInterceptor(child: (ConfirmDialogBuilder(imagePaths, useIconAsBasicLogo: true)
..key(const Key('confirm_dialog_delete_email_permanently'))
..title(DeleteActionType.single.getTitleDialog(context))
..content(DeleteActionType.single.getContentDialog(context))
..onCloseButtonAction(() => popBack())
..onConfirmButtonAction(DeleteActionType.single.getConfirmActionName(context), () => _deleteEmailPermanentlyAction(context, email))
..onCancelButtonAction(AppLocalizations.of(context).cancel, () => popBack()))
.build()
),
PointerInterceptor(child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_delete_email_permanently'),
imagePath: imagePaths,
useIconAsBasicLogo: true,
title: DeleteActionType.single.getTitleDialog(context),
textContent: DeleteActionType.single.getContentDialog(context),
confirmText: DeleteActionType.single.getConfirmActionName(context),
cancelText: AppLocalizations.of(context).cancel,
onConfirmButtonAction: () => _deleteEmailPermanentlyAction(context, email),
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
)),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
);
}
@@ -1884,19 +1887,14 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
showAsBottomSheet: true,
title: AppLocalizations.of(context).unsubscribeMail,
icon: SvgPicture.asset(imagePaths.icEmpty),
messageStyle: const TextStyle(
color: AppColor.messageDialogColor,
fontSize: 14,
fontWeight: FontWeight.w500
),
messageStyle: ThemeUtils.textStyleBodyBody2(color: AppColor.steelGray400),
listTextSpan: [
TextSpan(text: AppLocalizations.of(context).unsubscribeMailDialogMessage),
TextSpan(
text: ' ${presentationEmail.getSenderName()}',
style: const TextStyle(
color: AppColor.messageDialogHighlightColor,
fontSize: 15,
fontWeight: FontWeight.w500
style: ThemeUtils.textStyleBodyBody2(
color: AppColor.steelGray400,
fontWeight: FontWeight.w700,
),
),
const TextSpan(text: ' ?'),
@@ -1950,7 +1948,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
_printEmailInteractor.execute(
EmailPrint(
appName: appLocalizations.app_name,
userName: mailboxDashBoardController.userEmail,
userName: mailboxDashBoardController.getOwnEmailAddress(),
attachments: currentEmailLoaded.value!.attachments,
emailContent: currentEmailLoaded.value!.htmlContent,
fromPrefix: appLocalizations.from_email_address_prefix,
@@ -2431,7 +2429,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
listEmailAddressAttendees.addAll(listEmailAddress);
final currentUserEmail = mailboxDashBoardController.sessionCurrent?.getOwnEmailAddress() ?? '';
final currentUserEmail = mailboxDashBoardController.getOwnEmailAddress();
final listEmailAddressMailTo = listEmailAddressAttendees.removeInvalidEmails(currentUserEmail);
log('SingleEmailController::handleMailToAttendees: listEmailAddressMailTo = $listEmailAddressMailTo');
mailboxDashBoardController.goToComposer(
@@ -19,10 +19,6 @@ class EmailViewAppBarWidgetStyles {
}
static const Color bottomBorderColor = AppColor.colorDividerHorizontal;
static const Color backgroundColor = Colors.white;
static const Color emptyTrashButtonColor = AppColor.primaryColor;
static const Color deletePermanentButtonColor = AppColor.colorDeletePermanentlyButton;
static const Color buttonActivatedColor = AppColor.primaryColor;
static const Color buttonDeactivatedColor = AppColor.colorAttachmentIcon;
static const Color iconColor = AppColor.steelGrayA540;
static EdgeInsetsGeometry paddingIOS(BuildContext context, ResponsiveUtils responsiveUtils) {
@@ -1069,17 +1069,16 @@ class MailboxController extends BaseMailboxController
.show();
} else {
Get.dialog(
PointerInterceptor(child: (ConfirmDialogBuilder(imagePaths, useIconAsBasicLogo: true)
..key(const Key('confirm_dialog_delete_multiple_mailbox'))
..title(AppLocalizations.of(context).deleteFolders)
..content(AppLocalizations.of(context).messageConfirmationDialogDeleteMultipleFolder(selectedMailboxList.length))
..onCloseButtonAction(() => popBack())
..onConfirmButtonAction(AppLocalizations.of(context).delete, () =>
_deleteMultipleMailboxAction(selectedMailboxList))
..onCancelButtonAction(AppLocalizations.of(context).cancel, () =>
popBack()))
.build()
),
PointerInterceptor(child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_delete_multiple_mailbox'),
imagePath: imagePaths,
useIconAsBasicLogo: true,
title: AppLocalizations.of(context).deleteFolders,
textContent: AppLocalizations.of(context).messageConfirmationDialogDeleteMultipleFolder(selectedMailboxList.length),
onConfirmButtonAction: () => _deleteMultipleMailboxAction(selectedMailboxList),
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
)),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
);
}
@@ -1279,7 +1278,10 @@ class MailboxController extends BaseMailboxController
break;
case MailboxActions.copySubaddress:
try{
final subaddress = getSubaddress(mailboxDashBoardController.userEmail, findNodePathWithSeparator(mailbox.id, '.')!);
final subaddress = getSubaddress(
mailboxDashBoardController.getOwnEmailAddress(),
findNodePathWithSeparator(mailbox.id, '.')!,
);
copySubaddressAction(context, subaddress);
} catch (error) {
appToast.showToastErrorMessage(context, AppLocalizations.of(context).errorWhileFetchingSubaddress);
@@ -1294,7 +1296,10 @@ class MailboxController extends BaseMailboxController
break;
case MailboxActions.allowSubaddressing:
try{
final subaddress = getSubaddress(mailboxDashBoardController.userEmail, findNodePathWithSeparator(mailbox.id, '.')!);
final subaddress = getSubaddress(
mailboxDashBoardController.getOwnEmailAddress(),
findNodePathWithSeparator(mailbox.id, '.')!,
);
openConfirmationDialogSubaddressingAction(
context,
responsiveUtils,
@@ -1705,20 +1710,28 @@ class MailboxController extends BaseMailboxController
} else {
Get.dialog(
PointerInterceptor(
child: (ConfirmDialogBuilder(imagePaths, useIconAsBasicLogo: true)
..key(const Key('confirm_dialog_subaddressing'))
..title(AppLocalizations.of(context).allowSubaddressing)
..content(AppLocalizations.of(context).message_confirmation_dialog_allow_subaddressing(mailboxName))
..addWidgetContent(CopySubaddressWidget(
context: context,
imagePath: imagePaths,
subaddress: subaddress,
onCopyButtonAction: () => copySubaddressAction(context, subaddress),
))
..onCloseButtonAction(() => popBack())
..onConfirmButtonAction(AppLocalizations.of(context).allow, () => onAllowSubaddressingAction(mailboxId, currentRights, MailboxActions.allowSubaddressing))
..onCancelButtonAction(AppLocalizations.of(context).cancel, () => popBack())
).build()),
child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_subaddressing'),
imagePath: imagePaths,
useIconAsBasicLogo: true,
title: AppLocalizations.of(context).allowSubaddressing,
textContent: AppLocalizations.of(context).message_confirmation_dialog_allow_subaddressing(mailboxName),
confirmText: AppLocalizations.of(context).allow,
cancelText: AppLocalizations.of(context).cancel,
additionalWidgetContent: CopySubaddressWidget(
imagePath: imagePaths,
subaddress: subaddress,
onCopyButtonAction: () => copySubaddressAction(context, subaddress),
),
onConfirmButtonAction: () => onAllowSubaddressingAction(
mailboxId,
currentRights,
MailboxActions.allowSubaddressing,
),
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
),
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
);
}
@@ -3,7 +3,6 @@ import 'package:core/utils/direction_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:model/model.dart';
import 'package:tmail_ui_user/features/base/widget/application_version_widget.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/base_mailbox_view.dart';
@@ -140,12 +139,6 @@ class MailboxView extends BaseMailboxView {
child: ApplicationVersionWidget(
padding: EdgeInsets.zero,
title: '${AppLocalizations.of(context).version} ',
textStyle: Theme.of(context).textTheme.labelMedium?.copyWith(
fontSize: 13,
height: 16 / 13,
color: AppColor.steelGray400,
fontWeight: FontWeight.w400,
),
),
),
);
@@ -225,8 +218,8 @@ class MailboxView extends BaseMailboxView {
}
return UserInformationWidget(
userName: controller.mailboxDashBoardController.accountId.value != null
? UserName(controller.mailboxDashBoardController.sessionCurrent!.getOwnEmailAddress())
: null,
? controller.mailboxDashBoardController.getOwnEmailAddress()
: '',
subtitle: AppLocalizations.of(context).manage_account,
onSubtitleClick: controller.mailboxDashBoardController.goToSettings,
border: const Border(
@@ -366,10 +359,8 @@ class MailboxView extends BaseMailboxView {
categories.getTitle(context),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 14,
style: ThemeUtils.textStyleBodyBody3(
color: Colors.black,
fontWeight: FontWeight.w400,
)
)
),
@@ -2,7 +2,6 @@ import 'package:core/core.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:model/model.dart';
import 'package:tmail_ui_user/features/base/widget/application_logo_with_text_widget.dart';
import 'package:tmail_ui_user/features/base/widget/application_version_widget.dart';
@@ -119,12 +118,6 @@ class MailboxView extends BaseMailboxView {
child: ApplicationVersionWidget(
padding: EdgeInsets.zero,
title: '${AppLocalizations.of(context).version.toLowerCase()} ',
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(
fontSize: 13,
height: 16 / 13,
color: AppColor.steelGray400,
fontWeight: FontWeight.w400,
),
),
),
]),
@@ -142,8 +135,8 @@ class MailboxView extends BaseMailboxView {
if (!controller.responsiveUtils.isDesktop(context))
Obx(() => UserInformationWidget(
userName: controller.mailboxDashBoardController.accountId.value != null
? UserName(controller.mailboxDashBoardController.sessionCurrent!.getOwnEmailAddress())
: null,
? controller.mailboxDashBoardController.getOwnEmailAddress()
: '',
subtitle: AppLocalizations.of(context).manage_account,
onSubtitleClick: controller.mailboxDashBoardController.goToSettings,
border: const Border(
@@ -369,12 +369,7 @@ mixin MailboxWidgetMixin {
maxLines: 1,
overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 14,
height: 18 / 14,
color: Colors.black,
fontWeight: FontWeight.w400,
)
style: ThemeUtils.textStyleBodyBody3(color: Colors.black)
)),
])
);
@@ -7,7 +7,6 @@ typedef OnCopyButtonAction = void Function();
class CopySubaddressWidget extends StatelessWidget {
final BuildContext context;
final ImagePaths imagePath;
final String subaddress;
@@ -15,7 +14,6 @@ class CopySubaddressWidget extends StatelessWidget {
const CopySubaddressWidget({
super.key,
required this.context,
required this.imagePath,
required this.subaddress,
required this.onCopyButtonAction
@@ -1,17 +1,17 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/extensions/string_extension.dart';
import 'package:core/presentation/views/image/avatar_builder.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:model/extensions/username_extension.dart';
import 'package:tmail_ui_user/features/base/widget/material_text_button.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
typedef OnSubtitleClick = void Function();
class UserInformationWidget extends StatelessWidget {
final UserName? userName;
final String userName;
final String? subtitle;
final EdgeInsetsGeometry? titlePadding;
final OnSubtitleClick? onSubtitleClick;
@@ -20,7 +20,7 @@ class UserInformationWidget extends StatelessWidget {
const UserInformationWidget({
Key? key,
this.userName,
required this.userName,
this.subtitle,
this.titlePadding,
this.onSubtitleClick,
@@ -35,7 +35,7 @@ class UserInformationWidget extends StatelessWidget {
decoration: BoxDecoration(border: border),
child: Row(children: [
(AvatarBuilder()
..text(userName?.firstCharacter ?? '')
..text(userName.firstCharacterToUpperCase)
..backgroundColor(Colors.white)
..textColor(Colors.black)
..addBoxShadows([const BoxShadow(
@@ -48,7 +48,7 @@ class UserInformationWidget extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SelectableText(
userName?.value ?? '',
userName,
maxLines: 1,
style: const TextStyle(
fontSize: 17,
@@ -1552,23 +1552,26 @@ class MailboxDashBoardController extends ReloadableController
.show();
} else {
Get.dialog(
PointerInterceptor(child: (ConfirmDialogBuilder(imagePaths, useIconAsBasicLogo: true)
..key(const Key('confirm_dialog_delete_emails_permanently'))
..title(actionType.getTitleDialog(context))
..content(actionType.getContentDialog(
context,
count: listEmails?.length,
mailboxName: mailboxCurrent?.getDisplayName(context)))
..onCloseButtonAction(() => popBack())
..onConfirmButtonAction(
actionType.getConfirmActionName(context),
() => _deleteSelectionEmailsPermanentlyAction(
actionType,
listEmails: listEmails,
onCancelSelectionEmail: onCancelSelectionEmail))
..onCancelButtonAction(AppLocalizations.of(context).cancel, () => popBack()))
.build()
),
PointerInterceptor(child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_delete_emails_permanently'),
imagePath: imagePaths,
useIconAsBasicLogo: true,
title: actionType.getTitleDialog(context),
textContent: actionType.getContentDialog(
context,
count: listEmails?.length,
mailboxName: mailboxCurrent?.getDisplayName(context),
),
confirmText: actionType.getConfirmActionName(context),
cancelText: AppLocalizations.of(context).cancel,
onConfirmButtonAction: () => _deleteSelectionEmailsPermanentlyAction(
actionType,
listEmails: listEmails,
onCancelSelectionEmail: onCancelSelectionEmail,
),
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
)),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
);
}
@@ -2693,24 +2696,31 @@ class MailboxDashBoardController extends ReloadableController
.show();
} else {
Get.dialog(
PointerInterceptor(child: (ConfirmDialogBuilder(imagePaths, useIconAsBasicLogo: true)
..key(const Key('confirm_dialog_empty_spam'))
..title(AppLocalizations.of(context).emptySpamFolder)
..content(AppLocalizations.of(context).emptySpamMessageDialog)
..onCloseButtonAction(popBack)
..onConfirmButtonAction(AppLocalizations.of(context).delete_all, () {
PointerInterceptor(child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_empty_spam'),
imagePath: imagePaths,
useIconAsBasicLogo: true,
title: AppLocalizations.of(context).emptySpamFolder,
textContent: AppLocalizations.of(context).emptySpamMessageDialog,
confirmText: AppLocalizations.of(context).delete_all,
cancelText: AppLocalizations.of(context).cancel,
onConfirmButtonAction: () {
popBack();
if (spamMailbox.countTotalEmails > 0) {
emptySpamFolderAction(spamFolderId: spamMailbox.id, totalEmails: spamMailbox.countTotalEmails);
emptySpamFolderAction(
spamFolderId: spamMailbox.id,
totalEmails: spamMailbox.countTotalEmails,
);
} else {
appToast.showToastWarningMessage(
context,
AppLocalizations.of(context).noEmailInYourCurrentFolder
AppLocalizations.of(context).noEmailInYourCurrentFolder,
);
}
})
..onCancelButtonAction(AppLocalizations.of(context).cancel, popBack)
).build()),
},
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
)),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
);
}
@@ -3119,8 +3129,6 @@ class MailboxDashBoardController extends ReloadableController
isRecoveringDeletedMessage.value = true;
}
String get userEmail => sessionCurrent?.getOwnEmailAddress() ?? '';
Future<void> _removeComposerCacheOnWeb() async {
await _removeComposerCacheOnWebInteractor.execute();
}
@@ -3224,6 +3232,15 @@ class MailboxDashBoardController extends ReloadableController
}
}
String getOwnEmailAddress() {
try {
return sessionCurrent?.getOwnEmailAddress() ?? '';
} catch (e) {
logError('ManageAccountDashBoardController::getOwnEmailAddress:Exception: $e');
return '';
}
}
@override
void onClose() {
if (PlatformInfo.isWeb) {
@@ -6,7 +6,6 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:model/extensions/presentation_mailbox_extension.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:model/extensions/username_extension.dart';
import 'package:tmail_ui_user/features/base/widget/popup_item_no_icon_widget.dart';
import 'package:tmail_ui_user/features/base/widget/scrollbar_list_view.dart';
import 'package:tmail_ui_user/features/composer/presentation/composer_view_web.dart';
@@ -65,21 +64,22 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
child: Column(children: [
Obx(() {
final accountId = controller.accountId.value;
if (accountId == null) {
return const SizedBox.shrink();
} else {
return NavigationBarWidget(
imagePaths: controller.imagePaths,
avatarUserName: controller.sessionCurrent?.username.firstCharacter ?? '',
contactSupportCapability: controller.sessionCurrent?.getContactSupportCapability(accountId),
searchForm: SearchInputFormWidget(),
appGridController: controller.appGridDashboardController,
onTapApplicationLogoAction: controller.redirectToInboxAction,
onTapAvatarAction: (position) => controller.handleClickAvatarAction(context, position),
onTapContactSupportAction: (contactSupport) =>
return NavigationBarWidget(
imagePaths: controller.imagePaths,
accountId: accountId,
avatarUserName: controller.getOwnEmailAddress().firstCharacterToUpperCase,
contactSupportCapability: accountId != null
? controller.sessionCurrent?.getContactSupportCapability(accountId)
: null,
searchForm: SearchInputFormWidget(),
appGridController: controller.appGridDashboardController,
onTapApplicationLogoAction: controller.redirectToInboxAction,
onTapAvatarAction: (position) =>
controller.handleClickAvatarAction(context, position),
onTapContactSupportAction: (contactSupport) =>
controller.onGetHelpOrReportBug(contactSupport),
);
}
);
}),
Expanded(child: Row(children: [
Column(children: [
@@ -2,6 +2,7 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -37,11 +38,7 @@ class ComposeButtonWidget extends StatelessWidget {
iconColor: Colors.white,
padding: const EdgeInsetsDirectional.symmetric(vertical: 8),
backgroundColor: AppColor.blue700,
textStyle: const TextStyle(
fontSize: 15,
color: Colors.white,
fontWeight: FontWeight.w500,
),
textStyle: ThemeUtils.textStyleBodyBody2(color: Colors.white),
onTapActionCallback: onTapAction,
),
);
@@ -5,6 +5,7 @@ import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:core/presentation/views/image/avatar_builder.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:model/support/contact_support_capability.dart';
import 'package:tmail_ui_user/features/base/mixin/contact_support_mixin.dart';
import 'package:tmail_ui_user/features/base/widget/application_logo_with_text_widget.dart';
@@ -16,6 +17,7 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class NavigationBarWidget extends StatelessWidget {
final ImagePaths imagePaths;
final AccountId? accountId;
final String avatarUserName;
final ContactSupportCapability? contactSupportCapability;
final Widget? searchForm;
@@ -27,6 +29,7 @@ class NavigationBarWidget extends StatelessWidget {
const NavigationBarWidget({
super.key,
required this.imagePaths,
required this.accountId,
required this.avatarUserName,
this.contactSupportCapability,
this.searchForm,
@@ -83,22 +86,23 @@ class NavigationBarWidget extends StatelessWidget {
return const SizedBox.shrink();
}),
const SizedBox(width: 16),
(AvatarBuilder()
..text(avatarUserName)
..backgroundColor(Colors.white)
..textColor(Colors.black)
..context(context)
..size(48)
..addOnTapAvatarActionWithPositionClick(onTapAvatarAction)
..addBoxShadows([
const BoxShadow(
color: AppColor.colorShadowBgContentEmail,
spreadRadius: 1,
blurRadius: 1,
offset: Offset(0, 0.5)
)
])
).build()
if (accountId != null)
(AvatarBuilder()
..text(avatarUserName)
..backgroundColor(Colors.white)
..textColor(Colors.black)
..context(context)
..size(48)
..addOnTapAvatarActionWithPositionClick(onTapAvatarAction)
..addBoxShadows([
const BoxShadow(
color: AppColor.colorShadowBgContentEmail,
spreadRadius: 1,
blurRadius: 1,
offset: Offset(0, 0.5)
)
])
).build()
]
);
}))
@@ -125,22 +129,23 @@ class NavigationBarWidget extends StatelessWidget {
return const SizedBox.shrink();
}),
const SizedBox(width: 16),
(AvatarBuilder()
..text(avatarUserName)
..backgroundColor(Colors.white)
..textColor(Colors.black)
..context(context)
..size(48)
..addOnTapAvatarActionWithPositionClick(onTapAvatarAction)
..addBoxShadows([
const BoxShadow(
color: AppColor.colorShadowBgContentEmail,
spreadRadius: 1,
blurRadius: 1,
offset: Offset(0, 0.5)
)
])
).build()
if (accountId != null)
(AvatarBuilder()
..text(avatarUserName)
..backgroundColor(Colors.white)
..textColor(Colors.black)
..context(context)
..size(48)
..addOnTapAvatarActionWithPositionClick(onTapAvatarAction)
..addBoxShadows([
const BoxShadow(
color: AppColor.colorShadowBgContentEmail,
spreadRadius: 1,
blurRadius: 1,
offset: Offset(0, 0.5)
)
])
).build()
]
]),
);
@@ -7,7 +7,8 @@ class SettingDetailViewBuilder extends StatelessWidget {
final ResponsiveUtils responsiveUtils;
final Widget child;
final EdgeInsets? padding;
final EdgeInsetsGeometry? padding;
final Color backgroundColor;
final VoidCallback? onTapGestureDetector;
const SettingDetailViewBuilder({
@@ -15,6 +16,7 @@ class SettingDetailViewBuilder extends StatelessWidget {
required this.responsiveUtils,
required this.child,
this.padding,
this.backgroundColor = Colors.white,
this.onTapGestureDetector
});
@@ -27,8 +29,16 @@ class SettingDetailViewBuilder extends StatelessWidget {
child: Container(
width: double.infinity,
height: double.infinity,
color: SettingsUtils.getContentBackgroundColor(context, responsiveUtils),
decoration: SettingsUtils.getBoxDecorationForContent(context, responsiveUtils),
color: SettingsUtils.getContentBackgroundColor(
context,
responsiveUtils,
backgroundColor: backgroundColor,
),
decoration: SettingsUtils.getBoxDecorationForContent(
context,
responsiveUtils,
backgroundColor: backgroundColor,
),
margin: SettingsUtils.getMarginSettingDetailsView(context, responsiveUtils),
padding: padding,
child: child,
@@ -168,16 +168,17 @@ class EmailRulesController extends BaseController {
} else {
Get.dialog(
PointerInterceptor(
child: (ConfirmDialogBuilder(imagePaths, useIconAsBasicLogo: true)
..title(AppLocalizations.of(context).deleteEmailRule)
..content(AppLocalizations.of(context).messageConfirmationDialogDeleteEmailRule(emailRule.name))
..onCloseButtonAction(() => popBack())
..onConfirmButtonAction(AppLocalizations.of(context).delete, () {
_handleDeleteEmailRuleAction(emailRule);
})
..onCancelButtonAction(AppLocalizations.of(context).cancel, () =>
popBack()))
.build()
child: ConfirmationDialogBuilder(
imagePath: imagePaths,
useIconAsBasicLogo: true,
title: AppLocalizations.of(context).deleteEmailRule,
textContent: AppLocalizations.of(context).messageConfirmationDialogDeleteEmailRule(emailRule.name),
confirmText: AppLocalizations.of(context).delete,
cancelText: AppLocalizations.of(context).cancel,
onConfirmButtonAction: () => _handleDeleteEmailRuleAction(emailRule),
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
),
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
);
@@ -1,7 +1,8 @@
import 'package:core/core.dart';
import 'package:core/presentation/state/success.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/base/setting_detail_view_builder.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/email_rules_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/widgets/email_rules_header_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/widgets/list_email_rules_widget.dart';
@@ -13,15 +14,16 @@ class EmailRulesView extends GetWidget<EmailRulesController> with AppLoaderMixin
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: controller.responsiveUtils.isWebDesktop(context)
? AppColor.colorBgDesktop
: Colors.white,
body: Container(
width: double.infinity,
margin: SettingsUtils.getMarginViewForSettingDetails(context, controller.responsiveUtils),
child: SingleChildScrollView(
physics: const ClampingScrollPhysics(),
return SettingDetailViewBuilder(
responsiveUtils: controller.responsiveUtils,
backgroundColor: Colors.transparent,
child: SingleChildScrollView(
physics: const ClampingScrollPhysics(),
child: Padding(
padding: SettingsUtils.getSettingContentWithoutHeaderPadding(
context,
controller.responsiveUtils,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -30,7 +32,7 @@ class EmailRulesView extends GetWidget<EmailRulesController> with AppLoaderMixin
responsiveUtils: controller.responsiveUtils,
createRule: () => controller.goToCreateNewRule(context),
),
SizedBox(height: controller.responsiveUtils.isWebDesktop(context) ? 24 : 16),
const SizedBox(height: 16),
_buildLoadingView(),
const ListEmailRulesWidget()
],
@@ -3,6 +3,9 @@ import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/widgets/setting_explanation_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/widgets/setting_header_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class EmailRulesHeaderWidget extends StatelessWidget {
@@ -21,26 +24,23 @@ class EmailRulesHeaderWidget extends StatelessWidget {
Widget build(BuildContext context) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
decoration: const BoxDecoration(
color: AppColor.colorBackgroundWrapIconStyleCode,
borderRadius: BorderRadius.circular(16),
borderRadius: BorderRadius.all(Radius.circular(16)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (responsiveUtils.isWebDesktop(context))
const SettingHeaderWidget(menuItem: AccountMenuItem.emailRules)
else
const SettingExplanationWidget(menuItem: AccountMenuItem.emailRules),
Padding(
padding: const EdgeInsets.all(16),
child: _buildButtonAddNewRule(context),
),
],
),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(AppLocalizations.of(context).emailRules,
style: const TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold,
color: Colors.black)),
const SizedBox(height: 4),
Text(AppLocalizations.of(context).emailRuleSettingExplanation,
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.normal,
color: AppColor.colorTextButtonHeaderThread)),
const SizedBox(height: 24),
_buildButtonAddNewRule(context),
]),
);
}
@@ -45,7 +45,13 @@ class ListEmailRulesWidget extends GetWidget<EmailRulesController> {
fontWeight: FontWeight.w500,
color: AppColor.colorTextButtonHeaderThread)),
),
const Divider(),
Obx(() {
if (controller.listEmailRule.isNotEmpty) {
return const Divider();
} else {
return const SizedBox.shrink();
}
}),
Obx(() {
log('ListEmailRulesWidget::build(): ${controller.listEmailRule}');
return ListView.separated(
@@ -1,4 +1,3 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:core/presentation/utils/keyboard_utils.dart';
@@ -46,6 +45,7 @@ class ForwardController extends BaseController {
final selectionMode = Rx<SelectMode>(SelectMode.INACTIVE);
final listRecipientForward = RxList<RecipientForward>();
final currentForward = Rxn<TMailForward>();
final forwardWarningBannerState = Rxn<BannerState>();
bool get currentForwardLocalCopyState => currentForward.value?.localCopy ?? false;
@@ -122,20 +122,6 @@ class ForwardController extends BaseController {
onConfirmAction: () => _handleDeleteRecipientAction({emailAddress}),
showAsBottomSheet: true,
useIconAsBasicLogo: true,
actionStyle: const TextStyle(
fontSize: 17,
height: 24 / 17,
fontWeight: FontWeight.w500,
color: AppColor.steelGray600,
),
cancelStyle: const TextStyle(
fontSize: 17,
height: 24 / 17,
fontWeight: FontWeight.w500,
color: Colors.white,
),
actionButtonColor: AppColor.colorF3F6F9,
cancelButtonColor: AppColor.blue700,
);
}
@@ -218,20 +204,6 @@ class ForwardController extends BaseController {
onConfirmAction: () => _handleDeleteRecipientAction(listEmailAddress),
showAsBottomSheet: true,
useIconAsBasicLogo: true,
actionStyle: const TextStyle(
fontSize: 17,
height: 24 / 17,
fontWeight: FontWeight.w500,
color: AppColor.steelGray600,
),
cancelStyle: const TextStyle(
fontSize: 17,
height: 24 / 17,
fontWeight: FontWeight.w500,
color: Colors.white,
),
actionButtonColor: AppColor.colorF3F6F9,
cancelButtonColor: AppColor.blue700,
);
}
@@ -333,9 +305,9 @@ class ForwardController extends BaseController {
}
void _updateForwardWarningBannerState() {
accountDashBoardController.forwardWarningBannerState.value = _isExistRecipientSameServerDomain
forwardWarningBannerState.value = _isExistRecipientSameServerDomain
? BannerState.enabled
: BannerState.disabled;
log('ForwardController::_updateForwardWarningBannerState: forwardWarningBannerState = ${accountDashBoardController.forwardWarningBannerState.value}');
log('ForwardController::_updateForwardWarningBannerState: forwardWarningBannerState = ${forwardWarningBannerState.value}');
}
}
@@ -5,12 +5,17 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.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/state/banner_state.dart';
import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/base/setting_detail_view_builder.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/autocomplete_contact_text_field_with_tags.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_warning_banner.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/menu/settings_utils.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/widgets/setting_explanation_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/widgets/setting_header_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class ForwardView extends GetWidget<ForwardController> with AppLoaderMixin {
@@ -19,74 +24,76 @@ class ForwardView extends GetWidget<ForwardController> with AppLoaderMixin {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: SettingsUtils.getBackgroundColor(context, controller.responsiveUtils),
body: Container(
width: double.infinity,
height: double.infinity,
color: SettingsUtils.getContentBackgroundColor(context, controller.responsiveUtils),
decoration: SettingsUtils.getBoxDecorationForContent(context, controller.responsiveUtils),
margin: SettingsUtils.getMarginViewForForwardSettingDetails(context, controller.responsiveUtils),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (controller.responsiveUtils.isWebDesktop(context))
...[
ForwardHeaderWidget(imagePaths: controller.imagePaths, responsiveUtils: controller.responsiveUtils),
const Divider(height: 1, color: AppColor.colorDividerHeaderSetting)
return Column(
children: [
Obx(() {
if (controller.forwardWarningBannerState.value == BannerState.enabled) {
return ForwardWarningBanner(
imagePaths: controller.imagePaths,
responsiveUtils: controller.responsiveUtils,
);
} else {
return const SizedBox.shrink();
}
}),
Expanded(
child: SettingDetailViewBuilder(
responsiveUtils: controller.responsiveUtils,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (controller.responsiveUtils.isWebDesktop(context))
...[
const SettingHeaderWidget(menuItem: AccountMenuItem.forward),
const Divider(height: 1, color: AppColor.colorDividerHeaderSetting),
],
Expanded(child: SingleChildScrollView(
physics: const ClampingScrollPhysics(),
child: Padding(
padding: SettingsUtils.getSettingContentPadding(
context,
controller.responsiveUtils,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (!controller.responsiveUtils.isWebDesktop(context))
const SettingExplanationWidget(
menuItem: AccountMenuItem.forward,
padding: EdgeInsetsDirectional.only(bottom: 24),
),
_buildKeepLocalSwitchButton(context),
Obx(() => controller.currentForward.value != null
? _buildAddRecipientsFormWidget(context)
: const SizedBox.shrink()
),
_buildLoadingView(),
Obx(() {
if (controller.listRecipientForward.isNotEmpty) {
return const ListEmailForwardsWidget();
} else {
return const SizedBox.shrink();
}
})
],
),
)
))
],
Expanded(child: SingleChildScrollView(
physics: const ClampingScrollPhysics(),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
if (!controller.responsiveUtils.isWebDesktop(context))
_buildTitleHeader(context),
_buildKeepLocalSwitchButton(context),
Obx(() => controller.currentForward.value != null
? _buildAddRecipientsFormWidget(context)
: const SizedBox.shrink()
),
_buildLoadingView(),
Obx(() {
if (controller.listRecipientForward.isNotEmpty) {
return const ListEmailForwardsWidget();
} else {
return const SizedBox.shrink();
}
})
])
))
],
),
),
),
),
);
}
Widget _buildTitleHeader(BuildContext context) {
return Container(
color: Colors.transparent,
width: double.infinity,
padding: SettingsUtils.getPaddingTitleHeaderForwarding(context, controller.responsiveUtils),
child: Text(
AppLocalizations.of(context).forwardingSettingExplanation,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: AppColor.colorSettingExplanation
)
),
],
);
}
Widget _buildKeepLocalSwitchButton(BuildContext context) {
return Obx(() {
return controller.listRecipientForward.isNotEmpty
? Container(
color: Colors.transparent,
padding: SettingsUtils.getPaddingKeepLocalSwitchButtonForwarding(context, controller.responsiveUtils),
? Padding(
padding: const EdgeInsets.only(bottom: 24, top: 8),
child: Row(children: [
Padding(
padding: const EdgeInsets.only(right: 16),
child: InkWell(
InkWell(
onTap: controller.handleEditLocalCopy,
child: SvgPicture.asset(
controller.currentForwardLocalCopyState
@@ -94,19 +101,24 @@ class ForwardView extends GetWidget<ForwardController> with AppLoaderMixin {
: controller.imagePaths.icSwitchOff,
fit: BoxFit.fill,
width: 36,
height: 24))),
Expanded(
child: Text(
AppLocalizations.of(context).keepLocalCopyForwardLabel,
overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.black)
height: 24,
),
),
)
]))
const SizedBox(width: 16),
Expanded(
child: Text(
AppLocalizations.of(context).keepLocalCopyForwardLabel,
overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.black)
),
),
],
),
)
: const SizedBox();
});
@@ -116,9 +128,7 @@ class ForwardView extends GetWidget<ForwardController> with AppLoaderMixin {
return Obx(() => controller.viewState.value.fold(
(failure) => const SizedBox.shrink(),
(success) => success is LoadingState
? Padding(
padding: const EdgeInsets.all(24),
child: loadingWidget)
? loadingWidget
: const SizedBox.shrink()
));
}
@@ -22,7 +22,6 @@ import 'package:tmail_ui_user/features/contact/presentation/widgets/contact_inpu
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/domain/exceptions/forward_exception.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/utils/app_config.dart';
import 'package:tmail_ui_user/main/utils/app_utils.dart';
@@ -179,28 +178,23 @@ class _AutocompleteContactTextFieldWithTagsState extends State<AutocompleteConta
);
if (widget.hasAddContactButton == true) {
return Container(
color: Colors.transparent,
width: double.infinity,
padding: SettingsUtils.getPaddingInputRecipientForwarding(context, _responsiveUtils),
child: _responsiveUtils.isScreenWithShortestSide(context)
? Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
itemTagEditor,
const SizedBox(height: 16),
_buildAddRecipientButton(context, maxWidth: double.infinity)
],
)
: Row(
children: [
Expanded(child: itemTagEditor),
const SizedBox(width: 12),
_buildAddRecipientButton(context)
],
)
);
return _responsiveUtils.isScreenWithShortestSide(context)
? Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
itemTagEditor,
const SizedBox(height: 16),
_buildAddRecipientButton(context, maxWidth: double.infinity)
],
)
: Row(
children: [
Expanded(child: itemTagEditor),
const SizedBox(width: 12),
_buildAddRecipientButton(context)
],
);
} else {
return itemTagEditor;
}
@@ -461,22 +455,6 @@ class _AutocompleteContactTextFieldWithTagsState extends State<AutocompleteConta
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
),
);
}
}
@@ -1,39 +0,0 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class ForwardHeaderWidget extends StatelessWidget {
const ForwardHeaderWidget({
Key? key,
required this.imagePaths,
required this.responsiveUtils,
}) : super(key: key);
final ImagePaths imagePaths;
final ResponsiveUtils responsiveUtils;
@override
Widget build(BuildContext context) {
return Container(
color: Colors.transparent,
padding: const EdgeInsets.only(top: 24, left: 24, right: 24, bottom: 11),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(
AppLocalizations.of(context).forwarding,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black)),
const SizedBox(height: 8),
Text(
AppLocalizations.of(context).forwardingSettingExplanation,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: AppColor.colorSettingExplanation)),
]),
);
}
}
@@ -1,21 +1,27 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart';
import 'package:tmail_ui_user/main/utils/app_config.dart';
class ForwardWarningBanner extends StatelessWidget {
final ImagePaths _imagePaths = Get.find<ImagePaths>();
final ImagePaths imagePaths;
final ResponsiveUtils responsiveUtils;
ForwardWarningBanner({super.key});
const ForwardWarningBanner({
super.key,
required this.imagePaths,
required this.responsiveUtils,
});
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: const EdgeInsetsDirectional.only(top: 16, start: 16, end: 16),
margin: SettingsUtils.getForwardBannerPadding(context, responsiveUtils),
padding: const EdgeInsets.all(12),
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8)),
@@ -23,7 +29,7 @@ class ForwardWarningBanner extends StatelessWidget {
),
child: Row(children: [
SvgPicture.asset(
_imagePaths.icInfoCircleOutline,
imagePaths.icInfoCircleOutline,
colorFilter: AppColor.colorQuotaError.asFilter(),
),
const SizedBox(width: 12),
@@ -8,7 +8,6 @@ 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';
import 'package:tmail_ui_user/features/manage_account/presentation/model/recipient_forward.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -18,39 +17,35 @@ class ListEmailForwardsWidget extends GetWidget<ForwardController> {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.transparent,
padding: SettingsUtils.getPaddingListRecipientForwarding(context, controller.responsiveUtils),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
_buildTitleHeader(context),
Obx(() {
if (controller.listRecipientForward.isEmpty) {
return const SizedBox.shrink();
} else {
return ListView.builder(
shrinkWrap: true,
primary: false,
itemCount: controller.listRecipientForward.length,
padding: EdgeInsets.zero,
itemBuilder: (context, index) {
return EmailForwardItemWidget(
recipientForward: controller.listRecipientForward[index],
internalDomain: controller.accountDashBoardController.sessionCurrent?.internalDomain ?? '',
selectionMode: controller.selectionMode.value,
onSelectRecipientCallback: controller.selectRecipientForward,
onDeleteRecipientCallback: (recipientForward) {
controller.deleteRecipients(context, recipientForward.emailAddress.emailAddress);
},
);
}
);
}
}),
]
),
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
_buildTitleHeader(context),
Obx(() {
if (controller.listRecipientForward.isEmpty) {
return const SizedBox.shrink();
} else {
return ListView.builder(
shrinkWrap: true,
primary: false,
itemCount: controller.listRecipientForward.length,
padding: EdgeInsets.zero,
itemBuilder: (context, index) {
return EmailForwardItemWidget(
recipientForward: controller.listRecipientForward[index],
internalDomain: controller.accountDashBoardController.sessionCurrent?.internalDomain ?? '',
selectionMode: controller.selectionMode.value,
onSelectRecipientCallback: controller.selectRecipientForward,
onDeleteRecipientCallback: (recipientForward) {
controller.deleteRecipients(context, recipientForward.emailAddress.emailAddress);
},
);
}
);
}
}),
]
);
}
@@ -1,60 +1,43 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:flutter/material.dart';
import 'package:flutter_portal/flutter_portal.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/base/setting_detail_view_builder.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/language_and_region/language_and_region_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/language_and_region/widgets/change_language_button_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/language_and_region/widgets/language_and_region_header_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart';
import 'package:tmail_ui_user/main/utils/app_utils.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/widgets/setting_explanation_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/widgets/setting_header_widget.dart';
class LanguageAndRegionView extends GetWidget<LanguageAndRegionController> {
const LanguageAndRegionView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Portal(
child: Scaffold(
backgroundColor: controller.responsiveUtils.isWebDesktop(context)
? AppColor.colorBgDesktop
: Colors.white,
body: Container(
width: double.infinity,
margin: controller.responsiveUtils.isWebDesktop(context)
? const EdgeInsets.all(24)
: EdgeInsets.symmetric(horizontal: SettingsUtils.getHorizontalPadding(context, controller.responsiveUtils)),
color: controller.responsiveUtils.isWebDesktop(context) ? null : Colors.white,
decoration: controller.responsiveUtils.isWebDesktop(context)
? BoxDecoration(
borderRadius: BorderRadius.circular(20),
border: Border.all(color: AppColor.colorBorderBodyThread, width: 1),
color: Colors.white)
: null,
child: ClipRRect(
borderRadius: BorderRadius.circular(
controller.responsiveUtils.isWebDesktop(context) ? 20 : 0),
child: Padding(
padding: EdgeInsets.only(
right: AppUtils.isDirectionRTL(context)
? controller.responsiveUtils.isWebDesktop(context) ? 24 : 0
: 0,
left: AppUtils.isDirectionRTL(context)
? 0
: controller.responsiveUtils.isWebDesktop(context) ? 24 : 0,
top: 24
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const LanguageAndRegionHeaderWidget(),
const SizedBox(height: 22),
Expanded(child: ChangeLanguageButtonWidget())
]
child: SettingDetailViewBuilder(
responsiveUtils: controller.responsiveUtils,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (controller.responsiveUtils.isWebDesktop(context))
...[
const SettingHeaderWidget(menuItem: AccountMenuItem.languageAndRegion),
const Divider(height: 1, color: AppColor.colorDividerHeaderSetting),
]
else
const SettingExplanationWidget(menuItem: AccountMenuItem.languageAndRegion),
Expanded(
child: Padding(
padding: const EdgeInsetsDirectional.only(
start: 16,
top: 24,
end: 16,
),
child: ChangeLanguageButtonWidget(),
),
),
),
],
),
),
);
@@ -1,28 +0,0 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class LanguageAndRegionHeaderWidget extends StatelessWidget {
const LanguageAndRegionHeaderWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(AppLocalizations.of(context).language,
style: const TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold,
color: Colors.black)),
const SizedBox(height: 4),
Text(AppLocalizations.of(context).languageSubtitle,
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.normal,
color: AppColor.colorTextButtonHeaderThread))
]);
}
}
@@ -16,6 +16,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_i
import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_multiple_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart';
import 'package:tmail_ui_user/main/exceptions/remote_exception_thrower.dart';
import 'package:tmail_ui_user/main/utils/ios_sharing_manager.dart';
@@ -50,6 +51,7 @@ class MailboxVisibilityInteractorBindings extends InteractorsBindings {
Get.lazyPut(() => RefreshAllMailboxInteractor(Get.find<MailboxRepository>()));
Get.lazyPut(() => SubscribeMailboxInteractor(Get.find<MailboxRepository>()));
Get.lazyPut(() => SubscribeMultipleMailboxInteractor(Get.find<MailboxRepository>()));
Get.lazyPut(() => VerifyNameInteractor());
}
@override
@@ -13,7 +13,8 @@ import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visib
import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/state/mailbox_visibility_state.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/utils/mailbox_visibility_utils.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/widgets/mailbox_visibility_folder_tile_builder.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/widgets/mailbox_visibility_header_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/widgets/setting_header_widget.dart';
class MailboxVisibilityView extends GetWidget<MailboxVisibilityController>
with AppLoaderMixin,
@@ -30,13 +31,8 @@ class MailboxVisibilityView extends GetWidget<MailboxVisibilityController>
children: [
if (controller.responsiveUtils.isWebDesktop(context))
...[
const SizedBox(height: 24),
const MailboxVisibilityHeaderWidget(),
const SizedBox(height: 16),
const Divider(
color: AppColor.colorDividerMailbox,
height: 1
)
const SettingHeaderWidget(menuItem: AccountMenuItem.mailboxVisibility),
const Divider(height: 1, color: AppColor.colorDividerHeaderSetting),
],
_buildLoadingView(),
Expanded(child: Padding(
@@ -1,34 +0,0 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/utils/app_utils.dart';
class MailboxVisibilityHeaderWidget extends StatelessWidget {
const MailboxVisibilityHeaderWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(
left: AppUtils.isDirectionRTL(context) ? 0 : 24,
right: AppUtils.isDirectionRTL(context) ? 24 : 0
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(AppLocalizations.of(context).folderVisibility,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black)),
const SizedBox(height: 4),
Text(AppLocalizations.of(context).folderVisibilitySubtitle,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: AppColor.colorSettingExplanation))
]),
);
}
}
@@ -15,7 +15,6 @@ import 'package:rule_filter/rule_filter/capability_rule_filter.dart';
import 'package:server_settings/server_settings/capability_server_settings.dart';
import 'package:tmail_ui_user/features/base/action/ui_action.dart';
import 'package:tmail_ui_user/features/base/reloadable/reloadable_controller.dart';
import 'package:tmail_ui_user/features/base/state/banner_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mixin/user_setting_popup_menu_mixin.dart';
import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_vacation_state.dart';
import 'package:tmail_ui_user/features/manage_account/domain/state/update_vacation_state.dart';
@@ -51,7 +50,6 @@ class ManageAccountDashBoardController extends ReloadableController with UserSet
final accountMenuItemSelected = AccountMenuItem.profiles.obs;
final settingsPageLevel = SettingsPageLevel.universal.obs;
final vacationResponse = Rxn<VacationResponse>();
final forwardWarningBannerState = Rxn<BannerState>();
final dashboardSettingAction = Rxn<UIAction>();
Session? sessionCurrent;
@@ -372,7 +370,7 @@ class ManageAccountDashBoardController extends ReloadableController with UserSet
position,
popupMenuUserSettingActionTile(
context,
sessionCurrent?.getOwnEmailAddress(),
getOwnEmailAddress(),
onLogoutAction: () {
popBack();
logout(context, sessionCurrent, accountId.value);
@@ -390,6 +388,15 @@ class ManageAccountDashBoardController extends ReloadableController with UserSet
accountId: accountId.value!);
}
String getOwnEmailAddress() {
try {
return sessionCurrent?.getOwnEmailAddress() ?? '';
} catch (e) {
logError('ManageAccountDashBoardController::getOwnEmailAddress:Exception: $e');
return '';
}
}
@override
void onClose() {
BackButtonInterceptor.removeByName(AppRoutes.settings);
@@ -1,15 +1,13 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/extensions/string_extension.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/views/responsive/responsive_widget.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:model/model.dart';
import 'package:tmail_ui_user/features/base/state/banner_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/navigation_bar/navigation_bar_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/email_rules_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/forward/forward_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/forward/widgets/forward_warning_banner.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/language_and_region/language_and_region_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/mailbox_visibility_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart';
@@ -28,26 +26,24 @@ class ManageAccountDashBoardView extends GetWidget<ManageAccountDashBoardControl
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
backgroundColor: controller.responsiveUtils.isWebDesktop(context)
? AppColor.colorBgDesktop
: Colors.white,
drawerEnableOpenDragGesture: false,
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: ResponsiveWidget(
responsiveUtils: controller.responsiveUtils,
desktop: Column(children: [
Obx(() {
final accountId = controller.accountId.value;
if (accountId == null) {
return const SizedBox.shrink();
} else {
return NavigationBarWidget(
imagePaths: controller.imagePaths,
avatarUserName: controller.sessionCurrent?.username.firstCharacter ?? '',
onTapApplicationLogoAction: () => controller.backToMailboxDashBoard(context: context),
onTapAvatarAction: (position) => controller.handleClickAvatarAction(context, position),
);
}
}),
Obx(() => NavigationBarWidget(
imagePaths: controller.imagePaths,
accountId: controller.accountId.value,
avatarUserName: controller.getOwnEmailAddress().firstCharacterToUpperCase,
onTapApplicationLogoAction: () =>
controller.backToMailboxDashBoard(context: context),
onTapAvatarAction: (position) =>
controller.handleClickAvatarAction(context, position),
)),
Expanded(child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -55,7 +51,7 @@ class ManageAccountDashBoardView extends GetWidget<ManageAccountDashBoardControl
width: ResponsiveUtils.defaultSizeMenu,
child: ManageAccountMenuView()
),
Expanded(child: Container(
Expanded(child: ColoredBox(
color: AppColor.colorBgDesktop,
child: Column(children: [
Obx(() {
@@ -85,14 +81,6 @@ class ManageAccountDashBoardView extends GetWidget<ManageAccountDashBoardControl
return const SizedBox.shrink();
}
}),
Obx(() {
if (controller.forwardWarningBannerState.value == BannerState.enabled &&
controller.accountMenuItemSelected.value == AccountMenuItem.forward) {
return ForwardWarningBanner();
} else {
return const SizedBox.shrink();
}
}),
Expanded(child: _viewDisplayedOfAccountMenuItem())
]),
))
@@ -113,7 +101,7 @@ class ManageAccountDashBoardView extends GetWidget<ManageAccountDashBoardControl
return Obx(() {
switch(controller.accountMenuItemSelected.value) {
case AccountMenuItem.profiles:
return ProfilesView();
return ProfilesView(responsiveUtils: controller.responsiveUtils);
case AccountMenuItem.languageAndRegion:
return const LanguageAndRegionView();
case AccountMenuItem.emailRules:
@@ -20,7 +20,9 @@ class ManageAccountMenuView extends GetWidget<ManageAccountMenuController> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
backgroundColor: controller.responsiveUtils.isWebDesktop(context)
? AppColor.colorBgDesktop
: Colors.white,
body: SafeArea(right: false, bottom: false,
child: Column(
children: [
@@ -75,28 +77,30 @@ class ManageAccountMenuView extends GetWidget<ManageAccountMenuController> {
)
),
const SizedBox(height: 12),
Obx(() {
if (controller.listAccountMenuItem.isNotEmpty) {
return ListView.builder(
key: const Key('list_manage_account_menu_item'),
padding: const EdgeInsetsDirectional.only(start: 16, end: 8),
shrinkWrap: true,
itemCount: controller.listAccountMenuItem.length,
itemBuilder: (context, index) => Obx(() {
final menuItem = controller.listAccountMenuItem[index];
return AccountMenuItemTileBuilder(
imagePaths: controller.imagePaths,
responsiveUtils: controller.responsiveUtils,
menuItem: menuItem,
menuItemSelected: controller.dashBoardController.accountMenuItemSelected.value,
onSelectAccountMenuItemAction: controller.selectAccountMenuItem
);
})
);
} else {
return const SizedBox.shrink();
}
}),
Flexible(
child: Obx(() {
if (controller.listAccountMenuItem.isNotEmpty) {
return ListView.builder(
key: const Key('list_manage_account_menu_item'),
padding: const EdgeInsetsDirectional.only(start: 16, end: 8),
shrinkWrap: true,
itemCount: controller.listAccountMenuItem.length,
itemBuilder: (context, index) => Obx(() {
final menuItem = controller.listAccountMenuItem[index];
return AccountMenuItemTileBuilder(
imagePaths: controller.imagePaths,
responsiveUtils: controller.responsiveUtils,
menuItem: menuItem,
menuItemSelected: controller.dashBoardController.accountMenuItemSelected.value,
onSelectAccountMenuItemAction: controller.selectAccountMenuItem
);
})
);
} else {
return const SizedBox.shrink();
}
}),
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: Divider()),
@@ -145,6 +149,7 @@ class ManageAccountMenuView extends GetWidget<ManageAccountMenuController> {
),
)),
Container(
color: AppColor.colorBgDesktop,
width: double.infinity,
alignment: controller.responsiveUtils.isDesktop(context)
? AlignmentDirectional.centerStart
@@ -153,12 +158,6 @@ class ManageAccountMenuView extends GetWidget<ManageAccountMenuController> {
child: ApplicationVersionWidget(
padding: EdgeInsets.zero,
title: '${AppLocalizations.of(context).version.toLowerCase()} ',
textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(
fontSize: 13,
height: 16 / 13,
color: AppColor.steelGray400,
fontWeight: FontWeight.w400,
),
),
),
]
@@ -2,8 +2,6 @@ import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/user_information_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/settings_controller.dart';
@@ -22,8 +20,8 @@ class SettingsFirstLevelView extends GetWidget<SettingsController> {
child: Column(children: [
Obx(() => UserInformationWidget(
userName: controller.manageAccountDashboardController.accountId.value != null
? UserName(controller.manageAccountDashboardController.sessionCurrent!.getOwnEmailAddress())
: null,
? controller.manageAccountDashboardController.getOwnEmailAddress()
: '',
padding: SettingsUtils.getPaddingInFirstLevel(context, controller.responsiveUtils),
titlePadding: const EdgeInsetsDirectional.only(start: 16))),
Divider(
@@ -48,7 +46,7 @@ class SettingsFirstLevelView extends GetWidget<SettingsController> {
if (controller.manageAccountDashboardController.isRuleFilterCapabilitySupported) {
return Column(children: [
SettingFirstLevelTileBuilder(
AccountMenuItem.emailRules.getName(context),
AccountMenuItem.emailRules.getName(AppLocalizations.of(context)),
AccountMenuItem.emailRules.getIcon(controller.imagePaths),
subtitle: AppLocalizations.of(context).emailRuleSettingExplanation,
() => controller.selectSettings(AccountMenuItem.emailRules)
@@ -68,7 +66,7 @@ class SettingsFirstLevelView extends GetWidget<SettingsController> {
if (controller.manageAccountDashboardController.isServerSettingsCapabilitySupported) {
return Column(children: [
SettingFirstLevelTileBuilder(
AccountMenuItem.preferences.getName(context),
AccountMenuItem.preferences.getName(AppLocalizations.of(context)),
AccountMenuItem.preferences.getIcon(controller.imagePaths),
subtitle: AppLocalizations.of(context).emailReadReceiptsSettingExplanation,
() => controller.selectSettings(AccountMenuItem.preferences)
@@ -88,7 +86,7 @@ class SettingsFirstLevelView extends GetWidget<SettingsController> {
if (controller.manageAccountDashboardController.isForwardCapabilitySupported) {
return Column(children: [
SettingFirstLevelTileBuilder(
AccountMenuItem.forward.getName(context),
AccountMenuItem.forward.getName(AppLocalizations.of(context)),
AccountMenuItem.forward.getIcon(controller.imagePaths),
subtitle: AppLocalizations.of(context).forwardingSettingExplanation,
() => controller.selectSettings(AccountMenuItem.forward)
@@ -108,7 +106,7 @@ class SettingsFirstLevelView extends GetWidget<SettingsController> {
if (controller.manageAccountDashboardController.isVacationCapabilitySupported) {
return Column(children: [
SettingFirstLevelTileBuilder(
AccountMenuItem.vacation.getName(context),
AccountMenuItem.vacation.getName(AppLocalizations.of(context)),
AccountMenuItem.vacation.getIcon(controller.imagePaths),
subtitle: AppLocalizations.of(context).vacationSettingExplanation,
() => controller.selectSettings(AccountMenuItem.vacation)
@@ -125,7 +123,7 @@ class SettingsFirstLevelView extends GetWidget<SettingsController> {
}
}),
SettingFirstLevelTileBuilder(
AccountMenuItem.mailboxVisibility.getName(context),
AccountMenuItem.mailboxVisibility.getName(AppLocalizations.of(context)),
AccountMenuItem.mailboxVisibility.getIcon(controller.imagePaths),
subtitle: AppLocalizations.of(context).folderVisibilitySubtitle,
() => controller.selectSettings(AccountMenuItem.mailboxVisibility)
@@ -137,7 +135,7 @@ class SettingsFirstLevelView extends GetWidget<SettingsController> {
endIndent: SettingsUtils.getHorizontalPadding(context, controller.responsiveUtils)
),
SettingFirstLevelTileBuilder(
AccountMenuItem.languageAndRegion.getName(context),
AccountMenuItem.languageAndRegion.getName(AppLocalizations.of(context)),
AccountMenuItem.languageAndRegion.getIcon(controller.imagePaths),
() => controller.selectSettings(AccountMenuItem.languageAndRegion)
),
@@ -190,7 +188,7 @@ class SettingsFirstLevelView extends GetWidget<SettingsController> {
),
),
SettingFirstLevelTileBuilder(
AccountMenuItem.contactSupport.getName(context),
AccountMenuItem.contactSupport.getName(AppLocalizations.of(context)),
AccountMenuItem.contactSupport.getIcon(controller.imagePaths),
() => controller.onGetHelpOrReportBug(
contactSupportCapability!,
@@ -5,11 +5,9 @@ import 'package:core/utils/direction_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/base/state/banner_state.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/email_rules_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/forward/forward_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/forward/widgets/forward_warning_banner.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/language_and_region/language_and_region_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/mailbox_visibility_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/settings_controller.dart';
@@ -70,14 +68,6 @@ class SettingsView extends GetWidget<SettingsController> {
return const SizedBox.shrink();
}
}),
Obx(() {
if (controller.manageAccountDashboardController.forwardWarningBannerState.value == BannerState.enabled &&
controller.manageAccountDashboardController.accountMenuItemSelected.value == AccountMenuItem.forward) {
return ForwardWarningBanner();
} else {
return const SizedBox.shrink();
}
}),
Expanded(child: _bodySettingsScreen())
]
);
@@ -152,7 +142,7 @@ class SettingsView extends GetWidget<SettingsController> {
),
),
Expanded(child: Text(
controller.manageAccountDashboardController.accountMenuItemSelected.value.getName(context),
controller.manageAccountDashboardController.accountMenuItemSelected.value.getName(AppLocalizations.of(context)),
maxLines: 1,
textAlign: TextAlign.center,
overflow: CommonTextStyle.defaultTextOverFlow,
@@ -189,7 +179,7 @@ class SettingsView extends GetWidget<SettingsController> {
return Obx(() {
switch(controller.manageAccountDashboardController.accountMenuItemSelected.value) {
case AccountMenuItem.profiles:
return ProfilesView();
return ProfilesView(responsiveUtils: controller.responsiveUtils);
case AccountMenuItem.languageAndRegion:
return const LanguageAndRegionView();
case AccountMenuItem.emailRules:
@@ -2,9 +2,10 @@ import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/main/utils/app_utils.dart';
class SettingsUtils {
SettingsUtils._();
static double getHorizontalPadding(BuildContext context, ResponsiveUtils responsiveUtils) {
if (responsiveUtils.isMobile(context)) {
return 16;
@@ -54,22 +55,34 @@ class SettingsUtils {
}
}
static BoxDecoration? getBoxDecorationForContent(BuildContext context, ResponsiveUtils responsiveUtils) {
static BoxDecoration? getBoxDecorationForContent(
BuildContext context,
ResponsiveUtils responsiveUtils,
{
Color backgroundColor = Colors.white
}
) {
if (responsiveUtils.isWebDesktop(context)) {
return BoxDecoration(
borderRadius: BorderRadius.circular(16),
border: Border.all(color: AppColor.colorBorderSettingContentWeb, width: 1),
color: Colors.white);
borderRadius: const BorderRadius.all(Radius.circular(16)),
color: backgroundColor,
);
} else {
return null;
}
}
static Color? getContentBackgroundColor(BuildContext context, ResponsiveUtils responsiveUtils) {
static Color? getContentBackgroundColor(
BuildContext context,
ResponsiveUtils responsiveUtils,
{
Color backgroundColor = Colors.white
}
) {
if (responsiveUtils.isWebDesktop(context)) {
return null;
} else {
return Colors.white;
return backgroundColor;
}
}
@@ -81,58 +94,33 @@ class SettingsUtils {
}
}
static EdgeInsets getPaddingListRecipientForwarding(BuildContext context, ResponsiveUtils responsiveUtils) {
if (responsiveUtils.isPortraitMobile(context)) {
return const EdgeInsets.symmetric(horizontal: 16);
} else if (responsiveUtils.isLandscapeMobile(context)) {
return const EdgeInsets.all(12);
} else {
return const EdgeInsets.symmetric(horizontal: 32, vertical: 12);
}
}
static BoxDecoration? getBoxDecorationForListRecipient(BuildContext context, ResponsiveUtils responsiveUtils) {
return BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColor.colorBorderSettingContentWeb, width: 1),
color: Colors.white);
}
static EdgeInsets getPaddingTitleHeaderForwarding(BuildContext context, ResponsiveUtils responsiveUtils) {
if (responsiveUtils.isPortraitMobile(context)) {
return const EdgeInsets.symmetric(horizontal: 16, vertical: 12);
} else if (responsiveUtils.isLandscapeMobile(context)) {
return const EdgeInsets.all(12);
} else {
return const EdgeInsets.symmetric(horizontal: 32, vertical: 12);
}
}
static EdgeInsets getPaddingKeepLocalSwitchButtonForwarding(BuildContext context, ResponsiveUtils responsiveUtils) {
if (responsiveUtils.isPortraitMobile(context)) {
return const EdgeInsets.symmetric(horizontal: 18, vertical: 14);
} else if (responsiveUtils.isLandscapeMobile(context)) {
return const EdgeInsets.all(14);
} else {
return const EdgeInsets.symmetric(horizontal: 34, vertical: 14);
}
}
static EdgeInsets getPaddingInputRecipientForwarding(BuildContext context, ResponsiveUtils responsiveUtils) {
if (responsiveUtils.isPortraitMobile(context)) {
return const EdgeInsets.symmetric(horizontal: 16, vertical: 12);
} else if (responsiveUtils.isLandscapeMobile(context)) {
return const EdgeInsets.all(12);
} else {
return const EdgeInsets.symmetric(horizontal: 32, vertical: 12);
}
}
static EdgeInsets getMarginViewForForwardSettingDetails(BuildContext context, ResponsiveUtils responsiveUtils) {
static EdgeInsetsGeometry getSettingContentPadding(
BuildContext context,
ResponsiveUtils responsiveUtils,
) {
if (responsiveUtils.isWebDesktop(context)) {
return const EdgeInsets.all(16);
} else if (responsiveUtils.isPortraitMobile(context)) {
return const EdgeInsets.symmetric(horizontal: 16, vertical: 12);
} else if (responsiveUtils.isLandscapeMobile(context)) {
return const EdgeInsets.all(12);
} else {
return const EdgeInsets.symmetric(horizontal: 32, vertical: 12);
}
}
static EdgeInsetsGeometry getSettingContentWithoutHeaderPadding(
BuildContext context,
ResponsiveUtils responsiveUtils,
) {
if (responsiveUtils.isWebDesktop(context)) {
return EdgeInsets.zero;
} else if (responsiveUtils.isPortraitMobile(context)) {
return const EdgeInsets.symmetric(horizontal: 16, vertical: 12);
} else if (responsiveUtils.isLandscapeMobile(context)) {
return const EdgeInsets.all(12);
} else {
return const EdgeInsets.symmetric(horizontal: 32, vertical: 12);
}
}
@@ -144,30 +132,29 @@ class SettingsUtils {
}
}
static EdgeInsets getPaddingHeaderSetting(BuildContext context) {
if (AppUtils.isDirectionRTL(context)) {
return const EdgeInsets.only(top: 25, bottom: 25, right: 32);
} else {
return const EdgeInsets.only(top: 25, bottom: 25, left: 32);
}
}
static EdgeInsets getPaddingRightHeaderSetting(BuildContext context) {
if (AppUtils.isDirectionRTL(context)) {
return const EdgeInsets.only(right: 48, top: 16, bottom: 10, left: 10);
} else {
return const EdgeInsets.only(right: 10, top: 16, bottom: 10, left: 48);
}
}
static EdgeInsets getPaddingAlwaysReadReceiptSetting(
static EdgeInsetsGeometry getPreferencesSettingPadding(
BuildContext context,
ResponsiveUtils responsiveUtils
) {
if (responsiveUtils.isWebDesktop(context)) {
return const EdgeInsets.all(24);
} else {
return EdgeInsets.zero;
return const EdgeInsetsDirectional.symmetric(vertical: 8);
}
}
static EdgeInsetsGeometry getForwardBannerPadding(
BuildContext context,
ResponsiveUtils responsiveUtils,
) {
if (responsiveUtils.isWebDesktop(context)) {
return const EdgeInsetsDirectional.only(start: 16, end: 16, top: 16);
} else if (responsiveUtils.isPortraitMobile(context)) {
return const EdgeInsets.symmetric(horizontal: 16, vertical: 12);
} else if (responsiveUtils.isLandscapeMobile(context)) {
return const EdgeInsets.all(12);
} else {
return const EdgeInsets.symmetric(horizontal: 32, vertical: 12);
}
}
}
@@ -1,9 +1,11 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.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/manage_account/presentation/model/account_menu_item.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
typedef OnSelectAccountMenuItemAction = void Function(AccountMenuItem);
@@ -53,12 +55,8 @@ class AccountMenuItemTileBuilder extends StatelessWidget {
fit: BoxFit.fill),
const SizedBox(width: 12),
Expanded(child: Text(
menuItem.getName(context),
style: const TextStyle(
fontWeight: FontWeight.normal,
fontSize: 15,
color: Colors.black
)
menuItem.getName(AppLocalizations.of(context)),
style: ThemeUtils.textStyleBodyBody3(color: Colors.black)
))
]),
])
@@ -1,6 +1,5 @@
import 'package:core/presentation/resources/image_paths.dart';
import 'package:flutter/cupertino.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
enum AccountMenuItem {
@@ -43,30 +42,49 @@ enum AccountMenuItem {
}
}
String getName(BuildContext context) {
String getName(AppLocalizations appLocalizations) {
switch(this) {
case AccountMenuItem.profiles:
return AppLocalizations.of(context).profiles;
return appLocalizations.profiles;
case AccountMenuItem.languageAndRegion:
return AppLocalizations.of(context).language;
return appLocalizations.language;
case AccountMenuItem.emailRules:
return AppLocalizations.of(context).emailRules;
return appLocalizations.emailRules;
case AccountMenuItem.preferences:
return AppLocalizations.of(context).preferences;
return appLocalizations.preferences;
case AccountMenuItem.forward:
return AppLocalizations.of(context).forwarding;
return appLocalizations.forwarding;
case AccountMenuItem.vacation:
return AppLocalizations.of(context).vacation;
return appLocalizations.vacation;
case AccountMenuItem.mailboxVisibility:
return AppLocalizations.of(context).folderVisibility;
return appLocalizations.folderVisibility;
case AccountMenuItem.notification:
return AppLocalizations.of(context).notification;
return appLocalizations.notification;
case AccountMenuItem.contactSupport:
return AppLocalizations.of(context).contactSupport;
return appLocalizations.contactSupport;
case AccountMenuItem.signOut:
return AppLocalizations.of(context).sign_out;
return appLocalizations.sign_out;
case AccountMenuItem.none:
return AppLocalizations.of(context).profiles;
return appLocalizations.profiles;
}
}
String getExplanation(AppLocalizations appLocalizations) {
switch(this) {
case AccountMenuItem.profiles:
return appLocalizations.profilesSettingExplanation;
case AccountMenuItem.languageAndRegion:
return appLocalizations.languageSubtitle;
case AccountMenuItem.emailRules:
return appLocalizations.emailRuleSettingExplanation;
case AccountMenuItem.forward:
return appLocalizations.forwardingSettingExplanation;
case AccountMenuItem.vacation:
return appLocalizations.vacationSettingExplanation;
case AccountMenuItem.mailboxVisibility:
return appLocalizations.folderVisibilitySubtitle;
default:
return '';
}
}
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/base/setting_detail_view_builder.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/setting_option_type.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/preferences/preferences_controller.dart';
@@ -11,60 +12,63 @@ class PreferencesView extends GetWidget<PreferencesController> with AppLoaderMix
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: SettingsUtils.getBackgroundColor(context, controller.responsiveUtils),
body: Padding(
padding: SettingsUtils.getMarginViewForSettingDetails(context, controller.responsiveUtils),
child: Column(
children: [
Obx(() {
if (!controller.isLoading) {
return const SizedBox.shrink();
}
return Padding(
padding: const EdgeInsets.only(bottom: 8),
child: horizontalLoadingWidget,
);
}),
Expanded(
child: Container(
color: SettingsUtils.getContentBackgroundColor(
context, controller.responsiveUtils,
),
decoration: SettingsUtils.getBoxDecorationForContent(
context,
controller.responsiveUtils,
),
width: double.infinity,
padding: SettingsUtils.getPaddingAlwaysReadReceiptSetting(
context,
controller.responsiveUtils,
),
child: Obx(() {
final settingOption = controller.settingOption.value;
if (settingOption == null) return const SizedBox.shrink();
final settingOptionList = SettingOptionType.values.toList();
return ListView.separated(
itemCount: settingOptionList.length,
itemBuilder: (context, index) {
return SettingOptionItem(
imagePaths: controller.imagePaths,
settingOption: settingOption,
optionType: settingOptionList[index],
onTapSettingOptionAction: controller.updateStateSettingOption,
);
},
separatorBuilder: (_, __) => const SizedBox(height: 60),
);
}),
),
return Column(
children: [
Obx(() {
if (!controller.isLoading) {
return const SizedBox.shrink();
}
return Padding(
padding: controller.responsiveUtils.isTablet(context)
? const EdgeInsetsDirectional.only(start: 32, end: 32, top: 16)
: const EdgeInsetsDirectional.only(start: 16, end: 16, top: 16),
child: horizontalLoadingWidget,
);
}),
Expanded(
child: SettingDetailViewBuilder(
responsiveUtils: controller.responsiveUtils,
padding: SettingsUtils.getSettingContentWithoutHeaderPadding(
context,
controller.responsiveUtils,
),
],
child: Container(
color: SettingsUtils.getContentBackgroundColor(
context, controller.responsiveUtils,
),
decoration: SettingsUtils.getBoxDecorationForContent(
context,
controller.responsiveUtils,
),
width: double.infinity,
padding: SettingsUtils.getPreferencesSettingPadding(
context,
controller.responsiveUtils,
),
child: Obx(() {
final settingOption = controller.settingOption.value;
if (settingOption == null) return const SizedBox.shrink();
final settingOptionList = SettingOptionType.values.toList();
return ListView.separated(
itemCount: settingOptionList.length,
itemBuilder: (context, index) {
return SettingOptionItem(
imagePaths: controller.imagePaths,
settingOption: settingOption,
optionType: settingOptionList[index],
onTapSettingOptionAction: controller.updateStateSettingOption,
);
},
separatorBuilder: (_, __) => const SizedBox(height: 60),
);
}),
),
),
),
),
],
);
}
}
@@ -1,4 +1,5 @@
import 'package:core/presentation/constants/constants_ui.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
@@ -34,6 +35,7 @@ class SettingOptionItem extends StatelessWidget {
Text(
optionType.getTitle(appLocalizations),
style: const TextStyle(
fontFamily: ConstantsUI.fontApp,
fontSize: 15,
height: 20 / 15,
fontWeight: FontWeight.bold,
@@ -44,9 +46,7 @@ class SettingOptionItem extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 24),
child: Text(
optionType.getExplanation(appLocalizations),
style: const TextStyle(
fontSize: 13,
height: 16 / 13,
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Colors.black,
),
),
@@ -71,9 +71,7 @@ class SettingOptionItem extends StatelessWidget {
Expanded(
child: Text(
optionType.getToggleDescription(appLocalizations),
style: const TextStyle(
fontSize: 13,
height: 16 / 13,
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Colors.black,
),
),
@@ -312,12 +312,15 @@ class IdentitiesController extends ReloadableController implements BeforeReconne
void _deleteIdentityFailure(DeleteIdentityFailure failure) {
if (currentContext != null) {
Get.dialog(
(ConfirmDialogBuilder(imagePaths, useIconAsBasicLogo: true)
..key(const Key('dialog_message_delete_identity_failed'))
..title(AppLocalizations.of(currentContext!).delete_failed)
..onCloseButtonAction(() => popBack())
..onConfirmButtonAction('${AppLocalizations.of(currentContext!).got_it}!', () => popBack()))
.build(),
ConfirmationDialogBuilder(
key: const Key('dialog_message_delete_identity_failed'),
imagePath: imagePaths,
useIconAsBasicLogo: true,
title: AppLocalizations.of(currentContext!).delete_failed,
confirmText: '${AppLocalizations.of(currentContext!).got_it}!',
onConfirmButtonAction: popBack,
onCloseButtonAction: popBack,
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
);
}
@@ -2,6 +2,7 @@ import 'package:flutter/material.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/popup_menu_widget_mixin.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/identities_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/widgets/identities_header_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/widgets/identities_radio_list_builder.dart';
@@ -12,8 +13,11 @@ class IdentitiesView extends GetWidget<IdentitiesController> with PopupMenuWidge
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(24),
return Padding(
padding: SettingsUtils.getSettingContentPadding(
context,
controller.responsiveUtils,
),
child: controller.responsiveUtils.isWebDesktop(context)
? _buildIdentitiesViewWebDesktop(context)
: _buildIdentitiesViewMobile(context),
@@ -1,4 +1,8 @@
import 'package:core/core.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart';
import 'package:core/presentation/views/responsive/responsive_widget.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -21,32 +25,47 @@ class DeleteIdentityDialogBuilder extends StatelessWidget {
@override
Widget build(BuildContext context) {
final appLocalizations = AppLocalizations.of(context);
final deleteDialogBuilder = ResponsiveWidget(
responsiveUtils: responsiveUtils,
mobile: (_buildDeleteDialog(context)
..alignment(Alignment.bottomCenter)
..outsideDialogPadding(EdgeInsets.only(bottom: PlatformInfo.isWeb ? 42 : 16))
..widthDialog(MediaQuery.of(context).size.width - 16))
.build(),
landscapeMobile: _buildDeleteDialog(context).build(),
tablet: _buildDeleteDialog(context).build(),
tabletLarge: _buildDeleteDialog(context).build(),
landscapeTablet: _buildDeleteDialog(context).build(),
desktop: _buildDeleteDialog(context).build());
mobile: _buildDeleteDialog(
appLocalizations: appLocalizations,
alignment: Alignment.bottomCenter,
outsideDialogPadding: EdgeInsets.only(bottom: PlatformInfo.isWeb ? 42 : 16),
widthDialog: MediaQuery.of(context).size.width - 16,
),
landscapeMobile: _buildDeleteDialog(appLocalizations: appLocalizations),
tablet: _buildDeleteDialog(appLocalizations: appLocalizations),
tabletLarge: _buildDeleteDialog(appLocalizations: appLocalizations),
landscapeTablet: _buildDeleteDialog(appLocalizations: appLocalizations),
desktop: _buildDeleteDialog(appLocalizations: appLocalizations),
);
return PlatformInfo.isWeb
? PointerInterceptor(child: deleteDialogBuilder)
: deleteDialogBuilder;
}
ConfirmDialogBuilder _buildDeleteDialog(BuildContext context) {
return ConfirmDialogBuilder(imagePaths, useIconAsBasicLogo: true)
..key(const Key('confirm_dialog_delete_identity'))
..title(AppLocalizations.of(context).delete_identity)
..content(AppLocalizations.of(context).message_confirmation_dialog_delete_identity)
..onCloseButtonAction(popBack)
..onConfirmButtonAction(AppLocalizations.of(context).delete, () =>
onDeleteIdentityAction.call())
..onCancelButtonAction(AppLocalizations.of(context).cancel, () => popBack());
ConfirmationDialogBuilder _buildDeleteDialog({
required AppLocalizations appLocalizations,
Alignment? alignment,
EdgeInsets? outsideDialogPadding,
double? widthDialog,
}) {
return ConfirmationDialogBuilder(
key: const Key('confirm_dialog_delete_identity'),
imagePath: imagePaths,
useIconAsBasicLogo: true,
title: appLocalizations.delete_identity,
textContent: appLocalizations.message_confirmation_dialog_delete_identity,
confirmText: appLocalizations.delete,
cancelText: appLocalizations.cancel,
alignment: alignment,
outsideDialogPadding: outsideDialogPadding,
widthDialog: widthDialog,
onConfirmButtonAction: onDeleteIdentityAction,
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
);
}
}
@@ -1,31 +1,32 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/base/setting_detail_view_builder.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/identities_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/profiles/widgets/profiles_header_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/widgets/setting_header_widget.dart';
class ProfilesView extends StatelessWidget {
final _responsiveUtils = Get.find<ResponsiveUtils>();
final _imagePaths = Get.find<ImagePaths>();
final ResponsiveUtils responsiveUtils;
ProfilesView({Key? key}) : super(key: key);
const ProfilesView({
Key? key,
required this.responsiveUtils,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return SettingDetailViewBuilder(
responsiveUtils: _responsiveUtils,
responsiveUtils: responsiveUtils,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (_responsiveUtils.isWebDesktop(context))
if (responsiveUtils.isWebDesktop(context))
...[
ProfilesHeaderWidget(imagePaths: _imagePaths, responsiveUtils: _responsiveUtils),
Container(height: 1, color: AppColor.colorDividerHeaderSetting)
const SettingHeaderWidget(menuItem: AccountMenuItem.profiles),
const Divider(height: 1, color: AppColor.colorDividerHeaderSetting),
],
Expanded(child: SingleChildScrollView(
physics: const ClampingScrollPhysics(),
@@ -1,40 +0,0 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class ProfilesHeaderWidget extends StatelessWidget {
const ProfilesHeaderWidget({
Key? key,
required this.imagePaths,
required this.responsiveUtils,
}) : super(key: key);
final ImagePaths imagePaths;
final ResponsiveUtils responsiveUtils;
@override
Widget build(BuildContext context) {
return Container(
color: Colors.transparent,
padding: const EdgeInsets.only(top: 16, left: 16, right: 16, bottom: 15),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(
AppLocalizations.of(context).profiles,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black)),
const SizedBox(height: 4),
Text(
AppLocalizations.of(context).profilesSettingExplanation,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: AppColor.colorSettingExplanation)),
]),
);
}
}
@@ -19,10 +19,12 @@ import 'package:tmail_ui_user/features/composer/presentation/mixin/rich_text_but
import 'package:tmail_ui_user/features/composer/presentation/model/button_layout_type.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/base/setting_detail_view_builder.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/vacation/date_type.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/vacation/vacation_responder_status.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/utils/vacation_utils.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/vacation_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/widgets/setting_explanation_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/widgets/setting_header_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/utils/app_utils.dart';
@@ -36,31 +38,18 @@ class VacationView extends GetWidget<VacationController> with RichTextButtonMixi
physics: const ClampingScrollPhysics(),
controller: controller.scrollController,
child: Padding(
padding: VacationUtils.getPaddingView(context, controller.responsiveUtils),
padding: SettingsUtils.getSettingContentPadding(
context,
controller.responsiveUtils,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (controller.responsiveUtils.isWebDesktop(context))
...[
Text(
AppLocalizations.of(context).vacation,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
color: Colors.black
)
),
const SizedBox(height: 8)
],
Text(
AppLocalizations.of(context).vacationSettingExplanation,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
color: AppColor.colorVacationSettingExplanation
)
),
const SizedBox(height: 24),
if (!controller.responsiveUtils.isWebDesktop(context))
const SettingExplanationWidget(
menuItem: AccountMenuItem.vacation,
padding: EdgeInsets.only(bottom: 24)
),
Row(children: [
Obx(() {
return InkWell(
@@ -86,6 +75,7 @@ class VacationView extends GetWidget<VacationController> with RichTextButtonMixi
AppLocalizations.of(context).vacationSettingToggleButtonAutoReply,
style: const TextStyle(
fontSize: 16,
height: 20 / 16,
fontWeight: FontWeight.normal,
color: Colors.black
)
@@ -93,182 +83,177 @@ class VacationView extends GetWidget<VacationController> with RichTextButtonMixi
)
]),
const SizedBox(height: 28),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14),
child: Column(children: [
Obx(() => AbsorbPointer(
absorbing: controller.isVacationDeactivated,
child: Opacity(
opacity: controller.isVacationDeactivated ? 0.3 : 1.0,
child: controller.responsiveUtils.isPortraitMobile(context)
? Column(children: [
BorderButtonField<DateTime>(
label: AppLocalizations.of(context).startDate,
value: controller.vacationPresentation.value.startDate,
mouseCursor: SystemMouseCursors.text,
backgroundColor: AppColor.colorBackgroundVacationSettingField,
isEmpty: !controller.isVacationDeactivated && controller.vacationPresentation.value.startDateIsNull,
hintText: AppLocalizations.of(context).startDate,
tapActionCallback: (value) => controller.selectDate(context, DateType.start, value)
),
const SizedBox(height: 18),
BorderButtonField<TimeOfDay>(
label: AppLocalizations.of(context).startTime,
value: controller.vacationPresentation.value.startTime,
mouseCursor: SystemMouseCursors.text,
backgroundColor: AppColor.colorBackgroundVacationSettingField,
isEmpty: !controller.isVacationDeactivated && controller.vacationPresentation.value.starTimeIsNull,
hintText: AppLocalizations.of(context).noStartTime,
tapActionCallback: (value) => controller.selectTime(context, DateType.start, value)
),
])
: Row(children: [
Expanded(child: BorderButtonField<DateTime>(
label: AppLocalizations.of(context).startDate,
value: controller.vacationPresentation.value.startDate,
mouseCursor: SystemMouseCursors.text,
backgroundColor: AppColor.colorBackgroundVacationSettingField,
isEmpty: !controller.isVacationDeactivated && controller.vacationPresentation.value.startDateIsNull,
hintText: AppLocalizations.of(context).startDate,
tapActionCallback: (value) => controller.selectDate(context, DateType.start, value))
),
const SizedBox(width: 24),
Expanded(child: BorderButtonField<TimeOfDay>(
label: AppLocalizations.of(context).startTime,
value: controller.vacationPresentation.value.startTime,
mouseCursor: SystemMouseCursors.text,
backgroundColor: AppColor.colorBackgroundVacationSettingField,
isEmpty: !controller.isVacationDeactivated && controller.vacationPresentation.value.starTimeIsNull,
hintText: AppLocalizations.of(context).noStartTime,
tapActionCallback: (value) => controller.selectTime(context, DateType.start, value))
),
]),
),
)),
const SizedBox(height: 24),
Obx(() => AbsorbPointer(
absorbing: controller.isVacationDeactivated,
child: Opacity(
opacity: controller.isVacationDeactivated ? 0.3 : 1.0,
child: Row(children: [
Obx(() => InkWell(
onTap: () {
final value = !controller.vacationPresentation.value.vacationStopEnabled;
controller.updateVacationPresentation(vacationStopEnabled: value);
},
child: SvgPicture.asset(
controller.vacationPresentation.value.vacationStopEnabled
? controller.imagePaths.icSwitchOn
: controller.imagePaths.icSwitchOff,
fit: BoxFit.fill,
width: 24,
height: 24
)
)),
const SizedBox(width: 16),
Expanded(
child: Text(
AppLocalizations.of(context).vacationStopsAt,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
color: Colors.black
)
),
)
Obx(() => AbsorbPointer(
absorbing: controller.isVacationDeactivated,
child: Opacity(
opacity: controller.isVacationDeactivated ? 0.3 : 1.0,
child: controller.responsiveUtils.isPortraitMobile(context)
? Column(children: [
BorderButtonField<DateTime>(
label: AppLocalizations.of(context).startDate,
value: controller.vacationPresentation.value.startDate,
mouseCursor: SystemMouseCursors.text,
backgroundColor: AppColor.colorBackgroundVacationSettingField,
isEmpty: !controller.isVacationDeactivated && controller.vacationPresentation.value.startDateIsNull,
hintText: AppLocalizations.of(context).startDate,
tapActionCallback: (value) => controller.selectDate(context, DateType.start, value)
),
const SizedBox(height: 18),
BorderButtonField<TimeOfDay>(
label: AppLocalizations.of(context).startTime,
value: controller.vacationPresentation.value.startTime,
mouseCursor: SystemMouseCursors.text,
backgroundColor: AppColor.colorBackgroundVacationSettingField,
isEmpty: !controller.isVacationDeactivated && controller.vacationPresentation.value.starTimeIsNull,
hintText: AppLocalizations.of(context).noStartTime,
tapActionCallback: (value) => controller.selectTime(context, DateType.start, value)
),
])
: Row(children: [
Expanded(child: BorderButtonField<DateTime>(
label: AppLocalizations.of(context).startDate,
value: controller.vacationPresentation.value.startDate,
mouseCursor: SystemMouseCursors.text,
backgroundColor: AppColor.colorBackgroundVacationSettingField,
isEmpty: !controller.isVacationDeactivated && controller.vacationPresentation.value.startDateIsNull,
hintText: AppLocalizations.of(context).startDate,
tapActionCallback: (value) => controller.selectDate(context, DateType.start, value))
),
const SizedBox(width: 24),
Expanded(child: BorderButtonField<TimeOfDay>(
label: AppLocalizations.of(context).startTime,
value: controller.vacationPresentation.value.startTime,
mouseCursor: SystemMouseCursors.text,
backgroundColor: AppColor.colorBackgroundVacationSettingField,
isEmpty: !controller.isVacationDeactivated && controller.vacationPresentation.value.starTimeIsNull,
hintText: AppLocalizations.of(context).noStartTime,
tapActionCallback: (value) => controller.selectTime(context, DateType.start, value))
),
]),
)
)),
const SizedBox(height: 24),
Obx(() => AbsorbPointer(
absorbing: !controller.canChangeEndDate,
child: Opacity(
opacity: !controller.canChangeEndDate ? 0.3 : 1.0,
child: controller.responsiveUtils.isPortraitMobile(context)
? Column(children: [
BorderButtonField<DateTime>(
label: AppLocalizations.of(context).endDate,
value: controller.vacationPresentation.value.endDate,
mouseCursor: SystemMouseCursors.text,
backgroundColor: AppColor.colorBackgroundVacationSettingField,
isEmpty: controller.canChangeEndDate && controller.vacationPresentation.value.endDateIsNull,
hintText: AppLocalizations.of(context).noEndDate,
tapActionCallback: (value) => controller.selectDate(context, DateType.end, value)
),
const SizedBox(height: 18),
BorderButtonField<TimeOfDay>(
label: AppLocalizations.of(context).endTime,
value: controller.vacationPresentation.value.endTime,
mouseCursor: SystemMouseCursors.text,
backgroundColor: AppColor.colorBackgroundVacationSettingField,
isEmpty: controller.canChangeEndDate && controller.vacationPresentation.value.endTimeIsNull,
hintText: AppLocalizations.of(context).noEndTime,
tapActionCallback: (value) => controller.selectTime(context, DateType.end, value)
),
])
: Row(children: [
Expanded(child: BorderButtonField<DateTime>(
label: AppLocalizations.of(context).endDate,
value: controller.vacationPresentation.value.endDate,
mouseCursor: SystemMouseCursors.text,
backgroundColor: AppColor.colorBackgroundVacationSettingField,
isEmpty: controller.canChangeEndDate && controller.vacationPresentation.value.endDateIsNull,
hintText: AppLocalizations.of(context).noEndDate,
tapActionCallback: (value) => controller.selectDate(context, DateType.end, value))
),
const SizedBox(width: 24),
Expanded(child: BorderButtonField<TimeOfDay>(
label: AppLocalizations.of(context).endTime,
value: controller.vacationPresentation.value.endTime,
mouseCursor: SystemMouseCursors.text,
backgroundColor: AppColor.colorBackgroundVacationSettingField,
isEmpty: controller.canChangeEndDate && controller.vacationPresentation.value.endTimeIsNull,
hintText: AppLocalizations.of(context).noEndTime,
tapActionCallback: (value) => controller.selectTime(context, DateType.end, value))
),
]),
)
)),
const SizedBox(height: 24),
Obx(() => AbsorbPointer(
absorbing: controller.isVacationDeactivated,
child: controller.responsiveUtils.isPortraitMobile(context)
? Opacity(
opacity: controller.isVacationDeactivated ? 0.3 : 1.0,
child: TextInputFieldBuilder(
label: AppLocalizations.of(context).subject,
hint: AppLocalizations.of(context).hintSubjectInputVacationSetting,
editingController: controller.subjectTextController,
focusNode: controller.subjectTextFocusNode,
),
),
)),
const SizedBox(height: 24),
Obx(() => AbsorbPointer(
absorbing: controller.isVacationDeactivated,
child: Opacity(
opacity: controller.isVacationDeactivated ? 0.3 : 1.0,
child: Row(children: [
Obx(() => InkWell(
onTap: () {
final value = !controller.vacationPresentation.value.vacationStopEnabled;
controller.updateVacationPresentation(vacationStopEnabled: value);
},
child: SvgPicture.asset(
controller.vacationPresentation.value.vacationStopEnabled
? controller.imagePaths.icSwitchOn
: controller.imagePaths.icSwitchOff,
fit: BoxFit.fill,
width: 24,
height: 24
)
)),
const SizedBox(width: 16),
Expanded(
child: Text(
AppLocalizations.of(context).vacationStopsAt,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
color: Colors.black
)
: Row(children: [
Expanded(child: Opacity(
opacity: controller.isVacationDeactivated ? 0.3 : 1.0,
child: TextInputFieldBuilder(
label: AppLocalizations.of(context).subject,
hint: AppLocalizations.of(context).hintSubjectInputVacationSetting,
editingController: controller.subjectTextController,
focusNode: controller.subjectTextFocusNode,
),
)),
const SizedBox(width: 24),
const Expanded(child: SizedBox.shrink())
])
)),
const SizedBox(height: 24),
Obx(() => AbsorbPointer(
absorbing: controller.isVacationDeactivated,
child: Opacity(
),
)
]),
)
)),
const SizedBox(height: 24),
Obx(() => AbsorbPointer(
absorbing: !controller.canChangeEndDate,
child: Opacity(
opacity: !controller.canChangeEndDate ? 0.3 : 1.0,
child: controller.responsiveUtils.isPortraitMobile(context)
? Column(children: [
BorderButtonField<DateTime>(
label: AppLocalizations.of(context).endDate,
value: controller.vacationPresentation.value.endDate,
mouseCursor: SystemMouseCursors.text,
backgroundColor: AppColor.colorBackgroundVacationSettingField,
isEmpty: controller.canChangeEndDate && controller.vacationPresentation.value.endDateIsNull,
hintText: AppLocalizations.of(context).noEndDate,
tapActionCallback: (value) => controller.selectDate(context, DateType.end, value)
),
const SizedBox(height: 18),
BorderButtonField<TimeOfDay>(
label: AppLocalizations.of(context).endTime,
value: controller.vacationPresentation.value.endTime,
mouseCursor: SystemMouseCursors.text,
backgroundColor: AppColor.colorBackgroundVacationSettingField,
isEmpty: controller.canChangeEndDate && controller.vacationPresentation.value.endTimeIsNull,
hintText: AppLocalizations.of(context).noEndTime,
tapActionCallback: (value) => controller.selectTime(context, DateType.end, value)
),
])
: Row(children: [
Expanded(child: BorderButtonField<DateTime>(
label: AppLocalizations.of(context).endDate,
value: controller.vacationPresentation.value.endDate,
mouseCursor: SystemMouseCursors.text,
backgroundColor: AppColor.colorBackgroundVacationSettingField,
isEmpty: controller.canChangeEndDate && controller.vacationPresentation.value.endDateIsNull,
hintText: AppLocalizations.of(context).noEndDate,
tapActionCallback: (value) => controller.selectDate(context, DateType.end, value))
),
const SizedBox(width: 24),
Expanded(child: BorderButtonField<TimeOfDay>(
label: AppLocalizations.of(context).endTime,
value: controller.vacationPresentation.value.endTime,
mouseCursor: SystemMouseCursors.text,
backgroundColor: AppColor.colorBackgroundVacationSettingField,
isEmpty: controller.canChangeEndDate && controller.vacationPresentation.value.endTimeIsNull,
hintText: AppLocalizations.of(context).noEndTime,
tapActionCallback: (value) => controller.selectTime(context, DateType.end, value))
),
]),
)
)),
const SizedBox(height: 24),
Obx(() => AbsorbPointer(
absorbing: controller.isVacationDeactivated,
child: controller.responsiveUtils.isPortraitMobile(context)
? Opacity(
opacity: controller.isVacationDeactivated ? 0.3 : 1.0,
child: _buildVacationMessage(context),
),
)),
const SizedBox(height: 24),
_buildListButtonAction(context),
const SizedBox(height: 24),
]),
)
child: TextInputFieldBuilder(
label: AppLocalizations.of(context).subject,
hint: AppLocalizations.of(context).hintSubjectInputVacationSetting,
editingController: controller.subjectTextController,
focusNode: controller.subjectTextFocusNode,
),
)
: Row(children: [
Expanded(child: Opacity(
opacity: controller.isVacationDeactivated ? 0.3 : 1.0,
child: TextInputFieldBuilder(
label: AppLocalizations.of(context).subject,
hint: AppLocalizations.of(context).hintSubjectInputVacationSetting,
editingController: controller.subjectTextController,
focusNode: controller.subjectTextFocusNode,
),
)),
const SizedBox(width: 24),
const Expanded(child: SizedBox.shrink())
])
)),
const SizedBox(height: 24),
Obx(() => AbsorbPointer(
absorbing: controller.isVacationDeactivated,
child: Opacity(
opacity: controller.isVacationDeactivated ? 0.3 : 1.0,
child: _buildVacationMessage(context),
),
)),
const SizedBox(height: 24),
_buildListButtonAction(context),
const SizedBox(height: 24)
]
),
),
@@ -277,9 +262,18 @@ class VacationView extends GetWidget<VacationController> with RichTextButtonMixi
if (PlatformInfo.isWeb) {
return SettingDetailViewBuilder(
responsiveUtils: controller.responsiveUtils,
padding: const EdgeInsets.symmetric(horizontal: 4),
onTapGestureDetector: () => controller.clearFocusEditor(context),
child: vacationInputForm,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (controller.responsiveUtils.isWebDesktop(context))
...[
const SettingHeaderWidget(menuItem: AccountMenuItem.vacation),
const Divider(height: 1, color: AppColor.colorDividerHeaderSetting),
],
Expanded(child: vacationInputForm),
],
),
);
} else {
return ResponsiveWidget(
@@ -0,0 +1,27 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class SettingExplanationWidget extends StatelessWidget {
final AccountMenuItem menuItem;
final EdgeInsetsGeometry? padding;
const SettingExplanationWidget({
Key? key,
required this.menuItem,
this.padding,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: padding ?? const EdgeInsets.all(16),
child: Text(
menuItem.getExplanation(AppLocalizations.of(context)),
style: ThemeUtils.textStyleBodyBody1(color: AppColor.steelGray400),
),
);
}
}
@@ -0,0 +1,38 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class SettingHeaderWidget extends StatelessWidget {
final AccountMenuItem menuItem;
final EdgeInsetsGeometry? padding;
const SettingHeaderWidget({
Key? key,
required this.menuItem,
this.padding,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final appLocalizations = AppLocalizations.of(context);
return Padding(
padding: padding ?? const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
menuItem.getName(appLocalizations),
style: ThemeUtils.textStyleHeadingH6(color: Colors.black),
),
const SizedBox(height: 8),
Text(
menuItem.getExplanation(appLocalizations),
style: ThemeUtils.textStyleBodyBody1(color: AppColor.steelGray400),
),
],
),
);
}
}
@@ -48,15 +48,17 @@ class QuotasView extends GetWidget<QuotasController> {
fit: BoxFit.fill,
),
const SizedBox(width: QuotasViewStyles.iconPadding),
Text(
AppLocalizations.of(context).storageQuotas,
style: const TextStyle(
fontSize: QuotasViewStyles.labelTextSize,
fontWeight: QuotasViewStyles.labelFontWeight,
color: QuotasViewStyles.labelTextColor
Expanded(
child: Text(
AppLocalizations.of(context).storageQuotas,
style: const TextStyle(
fontSize: QuotasViewStyles.labelTextSize,
fontWeight: QuotasViewStyles.labelFontWeight,
color: QuotasViewStyles.labelTextColor
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
)
],
),
@@ -260,7 +260,7 @@ class RulesFilterCreatorController extends BaseMailboxController {
}
void _setUpRuleFilterActions() {
if (_currentTMailRule!.action.appendIn.mailboxIds.isNotEmpty != true) return;
if (_currentTMailRule?.action.appendIn.mailboxIds.isNotEmpty != true) return;
final mailboxNode = findMailboxNodeById(
_currentTMailRule!.action.appendIn.mailboxIds.first);
@@ -1,5 +1,4 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/state/success.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/platform_info.dart';
@@ -199,27 +198,6 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
title: AppLocalizations.of(currentContext!).deleteOfflineEmail,
icon: SvgPicture.asset(imagePaths.icDeleteDialogRecipients),
alignCenter: true,
messageStyle: const TextStyle(
color: AppColor.colorTitleSendingItem,
fontSize: 15,
fontWeight: FontWeight.normal
),
titleStyle: const TextStyle(
color: AppColor.colorDeletePermanentlyButton,
fontSize: 20,
fontWeight: FontWeight.bold
),
actionButtonColor: AppColor.colorDeletePermanentlyButton,
actionStyle: const TextStyle(
color: Colors.white,
fontSize: 17,
fontWeight: FontWeight.w500
),
cancelStyle: const TextStyle(
color: AppColor.colorDeletePermanentlyButton,
fontSize: 17,
fontWeight: FontWeight.w500
),
onConfirmAction: () => _handleDeleteListSendingEmail(listSendingEmails),
);
}
@@ -207,9 +207,19 @@ mixin BaseEmailItemTile {
imagePaths.icAttachment,
width: 16,
height: 16,
colorFilter: ItemEmailTileStyles.actionIconColor.asFilter(),
fit: BoxFit.fill);
}
Widget buildIconUnreadStatus() {
return SvgPicture.asset(
imagePaths.icUnreadStatus,
width: 9,
height: 9,
fit: BoxFit.fill,
);
}
Widget buildIconStar() {
return SvgPicture.asset(
imagePaths.icStar,
@@ -321,7 +331,7 @@ mixin BaseEmailItemTile {
iconPath,
width: width ?? 20,
height: height ?? 20,
colorFilter: AppColor.colorAttachmentIcon.asFilter(),
colorFilter: ItemEmailTileStyles.actionIconColor.asFilter(),
fit: BoxFit.fill);
}
@@ -349,7 +359,7 @@ mixin BaseEmailItemTile {
height: 20,
fit: BoxFit.fill,
colorFilter: presentationEmail.hasRead
? AppColor.steelGray400.asFilter()
? ItemEmailTileStyles.actionIconColor.asFilter()
: Colors.black.asFilter(),
),
);
@@ -367,7 +377,7 @@ mixin BaseEmailItemTile {
width: 20,
height: 20,
fit: BoxFit.fill,
colorFilter: AppColor.steelGray200.asFilter(),
colorFilter: ItemEmailTileStyles.actionIconColor.asFilter(),
),
);
}
@@ -237,18 +237,18 @@ mixin EmailActionController {
.show();
} else {
Get.dialog(
PointerInterceptor(child: (ConfirmDialogBuilder(imagePaths, useIconAsBasicLogo: true)
..key(const Key('confirm_dialog_delete_email_permanently'))
..title(DeleteActionType.single.getTitleDialog(context))
..content(DeleteActionType.single.getContentDialog(context))
..onCloseButtonAction(() => popBack())
..onConfirmButtonAction(
DeleteActionType.single.getConfirmActionName(context),
() => _deleteEmailPermanentlyAction(context, email))
..onCancelButtonAction(
AppLocalizations.of(context).cancel,
() => popBack()))
.build()),
PointerInterceptor(child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_delete_email_permanently'),
imagePath: imagePaths,
useIconAsBasicLogo: true,
title: DeleteActionType.single.getTitleDialog(context),
textContent: DeleteActionType.single.getContentDialog(context),
confirmText: DeleteActionType.single.getConfirmActionName(context),
cancelText: AppLocalizations.of(context).cancel,
onConfirmButtonAction: () => _deleteEmailPermanentlyAction(context, email),
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
)),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
);
}
@@ -1,12 +1,16 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:flutter/cupertino.dart';
class ItemEmailTileStyles {
ItemEmailTileStyles._();
static const double avatarIconSize = 60.0;
static const double horizontalTitleGap = 8.0;
static const Color actionIconColor = AppColor.steelGray200;
static EdgeInsetsGeometry getSpaceCalendarEventIcon(BuildContext context, ResponsiveUtils responsiveUtils) {
if (responsiveUtils.isScreenWithShortestSide(context)) {
return const EdgeInsetsDirectional.only(end: 4);
@@ -12,6 +12,7 @@ import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:model/mailbox/select_mode.dart';
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
import 'package:tmail_ui_user/features/thread/presentation/mixin/base_email_item_tile.dart';
import 'package:tmail_ui_user/features/thread/presentation/styles/item_email_tile_styles.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class EmailTileBuilder extends StatefulWidget {
@@ -94,12 +95,7 @@ class _EmailTileBuilderState extends State<EmailTileBuilder> with BaseEmailItem
if (!widget.presentationEmail.hasRead)
Padding(
padding: const EdgeInsetsDirectional.only(end: 5),
child: SvgPicture.asset(
imagePaths.icUnreadStatus,
width: 9,
height: 9,
fit: BoxFit.fill
)
child: buildIconUnreadStatus(),
),
Expanded(
child: buildInformationSender(
@@ -118,12 +114,7 @@ class _EmailTileBuilderState extends State<EmailTileBuilder> with BaseEmailItem
if (widget.presentationEmail.hasAttachment == true)
Padding(
padding: const EdgeInsetsDirectional.only(start: 8),
child: SvgPicture.asset(
imagePaths.icAttachment,
width: 16,
height: 16,
fit: BoxFit.fill
)
child: buildIconAttachment(),
),
Padding(
padding: const EdgeInsetsDirectional.only(
@@ -227,12 +218,7 @@ class _EmailTileBuilderState extends State<EmailTileBuilder> with BaseEmailItem
if (!widget.presentationEmail.hasRead)
Padding(
padding: const EdgeInsetsDirectional.only(end: 5),
child: SvgPicture.asset(
imagePaths.icUnreadStatus,
width: 9,
height: 9,
fit: BoxFit.fill
)
child: buildIconUnreadStatus(),
),
Expanded(
child: buildInformationSender(
@@ -414,12 +400,7 @@ class _EmailTileBuilderState extends State<EmailTileBuilder> with BaseEmailItem
alignment: Alignment.center,
width: 20,
height: 20,
child: SvgPicture.asset(
imagePaths.icUnreadStatus,
width: 9,
height: 9,
fit: BoxFit.fill
),
child: buildIconUnreadStatus(),
),
margin: const EdgeInsets.symmetric(vertical: 6),
iconPadding: EdgeInsets.zero,
@@ -512,7 +493,7 @@ class _EmailTileBuilderState extends State<EmailTileBuilder> with BaseEmailItem
return Row(children: [
buildSVGIconButton(
icon: imagePaths.icOpenInNewTab,
iconColor: AppColor.colorActionButtonHover,
iconColor: ItemEmailTileStyles.actionIconColor,
iconSize: _getIconSize(context),
padding: _getPaddingIcon(context),
tooltip: AppLocalizations.of(context).openInNewTab,
@@ -524,7 +505,7 @@ class _EmailTileBuilderState extends State<EmailTileBuilder> with BaseEmailItem
if(!widget.presentationEmail.isDraft)
buildSVGIconButton(
icon: widget.presentationEmail.hasRead ? imagePaths.icUnread: imagePaths.icRead,
iconColor: AppColor.colorActionButtonHover,
iconColor: ItemEmailTileStyles.actionIconColor,
iconSize: _getIconSize(context),
padding: _getPaddingIcon(context),
tooltip: widget.presentationEmail.hasRead
@@ -539,7 +520,7 @@ class _EmailTileBuilderState extends State<EmailTileBuilder> with BaseEmailItem
... [
buildSVGIconButton(
icon: imagePaths.icMove,
iconColor: AppColor.colorActionButtonHover,
iconColor: ItemEmailTileStyles.actionIconColor,
iconSize: _getIconSize(context),
padding: _getPaddingIcon(context),
tooltip: AppLocalizations.of(context).move,
@@ -551,7 +532,7 @@ class _EmailTileBuilderState extends State<EmailTileBuilder> with BaseEmailItem
],
buildSVGIconButton(
icon: imagePaths.icDeleteComposer,
iconColor: AppColor.colorActionButtonHover,
iconColor: ItemEmailTileStyles.actionIconColor,
iconSize: responsiveUtils.isDesktop(context) ? 16 : 14,
padding: _getPaddingIcon(context),
tooltip: canDeletePermanently
@@ -564,7 +545,7 @@ class _EmailTileBuilderState extends State<EmailTileBuilder> with BaseEmailItem
),
buildSVGIconButton(
icon: imagePaths.icMore,
iconColor: AppColor.colorActionButtonHover,
iconColor: ItemEmailTileStyles.actionIconColor,
iconSize: _getIconSize(context),
padding: _getPaddingIcon(context),
tooltip: AppLocalizations.of(context).more,
@@ -627,18 +608,18 @@ class _EmailTileBuilderState extends State<EmailTileBuilder> with BaseEmailItem
constraints: BoxConstraints(maxWidth: constraints.maxWidth / 2),
padding: const EdgeInsetsDirectional.only(end: 12),
child: buildEmailTitle(
context,
context,
widget.presentationEmail,
widget.isSearchEmailRunning,
widget.searchQuery
)),
Expanded(child: Container(
Expanded(
child: buildEmailPartialContent(
context,
widget.presentationEmail,
widget.isSearchEmailRunning,
widget.searchQuery
))
),
),
]);
});
@@ -396,18 +396,7 @@ class UploadController extends BaseController {
height: 40,
colorFilter: AppColor.colorBackgroundQuotasWarning.asFilter(),
),
messageStyle: Theme.of(context).textTheme.labelMedium?.copyWith(
fontSize: 14,
color: Colors.black
),
actionStyle: Theme.of(context).textTheme.labelMedium?.copyWith(
fontSize: 17,
color: Colors.white
),
cancelStyle: Theme.of(context).textTheme.labelMedium?.copyWith(
fontSize: 17,
color: Colors.black
));
);
}
bool get allUploadAttachmentsCompleted {
@@ -1,8 +0,0 @@
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
extension UsernameExtension on UserName {
String get firstCharacter => value.isNotEmpty ? value[0].toUpperCase() : '';
EmailAddress toEmailAddress() => EmailAddress(null, value);
}
-1
View File
@@ -58,7 +58,6 @@ export 'extensions/presentation_email_extension.dart';
export 'extensions/presentation_mailbox_extension.dart';
export 'extensions/properties_extension.dart';
export 'extensions/session_extension.dart';
export 'extensions/username_extension.dart';
export 'extensions/utc_date_extension.dart';
export 'extensions/contact_support_capability_extension.dart';
export 'extensions/list_id_extension.dart';
+6 -6
View File
@@ -292,10 +292,10 @@ packages:
dependency: transitive
description:
name: ffi
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.1.3"
file:
dependency: transitive
description:
@@ -1250,18 +1250,18 @@ packages:
dependency: transitive
description:
name: win32
sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c"
sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4
url: "https://pub.dev"
source: hosted
version: "4.1.4"
version: "5.5.1"
win32_registry:
dependency: transitive
description:
name: win32_registry
sha256: "1c52f994bdccb77103a6231ad4ea331a244dbcef5d1f37d8462f713143b0bfae"
sha256: "723b7f851e5724c55409bb3d5a32b203b3afe8587eaf5dafb93a5fed8ecda0d6"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
version: "1.1.4"
xdg_directories:
dependency: transitive
description:
+1 -1
View File
@@ -2280,7 +2280,7 @@ packages:
source: hosted
version: "2.4.4"
win32:
dependency: "direct main"
dependency: transitive
description:
name: win32
sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4
-2
View File
@@ -260,8 +260,6 @@ dependencies:
flutter_smart_dialog: 4.9.8+5
win32: 5.5.1
uri: 1.0.0
flutter_file_dialog: 3.0.2
+1 -1
View File
@@ -33,7 +33,7 @@
<link rel="manifest" href="manifest.json">
<link rel="stylesheet" type="text/css" href="splash/style.css">
<link rel="stylesheet" type="text/css" href="worker_service/style.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap">
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
<script type="application/javascript" src="assets/packages/flutter_inappwebview_web/assets/web/web_support.js" defer></script>