diff --git a/assets/images/ic_storage.svg b/assets/images/ic_storage.svg new file mode 100644 index 000000000..d6b9b758a --- /dev/null +++ b/assets/images/ic_storage.svg @@ -0,0 +1,5 @@ + + + diff --git a/assets/images/ic_warning.svg b/assets/images/ic_warning.svg new file mode 100644 index 000000000..a80addc83 --- /dev/null +++ b/assets/images/ic_warning.svg @@ -0,0 +1,4 @@ + + + + diff --git a/core/lib/presentation/extensions/color_extension.dart b/core/lib/presentation/extensions/color_extension.dart index fd70934ba..e99e62270 100644 --- a/core/lib/presentation/extensions/color_extension.dart +++ b/core/lib/presentation/extensions/color_extension.dart @@ -241,6 +241,7 @@ extension AppColor on Color { static const m3Tertiary20 = Color(0xFF71767C); static const m3Neutral70 = Color(0xFFAEAAAE); static const m3Neutral90 = Color(0xFFE6E1E5); + static const m3Neutral40 = Color(0xFF605D62); static const m3SysLightSecondaryBlue = Color(0xFF5C9CE6); static const m3SysLight = Color(0xFF0157AD); static const m3SysOutline = Color(0xFFAEAEC0); @@ -279,6 +280,9 @@ extension AppColor on Color { static const lightGreenBBF7D0 = Color(0xFFBBF7D0); static const lightBlueEFF6FF = Color(0xFFEFF6FF); static const lightBlueBFDBFE = Color(0xFFBFDBFE); + static const lightGrayF6FAFF = Color(0xFFF6FAFF); + static const lightGrayF7F6F9 = Color(0xFFF7F6F9); + static const blue25AEFE = Color(0xFF25AEFE); static const mapGradientColor = [ [Color(0xFF21D4FD), Color(0xFFB721FF)], diff --git a/core/lib/presentation/resources/image_paths.dart b/core/lib/presentation/resources/image_paths.dart index 24c417b89..edf946446 100644 --- a/core/lib/presentation/resources/image_paths.dart +++ b/core/lib/presentation/resources/image_paths.dart @@ -249,6 +249,8 @@ class ImagePaths { String get icPremium => _getImagePath('ic_premium.svg'); String get icCloud => _getImagePath('ic_cloud.svg'); String get icNoRules => _getImagePath('ic_no_rules.svg'); + String get icStorage => _getImagePath('ic_storage.svg'); + String get icWarning => _getImagePath('ic_warning.svg'); String _getImagePath(String imageName) { return AssetsPaths.images + imageName; diff --git a/lib/features/manage_account/presentation/extensions/validate_setting_capability_supported_extension.dart b/lib/features/manage_account/presentation/extensions/validate_setting_capability_supported_extension.dart new file mode 100644 index 000000000..fd4d5355a --- /dev/null +++ b/lib/features/manage_account/presentation/extensions/validate_setting_capability_supported_extension.dart @@ -0,0 +1,17 @@ +import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart'; +import 'package:tmail_ui_user/main/error/capability_validator.dart'; + +extension ValidateSettingCapabilitySupportedExtension + on ManageAccountDashBoardController { + bool get isStorageCapabilitySupported { + if (accountId.value != null && sessionCurrent != null) { + return CapabilityIdentifier.jmapQuota.isSupported( + sessionCurrent!, + accountId.value!, + ); + } else { + return false; + } + } +} 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 130fe044c..10828442f 100644 --- a/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart +++ b/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart @@ -38,6 +38,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/model/manage_ import 'package:tmail_ui_user/features/manage_account/presentation/model/settings_page_level.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/notification/bindings/notification_binding.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/preferences/bindings/preferences_bindings.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/storage/storage_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/vacation/vacation_controller_bindings.dart'; import 'package:tmail_ui_user/main/error/capability_validator.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; @@ -213,6 +214,9 @@ class ManageAccountDashBoardController extends ReloadableController case AccountMenuItem.notification: NotificationBinding().dependencies(); break; + case AccountMenuItem.storage: + StorageBindings().dependencies(); + break; default: break; } 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 78a99b7a3..5fc4864f0 100644 --- a/lib/features/manage_account/presentation/manage_account_dashboard_view.dart +++ b/lib/features/manage_account/presentation/manage_account_dashboard_view.dart @@ -11,6 +11,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/na 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/handle_profile_setting_action_type_click_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/extensions/validate_setting_capability_supported_extension.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/forward/forward_view.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/identities/identities_view.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/language_and_region/language_and_region_view.dart'; @@ -20,6 +21,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/menu/manage_a import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/settings_view.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/preferences/preferences_view.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/storage/storage_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'; @@ -167,6 +169,12 @@ class ManageAccountDashBoardView extends GetWidget { ), ]); }), + Obx(() { + if (controller.manageAccountDashboardController.isStorageCapabilitySupported) { + return Column(children: [ + Divider( + color: AppColor.colorDividerHorizontal, + height: 1, + indent: SettingsUtils.getHorizontalPadding( + context, + controller.responsiveUtils, + ), + endIndent: SettingsUtils.getHorizontalPadding( + context, + controller.responsiveUtils, + ), + ), + SettingFirstLevelTileBuilder( + key: const ValueKey('setting_storage'), + AccountMenuItem.storage.getName(AppLocalizations.of(context)), + AccountMenuItem.storage.getIcon(controller.imagePaths), + subtitle: AppLocalizations.of(context).storageSettingExplanation, + () => controller.selectSettings(AccountMenuItem.storage), + ), + ]); + } else { + return const SizedBox.shrink(); + } + }), Obx(() { if (controller.manageAccountDashboardController.isFcmCapabilitySupported && PlatformInfo.isMobile) { return Column(children: [ 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 b2c8d6774..2ffddefed 100644 --- a/lib/features/manage_account/presentation/menu/settings/settings_view.dart +++ b/lib/features/manage_account/presentation/menu/settings/settings_view.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.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/vacation_response_extension.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/extensions/validate_setting_capability_supported_extension.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/forward/forward_view.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/identities/identities_view.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/language_and_region/language_and_region_view.dart'; @@ -13,6 +14,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/model/account 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'; import 'package:tmail_ui_user/features/manage_account/presentation/preferences/preferences_view.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/storage/storage_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'; @@ -137,6 +139,12 @@ class SettingsView extends GetWidget { return MailboxVisibilityView(); case AccountMenuItem.notification: return const NotificationView(); + case AccountMenuItem.storage: + if (controller.manageAccountDashboardController.isStorageCapabilitySupported) { + return const StorageView(); + } else { + return const SizedBox.shrink(); + } default: return const SizedBox.shrink(); } diff --git a/lib/features/manage_account/presentation/model/account_menu_item.dart b/lib/features/manage_account/presentation/model/account_menu_item.dart index 2f08d8552..9ef9bd47f 100644 --- a/lib/features/manage_account/presentation/model/account_menu_item.dart +++ b/lib/features/manage_account/presentation/model/account_menu_item.dart @@ -12,6 +12,7 @@ enum AccountMenuItem { mailboxVisibility, notification, contactSupport, + storage, signOut, none; @@ -35,6 +36,8 @@ enum AccountMenuItem { return imagePaths.icNotification; case AccountMenuItem.contactSupport: return imagePaths.icHelp; + case AccountMenuItem.storage: + return imagePaths.icStorage; case AccountMenuItem.signOut: return imagePaths.icSignOut; case AccountMenuItem.none: @@ -62,6 +65,8 @@ enum AccountMenuItem { return appLocalizations.notification; case AccountMenuItem.contactSupport: return appLocalizations.contactSupport; + case AccountMenuItem.storage: + return appLocalizations.storageQuotas; case AccountMenuItem.signOut: return appLocalizations.sign_out; case AccountMenuItem.none: @@ -83,6 +88,8 @@ enum AccountMenuItem { return appLocalizations.vacationSettingExplanation; case AccountMenuItem.mailboxVisibility: return appLocalizations.folderVisibilitySubtitle; + case AccountMenuItem.storage: + return appLocalizations.storageSettingExplanation; default: return ''; } @@ -108,6 +115,8 @@ enum AccountMenuItem { return 'notification'; case AccountMenuItem.contactSupport: return 'contact-support'; + case AccountMenuItem.storage: + return 'storage'; case AccountMenuItem.signOut: return 'sign-out'; case AccountMenuItem.none: diff --git a/lib/features/manage_account/presentation/storage/storage_bindings.dart b/lib/features/manage_account/presentation/storage/storage_bindings.dart new file mode 100644 index 000000000..ca14ee73b --- /dev/null +++ b/lib/features/manage_account/presentation/storage/storage_bindings.dart @@ -0,0 +1,12 @@ +import 'package:get/get.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/storage/storage_controller.dart'; +import 'package:tmail_ui_user/features/quotas/domain/use_case/get_quotas_interactor.dart'; +import 'package:tmail_ui_user/features/quotas/presentation/quotas_interactor_bindings.dart'; + +class StorageBindings extends Bindings { + @override + void dependencies() { + QuotasInteractorBindings().dependencies(); + Get.lazyPut(() => StorageController(Get.find())); + } +} diff --git a/lib/features/manage_account/presentation/storage/storage_controller.dart b/lib/features/manage_account/presentation/storage/storage_controller.dart new file mode 100644 index 000000000..8d82f6ae2 --- /dev/null +++ b/lib/features/manage_account/presentation/storage/storage_controller.dart @@ -0,0 +1,67 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:get/get.dart'; +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/quotas/quota.dart'; +import 'package:tmail_ui_user/features/base/base_controller.dart'; +import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart'; +import 'package:tmail_ui_user/features/quotas/domain/extensions/list_quotas_extensions.dart'; +import 'package:tmail_ui_user/features/quotas/domain/state/get_quotas_state.dart'; +import 'package:tmail_ui_user/features/quotas/domain/use_case/get_quotas_interactor.dart'; + +class StorageController extends BaseController { + final dashBoardController = Get.find(); + + final GetQuotasInteractor _getQuotasInteractor; + + final octetsQuota = Rxn(); + + StorageController(this._getQuotasInteractor); + + @override + void onReady() { + final accountId = dashBoardController.accountId.value; + if(accountId != null) { + _getQuotasAction(accountId); + } else { + consumeState( + Stream.value( + Left(GetQuotasFailure(NotFoundAccountIdException())), + ), + ); + } + super.onReady(); + } + + void _getQuotasAction(AccountId accountId) { + consumeState(_getQuotasInteractor.execute(accountId)); + } + + void _handleGetQuotasSuccess(GetQuotasSuccess success) { + octetsQuota.value = success.quotas.octetsQuota; + } + + void onUpgradeStorage() { + + } + + @override + void handleSuccessViewState(Success success) { + if (success is GetQuotasSuccess) { + _handleGetQuotasSuccess(success); + } else { + super.handleSuccessViewState(success); + } + } + + @override + void handleFailureViewState(Failure failure) { + if (failure is GetQuotasFailure) { + octetsQuota.value = null; + } else { + super.handleFailureViewState(failure); + } + } +} diff --git a/lib/features/manage_account/presentation/storage/storage_view.dart b/lib/features/manage_account/presentation/storage/storage_view.dart new file mode 100644 index 000000000..d9ecfb8dc --- /dev/null +++ b/lib/features/manage_account/presentation/storage/storage_view.dart @@ -0,0 +1,107 @@ +import 'package:core/presentation/utils/theme_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/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/storage/storage_controller.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/storage/widgets/storage_progress_bar_widget.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/storage/widgets/upgrade_storage_widget.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/features/quotas/domain/extensions/quota_extensions.dart'; + +class StorageView extends GetWidget { + const StorageView({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final responsiveUtils = controller.responsiveUtils; + final isMobile = responsiveUtils.isMobile(context); + final isDesktop = responsiveUtils.isDesktop(context); + final isWebDesktop = responsiveUtils.isWebDesktop(context); + + return SettingDetailViewBuilder( + responsiveUtils: responsiveUtils, + child: Container( + color: SettingsUtils.getContentBackgroundColor( + context, + responsiveUtils, + ), + decoration: SettingsUtils.getBoxDecorationForContent( + context, + responsiveUtils, + ), + width: double.infinity, + padding: isDesktop + ? const EdgeInsets.symmetric(vertical: 30, horizontal: 22) + : null, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (isWebDesktop) + SettingHeaderWidget( + menuItem: AccountMenuItem.storage, + textStyle: ThemeUtils.textStyleInter600().copyWith( + color: Colors.black.withValues(alpha: 0.9), + ), + padding: EdgeInsets.zero, + ) + else + const SettingExplanationWidget( + menuItem: AccountMenuItem.storage, + padding: EdgeInsetsDirectional.only( + start: 16, + end: 16, + bottom: 16, + ), + isCenter: true, + textAlign: TextAlign.center, + ), + Expanded( + child: Padding( + padding: _getPadding(isMobile: isMobile, isDesktop: isDesktop), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Obx(() { + final octetsQuota = controller.octetsQuota.value; + if (octetsQuota != null && octetsQuota.storageAvailable) { + return StorageProgressBarWidget( + imagePaths: controller.imagePaths, + quota: octetsQuota, + isMobile: isMobile, + ); + } else { + return const SizedBox.shrink(); + } + }), + UpgradeStorageWidget( + imagePaths: controller.imagePaths, + isMobile: isMobile, + onUpgradeStorageAction: controller.onUpgradeStorage, + ) + ], + ), + ), + ), + ], + ), + ), + ); + } + + EdgeInsetsGeometry _getPadding({ + bool isMobile = false, + bool isDesktop = false, + }) { + if (isMobile) { + return const EdgeInsetsDirectional.only(top: 31, start: 24, end: 24); + } else if (isDesktop) { + return const EdgeInsetsDirectional.only(top: 37, start: 15); + } else { + return const EdgeInsetsDirectional.only(top: 31, start: 32, end: 32); + } + } +} diff --git a/lib/features/manage_account/presentation/storage/widgets/storage_progress_bar_widget.dart b/lib/features/manage_account/presentation/storage/widgets/storage_progress_bar_widget.dart new file mode 100644 index 000000000..366130943 --- /dev/null +++ b/lib/features/manage_account/presentation/storage/widgets/storage_progress_bar_widget.dart @@ -0,0 +1,141 @@ +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/utils/theme_utils.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:jmap_dart_client/jmap/quotas/quota.dart'; +import 'package:tmail_ui_user/features/quotas/domain/extensions/quota_extensions.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +class StorageProgressBarWidget extends StatelessWidget { + final ImagePaths imagePaths; + final Quota quota; + final bool isMobile; + + const StorageProgressBarWidget({ + super.key, + required this.imagePaths, + required this.quota, + this.isMobile = false, + }); + + @override + Widget build(BuildContext context) { + final appLocalizations = AppLocalizations.of(context); + + final logoStorageWidget = Container( + width: 64, + height: 64, + decoration: const BoxDecoration( + color: AppColor.lightGrayF6FAFF, + borderRadius: BorderRadius.all(Radius.circular(100)), + ), + alignment: Alignment.center, + child: SvgPicture.asset( + imagePaths.icCloud, + width: 30.72, + height: 30.72, + fit: BoxFit.fill, + ), + ); + + final infoStorageWidgets = [ + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + quota.usedStorageAsString, + style: ThemeUtils.textStyleInter600().copyWith( + color: AppColor.m3SurfaceBackground, + fontSize: 18.13, + height: 22.66 / 18.13, + letterSpacing: 0.0, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + Expanded( + child: Row( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8, + ), + child: Text( + appLocalizations.storageUsedMessage( + quota.hardLimitStorageAsString, + ), + style: ThemeUtils.textStyleInter500().copyWith( + color: AppColor.m3Tertiary20, + fontSize: 9.06, + height: 13.6 / 9.06, + letterSpacing: 0.08, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + ), + Text( + appLocalizations.storageAvailableMessage( + quota.quotaAvailableStorageAsString, + ), + style: ThemeUtils.textStyleInter600().copyWith( + color: AppColor.m3Tertiary20, + fontSize: 9.06, + height: 13.6 / 9.06, + letterSpacing: 0.08, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + ], + ), + Container( + padding: const EdgeInsets.only(top: 5), + width: double.infinity, + child: LinearProgressIndicator( + color: quota.getQuotasStateProgressBarColor( + fromSetting: true, + ), + minHeight: 4.53, + backgroundColor: AppColor.lightGrayF7F6F9, + borderRadius: const BorderRadius.all( + Radius.circular(13.03), + ), + value: quota.usedStoragePercent, + ), + ), + ]; + + return Container( + width: isMobile ? double.infinity : 439, + padding: const EdgeInsets.only(bottom: 16), + child: isMobile + ? Column( + mainAxisSize: MainAxisSize.min, + children: [ + logoStorageWidget, + const SizedBox(height: 8), + ...infoStorageWidgets, + ], + ) + : Row( + children: [ + logoStorageWidget, + const SizedBox(width: 24), + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + children: infoStorageWidgets, + ), + ), + ], + ), + ); + } +} diff --git a/lib/features/manage_account/presentation/storage/widgets/upgrade_storage_widget.dart b/lib/features/manage_account/presentation/storage/widgets/upgrade_storage_widget.dart new file mode 100644 index 000000000..18f66e78e --- /dev/null +++ b/lib/features/manage_account/presentation/storage/widgets/upgrade_storage_widget.dart @@ -0,0 +1,68 @@ +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/utils/theme_utils.dart'; +import 'package:core/presentation/views/dialog/confirm_dialog_button.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +class UpgradeStorageWidget extends StatelessWidget { + final ImagePaths imagePaths; + final bool isMobile; + final VoidCallback onUpgradeStorageAction; + + const UpgradeStorageWidget({ + super.key, + required this.imagePaths, + required this.onUpgradeStorageAction, + this.isMobile = false, + }); + + @override + Widget build(BuildContext context) { + final appLocalizations = AppLocalizations.of(context); + return SizedBox( + width: isMobile ? double.infinity : 439, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SvgPicture.asset( + imagePaths.icWarning, + width: 16, + height: 16, + fit: BoxFit.fill, + ), + const SizedBox(width: 7), + Expanded( + child: Text( + appLocalizations.storageIsAlmostFullMessage, + style: ThemeUtils.textStyleInter600().copyWith( + color: AppColor.m3Neutral40, + fontSize: 12, + height: 16 / 12, + letterSpacing: 0.4, + ), + ), + ), + ], + ), + const SizedBox(height: 16), + Container( + constraints: const BoxConstraints(minWidth: 179), + height: 48, + child: ConfirmDialogButton( + label: appLocalizations.upgradeStorage, + backgroundColor: AppColor.primaryMain, + textColor: Colors.white, + onTapAction: onUpgradeStorageAction, + ), + ), + ], + ), + ); + } +} diff --git a/lib/features/quotas/domain/extensions/quota_extensions.dart b/lib/features/quotas/domain/extensions/quota_extensions.dart index 64828530f..457c76a1e 100644 --- a/lib/features/quotas/domain/extensions/quota_extensions.dart +++ b/lib/features/quotas/domain/extensions/quota_extensions.dart @@ -68,13 +68,13 @@ extension QuotasExtensions on Quota { } } - Color getQuotasStateProgressBarColor() { + Color getQuotasStateProgressBarColor({bool fromSetting = false}) { if (isHardLimitReached) { return AppColor.colorQuotaError; } else if (isWarnLimitReached) { return AppColor.colorBackgroundQuotasWarning; } else { - return AppColor.blue400; + return fromSetting ? AppColor.blue25AEFE : AppColor.blue400; } } diff --git a/lib/features/quotas/presentation/quotas_bindings.dart b/lib/features/quotas/presentation/quotas_bindings.dart index ed57fd337..1868fc51b 100644 --- a/lib/features/quotas/presentation/quotas_bindings.dart +++ b/lib/features/quotas/presentation/quotas_bindings.dart @@ -1,43 +1,12 @@ import 'package:get/get.dart'; -import 'package:tmail_ui_user/features/base/base_bindings.dart'; -import 'package:tmail_ui_user/features/quotas/data/datasource/quotas_data_source.dart'; -import 'package:tmail_ui_user/features/quotas/data/datasource_impl/quotas_data_source_impl.dart'; -import 'package:tmail_ui_user/features/quotas/data/network/quotas_api.dart'; -import 'package:tmail_ui_user/features/quotas/data/repository/quotas_repository_impl.dart'; -import 'package:tmail_ui_user/features/quotas/domain/repository/quotas_repository.dart'; import 'package:tmail_ui_user/features/quotas/domain/use_case/get_quotas_interactor.dart'; import 'package:tmail_ui_user/features/quotas/presentation/quotas_controller.dart'; -import 'package:tmail_ui_user/main/exceptions/remote_exception_thrower.dart'; - -class QuotasBindings extends BaseBindings { +import 'package:tmail_ui_user/features/quotas/presentation/quotas_interactor_bindings.dart'; +class QuotasBindings extends Bindings { @override - void bindingsController() { + void dependencies() { + QuotasInteractorBindings().dependencies(); Get.put(QuotasController(Get.find())); } - - @override - void bindingsDataSource() { - Get.lazyPut(() => (Get.find())); - } - - @override - void bindingsDataSourceImpl() { - Get.lazyPut(() => QuotasDataSourceImpl(Get.find(), Get.find())); - } - - @override - void bindingsInteractor() { - Get.lazyPut(() => GetQuotasInteractor(Get.find())); - } - - @override - void bindingsRepository() { - Get.lazyPut(() => Get.find()); - } - - @override - void bindingsRepositoryImpl() { - Get.lazyPut(() => QuotasRepositoryImpl(Get.find())); - } } \ No newline at end of file diff --git a/lib/features/quotas/presentation/quotas_interactor_bindings.dart b/lib/features/quotas/presentation/quotas_interactor_bindings.dart new file mode 100644 index 000000000..100b4f2ef --- /dev/null +++ b/lib/features/quotas/presentation/quotas_interactor_bindings.dart @@ -0,0 +1,37 @@ +import 'package:get/get.dart'; +import 'package:tmail_ui_user/features/base/interactors_bindings.dart'; +import 'package:tmail_ui_user/features/quotas/data/datasource/quotas_data_source.dart'; +import 'package:tmail_ui_user/features/quotas/data/datasource_impl/quotas_data_source_impl.dart'; +import 'package:tmail_ui_user/features/quotas/data/network/quotas_api.dart'; +import 'package:tmail_ui_user/features/quotas/data/repository/quotas_repository_impl.dart'; +import 'package:tmail_ui_user/features/quotas/domain/repository/quotas_repository.dart'; +import 'package:tmail_ui_user/features/quotas/domain/use_case/get_quotas_interactor.dart'; +import 'package:tmail_ui_user/main/exceptions/remote_exception_thrower.dart'; + +class QuotasInteractorBindings extends InteractorsBindings { + + @override + void bindingsDataSource() { + Get.lazyPut(() => (Get.find())); + } + + @override + void bindingsDataSourceImpl() { + Get.lazyPut(() => QuotasDataSourceImpl(Get.find(), Get.find())); + } + + @override + void bindingsInteractor() { + Get.lazyPut(() => GetQuotasInteractor(Get.find())); + } + + @override + void bindingsRepository() { + Get.lazyPut(() => Get.find()); + } + + @override + void bindingsRepositoryImpl() { + Get.lazyPut(() => QuotasRepositoryImpl(Get.find())); + } +} \ No newline at end of file diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index 495fc749b..d3b1d4af4 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -4887,5 +4887,43 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "storageSettingExplanation": "Monitor your available space.", + "@storageSettingExplanation": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "storageIsAlmostFullMessage": "The storage is almost full. You can free up space by deleting unnecessary files or subscribe to get extra space.", + "@storageIsAlmostFullMessage": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "upgradeStorage": "Upgrade storage", + "@upgradeStorage": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "storageUsedMessage": "of {limit} used", + "@storageUsedMessage": { + "type": "text", + "placeholders_order": [ + "limit" + ], + "placeholders": { + "limit": {} + } + }, + "storageAvailableMessage": "Available: {count}", + "@storageAvailableMessage": { + "type": "text", + "placeholders_order": [ + "count" + ], + "placeholders": { + "count": {} + } } } \ No newline at end of file diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index ae9b189b0..fe4b835f5 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -5161,4 +5161,41 @@ class AppLocalizations { name: 'defaultIdentitySetupSuccessful', ); } + + String get storageSettingExplanation { + return Intl.message( + 'Monitor your available space.', + name: 'storageSettingExplanation', + ); + } + + String get storageIsAlmostFullMessage { + return Intl.message( + 'The storage is almost full. You can free up space by deleting unnecessary files or subscribe to get extra space.', + name: 'storageIsAlmostFullMessage', + ); + } + + String get upgradeStorage { + return Intl.message( + 'Upgrade storage', + name: 'upgradeStorage', + ); + } + + String storageUsedMessage(String limit) { + return Intl.message( + 'of $limit used', + name: 'storageUsedMessage', + args: [limit], + ); + } + + String storageAvailableMessage(String count) { + return Intl.message( + 'Available: $count', + name: 'storageAvailableMessage', + args: [count], + ); + } }