Apply new style Language section in Setting on mobile

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2025-07-04 12:45:42 +07:00
committed by Dat H. Pham
parent 8289593247
commit 672188baa2
22 changed files with 397 additions and 207 deletions
+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="M20 11H7.83L13.42 5.41L12 4L4 12L12 20L13.41 18.59L7.83 13H20V11Z" fill="#1C1B1F"/>
</svg>

After

Width:  |  Height:  |  Size: 196 B

@@ -231,7 +231,10 @@ class ImagePaths {
String get icDoubleArrowDown => _getImagePath('ic_double_arrow_down.svg');
String get icRefreshQuotas => _getImagePath('ic_refresh_quotas.svg');
String get icCreateFilter => _getImagePath('ic_create_filter.svg');
String get icArrowBack => _getImagePath('ic_arrow_back.svg');
String get icTwakeWorkplace => _getIconPath('icon_twp.png');
String get animLottieTmail => _getAnimationPath('lottie-tmail.json');
String _getImagePath(String imageName) {
@@ -280,6 +280,15 @@ class ThemeUtils {
color: AppColor.textSecondary.withOpacity(0.48),
);
static const TextStyle textStyleM3BodyLarge = TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.w500,
letterSpacing: 00.15,
fontSize: 17,
height: 24 / 17,
color: AppColor.m3SurfaceBackground,
);
static TextStyle textStyleAppShortcut() => const TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.normal,
+1
View File
@@ -23,6 +23,7 @@ class LogTracking {
final Queue<String> _messagesQueue = Queue();
bool _isScheduled = false;
bool isEnabled = false;
Future<void> addLog({required String message}) async {
try {
@@ -35,7 +35,10 @@ class EmailRulesHeaderWidget extends StatelessWidget {
if (responsiveUtils.isWebDesktop(context))
const SettingHeaderWidget(menuItem: AccountMenuItem.emailRules)
else
const SettingExplanationWidget(menuItem: AccountMenuItem.emailRules),
const SettingExplanationWidget(
menuItem: AccountMenuItem.emailRules,
padding: EdgeInsets.all(16),
),
Padding(
padding: const EdgeInsets.all(16),
child: _buildButtonAddNewRule(context),
@@ -4,22 +4,22 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
extension LocaleExtension on Locale {
String getLanguageNameByCurrentLocale(BuildContext context) {
String getLanguageNameByCurrentLocale(AppLocalizations appLocalizations) {
switch(languageCode) {
case 'fr':
return AppLocalizations.of(context).languageFrench;
return appLocalizations.languageFrench;
case 'en':
return AppLocalizations.of(context).languageEnglish;
return appLocalizations.languageEnglish;
case 'vi':
return AppLocalizations.of(context).languageVietnamese;
return appLocalizations.languageVietnamese;
case 'ru':
return AppLocalizations.of(context).languageRussian;
return appLocalizations.languageRussian;
case 'ar':
return AppLocalizations.of(context).languageArabic;
return appLocalizations.languageArabic;
case 'it':
return AppLocalizations.of(context).languageItalian;
return appLocalizations.languageItalian;
case 'de':
return AppLocalizations.of(context).languageGerman;
return appLocalizations.languageGerman;
default:
return '';
}
@@ -1,8 +1,6 @@
import 'dart:ui';
import 'package:core/presentation/state/success.dart';
import 'package:core/utils/app_logger.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:server_settings/server_settings/capability_server_settings.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
@@ -11,8 +9,11 @@ import 'package:tmail_ui_user/features/manage_account/domain/state/save_language
import 'package:tmail_ui_user/features/manage_account/domain/usecases/save_language_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/save_language_to_server_settings_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/language/context_item_language_action.dart';
import 'package:tmail_ui_user/main/error/capability_validator.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/localizations/localization_service.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
class LanguageAndRegionController extends BaseController {
@@ -75,4 +76,24 @@ class LanguageAndRegionController extends BaseController {
localeCurrent,
));
}
void openLanguageContextMenu(BuildContext context) {
final contextMenuActions = listSupportedLanguages.map((language) {
return ContextItemLanguageAction(
language,
languageSelected.value,
AppLocalizations.of(context),
imagePaths,
);
}).toList();
openBottomSheetContextMenuAction(
context: context,
itemActions: contextMenuActions,
onContextMenuActionClick: (menuAction) {
popBack();
selectLanguage(menuAction.action);
},
);
}
}
@@ -45,11 +45,20 @@ class LanguageAndRegionView extends GetWidget<LanguageAndRegionController> {
else
const SettingExplanationWidget(
menuItem: AccountMenuItem.languageAndRegion,
padding: EdgeInsetsDirectional.only(
start: 16,
end: 16,
bottom: 16,
),
isCenter: true,
),
const Expanded(
Expanded(
child: Padding(
padding: EdgeInsets.only(top: 39),
child: ChangeLanguageButtonWidget(),
padding: const EdgeInsets.only(top: 39),
child: ChangeLanguageButtonWidget(
onOpenLanguageContextMenu:
controller.openLanguageContextMenu,
),
),
),
],
@@ -12,9 +12,16 @@ import 'package:tmail_ui_user/features/manage_account/presentation/language_and_
import 'package:tmail_ui_user/features/manage_account/presentation/language_and_region/widgets/language_menu_overlay.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
typedef OnOpenLanguageContextMenuAction = Function(BuildContext context);
class ChangeLanguageButtonWidget extends StatefulWidget {
const ChangeLanguageButtonWidget({Key? key}) : super(key: key);
final OnOpenLanguageContextMenuAction? onOpenLanguageContextMenu;
const ChangeLanguageButtonWidget({
Key? key,
this.onOpenLanguageContextMenu,
}) : super(key: key);
@override
State<ChangeLanguageButtonWidget> createState() => _ChangeLanguageButtonWidgetState();
@@ -44,15 +51,19 @@ class _ChangeLanguageButtonWidgetState extends State<ChangeLanguageButtonWidget>
],
);
} else {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildTitleLanguageWidget(context),
const SizedBox(height: 8),
_buildLanguageMenu(context, double.infinity),
],
),
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: _getMobileTitlePadding(context),
child: _buildTitleLanguageWidget(context),
),
const SizedBox(height: 12),
Padding(
padding: _getMobileLanguageMenuPadding(context),
child: _buildMobileLanguageMenu(context),
),
],
);
}
}
@@ -90,7 +101,7 @@ class _ChangeLanguageButtonWidgetState extends State<ChangeLanguageButtonWidget>
widthFactor: 1,
),
),
portalFollower: Obx(() => LanguageRegionOverlay(
portalFollower: LanguageRegionOverlay(
imagePaths: _imagePaths,
responsiveUtils: _responsiveUtils,
listSupportedLanguages: _languageAndRegionController.listSupportedLanguages,
@@ -100,13 +111,13 @@ class _ChangeLanguageButtonWidgetState extends State<ChangeLanguageButtonWidget>
_toggleLanguageMenuOverlay(false);
_languageAndRegionController.selectLanguage(language);
},
)),
),
visible: isVisible,
child: TMailDropDownWidget(
text: _languageAndRegionController
.languageSelected
.value
.getLanguageNameByCurrentLocale(context),
.getLanguageNameByCurrentLocale(AppLocalizations.of(context)),
dropDownIcon: _imagePaths.icDropDown,
backgroundColor: isVisible
? AppColor.lightGrayEBEDF0.withOpacity(0.6)
@@ -119,13 +130,38 @@ class _ChangeLanguageButtonWidgetState extends State<ChangeLanguageButtonWidget>
);
}
Widget _buildMobileLanguageMenu(BuildContext context) {
return Obx(() => TMailDropDownWidget(
text: _languageAndRegionController
.languageSelected
.value
.getLanguageNameByCurrentLocale(AppLocalizations.of(context)),
dropDownIcon: _imagePaths.icDropDown,
onTap: () => widget.onOpenLanguageContextMenu?.call(context),
));
}
void _toggleLanguageMenuOverlay(bool visible) {
_languageMenuIsVisibleNotifier.value = visible;
}
@override
void dispose() {
_languageMenuIsVisibleNotifier.dispose();
super.dispose();
EdgeInsetsGeometry _getMobileTitlePadding(BuildContext context) {
if (_responsiveUtils.isPortraitMobile(context)) {
return const EdgeInsetsDirectional.symmetric(horizontal: 28);
} else if (_responsiveUtils.isLandscapeMobile(context)) {
return const EdgeInsetsDirectional.symmetric(horizontal: 40);
} else {
return const EdgeInsetsDirectional.symmetric(horizontal: 50);
}
}
EdgeInsetsGeometry _getMobileLanguageMenuPadding(BuildContext context) {
if (_responsiveUtils.isPortraitMobile(context)) {
return const EdgeInsetsDirectional.symmetric(horizontal: 20);
} else if (_responsiveUtils.isLandscapeMobile(context)) {
return const EdgeInsetsDirectional.symmetric(horizontal: 24);
} else {
return const EdgeInsetsDirectional.symmetric(horizontal: 44);
}
}
}
@@ -4,6 +4,7 @@ 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/language_and_region/extensions/locale_extension.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
typedef OnSelectLanguageAction = Function(Locale? localeSelected);
@@ -35,7 +36,7 @@ class LanguageItemWidget extends StatelessWidget {
height: 51,
child: Row(children: [
Expanded(child: Text(
'${localeCurrent.getLanguageNameByCurrentLocale(context)} - ${localeCurrent.getSourceLanguageName()}',
'${localeCurrent.getLanguageNameByCurrentLocale(AppLocalizations.of(context))} - ${localeCurrent.getSourceLanguageName()}',
style: ThemeUtils.textStyleInter400.copyWith(
letterSpacing: -0.15,
fontSize: 16,
@@ -62,7 +62,7 @@ class ManageAccountDashBoardController extends ReloadableController {
void onInit() {
BackButtonInterceptor.add(_onBackButtonInterceptor, name: AppRoutes.settings);
super.onInit();
if (AppConfig.isApiLoggingEnabled) {
if (LogTracking().isEnabled) {
injectTraceLogDependencies();
}
}
@@ -405,7 +405,7 @@ class ManageAccountDashBoardController extends ReloadableController {
@override
void onClose() {
BackButtonInterceptor.removeByName(AppRoutes.settings);
if (AppConfig.isApiLoggingEnabled) {
if (LogTracking().isEnabled) {
disposeTraceLogDependencies();
}
super.onClose();
@@ -102,11 +102,7 @@ class ManageAccountDashBoardView extends GetWidget<ManageAccountDashBoardControl
],
))
]),
mobile: SafeArea(
child: SettingsView(
closeAction: () =>
controller.backToMailboxDashBoard(context: context)),
)
mobile: const SafeArea(child: SettingsView())
),
),
),
@@ -0,0 +1,45 @@
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/features/manage_account/presentation/menu/settings/setting_first_level_app_bar.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/universal_setting_app_bar.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/settings_page_level.dart';
class SettingAppBar extends StatelessWidget {
final SettingsPageLevel pageLevel;
final AccountMenuItem accountMenuItem;
final ImagePaths imagePaths;
final ResponsiveUtils responsiveUtils;
final VoidCallback onBackAction;
final VoidCallback? onExportTraceLogAction;
const SettingAppBar({
super.key,
required this.pageLevel,
required this.accountMenuItem,
required this.imagePaths,
required this.responsiveUtils,
required this.onBackAction,
this.onExportTraceLogAction,
});
@override
Widget build(BuildContext context) {
if (pageLevel == SettingsPageLevel.universal) {
return UniversalSettingAppBar(
imagePaths: imagePaths,
responsiveUtils: responsiveUtils,
onBackAction: onBackAction,
onExportTraceLogAction: onExportTraceLogAction,
);
} else {
return SettingFirstLevelAppBar(
accountMenuItem: accountMenuItem,
imagePaths: imagePaths,
responsiveUtils: responsiveUtils,
onBackAction: onBackAction,
);
}
}
}
@@ -0,0 +1,67 @@
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/features/manage_account/presentation/model/account_menu_item.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class SettingFirstLevelAppBar extends StatelessWidget {
final AccountMenuItem accountMenuItem;
final ImagePaths imagePaths;
final ResponsiveUtils responsiveUtils;
final VoidCallback onBackAction;
const SettingFirstLevelAppBar({
super.key,
required this.accountMenuItem,
required this.imagePaths,
required this.responsiveUtils,
required this.onBackAction,
});
@override
Widget build(BuildContext context) {
final appLocalizations = AppLocalizations.of(context);
return Container(
height: 64,
padding: _getPadding(context),
child: Stack(
alignment: Alignment.center,
children: [
PositionedDirectional(
start: 0,
child: TMailButtonWidget.fromIcon(
icon: imagePaths.icArrowBack,
tooltipMessage: appLocalizations.back,
backgroundColor: Colors.transparent,
onTapActionCallback: onBackAction,
),
),
Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 50),
child: Text(
accountMenuItem.getName(appLocalizations),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: ThemeUtils.textStyleM3BodyLarge,
),
),
),
],
),
);
}
EdgeInsetsGeometry _getPadding(BuildContext context) {
if (responsiveUtils.isPortraitMobile(context)) {
return const EdgeInsetsDirectional.symmetric(horizontal: 16);
} else if (responsiveUtils.isLandscapeMobile(context)) {
return const EdgeInsetsDirectional.symmetric(horizontal: 24);
} else {
return const EdgeInsetsDirectional.symmetric(horizontal: 32);
}
}
}
@@ -1,9 +1,12 @@
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/base/mixin/contact_support_mixin.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/export_trace_log_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.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/settings_page_level.dart';
class SettingsController extends GetxController with ContactSupportMixin {
final manageAccountDashboardController = Get.find<ManageAccountDashBoardController>();
@@ -13,4 +16,17 @@ class SettingsController extends GetxController with ContactSupportMixin {
void selectSettings(AccountMenuItem accountMenuItem) => manageAccountDashboardController.selectSettings(accountMenuItem);
void backToUniversalSettings() => manageAccountDashboardController.backToUniversalSettings();
void onBackSettingAction(BuildContext context) {
if (manageAccountDashboardController.settingsPageLevel.value ==
SettingsPageLevel.universal) {
manageAccountDashboardController.backToMailboxDashBoard(context: context);
} else {
backToUniversalSettings();
}
}
void showExportTraceLogConfirmDialog(BuildContext context) {
manageAccountDashboardController.showExportTraceLogConfirmDialog(context);
}
}
@@ -1,21 +1,13 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/utils/style_utils.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:core/presentation/views/button/multi_click_widget.dart';
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/manage_account/presentation/email_rules/email_rules_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/export_trace_log_extension.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/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/setting_app_bar.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/settings_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/settings_first_level_view.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/settings_page_level.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/notification/notification_view.dart';
@@ -23,27 +15,30 @@ import 'package:tmail_ui_user/features/manage_account/presentation/preferences/p
import 'package:tmail_ui_user/features/manage_account/presentation/profiles/profiles_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/vacation_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/utils/app_config.dart';
typedef CloseSettingsViewAction = void Function();
class SettingsView extends GetWidget<SettingsController> {
const SettingsView({Key? key, this.closeAction}) : super(key: key);
final CloseSettingsViewAction? closeAction;
const SettingsView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox.fromSize(
size: const Size.fromHeight(52),
child: Padding(
padding: SettingsUtils.getPaddingAppBar(context, controller.responsiveUtils),
child: _buildAppbar(context))),
const Divider(color: AppColor.colorDividerComposer, height: 1),
Obx(() => SettingAppBar(
pageLevel: controller
.manageAccountDashboardController
.settingsPageLevel
.value,
accountMenuItem: controller
.manageAccountDashboardController
.accountMenuItemSelected
.value,
imagePaths: controller.imagePaths,
responsiveUtils: controller.responsiveUtils,
onBackAction: () => controller.onBackSettingAction(context),
onExportTraceLogAction: () =>
controller.showExportTraceLogConfirmDialog(context),
)),
Obx(() {
if (controller.manageAccountDashboardController.vacationResponse.value?.vacationResponderIsValid == true) {
return VacationNotificationMessageWidget(
@@ -77,110 +72,6 @@ class SettingsView extends GetWidget<SettingsController> {
);
}
Widget _buildAppbar(BuildContext context) {
return Obx(() {
if (controller.manageAccountDashboardController.settingsPageLevel.value == SettingsPageLevel.universal) {
return _buildUniversalSettingAppBar(context);
} else {
return _buildSettingLevel1AppBar(context);
}
});
}
Widget _buildUniversalSettingAppBar(BuildContext context) {
final appBarWidget = Stack(
alignment: Alignment.center,
children: [
Positioned(left: 0,child: _buildCloseSettingButton(context)),
Padding(
padding: const EdgeInsets.only(left: 50, right: 50),
child: Text(
AppLocalizations.of(context).settings,
maxLines: 1,
softWrap: CommonTextStyle.defaultSoftWrap,
overflow: CommonTextStyle.defaultTextOverFlow,
style: ThemeUtils.defaultTextStyleInterFont.copyWith(
fontSize: 20,
color: AppColor.colorNameEmail,
fontWeight: FontWeight.w700,
),
),
),
],
);
if (AppConfig.isApiLoggingEnabled) {
return MultiClickWidget(
onMultiTap: () => controller
.manageAccountDashboardController
.showExportTraceLogConfirmDialog(context),
child: appBarWidget,
);
} else {
return appBarWidget;
}
}
Widget _buildSettingLevel1AppBar(BuildContext context) {
return Row(children: [
Material(
color: Colors.transparent,
child: InkWell(
onTap: controller.backToUniversalSettings,
customBorder: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15))),
child: Tooltip(
message: AppLocalizations.of(context).back,
child: Container(
color: Colors.transparent,
height: 40,
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Row(mainAxisSize: MainAxisSize.min, children: [
SvgPicture.asset(
DirectionUtils.isDirectionRTLByLanguage(context)
? controller.imagePaths.icCollapseFolder
: controller.imagePaths.icBack,
colorFilter: AppColor.colorTextButton.asFilter(),
fit: BoxFit.fill),
Container(
margin: const EdgeInsetsDirectional.only(start: 4),
constraints: const BoxConstraints(maxWidth: 80),
child: Text(
AppLocalizations.of(context).settings,
maxLines: 1,
overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap,
style: ThemeUtils.defaultTextStyleInterFont.copyWith(fontSize: 17, color: AppColor.colorTextButton)
)
),
]),
),
),
),
),
Expanded(child: Text(
controller.manageAccountDashboardController.accountMenuItemSelected.value.getName(AppLocalizations.of(context)),
maxLines: 1,
textAlign: TextAlign.center,
overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap,
style: ThemeUtils.defaultTextStyleInterFont.copyWith(
fontSize: 20,
color: Colors.black,
fontWeight: FontWeight.bold
)
)),
Container(constraints: const BoxConstraints(maxWidth: 80))
]);
}
Widget _buildCloseSettingButton(BuildContext context) {
return buildIconWeb(
icon: SvgPicture.asset(controller.imagePaths.icClose, width: 28, height: 28, fit: BoxFit.fill),
tooltip: AppLocalizations.of(context).close,
onTap: closeAction);
}
Widget _bodySettingsScreen() {
return Obx(() {
switch (controller.manageAccountDashboardController.settingsPageLevel.value) {
@@ -0,0 +1,86 @@
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/multi_click_widget.dart';
import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:core/utils/logger/log_tracking.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class UniversalSettingAppBar extends StatelessWidget {
final ImagePaths imagePaths;
final ResponsiveUtils responsiveUtils;
final VoidCallback onBackAction;
final VoidCallback? onExportTraceLogAction;
const UniversalSettingAppBar({
super.key,
required this.imagePaths,
required this.responsiveUtils,
required this.onBackAction,
this.onExportTraceLogAction,
});
@override
Widget build(BuildContext context) {
final appLocalizations = AppLocalizations.of(context);
Widget appBarWidget = Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
height: 52,
padding: _getPadding(context),
child: Stack(
alignment: Alignment.center,
children: [
PositionedDirectional(
start: 24,
child: TMailButtonWidget.fromIcon(
icon: imagePaths.icClose,
iconSize: 28,
padding: const EdgeInsets.all(5),
tooltipMessage: appLocalizations.close,
backgroundColor: Colors.transparent,
onTapActionCallback: onBackAction,
),
),
Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 60),
child: Text(
appLocalizations.settings,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: ThemeUtils.textStyleInter700().copyWith(
fontSize: 20,
height: 24 / 20,
),
),
),
),
],
),
),
const Divider(color: Colors.black12),
],
);
if (onExportTraceLogAction != null && LogTracking().isEnabled) {
return MultiClickWidget(
onMultiTap: onExportTraceLogAction!,
child: appBarWidget,
);
} else {
return appBarWidget;
}
}
EdgeInsetsGeometry _getPadding(BuildContext context) {
if (responsiveUtils.isPortraitMobile(context)) {
return EdgeInsetsDirectional.zero;
} else {
return const EdgeInsetsDirectional.symmetric(horizontal: 16);
}
}
}
@@ -22,16 +22,6 @@ class SettingsUtils {
}
}
static EdgeInsets getPaddingAppBar(BuildContext context, ResponsiveUtils responsiveUtils) {
if (responsiveUtils.isPortraitMobile(context)) {
return const EdgeInsets.symmetric(horizontal: 16);
} else if (responsiveUtils.isLandscapeMobile(context)) {
return const EdgeInsets.symmetric(horizontal: 12);
} else {
return const EdgeInsets.symmetric(horizontal: 32);
}
}
static EdgeInsets getMarginViewForSettingDetails(BuildContext context, ResponsiveUtils responsiveUtils) {
if (PlatformInfo.isWeb) {
if (responsiveUtils.isDesktop(context)) {
@@ -0,0 +1,24 @@
import 'package:core/presentation/resources/image_paths.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/features/base/widget/context_menu/context_menu_item_action.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/language_and_region/extensions/locale_extension.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class ContextItemLanguageAction
extends ContextMenuItemActionRequiredSelectedIcon<Locale> {
final AppLocalizations appLocalizations;
final ImagePaths imagePaths;
ContextItemLanguageAction(
super.action,
super.selectedAction,
this.appLocalizations,
this.imagePaths,
);
@override
String get actionName => '${action.getLanguageNameByCurrentLocale(appLocalizations)} - ${action.getSourceLanguageName()}';
@override
String get selectedIcon => imagePaths.icFilterSelected;
}
@@ -7,21 +7,31 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class SettingExplanationWidget extends StatelessWidget {
final AccountMenuItem menuItem;
final EdgeInsetsGeometry? padding;
final bool isCenter;
const SettingExplanationWidget({
Key? key,
required this.menuItem,
this.isCenter = false,
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),
),
Widget child = Text(
menuItem.getExplanation(AppLocalizations.of(context)),
style: ThemeUtils.textStyleM3BodyMedium1
.copyWith(color: AppColor.gray424244.withOpacity(0.64)),
);
if (isCenter) {
child = Center(child: child);
}
if (padding != null) {
child = Padding(padding: padding!, child: child);
}
return child;
}
}
}
@@ -1,7 +1,6 @@
import 'dart:async';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/logger/log_tracking.dart';
import 'package:jmap_dart_client/http/http_client.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/filter/filter.dart';
@@ -31,7 +30,6 @@ import 'package:tmail_ui_user/features/thread/data/model/email_change_response.d
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
import 'package:tmail_ui_user/features/thread/domain/model/search_emails_response.dart';
import 'package:tmail_ui_user/main/error/capability_validator.dart';
import 'package:tmail_ui_user/main/utils/app_config.dart';
class ThreadAPI {
@@ -103,12 +101,7 @@ class ThreadAPI {
?.notFound
?.toEmailIds()
.toList();
log('ThreadAPI::getAllEmail:notFoundEmailIds = $notFoundEmailIds');
if (notFoundEmailIds?.isNotEmpty == true && AppConfig.isApiLoggingEnabled) {
await LogTracking().addLog(
message: 'ThreadAPI::getAllEmail:notFoundEmailIds = ${notFoundEmailIds!.asListString.toString()} | NewState = ${responseOfGetEmailMethod?.state.value}',
);
}
log('ThreadAPI::getAllEmail:notFoundEmailIds = ${notFoundEmailIds!.asListString.toString()} | NewState = ${responseOfGetEmailMethod?.state.value}');
return EmailsResponse(
emailList: emailList,
notFoundEmailIds: notFoundEmailIds,
@@ -309,12 +302,7 @@ class ThreadAPI {
log('ThreadAPI::getChanges:notFoundIdsUpdated = $notFoundIdsUpdated');
if (notFoundIdsUpdated.isNotEmpty) {
destroyedEmailIds.addAll(notFoundIdsUpdated);
if (AppConfig.isApiLoggingEnabled) {
await LogTracking().addLog(
message: 'ThreadAPI::getChanges:notFoundIdsUpdated = ${notFoundIdsUpdated.asListString.toString()} | SinceState = ${sinceState.value}',
);
}
log('ThreadAPI::getChanges:notFoundIdsUpdated = ${notFoundIdsUpdated.asListString.toString()} | SinceState = ${sinceState.value}');
}
}
@@ -329,12 +317,7 @@ class ThreadAPI {
log('ThreadAPI::getChanges:notFoundIdsCreated = $notFoundIdsCreated');
if (notFoundIdsCreated.isNotEmpty) {
destroyedEmailIds.addAll(notFoundIdsCreated);
if (AppConfig.isApiLoggingEnabled) {
await LogTracking().addLog(
message: 'ThreadAPI::getChanges:notFoundIdsCreated = ${notFoundIdsCreated.asListString.toString()} | SinceState = ${sinceState.value}',
);
}
log('ThreadAPI::getChanges:notFoundIdsCreated = ${notFoundIdsCreated.asListString.toString()} | SinceState = ${sinceState.value}');
}
}
log('ThreadAPI::getChanges:newStateChanges = $newStateChanges | newStateEmail = $newStateEmail | hasMoreChanges = $hasMoreChanges');
-4
View File
@@ -1,6 +1,5 @@
import 'dart:io';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
@@ -14,9 +13,6 @@ class AppConfig {
static const int warningAttachmentFileSizeInMegabytes = 10;
static const int defaultLimitAutocomplete = 8;
// For testing
static bool isApiLoggingEnabled = PlatformInfo.isAndroid;
static const String envFileName = 'env.file';
static const String appDashboardConfigurationPath = "configurations/app_dashboard.json";
static const String appFCMConfigurationPath = "configurations/env.fcm";