From db43a1d7f8989d8501a43c6021e08fc81185d8b4 Mon Sep 17 00:00:00 2001 From: otsmr Date: Sat, 10 May 2025 17:13:17 +0200 Subject: [PATCH] redeem twonly-codes --- lib/src/localization/app_de.arb | 2 + lib/src/localization/app_en.arb | 3 +- .../generated/app_localizations.dart | 12 ++- .../generated/app_localizations_de.dart | 5 +- .../generated/app_localizations_en.dart | 5 +- lib/src/providers/api_provider.dart | 7 ++ .../subscription/subscription_view.dart | 86 ++++++++++++++++++- 7 files changed, 110 insertions(+), 10 deletions(-) diff --git a/lib/src/localization/app_de.arb b/lib/src/localization/app_de.arb index a8e52b0..b506780 100644 --- a/lib/src/localization/app_de.arb +++ b/lib/src/localization/app_de.arb @@ -193,6 +193,8 @@ "createVoucher": "Gutschein kaufen", "createVoucherDesc": "Wähle den Wert des Gutscheins. Der Wert des Gutschein wird von deinem twonly-Guthaben abgezogen.", "redeemVoucher": "Gutschein einlösen", + "redeemUserInviteCodeTitle": "twonly-Code einlösen", + "redeemUserInviteCodeSuccess": "Dein Plan wurde erfolgreich angepasst.", "voucherCreated": "Gutschein wurde erstellt", "openVouchers": "Offene Gutscheine", "enterVoucherCode": "Gutschein Code eingeben", diff --git a/lib/src/localization/app_en.arb b/lib/src/localization/app_en.arb index 18dd719..1b2b1e0 100644 --- a/lib/src/localization/app_en.arb +++ b/lib/src/localization/app_en.arb @@ -336,7 +336,8 @@ "familyFeature1": "✓ Unlimited media file uploads", "familyFeature2": "4 additional Plus users", "familyFeature3": "4 additional Free users", - "redeemUserInviteCode": "Or redeem an additional user invite code.", + "redeemUserInviteCodeTitle": "Redeem twonly-Code", + "redeemUserInviteCodeSuccess": "Your plan has been successfully adjusted.", "freeFeature1": "3 Media file uploads per day", "plusFeature1": "✓ Unlimited media file uploads", "transactionHistory": "Your transaction history", diff --git a/lib/src/localization/generated/app_localizations.dart b/lib/src/localization/generated/app_localizations.dart index 2ea19c6..7ac16da 100644 --- a/lib/src/localization/generated/app_localizations.dart +++ b/lib/src/localization/generated/app_localizations.dart @@ -1079,11 +1079,17 @@ abstract class AppLocalizations { /// **'4 additional Free users'** String get familyFeature3; - /// No description provided for @redeemUserInviteCode. + /// No description provided for @redeemUserInviteCodeTitle. /// /// In en, this message translates to: - /// **'Or redeem an additional user invite code.'** - String get redeemUserInviteCode; + /// **'Redeem twonly-Code'** + String get redeemUserInviteCodeTitle; + + /// No description provided for @redeemUserInviteCodeSuccess. + /// + /// In en, this message translates to: + /// **'Your plan has been successfully adjusted.'** + String get redeemUserInviteCodeSuccess; /// No description provided for @freeFeature1. /// diff --git a/lib/src/localization/generated/app_localizations_de.dart b/lib/src/localization/generated/app_localizations_de.dart index fd52500..ddf535a 100644 --- a/lib/src/localization/generated/app_localizations_de.dart +++ b/lib/src/localization/generated/app_localizations_de.dart @@ -513,7 +513,10 @@ class AppLocalizationsDe extends AppLocalizations { String get familyFeature3 => '4 zusätzliche kostenlose Benutzer'; @override - String get redeemUserInviteCode => 'Oder löse einen zusätzlichen twonly-Code ein.'; + String get redeemUserInviteCodeTitle => 'twonly-Code einlösen'; + + @override + String get redeemUserInviteCodeSuccess => 'Dein Plan wurde erfolgreich angepasst.'; @override String get freeFeature1 => '3 Medien-Datei-Uploads pro Tag'; diff --git a/lib/src/localization/generated/app_localizations_en.dart b/lib/src/localization/generated/app_localizations_en.dart index 980f50e..1a0c3b3 100644 --- a/lib/src/localization/generated/app_localizations_en.dart +++ b/lib/src/localization/generated/app_localizations_en.dart @@ -513,7 +513,10 @@ class AppLocalizationsEn extends AppLocalizations { String get familyFeature3 => '4 additional Free users'; @override - String get redeemUserInviteCode => 'Or redeem an additional user invite code.'; + String get redeemUserInviteCodeTitle => 'Redeem twonly-Code'; + + @override + String get redeemUserInviteCodeSuccess => 'Your plan has been successfully adjusted.'; @override String get freeFeature1 => '3 Media file uploads per day'; diff --git a/lib/src/providers/api_provider.dart b/lib/src/providers/api_provider.dart index 6f65f6b..d0d81b3 100644 --- a/lib/src/providers/api_provider.dart +++ b/lib/src/providers/api_provider.dart @@ -486,6 +486,13 @@ class ApiProvider { return await sendRequestSync(req); } + Future redeemUserInviteCode(String inviteCode) async { + var get = ApplicationData_RedeemAdditionalCode()..inviteCode = inviteCode; + var appData = ApplicationData()..redeemadditionalcode = get; + var req = createClientToServerFromApplicationData(appData); + return await sendRequestSync(req); + } + Future updateFCMToken(String googleFcm) async { var get = ApplicationData_UpdateGoogleFcmToken()..googleFcm = googleFcm; var appData = ApplicationData()..updategooglefcmtoken = get; diff --git a/lib/src/views/settings/subscription/subscription_view.dart b/lib/src/views/settings/subscription/subscription_view.dart index 2d4ab36..f65487a 100644 --- a/lib/src/views/settings/subscription/subscription_view.dart +++ b/lib/src/views/settings/subscription/subscription_view.dart @@ -72,8 +72,10 @@ int calculateRefund(Response_PlanBallance current) { // => 5€ refund = (((YEARLY_PAYMENT_DAYS - elapsedDays) / YEARLY_PAYMENT_DAYS) * - getPlanPrice("Pro", false)) - .ceil(); + getPlanPrice("Pro", false) / + 100) + .ceil() * + 100; } } return refund; @@ -211,11 +213,17 @@ class _SubscriptionViewState extends State { if (currentPlan != "Free") PlanCard( planId: "Free", - onTap: () {}, + onTap: () async { + await redeemUserInviteCode(context, "Free"); + initAsync(); + }, ), PlanCard( planId: "Plus", - onTap: () {}, + onTap: () async { + await redeemUserInviteCode(context, "Plus"); + initAsync(); + }, ), ], SizedBox(height: 10), @@ -433,3 +441,73 @@ class PlanCard extends StatelessWidget { ); } } + +Future redeemUserInviteCode(BuildContext context, String newPlan) async { + String inviteCode = ''; + await showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text(context.lang.redeemUserInviteCodeTitle), + content: StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: TextField( + onChanged: (value) { + // Convert to uppercase + setState(() { + inviteCode = value.toUpperCase(); + }); + }, + decoration: InputDecoration( + labelText: context.lang.registerTwonlyCodeLabel, + border: OutlineInputBorder(), + ), + // Set the text to be uppercase + textCapitalization: TextCapitalization.characters, + ), + ), + ], + ), + ); + }, + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text(context.lang.cancel), + ), + TextButton( + onPressed: () async { + final res = await apiProvider.redeemUserInviteCode(inviteCode); + if (!context.mounted) return; + if (res.isSuccess) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(context.lang.redeemUserInviteCodeSuccess)), + ); + // reconnect to load new plan. + apiProvider.close(() { + apiProvider.connect(); + }); + } else { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(errorCodeToText(context, res.error))), + ); + } + Navigator.of(context).pop(); + }, + child: Text(context.lang.ok), + ), + ], + ); + }, + ); +}