import 'package:collection/collection.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/constants/local.key.dart'; import 'package:fluffychat/pangea/controllers/subscription_controller.dart'; import 'package:fluffychat/pangea/repo/subscription_repo.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/pangea/utils/subscription_app_id.dart'; import 'package:fluffychat/widgets/matrix.dart'; /// Contains information about the users's current subscription class CurrentSubscriptionInfo { final String userID; final AvailableSubscriptionsInfo availableSubscriptionInfo; DateTime? expirationDate; String? currentSubscriptionId; CurrentSubscriptionInfo({ required this.userID, required this.availableSubscriptionInfo, }); SubscriptionDetails? get currentSubscription { if (currentSubscriptionId == null) return null; return availableSubscriptionInfo.allProducts?.firstWhereOrNull( (SubscriptionDetails sub) => sub.id.contains(currentSubscriptionId!) || currentSubscriptionId!.contains(sub.id), ); } Future configure() async {} bool get isNewUserTrial => currentSubscriptionId == AppConfig.trialSubscriptionId; bool get currentSubscriptionIsPromotional => currentSubscriptionId?.startsWith("rc_promo") ?? false; bool get isPaidSubscription => (currentSubscription != null || currentSubscriptionId != null) && !isNewUserTrial && !currentSubscriptionIsPromotional; bool get isLifetimeSubscription => currentSubscriptionIsPromotional && expirationDate != null && expirationDate!.isAfter(DateTime(2100)); String? get purchasePlatformDisplayName { if (currentSubscription?.appId == null) return null; return availableSubscriptionInfo.appIds ?.appDisplayName(currentSubscription!.appId!); } bool get purchasedOnWeb => (currentSubscription != null && availableSubscriptionInfo.appIds != null) && (currentSubscription?.appId == availableSubscriptionInfo.appIds?.stripeId); bool get currentPlatformMatchesPurchasePlatform => (currentSubscription != null && availableSubscriptionInfo.appIds != null) && (currentSubscription?.appId == availableSubscriptionInfo.appIds?.currentAppId); void resetSubscription() => currentSubscriptionId = null; void setTrial(DateTime expiration) { expirationDate = expiration; currentSubscriptionId = AppConfig.trialSubscriptionId; if (currentSubscription == null) { availableSubscriptionInfo.availableSubscriptions.add( SubscriptionDetails( price: 0, id: AppConfig.trialSubscriptionId, periodType: SubscriptionPeriodType.trial, ), ); } } Future setCurrentSubscription() async {} } /// Contains information about the suscriptions available on revenuecat class AvailableSubscriptionsInfo { List availableSubscriptions = []; SubscriptionAppIds? appIds; List? allProducts; AvailableSubscriptionsInfo({ this.appIds, this.allProducts, }); Future setAvailableSubscriptions() async { final cachedInfo = _getCachedSubscriptionInfo(); appIds ??= cachedInfo?.appIds ?? await SubscriptionRepo.getAppIds(); allProducts ??= cachedInfo?.allProducts ?? await SubscriptionRepo.getAllProducts(); if (cachedInfo == null) await _cacheSubscriptionInfo(); availableSubscriptions = (allProducts ?? []) .where((product) => product.appId == appIds!.currentAppId) .sorted((a, b) => a.price.compareTo(b.price)) .toList(); } Future _cacheSubscriptionInfo() async { await MatrixState.pangeaController.pStoreService.save( PLocalKey.availableSubscriptionInfo, toJson(), ); } static AvailableSubscriptionsInfo? _getCachedSubscriptionInfo() { final json = MatrixState.pangeaController.pStoreService.read( PLocalKey.availableSubscriptionInfo, ); if (json is! Map) { return null; } try { return AvailableSubscriptionsInfo.fromJson(json); } catch (e, s) { ErrorHandler.logError(e: e, s: s); return null; } } factory AvailableSubscriptionsInfo.fromJson(Map json) { final appIds = SubscriptionAppIds.fromJson(json['app_ids']); final allProducts = (json['all_products'] as List) .map((product) => SubscriptionDetails.fromJson(product)) .toList() .cast(); return AvailableSubscriptionsInfo( appIds: appIds, allProducts: allProducts, ); } Map toJson() { final data = {}; data['app_ids'] = appIds?.toJson(); data['all_products'] = allProducts?.map((product) => product.toJson()).toList(); return data; } }