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
@@ -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)) {