chore: add loading state to subscription controller, act as if user is subscribed if loading (#2148)

This commit is contained in:
ggurdin 2025-03-17 12:16:18 -04:00 committed by GitHub
parent 91699dda04
commit 69ea5f2e44
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 49 additions and 50 deletions

View file

@ -1870,8 +1870,6 @@ class ChatController extends State<ChatPageWithRoom>
child: overlayEntry!,
transformTargetId: "",
backgroundColor: Colors.black,
closePrevOverlay:
MatrixState.pangeaController.subscriptionController.isSubscribed,
position: OverlayPositionEnum.centered,
onDismiss: clearSelectedEvents,
blurBackground: true,

View file

@ -97,11 +97,12 @@ class Choreographer {
return;
}
if (!pangeaController.subscriptionController.isSubscribed) {
final isSubscribed = pangeaController.subscriptionController.isSubscribed;
if (isSubscribed != null && !isSubscribed) {
// don't want to run IGC if user isn't subscribed, so either
// show the paywall if applicable or just send the message
final status = pangeaController.subscriptionController.subscriptionStatus;
status == SubscriptionStatus.showPaywall
status == SubscriptionStatus.shouldShowPaywall
? OverlayUtil.showPositionedCard(
context: context,
cardToShow: PaywallCard(
@ -680,7 +681,8 @@ class Choreographer {
);
AssistanceState get assistanceState {
if (!pangeaController.subscriptionController.isSubscribed) {
final isSubscribed = pangeaController.subscriptionController.isSubscribed;
if (isSubscribed != null && !isSubscribed) {
return AssistanceState.noSub;
}

View file

@ -4,8 +4,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:fluffychat/config/app_config.dart';
enum AssistanceState {
@ -31,19 +29,4 @@ extension AssistanceStateExtension on AssistanceState {
return AppConfig.success;
}
}
String tooltip(L10n l10n) {
switch (this) {
case AssistanceState.noMessage:
case AssistanceState.notFetched:
return l10n.runGrammarCorrection;
case AssistanceState.noSub:
case AssistanceState.fetching:
return "";
case AssistanceState.fetched:
return l10n.grammarCorrectionFailed;
case AssistanceState.complete:
return l10n.grammarCorrectionComplete;
}
}
}

View file

@ -45,7 +45,7 @@ class PangeaTextController extends TextEditingController {
// show the paywall if appropriate
if (choreographer
.pangeaController.subscriptionController.subscriptionStatus ==
SubscriptionStatus.showPaywall &&
SubscriptionStatus.shouldShowPaywall &&
!choreographer.isFetching &&
text.isNotEmpty) {
OverlayUtil.showPositionedCard(
@ -155,7 +155,7 @@ class PangeaTextController extends TextEditingController {
final SubscriptionStatus canSendStatus = choreographer
.pangeaController.subscriptionController.subscriptionStatus;
if (canSendStatus == SubscriptionStatus.showPaywall &&
if (canSendStatus == SubscriptionStatus.shouldShowPaywall &&
!choreographer.isFetching &&
text.isNotEmpty) {
return TextSpan(

View file

@ -29,9 +29,10 @@ import 'package:fluffychat/pangea/user/controllers/user_controller.dart';
import 'package:fluffychat/utils/platform_infos.dart';
enum SubscriptionStatus {
loading,
subscribed,
dimissedPaywall,
showPaywall,
shouldShowPaywall,
}
class SubscriptionController extends BaseController {
@ -50,7 +51,9 @@ class SubscriptionController extends BaseController {
UserController get _userController => _pangeaController.userController;
String? get _userID => _pangeaController.matrixState.client.userID;
bool get isSubscribed {
bool? get isSubscribed {
if (!initCompleter.isCompleted) return null;
final bool hasSubscription =
currentSubscriptionInfo?.currentSubscriptionId != null;
@ -63,22 +66,22 @@ class SubscriptionController extends BaseController {
}
bool _isInitializing = false;
Completer<void> initialized = Completer<void>();
Completer<void> initCompleter = Completer<void>();
Future<void> initialize() async {
if (initialized.isCompleted) return;
if (initCompleter.isCompleted) return;
if (_isInitializing) {
await initialized.future;
await initCompleter.future;
return;
}
_isInitializing = true;
await _initialize();
_isInitializing = false;
initialized.complete();
initCompleter.complete();
}
Future<void> reinitialize() async {
initialized = Completer<void>();
initCompleter = Completer<void>();
_isInitializing = false;
await initialize();
}
@ -117,9 +120,9 @@ class SubscriptionController extends BaseController {
if (!kIsWeb) {
Purchases.addCustomerInfoUpdateListener(
(CustomerInfo info) async {
final bool wasSubscribed = isSubscribed;
final bool wasSubscribed = isSubscribed != null && isSubscribed!;
await updateCustomerInfo();
if (!wasSubscribed && isSubscribed) {
if (!wasSubscribed && (isSubscribed != null && isSubscribed!)) {
subscriptionStream.add(true);
}
},
@ -131,7 +134,7 @@ class SubscriptionController extends BaseController {
await subscriptionBox.remove(
PLocalKey.beganWebPayment,
);
if (isSubscribed) {
if (isSubscribed != null && isSubscribed!) {
subscriptionStream.add(true);
}
}
@ -245,7 +248,7 @@ class SubscriptionController extends BaseController {
}
Future<void> updateCustomerInfo() async {
if (!initialized.isCompleted) {
if (!initCompleter.isCompleted) {
await initialize();
}
await currentSubscriptionInfo!.setCurrentSubscription();
@ -254,11 +257,17 @@ class SubscriptionController extends BaseController {
/// if the user is subscribed, returns subscribed
/// if the user has dismissed the paywall, returns dismissed
SubscriptionStatus get subscriptionStatus => isSubscribed
? SubscriptionStatus.subscribed
: _shouldShowPaywall
? SubscriptionStatus.showPaywall
: SubscriptionStatus.dimissedPaywall;
SubscriptionStatus get subscriptionStatus {
if (isSubscribed == null) {
return SubscriptionStatus.loading;
}
return isSubscribed!
? SubscriptionStatus.subscribed
: _shouldShowPaywall
? SubscriptionStatus.shouldShowPaywall
: SubscriptionStatus.dimissedPaywall;
}
DateTime? get _lastDismissedPaywall {
final lastDismissed = subscriptionBox.read(
@ -278,8 +287,9 @@ class SubscriptionController extends BaseController {
/// whether or not the paywall should be shown
bool get _shouldShowPaywall {
return initialized.isCompleted &&
!isSubscribed &&
return initCompleter.isCompleted &&
isSubscribed != null &&
!isSubscribed! &&
(_lastDismissedPaywall == null ||
DateTime.now().difference(_lastDismissedPaywall!).inHours >
(1 * (_paywallBackoff ?? 1)));
@ -306,13 +316,13 @@ class SubscriptionController extends BaseController {
Future<void> showPaywall(BuildContext context) async {
try {
if (!initialized.isCompleted) {
if (!initCompleter.isCompleted) {
await initialize();
}
if (availableSubscriptionInfo?.availableSubscriptions.isEmpty ?? true) {
return;
}
if (isSubscribed) return;
if (isSubscribed == null || isSubscribed!) return;
await showModalBottomSheet(
isScrollControlled: true,
useRootNavigator: !PlatformInfos.isMobile,

View file

@ -34,7 +34,7 @@ class SubscriptionManagementController extends State<SubscriptionManagement> {
@override
void initState() {
if (!subscriptionController.initialized.isCompleted) {
if (!subscriptionController.initCompleter.isCompleted) {
subscriptionController.initialize().then((_) => setState(() {}));
}
@ -66,7 +66,8 @@ class SubscriptionManagementController extends State<SubscriptionManagement> {
false;
bool get currentSubscriptionAvailable =>
subscriptionController.isSubscribed &&
subscriptionController.isSubscribed != null &&
subscriptionController.isSubscribed! &&
subscriptionController.currentSubscriptionInfo?.currentSubscription !=
null;

View file

@ -67,11 +67,16 @@ class SettingsSubscriptionView extends StatelessWidget {
child: MaxWidthBody(
child: Column(
children: [
if (isSubscribed && !controller.showManagementOptions)
if (isSubscribed == null)
const Center(child: CircularProgressIndicator.adaptive()),
if (isSubscribed != null &&
isSubscribed &&
!controller.showManagementOptions)
ManagementNotAvailableWarning(
controller: controller,
),
if (!isSubscribed || controller.isNewUserTrial)
if (isSubscribed != null && !isSubscribed ||
controller.isNewUserTrial)
ChangeSubscription(controller: controller),
if (controller.showManagementOptions) ...managementButtons,
],

View file

@ -37,10 +37,10 @@ class ReadingAssistanceContentCard extends StatelessWidget {
overlayController.widget.chatController.choreographer.tts;
Widget? toolbarContent(BuildContext context) {
final bool subscribed =
final bool? subscribed =
MatrixState.pangeaController.subscriptionController.isSubscribed;
if (!subscribed) {
if (subscribed != null && !subscribed) {
return MessageUnsubscribedCard(
controller: overlayController,
);