diff --git a/assets/images/ic_arrow_back.svg b/assets/images/ic_arrow_back.svg
new file mode 100644
index 000000000..5e37af032
--- /dev/null
+++ b/assets/images/ic_arrow_back.svg
@@ -0,0 +1,3 @@
+
diff --git a/core/lib/presentation/resources/image_paths.dart b/core/lib/presentation/resources/image_paths.dart
index 9a0640c99..379370f16 100644
--- a/core/lib/presentation/resources/image_paths.dart
+++ b/core/lib/presentation/resources/image_paths.dart
@@ -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) {
diff --git a/core/lib/presentation/utils/theme_utils.dart b/core/lib/presentation/utils/theme_utils.dart
index 4779e69ec..1ca480027 100644
--- a/core/lib/presentation/utils/theme_utils.dart
+++ b/core/lib/presentation/utils/theme_utils.dart
@@ -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,
diff --git a/core/lib/utils/logger/log_tracking.dart b/core/lib/utils/logger/log_tracking.dart
index de05fb61e..f6a64009f 100644
--- a/core/lib/utils/logger/log_tracking.dart
+++ b/core/lib/utils/logger/log_tracking.dart
@@ -23,6 +23,7 @@ class LogTracking {
final Queue _messagesQueue = Queue();
bool _isScheduled = false;
+ bool isEnabled = false;
Future addLog({required String message}) async {
try {
diff --git a/lib/features/manage_account/presentation/email_rules/widgets/email_rules_header_widget.dart b/lib/features/manage_account/presentation/email_rules/widgets/email_rules_header_widget.dart
index e2d92b149..990e24141 100644
--- a/lib/features/manage_account/presentation/email_rules/widgets/email_rules_header_widget.dart
+++ b/lib/features/manage_account/presentation/email_rules/widgets/email_rules_header_widget.dart
@@ -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),
diff --git a/lib/features/manage_account/presentation/language_and_region/extensions/locale_extension.dart b/lib/features/manage_account/presentation/language_and_region/extensions/locale_extension.dart
index d5254461c..d4e5a7483 100644
--- a/lib/features/manage_account/presentation/language_and_region/extensions/locale_extension.dart
+++ b/lib/features/manage_account/presentation/language_and_region/extensions/locale_extension.dart
@@ -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 '';
}
diff --git a/lib/features/manage_account/presentation/language_and_region/language_and_region_controller.dart b/lib/features/manage_account/presentation/language_and_region/language_and_region_controller.dart
index b3706d158..cae7ebe6c 100644
--- a/lib/features/manage_account/presentation/language_and_region/language_and_region_controller.dart
+++ b/lib/features/manage_account/presentation/language_and_region/language_and_region_controller.dart
@@ -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);
+ },
+ );
+ }
}
\ No newline at end of file
diff --git a/lib/features/manage_account/presentation/language_and_region/language_and_region_view.dart b/lib/features/manage_account/presentation/language_and_region/language_and_region_view.dart
index 02b8535a2..d93236d82 100644
--- a/lib/features/manage_account/presentation/language_and_region/language_and_region_view.dart
+++ b/lib/features/manage_account/presentation/language_and_region/language_and_region_view.dart
@@ -45,11 +45,20 @@ class LanguageAndRegionView extends GetWidget {
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,
+ ),
),
),
],
diff --git a/lib/features/manage_account/presentation/language_and_region/widgets/change_language_button_widget.dart b/lib/features/manage_account/presentation/language_and_region/widgets/change_language_button_widget.dart
index 3f71e29b1..a2784b12d 100644
--- a/lib/features/manage_account/presentation/language_and_region/widgets/change_language_button_widget.dart
+++ b/lib/features/manage_account/presentation/language_and_region/widgets/change_language_button_widget.dart
@@ -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 createState() => _ChangeLanguageButtonWidgetState();
@@ -44,15 +51,19 @@ class _ChangeLanguageButtonWidgetState extends State
],
);
} 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
widthFactor: 1,
),
),
- portalFollower: Obx(() => LanguageRegionOverlay(
+ portalFollower: LanguageRegionOverlay(
imagePaths: _imagePaths,
responsiveUtils: _responsiveUtils,
listSupportedLanguages: _languageAndRegionController.listSupportedLanguages,
@@ -100,13 +111,13 @@ class _ChangeLanguageButtonWidgetState extends State
_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
);
}
+ 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);
+ }
}
}
\ No newline at end of file
diff --git a/lib/features/manage_account/presentation/language_and_region/widgets/lanuage_item_widget.dart b/lib/features/manage_account/presentation/language_and_region/widgets/lanuage_item_widget.dart
index da28d5e89..9b1e290d5 100644
--- a/lib/features/manage_account/presentation/language_and_region/widgets/lanuage_item_widget.dart
+++ b/lib/features/manage_account/presentation/language_and_region/widgets/lanuage_item_widget.dart
@@ -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,
diff --git a/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart b/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart
index 8ae32f154..413eb4cb2 100644
--- a/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart
+++ b/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart
@@ -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();
diff --git a/lib/features/manage_account/presentation/manage_account_dashboard_view.dart b/lib/features/manage_account/presentation/manage_account_dashboard_view.dart
index c1d56131a..2311874e3 100644
--- a/lib/features/manage_account/presentation/manage_account_dashboard_view.dart
+++ b/lib/features/manage_account/presentation/manage_account_dashboard_view.dart
@@ -102,11 +102,7 @@ class ManageAccountDashBoardView extends GetWidget
- controller.backToMailboxDashBoard(context: context)),
- )
+ mobile: const SafeArea(child: SettingsView())
),
),
),
diff --git a/lib/features/manage_account/presentation/menu/settings/setting_app_bar.dart b/lib/features/manage_account/presentation/menu/settings/setting_app_bar.dart
new file mode 100644
index 000000000..0ddb0bd29
--- /dev/null
+++ b/lib/features/manage_account/presentation/menu/settings/setting_app_bar.dart
@@ -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,
+ );
+ }
+ }
+}
diff --git a/lib/features/manage_account/presentation/menu/settings/setting_first_level_app_bar.dart b/lib/features/manage_account/presentation/menu/settings/setting_first_level_app_bar.dart
new file mode 100644
index 000000000..917c9280a
--- /dev/null
+++ b/lib/features/manage_account/presentation/menu/settings/setting_first_level_app_bar.dart
@@ -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);
+ }
+ }
+}
diff --git a/lib/features/manage_account/presentation/menu/settings/settings_controller.dart b/lib/features/manage_account/presentation/menu/settings/settings_controller.dart
index a1bb5e454..e467bac82 100644
--- a/lib/features/manage_account/presentation/menu/settings/settings_controller.dart
+++ b/lib/features/manage_account/presentation/menu/settings/settings_controller.dart
@@ -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();
@@ -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);
+ }
}
\ No newline at end of file
diff --git a/lib/features/manage_account/presentation/menu/settings/settings_view.dart b/lib/features/manage_account/presentation/menu/settings/settings_view.dart
index 2fd808022..0900f1a73 100644
--- a/lib/features/manage_account/presentation/menu/settings/settings_view.dart
+++ b/lib/features/manage_account/presentation/menu/settings/settings_view.dart
@@ -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 {
- 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 {
);
}
- 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) {
diff --git a/lib/features/manage_account/presentation/menu/settings/universal_setting_app_bar.dart b/lib/features/manage_account/presentation/menu/settings/universal_setting_app_bar.dart
new file mode 100644
index 000000000..da7808e46
--- /dev/null
+++ b/lib/features/manage_account/presentation/menu/settings/universal_setting_app_bar.dart
@@ -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);
+ }
+ }
+}
diff --git a/lib/features/manage_account/presentation/menu/settings_utils.dart b/lib/features/manage_account/presentation/menu/settings_utils.dart
index 8fbb18d6b..30b9d9bf9 100644
--- a/lib/features/manage_account/presentation/menu/settings_utils.dart
+++ b/lib/features/manage_account/presentation/menu/settings_utils.dart
@@ -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)) {
diff --git a/lib/features/manage_account/presentation/model/language/context_item_language_action.dart b/lib/features/manage_account/presentation/model/language/context_item_language_action.dart
new file mode 100644
index 000000000..edfe9f59c
--- /dev/null
+++ b/lib/features/manage_account/presentation/model/language/context_item_language_action.dart
@@ -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 {
+ 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;
+}
diff --git a/lib/features/manage_account/presentation/widgets/setting_explanation_widget.dart b/lib/features/manage_account/presentation/widgets/setting_explanation_widget.dart
index c56be4cd6..5864158f6 100644
--- a/lib/features/manage_account/presentation/widgets/setting_explanation_widget.dart
+++ b/lib/features/manage_account/presentation/widgets/setting_explanation_widget.dart
@@ -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;
}
-}
\ No newline at end of file
+}
diff --git a/lib/features/thread/data/network/thread_api.dart b/lib/features/thread/data/network/thread_api.dart
index 5772f7bf4..c9d3d2abb 100644
--- a/lib/features/thread/data/network/thread_api.dart
+++ b/lib/features/thread/data/network/thread_api.dart
@@ -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');
diff --git a/lib/main/utils/app_config.dart b/lib/main/utils/app_config.dart
index a5b3e5526..0883dda31 100644
--- a/lib/main/utils/app_config.dart
+++ b/lib/main/utils/app_config.dart
@@ -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";