From 91b078bddfa598d70d94539cfac2580bf7c7f590 Mon Sep 17 00:00:00 2001 From: Mati Date: Tue, 26 Sep 2023 17:15:54 -0300 Subject: [PATCH 1/2] feat(snapshot & upload): makes no balance message be part of payment method selector and not to be shown when turbo free uploads; makes the button be disabled when no balance PE-4676 --- .../create_snapshot_cubit.dart | 50 +++--- lib/components/create_snapshot_dialog.dart | 5 + .../payment_method_selector_widget.dart | 121 ++++++++++++- lib/components/upload_form.dart | 164 +++--------------- 4 files changed, 175 insertions(+), 165 deletions(-) diff --git a/lib/blocs/create_snapshot/create_snapshot_cubit.dart b/lib/blocs/create_snapshot/create_snapshot_cubit.dart index edb04a2148..2133d43a16 100644 --- a/lib/blocs/create_snapshot/create_snapshot_cubit.dart +++ b/lib/blocs/create_snapshot/create_snapshot_cubit.dart @@ -135,6 +135,7 @@ class CreateSnapshotCubit extends Cubit { _computeIsSufficientBalance(); _computeIsTurboEnabled(); _computeIsFreeThanksToTurbo(); + _computeIsButtonEnabled(); await _emitConfirming( dataSize: data.length, @@ -461,34 +462,35 @@ class CreateSnapshotCubit extends Cubit { logger.d('Upload method set to $method'); _uploadMethod = method; - _refreshIsButtonEnabled(); + _computeIsButtonEnabled(); + if (state is ConfirmingSnapshotCreation) { + final stateAsConfirming = state as ConfirmingSnapshotCreation; + emit( + stateAsConfirming.copyWith( + uploadMethod: method, + isButtonToUploadEnabled: _isButtonToUploadEnabled, + ), + ); + } } - void _refreshIsButtonEnabled() { + void _computeIsButtonEnabled() { _isButtonToUploadEnabled = false; - if (state is ConfirmingSnapshotCreation) { - final stateAsConfirming = state as ConfirmingSnapshotCreation; - logger.d('Sufficient Balance To Pay With AR: $_sufficientArBalance'); - - if (_uploadMethod == UploadMethod.ar && _sufficientArBalance) { - logger.d('Enabling button for AR payment method'); - _isButtonToUploadEnabled = true; - } else if (_uploadMethod == UploadMethod.turbo && - stateAsConfirming.isTurboUploadPossible && - _sufficentCreditsBalance) { - logger.d('Enabling button for Turbo payment method'); - _isButtonToUploadEnabled = true; - } else if (stateAsConfirming.isFreeThanksToTurbo) { - logger.d('Enabling button for free upload using Turbo'); - _isButtonToUploadEnabled = true; - } else { - logger.d('Disabling button'); - } - emit(stateAsConfirming.copyWith( - uploadMethod: _uploadMethod, - isButtonToUploadEnabled: _isButtonToUploadEnabled, - )); + logger.d('Sufficient Balance To Pay With AR: $_sufficientArBalance'); + if (_uploadMethod == UploadMethod.ar && _sufficientArBalance) { + logger.d('Enabling button for AR payment method'); + _isButtonToUploadEnabled = true; + } else if (_uploadMethod == UploadMethod.turbo && + _isTurboUploadPossible && + _sufficentCreditsBalance) { + logger.d('Enabling button for Turbo payment method'); + _isButtonToUploadEnabled = true; + } else if (_isFreeThanksToTurbo) { + logger.d('Enabling button for free upload using Turbo'); + _isButtonToUploadEnabled = true; + } else { + logger.d('Disabling button'); } } diff --git a/lib/components/create_snapshot_dialog.dart b/lib/components/create_snapshot_dialog.dart index e653d6ebcd..a3a7a40c18 100644 --- a/lib/components/create_snapshot_dialog.dart +++ b/lib/components/create_snapshot_dialog.dart @@ -407,7 +407,11 @@ Widget _confirmDialog( hasNoTurboBalance: state.hasNoTurboBalance, isTurboUploadPossible: true, arBalance: state.arBalance, + sufficientArBalance: state.sufficientBalanceToPayWithAr, turboCredits: state.turboCredits, + sufficentCreditsBalance: + state.sufficientBalanceToPayWithTurbo, + isFreeThanksToTurbo: false, onTurboTopupSucess: () { createSnapshotCubit .setUploadMethod(UploadMethod.turbo); @@ -444,6 +448,7 @@ Widget _confirmDialog( await createSnapshotCubit.confirmSnapshotCreation(), }, title: appLocalizationsOf(context).uploadEmphasized, + isEnable: state.isButtonToUploadEnabled, ), } ], diff --git a/lib/components/payment_method_selector_widget.dart b/lib/components/payment_method_selector_widget.dart index 49f577e5d5..cc188de72d 100644 --- a/lib/components/payment_method_selector_widget.dart +++ b/lib/components/payment_method_selector_widget.dart @@ -12,7 +12,10 @@ class PaymentMethodSelector extends StatelessWidget { final bool hasNoTurboBalance; final bool isTurboUploadPossible; final String arBalance; + final bool sufficientArBalance; final String turboCredits; + final bool sufficentCreditsBalance; + final bool isFreeThanksToTurbo; final void Function() onTurboTopupSucess; final void Function() onArSelect; final void Function() onTurboSelect; @@ -25,7 +28,10 @@ class PaymentMethodSelector extends StatelessWidget { required this.hasNoTurboBalance, required this.isTurboUploadPossible, required this.arBalance, + required this.sufficientArBalance, required this.turboCredits, + required this.sufficentCreditsBalance, + required this.isFreeThanksToTurbo, required this.onTurboTopupSucess, required this.onArSelect, required this.onTurboSelect, @@ -33,7 +39,15 @@ class PaymentMethodSelector extends StatelessWidget { @override Widget build(context) { - return _buildContent(context); + return Column( + children: [ + if (!isFreeThanksToTurbo) ...[ + _buildContent(context), + const SizedBox(height: 16), + _getInsufficientBalanceMessage(context: context), + ], + ], + ); } Widget _buildContent(BuildContext context) { @@ -146,4 +160,109 @@ class PaymentMethodSelector extends StatelessWidget { ], ); } + + Widget _getInsufficientBalanceMessage({ + required BuildContext context, + }) { + if (uploadMethod == UploadMethod.turbo && + !sufficentCreditsBalance && + sufficientArBalance) { + return GestureDetector( + onTap: () { + showTurboTopupModal(context, onSuccess: () { + onTurboTopupSucess(); + }); + }, + child: ArDriveClickArea( + child: Text.rich( + TextSpan( + text: 'Insufficient Credit balance for purchase. ', + style: ArDriveTypography.body.captionBold( + color: + ArDriveTheme.of(context).themeData.colors.themeErrorDefault, + ), + children: [ + TextSpan( + text: 'Add Credits', + style: ArDriveTypography.body + .captionBold( + color: ArDriveTheme.of(context) + .themeData + .colors + .themeErrorDefault, + ) + .copyWith(decoration: TextDecoration.underline), + ), + TextSpan( + text: ' to use Turbo.', + style: ArDriveTypography.body.captionBold( + color: ArDriveTheme.of(context) + .themeData + .colors + .themeErrorDefault, + ), + ), + ], + ), + ), + ), + ); + } else if (uploadMethod == UploadMethod.ar && !sufficientArBalance) { + return Text( + 'Insufficient AR balance for purchase.', + style: ArDriveTypography.body.captionBold( + color: ArDriveTheme.of(context).themeData.colors.themeErrorDefault, + ), + ); + } else if (!sufficentCreditsBalance && !sufficientArBalance) { + return GestureDetector( + onTap: () { + showTurboTopupModal(context, onSuccess: () { + onTurboTopupSucess(); + }); + }, + child: ArDriveClickArea( + child: RichText( + text: TextSpan( + children: [ + TextSpan( + text: + 'Insufficient balance to pay for this upload. You can either', + style: ArDriveTypography.body.captionBold( + color: ArDriveTheme.of(context) + .themeData + .colors + .themeErrorDefault, + ), + ), + TextSpan( + text: ' add Turbo credits to your profile', + style: ArDriveTypography.body + .captionBold( + color: ArDriveTheme.of(context) + .themeData + .colors + .themeErrorDefault, + ) + .copyWith( + decoration: TextDecoration.underline, + ), + ), + TextSpan( + text: ' or use AR', + style: ArDriveTypography.body.captionBold( + color: ArDriveTheme.of(context) + .themeData + .colors + .themeErrorDefault, + ), + ), + ], + ), + ), + ), + ); + } + return const SizedBox(); + } } diff --git a/lib/components/upload_form.dart b/lib/components/upload_form.dart index 489bf5f454..82f7186e64 100644 --- a/lib/components/upload_form.dart +++ b/lib/components/upload_form.dart @@ -17,7 +17,6 @@ import 'package:ardrive/services/services.dart'; import 'package:ardrive/theme/theme.dart'; import 'package:ardrive/turbo/services/payment_service.dart'; import 'package:ardrive/turbo/services/upload_service.dart'; -import 'package:ardrive/turbo/topup/views/topup_modal.dart'; import 'package:ardrive/turbo/turbo.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; import 'package:ardrive/utils/filesize.dart'; @@ -496,37 +495,32 @@ class _UploadFormState extends State { height: 8, ), }, - if (!state.isFreeThanksToTurbo) - PaymentMethodSelector( - uploadMethod: state.uploadMethod, - costEstimateTurbo: state.costEstimateTurbo, - costEstimateAr: state.costEstimateAr, - hasNoTurboBalance: state.isZeroBalance, - isTurboUploadPossible: state.isTurboUploadPossible, - arBalance: state.arBalance, - turboCredits: state.turboCredits, - onArSelect: () { - context - .read() - .setUploadMethod(UploadMethod.ar); - }, - onTurboSelect: () { - context - .read() - .setUploadMethod(UploadMethod.turbo); - }, - onTurboTopupSucess: () { - context.read().startUploadPreparation( - isRetryingToPayWithTurbo: true, - ); - }, - ), - const SizedBox( - height: 16, - ), - _getInsufficientBalanceMessage( + PaymentMethodSelector( + uploadMethod: state.uploadMethod, + costEstimateTurbo: state.costEstimateTurbo, + costEstimateAr: state.costEstimateAr, + hasNoTurboBalance: state.isZeroBalance, + isTurboUploadPossible: state.isTurboUploadPossible, + arBalance: state.arBalance, sufficientArBalance: state.sufficientArBalance, + turboCredits: state.turboCredits, sufficentCreditsBalance: state.sufficentCreditsBalance, + isFreeThanksToTurbo: state.isFreeThanksToTurbo, + onArSelect: () { + context + .read() + .setUploadMethod(UploadMethod.ar); + }, + onTurboSelect: () { + context + .read() + .setUploadMethod(UploadMethod.turbo); + }, + onTurboTopupSucess: () { + context.read().startUploadPreparation( + isRetryingToPayWithTurbo: true, + ); + }, ), ], ), @@ -756,114 +750,4 @@ class _UploadFormState extends State { return const SizedBox(); }, ); - - Widget _getInsufficientBalanceMessage({ - required bool sufficientArBalance, - required bool sufficentCreditsBalance, - }) { - if (_uploadMethod == UploadMethod.turbo && - !sufficentCreditsBalance && - sufficientArBalance) { - return GestureDetector( - onTap: () { - showTurboTopupModal(context, onSuccess: () { - context.read().startUploadPreparation( - isRetryingToPayWithTurbo: true, - ); - }); - }, - child: ArDriveClickArea( - child: Text.rich( - TextSpan( - text: 'Insufficient Credit balance for purchase. ', - style: ArDriveTypography.body.captionBold( - color: - ArDriveTheme.of(context).themeData.colors.themeErrorDefault, - ), - children: [ - TextSpan( - text: 'Add Credits', - style: ArDriveTypography.body - .captionBold( - color: ArDriveTheme.of(context) - .themeData - .colors - .themeErrorDefault, - ) - .copyWith(decoration: TextDecoration.underline), - ), - TextSpan( - text: ' to use Turbo.', - style: ArDriveTypography.body.captionBold( - color: ArDriveTheme.of(context) - .themeData - .colors - .themeErrorDefault, - ), - ), - ], - ), - ), - ), - ); - } else if (_uploadMethod == UploadMethod.ar && !sufficientArBalance) { - return Text( - 'Insufficient AR balance for purchase.', - style: ArDriveTypography.body.captionBold( - color: ArDriveTheme.of(context).themeData.colors.themeErrorDefault, - ), - ); - } else if (!sufficentCreditsBalance && !sufficientArBalance) { - return GestureDetector( - onTap: () { - showTurboTopupModal(context, onSuccess: () { - context.read().startUploadPreparation( - isRetryingToPayWithTurbo: true, - ); - }); - }, - child: ArDriveClickArea( - child: RichText( - text: TextSpan( - children: [ - TextSpan( - text: - 'Insufficient balance to pay for this upload. You can either', - style: ArDriveTypography.body.captionBold( - color: ArDriveTheme.of(context) - .themeData - .colors - .themeErrorDefault, - ), - ), - TextSpan( - text: ' add Turbo credits to your profile', - style: ArDriveTypography.body - .captionBold( - color: ArDriveTheme.of(context) - .themeData - .colors - .themeErrorDefault, - ) - .copyWith( - decoration: TextDecoration.underline, - ), - ), - TextSpan( - text: ' or use AR', - style: ArDriveTypography.body.captionBold( - color: ArDriveTheme.of(context) - .themeData - .colors - .themeErrorDefault, - ), - ), - ], - ), - ), - ), - ); - } - return const SizedBox(); - } } From 1a2e618fe3609c9e27b21dd8e59dae05f605ab28 Mon Sep 17 00:00:00 2001 From: Mati Date: Tue, 26 Sep 2023 17:49:04 -0300 Subject: [PATCH 2/2] feat(upload cubit): makes the file upload modal show the correct not enough balance message PE-4676 --- lib/blocs/upload/upload_cubit.dart | 2 +- lib/blocs/upload/upload_state.dart | 31 ++++++++++++++++++++++++++++++ lib/components/upload_form.dart | 3 --- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/lib/blocs/upload/upload_cubit.dart b/lib/blocs/upload/upload_cubit.dart index dd1faea622..84e28317f1 100644 --- a/lib/blocs/upload/upload_cubit.dart +++ b/lib/blocs/upload/upload_cubit.dart @@ -71,7 +71,7 @@ class UploadCubit extends Cubit { logger.d('Disabling button'); } - emit((state as UploadReady).copyWith( + emit(uploadReady.copyWith( uploadMethod: method, isButtonToUploadEnabled: isButtonEnabled, )); diff --git a/lib/blocs/upload/upload_state.dart b/lib/blocs/upload/upload_state.dart index 0016b3a182..d3096eeea8 100644 --- a/lib/blocs/upload/upload_state.dart +++ b/lib/blocs/upload/upload_state.dart @@ -155,11 +155,42 @@ class UploadReady extends UploadState { @override List get props => [ costEstimateAr, + costEstimateTurbo, sufficientArBalance, + isZeroBalance, + sufficentCreditsBalance, + uploadIsPublic, uploadPlanForAR, + uploadPlanForTurbo, + isTurboUploadPossible, isFreeThanksToTurbo, + uploadSize, + credits, + arBalance, + turboCredits, + uploadMethod, isButtonToUploadEnabled, ]; + + @override + toString() => 'UploadReady { ' + 'costEstimateAr: $costEstimateAr, ' + 'costEstimateTurbo: $costEstimateTurbo, ' + 'sufficientArBalance: $sufficientArBalance, ' + 'isZeroBalance: $isZeroBalance, ' + 'sufficentCreditsBalance: $sufficentCreditsBalance, ' + 'uploadIsPublic: $uploadIsPublic, ' + 'uploadPlanForAR: $uploadPlanForAR, ' + 'uploadPlanForTurbo: $uploadPlanForTurbo, ' + 'isTurboUploadPossible: $isTurboUploadPossible, ' + 'isFreeThanksToTurbo: $isFreeThanksToTurbo, ' + 'uploadSize: $uploadSize, ' + 'credits: $credits, ' + 'arBalance: $arBalance, ' + 'turboCredits: $turboCredits, ' + 'uploadMethod: $uploadMethod, ' + 'isButtonToUploadEnabled: $isButtonToUploadEnabled, ' + '}'; } class UploadInProgress extends UploadState { diff --git a/lib/components/upload_form.dart b/lib/components/upload_form.dart index 82f7186e64..92b89c825b 100644 --- a/lib/components/upload_form.dart +++ b/lib/components/upload_form.dart @@ -135,7 +135,6 @@ class UploadForm extends StatefulWidget { class _UploadFormState extends State { final _scrollController = ScrollController(); - UploadMethod? _uploadMethod; @override Widget build(BuildContext context) => BlocConsumer( @@ -338,8 +337,6 @@ class _UploadFormState extends State { final numberOfV2Files = state.uploadPlanForAR.fileV2UploadHandles.length; - _uploadMethod = state.uploadMethod; - logger.d( ' is button to upload enabled: ${state.isButtonToUploadEnabled}', );