TF-4045 Only show upgrade storage when premium is available and quota is available

This commit is contained in:
dab246
2025-10-01 17:55:22 +07:00
committed by Dat H. Pham
parent 2cc727c209
commit dcb19992c6
16 changed files with 184 additions and 97 deletions
@@ -114,7 +114,7 @@ class MailboxMenuRobot extends CoreRobot {
int getUsedQuota() { int getUsedQuota() {
final usedQuota = final usedQuota =
getBinding<QuotasController>()?.octetsQuota.value?.used?.value.toInt(); getBinding<MailboxDashBoardController>()?.octetsQuota.value?.used?.value.toInt();
if (usedQuota == null) throw NullQuotaException(); if (usedQuota == null) throw NullQuotaException();
return usedQuota; return usedQuota;
@@ -3,9 +3,8 @@ import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:model/mailbox/expand_mode.dart'; import 'package:model/mailbox/expand_mode.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_paywall_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/validate_premium_storage_extension.dart';
import 'package:tmail_ui_user/features/quotas/domain/extensions/quota_extensions.dart'; import 'package:tmail_ui_user/features/quotas/domain/extensions/quota_extensions.dart';
import 'package:tmail_ui_user/features/quotas/presentation/quotas_controller.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart';
mixin ExpandFolderTriggerScrollableMixin { mixin ExpandFolderTriggerScrollableMixin {
@@ -50,7 +49,7 @@ mixin ExpandFolderTriggerScrollableMixin {
double _getOffsetY() { double _getOffsetY() {
try { try {
final quota = getBinding<QuotasController>()?.octetsQuota.value; final quota = getBinding<MailboxDashBoardController>()?.octetsQuota.value;
final isQuotaViewDisplayed = quota?.storageAvailable ?? false; final isQuotaViewDisplayed = quota?.storageAvailable ?? false;
final isPremiumAvailable = getBinding<MailboxDashBoardController>() final isPremiumAvailable = getBinding<MailboxDashBoardController>()
@@ -100,7 +100,7 @@ import 'package:tmail_ui_user/features/email/presentation/model/composer_argumen
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_composer_cache_by_id_on_web_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_composer_cache_by_id_on_web_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_paywall_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/validate_premium_storage_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/draggable_app_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/draggable_app_state.dart';
import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_identities_state.dart'; import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_identities_state.dart';
@@ -1051,7 +1051,7 @@ class ComposerController extends BaseController
popBack(); popBack();
if (needIncreaseMySpace) { if (needIncreaseMySpace) {
mailboxDashBoardController.navigateToPaywall(context); mailboxDashBoardController.paywallController?.navigateToPaywall(context);
} else { } else {
_autoFocusFieldWhenLauncher(); _autoFocusFieldWhenLauncher();
} }
@@ -1334,7 +1334,7 @@ class ComposerController extends BaseController
popBack(); popBack();
if (needIncreaseMySpace) { if (needIncreaseMySpace) {
mailboxDashBoardController.navigateToPaywall(context); mailboxDashBoardController.paywallController?.navigateToPaywall(context);
} else { } else {
_autoFocusFieldWhenLauncher(); _autoFocusFieldWhenLauncher();
} }
@@ -2270,7 +2270,7 @@ class ComposerController extends BaseController
popBack(); popBack();
if (needIncreaseMySpace) { if (needIncreaseMySpace) {
mailboxDashBoardController.navigateToPaywall(context); mailboxDashBoardController.paywallController?.navigateToPaywall(context);
} else { } else {
_autoFocusFieldWhenLauncher(); _autoFocusFieldWhenLauncher();
} }
@@ -8,7 +8,8 @@ import 'package:tmail_ui_user/features/base/widget/application_version_widget.da
import 'package:tmail_ui_user/features/base/widget/premium/increase_space_button_widget.dart'; import 'package:tmail_ui_user/features/base/widget/premium/increase_space_button_widget.dart';
import 'package:tmail_ui_user/features/base/widget/scrollbar_list_view.dart'; import 'package:tmail_ui_user/features/base/widget/scrollbar_list_view.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/base_mailbox_view.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/base_mailbox_view.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_paywall_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/validate_premium_storage_extension.dart';
import 'package:tmail_ui_user/features/quotas/domain/extensions/quota_extensions.dart';
import 'package:tmail_ui_user/features/quotas/presentation/quotas_view.dart'; import 'package:tmail_ui_user/features/quotas/presentation/quotas_view.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -41,9 +42,15 @@ class MailboxView extends BaseMailboxView {
final isPremiumAvailable = controller final isPremiumAvailable = controller
.mailboxDashBoardController .mailboxDashBoardController
.validatePremiumIsAvailable(); .validatePremiumIsAvailable();
final octetQuota = controller
.mailboxDashBoardController
.octetsQuota
.value;
final isDesktop = controller.responsiveUtils.isDesktop(context); final isDesktop = controller.responsiveUtils.isDesktop(context);
if (isPremiumAvailable) { if (isPremiumAvailable && octetQuota?.storageAvailable == true) {
return IncreaseSpaceButtonWidget( return IncreaseSpaceButtonWidget(
imagePaths: controller.imagePaths, imagePaths: controller.imagePaths,
margin: EdgeInsetsDirectional.only( margin: EdgeInsetsDirectional.only(
@@ -54,7 +61,8 @@ class MailboxView extends BaseMailboxView {
isDesktop: isDesktop, isDesktop: isDesktop,
onTapAction: () => controller onTapAction: () => controller
.mailboxDashBoardController .mailboxDashBoardController
.navigateToPaywall(context), .paywallController
?.navigateToPaywall(context),
); );
} else { } else {
return const SizedBox.shrink(); return const SizedBox.shrink();
@@ -25,9 +25,11 @@ import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart'; import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart'; import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart';
import 'package:jmap_dart_client/jmap/quotas/quota.dart';
import 'package:model/model.dart'; import 'package:model/model.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart'; import 'package:receive_sharing_intent/receive_sharing_intent.dart';
import 'package:rxdart/transformers.dart'; import 'package:rxdart/transformers.dart';
import 'package:server_settings/server_settings/tmail_server_settings_extension.dart';
import 'package:tmail_ui_user/features/base/action/ui_action.dart'; import 'package:tmail_ui_user/features/base/action/ui_action.dart';
import 'package:tmail_ui_user/features/base/mixin/contact_support_mixin.dart'; import 'package:tmail_ui_user/features/base/mixin/contact_support_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart'; import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
@@ -128,7 +130,6 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/select_search_filter_action_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/select_search_filter_action_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/set_error_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/set_error_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/update_current_emails_flags_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/update_current_emails_flags_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_paywall_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/web_auth_redirect_processor_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/web_auth_redirect_processor_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/download/download_task_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/download/download_task_state.dart';
@@ -154,8 +155,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/model/account
import 'package:tmail_ui_user/features/manage_account/presentation/model/manage_account_arguments.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/manage_account_arguments.dart';
import 'package:tmail_ui_user/features/network_connection/presentation/network_connection_controller.dart' import 'package:tmail_ui_user/features/network_connection/presentation/network_connection_controller.dart'
if (dart.library.html) 'package:tmail_ui_user/features/network_connection/presentation/web_network_connection_controller.dart'; if (dart.library.html) 'package:tmail_ui_user/features/network_connection/presentation/web_network_connection_controller.dart';
import 'package:tmail_ui_user/features/paywall/domain/model/paywall_url_pattern.dart'; import 'package:tmail_ui_user/features/paywall/presentation/paywall_controller.dart';
import 'package:tmail_ui_user/features/paywall/domain/state/get_paywall_url_state.dart';
import 'package:tmail_ui_user/features/paywall/presentation/saas_premium_mixin.dart'; import 'package:tmail_ui_user/features/paywall/presentation/saas_premium_mixin.dart';
import 'package:tmail_ui_user/features/push_notification/presentation/controller/web_socket_controller.dart'; import 'package:tmail_ui_user/features/push_notification/presentation/controller/web_socket_controller.dart';
import 'package:tmail_ui_user/features/push_notification/presentation/notification/local_notification_manager.dart'; import 'package:tmail_ui_user/features/push_notification/presentation/notification/local_notification_manager.dart';
@@ -204,7 +204,6 @@ import 'package:tmail_ui_user/main/universal_import/html_stub.dart' as html;
import 'package:tmail_ui_user/main/utils/app_config.dart'; import 'package:tmail_ui_user/main/utils/app_config.dart';
import 'package:tmail_ui_user/main/utils/email_receive_manager.dart'; import 'package:tmail_ui_user/main/utils/email_receive_manager.dart';
import 'package:tmail_ui_user/main/utils/ios_notification_manager.dart'; import 'package:tmail_ui_user/main/utils/ios_notification_manager.dart';
import 'package:server_settings/server_settings/tmail_server_settings_extension.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
class MailboxDashBoardController extends ReloadableController class MailboxDashBoardController extends ReloadableController
@@ -292,6 +291,7 @@ class MailboxDashBoardController extends ReloadableController
final isDrawerOpened = RxBool(false); final isDrawerOpened = RxBool(false);
final isContextMenuOpened = RxBool(false); final isContextMenuOpened = RxBool(false);
final isPopupMenuOpened = RxBool(false); final isPopupMenuOpened = RxBool(false);
final octetsQuota = Rxn<Quota>();
Map<Role, MailboxId> mapDefaultMailboxIdByRole = {}; Map<Role, MailboxId> mapDefaultMailboxIdByRole = {};
Map<MailboxId, PresentationMailbox> mapMailboxById = {}; Map<MailboxId, PresentationMailbox> mapMailboxById = {};
@@ -309,8 +309,7 @@ class MailboxDashBoardController extends ReloadableController
StreamSubscription<DeepLinkData?>? _deepLinkDataStreamSubscription; StreamSubscription<DeepLinkData?>? _deepLinkDataStreamSubscription;
int minInputLengthAutocomplete = AppConfig.defaultMinInputLengthAutocomplete; int minInputLengthAutocomplete = AppConfig.defaultMinInputLengthAutocomplete;
EmailSortOrderType currentSortOrder = SearchEmailFilter.defaultSortOrder; EmailSortOrderType currentSortOrder = SearchEmailFilter.defaultSortOrder;
PaywallUrlPattern? paywallUrlPattern; PaywallController? paywallController;
bool isRetryGetPaywallUrl = false;
final StreamController<Either<Failure, Success>> _progressStateController = final StreamController<Either<Failure, Success>> _progressStateController =
StreamController<Either<Failure, Success>>.broadcast(); StreamController<Either<Failure, Success>>.broadcast();
@@ -377,7 +376,6 @@ class MailboxDashBoardController extends ReloadableController
if (PlatformInfo.isWeb) { if (PlatformInfo.isWeb) {
listSearchFilterScrollController = ScrollController(); listSearchFilterScrollController = ScrollController();
twakeAppManager.setExecutingBeforeReconnect(false); twakeAppManager.setExecutingBeforeReconnect(false);
isRetryGetPaywallUrl = false;
} }
if (PlatformInfo.isIOS) { if (PlatformInfo.isIOS) {
_registerPendingCurrentEmailIdInNotification(); _registerPendingCurrentEmailIdInNotification();
@@ -507,8 +505,6 @@ class MailboxDashBoardController extends ReloadableController
); );
} else if (success is GetStoredEmailSortOrderSuccess) { } else if (success is GetStoredEmailSortOrderSuccess) {
setUpDefaultEmailSortOrder(success.emailSortOrderType); setUpDefaultEmailSortOrder(success.emailSortOrderType);
} else if (success is GetPaywallUrlSuccess) {
loadPaywallUrlSuccess(success.paywallUrlPattern);
} else { } else {
super.handleSuccessViewState(success); super.handleSuccessViewState(success);
} }
@@ -554,25 +550,11 @@ class MailboxDashBoardController extends ReloadableController
tryGetAuthenticatedAccountToUseApp(); tryGetAuthenticatedAccountToUseApp();
} else if (isGetTokenOIDCFailure(failure)) { } else if (isGetTokenOIDCFailure(failure)) {
backToHomeScreen(); backToHomeScreen();
} else if (failure is GetPaywallUrlFailure) {
loadPaywallUrlFailure();
} else { } else {
super.handleFailureViewState(failure); super.handleFailureViewState(failure);
} }
} }
@override
void handleErrorViewState(Object error, StackTrace stackTrace) {
super.handleErrorViewState(error, stackTrace);
isRetryGetPaywallUrl = false;
}
@override
void handleUrgentExceptionOnWeb({Failure? failure, Exception? exception}) {
super.handleUrgentExceptionOnWeb(failure: failure, exception: exception);
isRetryGetPaywallUrl = false;
}
@override @override
void handleUrgentExceptionOnMobile({Failure? failure, Exception? exception}) { void handleUrgentExceptionOnMobile({Failure? failure, Exception? exception}) {
SmartDialog.dismiss(); SmartDialog.dismiss();
@@ -857,7 +839,10 @@ class MailboxDashBoardController extends ReloadableController
getAllSendingEmails(); getAllSendingEmails();
_storeSessionAction(session); _storeSessionAction(session);
} else { } else {
loadPaywallUrl(); paywallController = PaywallController(
ownEmailAddress: ownEmailAddress.value,
);
paywallController?.loadPaywallUrl();
} }
} }
@@ -3314,6 +3299,8 @@ class MailboxDashBoardController extends ReloadableController
_currentEmailState = null; _currentEmailState = null;
_isFirstSessionLoad = false; _isFirstSessionLoad = false;
twakeAppManager.setHasComposer(false); twakeAppManager.setHasComposer(false);
paywallController?.onClose();
paywallController = null;
super.onClose(); super.onClose();
} }
} }
@@ -0,0 +1,23 @@
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
extension ValidatePremiumStorageExtension on MailboxDashBoardController {
bool validatePremiumIsAvailable() {
if (accountId.value == null || sessionCurrent == null) {
return false;
}
return isPremiumAvailable(
accountId: accountId.value,
session: sessionCurrent,
);
}
bool validateUserHasIsAlreadyHighestSubscription() {
if (accountId.value == null || sessionCurrent == null) {
return false;
}
return isAlreadyHighestSubscription(
accountId: accountId.value,
session: sessionCurrent,
);
}
}
@@ -10,6 +10,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/identities/id
import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/manage_account_menu_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/menu/manage_account_menu_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/settings_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/settings_bindings.dart';
import 'package:tmail_ui_user/features/paywall/presentation/paywall_bindings.dart';
import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart'; import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart';
class ManageAccountDashBoardBindings extends BaseBindings { class ManageAccountDashBoardBindings extends BaseBindings {
@@ -41,7 +42,9 @@ class ManageAccountDashBoardBindings extends BaseBindings {
} }
@override @override
void bindingsInteractor() {} void bindingsInteractor() {
PaywallBindings().dependencies();
}
@override @override
void bindingsRepository() { void bindingsRepository() {
@@ -40,6 +40,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/notification/
import 'package:tmail_ui_user/features/manage_account/presentation/preferences/bindings/preferences_bindings.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/storage/storage_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/vacation_controller_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/vacation/vacation_controller_bindings.dart';
import 'package:tmail_ui_user/features/paywall/presentation/paywall_controller.dart';
import 'package:tmail_ui_user/main/error/capability_validator.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/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart'; import 'package:tmail_ui_user/main/routes/app_routes.dart';
@@ -53,6 +54,7 @@ class ManageAccountDashBoardController extends ReloadableController
GetAllVacationInteractor? _getAllVacationInteractor; GetAllVacationInteractor? _getAllVacationInteractor;
UpdateVacationInteractor? _updateVacationInteractor; UpdateVacationInteractor? _updateVacationInteractor;
PaywallController? paywallController;
final accountId = Rxn<AccountId>(); final accountId = Rxn<AccountId>();
final accountMenuItemSelected = AccountMenuItem.profiles.obs; final accountMenuItemSelected = AccountMenuItem.profiles.obs;
@@ -130,6 +132,10 @@ class ManageAccountDashBoardController extends ReloadableController
_setUpMinInputLengthAutocomplete(); _setUpMinInputLengthAutocomplete();
_bindingInteractorForMenuItemView(sessionCurrent, accountId.value); _bindingInteractorForMenuItemView(sessionCurrent, accountId.value);
_getVacationResponse(); _getVacationResponse();
paywallController = PaywallController(
ownEmailAddress: ownEmailAddress.value,
);
paywallController?.loadPaywallUrl();
} }
void _getParametersRouter() { void _getParametersRouter() {
@@ -424,6 +430,8 @@ class ManageAccountDashBoardController extends ReloadableController
if (LogTracking().isEnabled) { if (LogTracking().isEnabled) {
disposeTraceLogDependencies(); disposeTraceLogDependencies();
} }
paywallController?.onClose();
paywallController = null;
super.onClose(); super.onClose();
} }
} }
@@ -1,17 +1,19 @@
import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart'; import 'package:core/presentation/state/success.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/quotas/quota.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/base/base_controller.dart';
import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.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/manage_account/presentation/manage_account_dashboard_controller.dart';
import 'package:tmail_ui_user/features/paywall/presentation/saas_premium_mixin.dart';
import 'package:tmail_ui_user/features/quotas/domain/extensions/list_quotas_extensions.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/state/get_quotas_state.dart';
import 'package:tmail_ui_user/features/quotas/domain/use_case/get_quotas_interactor.dart'; import 'package:tmail_ui_user/features/quotas/domain/use_case/get_quotas_interactor.dart';
class StorageController extends BaseController { class StorageController extends BaseController with SaaSPremiumMixin {
final dashBoardController = Get.find<ManageAccountDashBoardController>(); final dashBoardController = Get.find<ManageAccountDashBoardController>();
final GetQuotasInteractor _getQuotasInteractor; final GetQuotasInteractor _getQuotasInteractor;
@@ -23,7 +25,7 @@ class StorageController extends BaseController {
@override @override
void onReady() { void onReady() {
final accountId = dashBoardController.accountId.value; final accountId = dashBoardController.accountId.value;
if(accountId != null) { if (accountId != null) {
_getQuotasAction(accountId); _getQuotasAction(accountId);
} else { } else {
consumeState( consumeState(
@@ -43,8 +45,18 @@ class StorageController extends BaseController {
octetsQuota.value = success.quotas.octetsQuota; octetsQuota.value = success.quotas.octetsQuota;
} }
void onUpgradeStorage() { bool validatePremiumIsAvailable() {
final accountId = dashBoardController.accountId.value;
final session = dashBoardController.sessionCurrent;
if (accountId == null || session == null) {
return false;
}
return isPremiumAvailable(accountId: accountId, session: session);
}
void onUpgradeStorage(BuildContext context) {
dashBoardController.paywallController?.navigateToPaywall(context);
} }
@override @override
@@ -1,4 +1,5 @@
import 'package:core/presentation/utils/theme_utils.dart'; import 'package:core/presentation/utils/theme_utils.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.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/base/setting_detail_view_builder.dart';
@@ -77,11 +78,19 @@ class StorageView extends GetWidget<StorageController> {
quota: octetsQuota, quota: octetsQuota,
isMobile: isMobile, isMobile: isMobile,
), ),
UpgradeStorageWidget( Obx(() {
imagePaths: controller.imagePaths, if (controller.validatePremiumIsAvailable() &&
isMobile: isMobile, PlatformInfo.isWeb) {
onUpgradeStorageAction: controller.onUpgradeStorage, return UpgradeStorageWidget(
) imagePaths: controller.imagePaths,
isMobile: isMobile,
onUpgradeStorageAction: () =>
controller.onUpgradeStorage(context),
);
} else {
return const SizedBox.shrink();
}
})
], ],
), ),
), ),
@@ -1,34 +1,24 @@
import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/paywall/domain/model/paywall_url_pattern.dart'; import 'package:tmail_ui_user/features/paywall/domain/model/paywall_url_pattern.dart';
import 'package:tmail_ui_user/features/paywall/domain/state/get_paywall_url_state.dart';
import 'package:tmail_ui_user/features/paywall/domain/usecases/get_paywall_url_interactor.dart'; import 'package:tmail_ui_user/features/paywall/domain/usecases/get_paywall_url_interactor.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/main/routes/route_utils.dart'; import 'package:tmail_ui_user/main/routes/route_utils.dart';
import 'package:tmail_ui_user/main/utils/app_utils.dart'; import 'package:tmail_ui_user/main/utils/app_utils.dart';
extension HandlePaywallExtension on MailboxDashBoardController { class PaywallController extends BaseController {
bool validatePremiumIsAvailable() { final String ownEmailAddress;
if (accountId.value == null || sessionCurrent == null) {
return false;
}
return isPremiumAvailable(
accountId: accountId.value,
session: sessionCurrent,
);
}
bool validateUserHasIsAlreadyHighestSubscription() { PaywallUrlPattern? paywallUrlPattern;
if (accountId.value == null || sessionCurrent == null) { bool isRetryGetPaywallUrl = false;
return false;
} PaywallController({required this.ownEmailAddress});
return isAlreadyHighestSubscription(
accountId: accountId.value,
session: sessionCurrent,
);
}
void loadPaywallUrl() { void loadPaywallUrl() {
final getPaywallUrlInteractor = getBinding<GetPaywallUrlInteractor>(); final getPaywallUrlInteractor = getBinding<GetPaywallUrlInteractor>();
@@ -50,7 +40,7 @@ extension HandlePaywallExtension on MailboxDashBoardController {
if (isRetryGetPaywallUrl) { if (isRetryGetPaywallUrl) {
isRetryGetPaywallUrl = false; isRetryGetPaywallUrl = false;
final qualifiedPaywall = paywallUrlPattern!.getQualifiedUrl( final qualifiedPaywall = paywallUrlPattern!.getQualifiedUrl(
ownerEmail: ownEmailAddress.value, ownerEmail: ownEmailAddress,
domainName: RouteUtils.getRootDomain(), domainName: RouteUtils.getRootDomain(),
); );
AppUtils.launchLink(qualifiedPaywall); AppUtils.launchLink(qualifiedPaywall);
@@ -100,7 +90,7 @@ extension HandlePaywallExtension on MailboxDashBoardController {
} }
final qualifiedPaywall = paywallUrlPattern!.getQualifiedUrl( final qualifiedPaywall = paywallUrlPattern!.getQualifiedUrl(
ownerEmail: ownEmailAddress.value, ownerEmail: ownEmailAddress,
domainName: RouteUtils.getRootDomain(), domainName: RouteUtils.getRootDomain(),
); );
@@ -111,4 +101,41 @@ extension HandlePaywallExtension on MailboxDashBoardController {
isRetryGetPaywallUrl = true; isRetryGetPaywallUrl = true;
loadPaywallUrl(); loadPaywallUrl();
} }
@override
void handleSuccessViewState(Success success) {
if (success is GetPaywallUrlSuccess) {
loadPaywallUrlSuccess(success.paywallUrlPattern);
} else {
super.handleSuccessViewState(success);
}
}
@override
void handleFailureViewState(Failure failure) {
if (failure is GetPaywallUrlFailure) {
loadPaywallUrlFailure();
} else {
super.handleFailureViewState(failure);
}
}
@override
void handleErrorViewState(Object error, StackTrace stackTrace) {
super.handleErrorViewState(error, stackTrace);
isRetryGetPaywallUrl = false;
}
@override
void handleUrgentExceptionOnWeb({Failure? failure, Exception? exception}) {
super.handleUrgentExceptionOnWeb(failure: failure, exception: exception);
isRetryGetPaywallUrl = false;
}
@override
void onClose() {
paywallUrlPattern = null;
isRetryGetPaywallUrl = false;
super.onClose();
}
} }
@@ -1,16 +1,8 @@
import 'package:collection/collection.dart';
import 'package:core/utils/app_logger.dart';
import 'package:jmap_dart_client/jmap/quotas/data_types.dart'; import 'package:jmap_dart_client/jmap/quotas/data_types.dart';
import 'package:jmap_dart_client/jmap/quotas/quota.dart'; import 'package:jmap_dart_client/jmap/quotas/quota.dart';
extension ListQuotasExtensions on List<Quota> { extension ListQuotasExtensions on List<Quota> {
Quota? get octetsQuota =>
Quota? get octetsQuota { firstWhereOrNull((quota) => quota.resourceType == ResourceType.octets);
try {
return firstWhere((quota) => quota.resourceType == ResourceType.octets);
} catch(e) {
logError('ListQuotasExtensions::octetsQuota: Not found octets quota');
return null;
}
}
} }
@@ -51,7 +51,7 @@ extension QuotasExtensions on Quota {
bool get isStorageUsageIndicatorAppear { bool get isStorageUsageIndicatorAppear {
if (storageAvailable) { if (storageAvailable) {
return used!.value <= presentationHardLimit!.value * 0.8; return used!.value > presentationHardLimit!.value * 0.8;
} else { } else {
return false; return false;
} }
@@ -1,13 +1,15 @@
import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart'; import 'package:core/presentation/state/success.dart';
import 'package:core/utils/app_logger.dart';
import 'package:dartz/dartz.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart'; import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.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/base/base_controller.dart';
import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_paywall_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/validate_premium_storage_extension.dart';
import 'package:tmail_ui_user/features/quotas/domain/extensions/list_quotas_extensions.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/state/get_quotas_state.dart';
import 'package:tmail_ui_user/features/quotas/domain/use_case/get_quotas_interactor.dart'; import 'package:tmail_ui_user/features/quotas/domain/use_case/get_quotas_interactor.dart';
@@ -19,7 +21,6 @@ class QuotasController extends BaseController {
final GetQuotasInteractor _getQuotasInteractor; final GetQuotasInteractor _getQuotasInteractor;
final octetsQuota = Rxn<Quota>();
final isBannerEnabled = RxBool(false); final isBannerEnabled = RxBool(false);
late Worker accountIdListener; late Worker accountIdListener;
@@ -31,26 +32,39 @@ class QuotasController extends BaseController {
} }
void _handleGetQuotasSuccess(GetQuotasSuccess success) { void _handleGetQuotasSuccess(GetQuotasSuccess success) {
octetsQuota.value = success.quotas.octetsQuota; log('$runtimeType::_handleGetQuotasSuccess: Quotas is ${success.quotas}');
mailboxDashBoardController.octetsQuota.value = success.quotas.octetsQuota;
isBannerEnabled.value = true; isBannerEnabled.value = true;
} }
void _initWorker() { void _initWorker() {
accountIdListener = ever(mailboxDashBoardController.accountId, (accountId) { accountIdListener = ever(
final session = mailboxDashBoardController.sessionCurrent; mailboxDashBoardController.accountId,
if (accountId is AccountId && (_) => reloadQuota(),
session != null && );
CapabilityIdentifier.jmapQuota.isSupported(session, accountId) }
) {
_getQuotasAction(accountId); bool get isStorageCapabilitySupported {
} final accountId = mailboxDashBoardController.accountId.value;
}); final session = mailboxDashBoardController.sessionCurrent;
if (accountId != null && session != null) {
return CapabilityIdentifier.jmapQuota.isSupported(session, accountId);
} else {
return false;
}
} }
void reloadQuota() { void reloadQuota() {
if (mailboxDashBoardController.accountId.value == null) return; if (isStorageCapabilitySupported) {
_getQuotasAction(mailboxDashBoardController.accountId.value!);
_getQuotasAction(mailboxDashBoardController.accountId.value!); } else {
consumeState(
Stream.value(
Left(GetQuotasFailure(NotFoundAccountIdException())),
),
);
}
} }
@override @override
@@ -77,6 +91,8 @@ class QuotasController extends BaseController {
@override @override
void handleFailureViewState(Failure failure) { void handleFailureViewState(Failure failure) {
if (failure is GetQuotasFailure) { if (failure is GetQuotasFailure) {
logError('$runtimeType::handleFailureViewState');
mailboxDashBoardController.octetsQuota.value = null;
isBannerEnabled.value = true; isBannerEnabled.value = true;
} else { } else {
super.handleFailureViewState(failure); super.handleFailureViewState(failure);
@@ -89,7 +105,7 @@ class QuotasController extends BaseController {
} }
void handleManageMyStorage(BuildContext context) { void handleManageMyStorage(BuildContext context) {
mailboxDashBoardController.navigateToPaywall(context); mailboxDashBoardController.paywallController?.navigateToPaywall(context);
} }
void closeBanner() { void closeBanner() {
@@ -17,7 +17,7 @@ class QuotasView extends GetWidget<QuotasController> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Obx(() { return Obx(() {
final octetQuota = controller.octetsQuota.value; final octetQuota = controller.mailboxDashBoardController.octetsQuota.value;
bool isDesktop = controller.responsiveUtils.isDesktop(context); bool isDesktop = controller.responsiveUtils.isDesktop(context);
if (octetQuota != null && octetQuota.isStorageUsageIndicatorAppear) { if (octetQuota != null && octetQuota.isStorageUsageIndicatorAppear) {
@@ -18,7 +18,10 @@ class QuotasBannerWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Obx(() { return Obx(() {
final octetQuota = _quotasController.octetsQuota.value; final octetQuota = _quotasController
.mailboxDashBoardController
.octetsQuota
.value;
if (octetQuota != null && if (octetQuota != null &&
octetQuota.allowedDisplayToQuotaBanner && octetQuota.allowedDisplayToQuotaBanner &&