✨ Finishing up stellar program
This commit is contained in:
parent
4728df93e2
commit
35b79d7562
@ -255,7 +255,7 @@
|
||||
"walletCurrencyPoints": "New Solar Points",
|
||||
"walletCurrencyShortPoints": "NSP",
|
||||
"walletCurrencyGolds": "The Solar Dollars",
|
||||
"walletCurrencyShortGolds": "TSD",
|
||||
"walletCurrencyShortGolds": "NSD",
|
||||
"retry": "Retry",
|
||||
"creatorHubUnselectedHint": "Pick / create a publisher to get started.",
|
||||
"relationships": "Relationships",
|
||||
@ -487,5 +487,31 @@
|
||||
"biometricAuthFailed": "Biometric authentication failed. Please try again.",
|
||||
"paymentSuccess": "Payment completed successfully!",
|
||||
"membershipPurchaseSuccess": "Membership purchased successfully!",
|
||||
"paymentError": "Payment failed: {error}"
|
||||
"paymentError": "Payment failed: {error}",
|
||||
"usePinInstead": "Use PIN Code",
|
||||
"levelProgress": "Level Progress",
|
||||
"unlockedFeatures": "Unlocked Features",
|
||||
"unlockedFeaturesDescription": "Features unlocked at your current level will be displayed here.",
|
||||
"stellarMembership": "Stellar Membership",
|
||||
"upgradeYourPlan": "Upgrade Your Plan",
|
||||
"chooseYourPlan": "Choose Your Plan",
|
||||
"currentMembership": "Current: {}",
|
||||
"membershipExpires": "Expires: {}",
|
||||
"membershipTierStellar": "Stellar",
|
||||
"membershipTierNova": "Nova",
|
||||
"membershipTierSupernova": "Supernova",
|
||||
"membershipTierUnknown": "Unknown",
|
||||
"membershipPriceStellar": "10 NS$ per month",
|
||||
"membershipPriceNova": "20 NS$ per month",
|
||||
"membershipPriceSupernova": "30 NS$ per month",
|
||||
"membershipFeatureBasic": "Basic features",
|
||||
"membershipFeaturePrioritySupport": "Priority support",
|
||||
"membershipFeatureAdFree": "Ad-free experience",
|
||||
"membershipFeatureAllPrimary": "All Primary features",
|
||||
"membershipFeatureAdvancedCustomization": "Advanced customization",
|
||||
"membershipFeatureEarlyAccess": "Early access",
|
||||
"membershipFeatureAllNova": "All Nova features",
|
||||
"membershipFeatureExclusiveContent": "Exclusive content",
|
||||
"membershipFeatureVipSupport": "VIP support",
|
||||
"membershipCurrentBadge": "CURRENT"
|
||||
}
|
||||
|
@ -307,5 +307,32 @@
|
||||
"chatBreakCleared": "聊天暫停已清除。",
|
||||
"chatBreakCustom": "自訂時長",
|
||||
"chatBreakEnterMinutes": "輸入分鐘數",
|
||||
"chatBreakNone": "無"
|
||||
"chatBreakNone": "無",
|
||||
"paymentError": "付款失敗:{error}",
|
||||
"usePinInstead": "使用密碼",
|
||||
"levelProgress": "等級進度",
|
||||
"unlockedFeatures": "已解鎖功能",
|
||||
"unlockedFeaturesDescription": "您目前等級解鎖的功能將會顯示在此。",
|
||||
"stellarMembership": "星際會員",
|
||||
"upgradeYourPlan": "升級您的方案",
|
||||
"chooseYourPlan": "選擇您的方案",
|
||||
"currentMembership": "目前:{}",
|
||||
"membershipExpires": "到期:{}",
|
||||
"membershipTierStellar": "星際",
|
||||
"membershipTierNova": "新星",
|
||||
"membershipTierSupernova": "超新星",
|
||||
"membershipTierUnknown": "未知",
|
||||
"membershipPriceStellar": "每月 10 星幣",
|
||||
"membershipPriceNova": "每月 20 星幣",
|
||||
"membershipPriceSupernova": "每月 30 星幣",
|
||||
"membershipFeatureBasic": "基本功能",
|
||||
"membershipFeaturePrioritySupport": "優先支援",
|
||||
"membershipFeatureAdFree": "無廣告體驗",
|
||||
"membershipFeatureAllPrimary": "所有主要功能",
|
||||
"membershipFeatureAdvancedCustomization": "進階自訂",
|
||||
"membershipFeatureEarlyAccess": "搶先體驗",
|
||||
"membershipFeatureAllNova": "所有新星功能",
|
||||
"membershipFeatureExclusiveContent": "獨家內容",
|
||||
"membershipFeatureVipSupport": "VIP 支援",
|
||||
"membershipCurrentBadge": "目前"
|
||||
}
|
@ -74,6 +74,8 @@
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>NSFaceIDUsageDescription</key>
|
||||
<string>Allow the Solar Network verify your ownership of the logged in account and continue your action quickly.</string>
|
||||
<key>NSUserActivityTypes</key>
|
||||
<array>
|
||||
<string>INStartCallIntent</string>
|
||||
|
@ -62,21 +62,21 @@ sealed class SnWalletSubscription with _$SnWalletSubscription {
|
||||
const factory SnWalletSubscription({
|
||||
required String id,
|
||||
required DateTime begunAt,
|
||||
required DateTime endedAt,
|
||||
required DateTime? endedAt,
|
||||
required String identifier,
|
||||
required bool isActive,
|
||||
required bool isFreeTrial,
|
||||
required int status,
|
||||
required String paymentMethod,
|
||||
required Map<String, dynamic> paymentDetails,
|
||||
required double basePrice,
|
||||
@Default(true) bool isActive,
|
||||
@Default(false) bool isFreeTrial,
|
||||
@Default(1) int status,
|
||||
required String? paymentMethod,
|
||||
required Map<String, dynamic>? paymentDetails,
|
||||
required double? basePrice,
|
||||
required String? couponId,
|
||||
required dynamic coupon,
|
||||
required DateTime renewalAt,
|
||||
required DateTime? renewalAt,
|
||||
required String accountId,
|
||||
required SnAccount? account,
|
||||
required bool isAvailable,
|
||||
required double finalPrice,
|
||||
@Default(true) bool isAvailable,
|
||||
required double? finalPrice,
|
||||
required DateTime createdAt,
|
||||
required DateTime updatedAt,
|
||||
required DateTime? deletedAt,
|
||||
|
@ -562,7 +562,7 @@ $SnWalletCopyWith<$Res>? get payeeWallet {
|
||||
/// @nodoc
|
||||
mixin _$SnWalletSubscription {
|
||||
|
||||
String get id; DateTime get begunAt; DateTime get endedAt; String get identifier; bool get isActive; bool get isFreeTrial; int get status; String get paymentMethod; Map<String, dynamic> get paymentDetails; double get basePrice; String? get couponId; dynamic get coupon; DateTime get renewalAt; String get accountId; SnAccount? get account; bool get isAvailable; double get finalPrice; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
||||
String get id; DateTime get begunAt; DateTime? get endedAt; String get identifier; bool get isActive; bool get isFreeTrial; int get status; String? get paymentMethod; Map<String, dynamic>? get paymentDetails; double? get basePrice; String? get couponId; dynamic get coupon; DateTime? get renewalAt; String get accountId; SnAccount? get account; bool get isAvailable; double? get finalPrice; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
||||
/// Create a copy of SnWalletSubscription
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@ -595,7 +595,7 @@ abstract mixin class $SnWalletSubscriptionCopyWith<$Res> {
|
||||
factory $SnWalletSubscriptionCopyWith(SnWalletSubscription value, $Res Function(SnWalletSubscription) _then) = _$SnWalletSubscriptionCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id, DateTime begunAt, DateTime endedAt, String identifier, bool isActive, bool isFreeTrial, int status, String paymentMethod, Map<String, dynamic> paymentDetails, double basePrice, String? couponId, dynamic coupon, DateTime renewalAt, String accountId, SnAccount? account, bool isAvailable, double finalPrice, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||
String id, DateTime begunAt, DateTime? endedAt, String identifier, bool isActive, bool isFreeTrial, int status, String? paymentMethod, Map<String, dynamic>? paymentDetails, double? basePrice, String? couponId, dynamic coupon, DateTime? renewalAt, String accountId, SnAccount? account, bool isAvailable, double? finalPrice, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||
});
|
||||
|
||||
|
||||
@ -612,26 +612,26 @@ class _$SnWalletSubscriptionCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of SnWalletSubscription
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? begunAt = null,Object? endedAt = null,Object? identifier = null,Object? isActive = null,Object? isFreeTrial = null,Object? status = null,Object? paymentMethod = null,Object? paymentDetails = null,Object? basePrice = null,Object? couponId = freezed,Object? coupon = freezed,Object? renewalAt = null,Object? accountId = null,Object? account = freezed,Object? isAvailable = null,Object? finalPrice = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? begunAt = null,Object? endedAt = freezed,Object? identifier = null,Object? isActive = null,Object? isFreeTrial = null,Object? status = null,Object? paymentMethod = freezed,Object? paymentDetails = freezed,Object? basePrice = freezed,Object? couponId = freezed,Object? coupon = freezed,Object? renewalAt = freezed,Object? accountId = null,Object? account = freezed,Object? isAvailable = null,Object? finalPrice = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,begunAt: null == begunAt ? _self.begunAt : begunAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,endedAt: null == endedAt ? _self.endedAt : endedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,identifier: null == identifier ? _self.identifier : identifier // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,endedAt: freezed == endedAt ? _self.endedAt : endedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,identifier: null == identifier ? _self.identifier : identifier // ignore: cast_nullable_to_non_nullable
|
||||
as String,isActive: null == isActive ? _self.isActive : isActive // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isFreeTrial: null == isFreeTrial ? _self.isFreeTrial : isFreeTrial // ignore: cast_nullable_to_non_nullable
|
||||
as bool,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
|
||||
as int,paymentMethod: null == paymentMethod ? _self.paymentMethod : paymentMethod // ignore: cast_nullable_to_non_nullable
|
||||
as String,paymentDetails: null == paymentDetails ? _self.paymentDetails : paymentDetails // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, dynamic>,basePrice: null == basePrice ? _self.basePrice : basePrice // ignore: cast_nullable_to_non_nullable
|
||||
as double,couponId: freezed == couponId ? _self.couponId : couponId // ignore: cast_nullable_to_non_nullable
|
||||
as int,paymentMethod: freezed == paymentMethod ? _self.paymentMethod : paymentMethod // ignore: cast_nullable_to_non_nullable
|
||||
as String?,paymentDetails: freezed == paymentDetails ? _self.paymentDetails : paymentDetails // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, dynamic>?,basePrice: freezed == basePrice ? _self.basePrice : basePrice // ignore: cast_nullable_to_non_nullable
|
||||
as double?,couponId: freezed == couponId ? _self.couponId : couponId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,coupon: freezed == coupon ? _self.coupon : coupon // ignore: cast_nullable_to_non_nullable
|
||||
as dynamic,renewalAt: null == renewalAt ? _self.renewalAt : renewalAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||
as dynamic,renewalAt: freezed == renewalAt ? _self.renewalAt : renewalAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||
as String,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
|
||||
as SnAccount?,isAvailable: null == isAvailable ? _self.isAvailable : isAvailable // ignore: cast_nullable_to_non_nullable
|
||||
as bool,finalPrice: null == finalPrice ? _self.finalPrice : finalPrice // ignore: cast_nullable_to_non_nullable
|
||||
as double,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as bool,finalPrice: freezed == finalPrice ? _self.finalPrice : finalPrice // ignore: cast_nullable_to_non_nullable
|
||||
as double?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
@ -657,32 +657,34 @@ $SnAccountCopyWith<$Res>? get account {
|
||||
@JsonSerializable()
|
||||
|
||||
class _SnWalletSubscription implements SnWalletSubscription {
|
||||
const _SnWalletSubscription({required this.id, required this.begunAt, required this.endedAt, required this.identifier, required this.isActive, required this.isFreeTrial, required this.status, required this.paymentMethod, required final Map<String, dynamic> paymentDetails, required this.basePrice, required this.couponId, required this.coupon, required this.renewalAt, required this.accountId, required this.account, required this.isAvailable, required this.finalPrice, required this.createdAt, required this.updatedAt, required this.deletedAt}): _paymentDetails = paymentDetails;
|
||||
const _SnWalletSubscription({required this.id, required this.begunAt, required this.endedAt, required this.identifier, this.isActive = true, this.isFreeTrial = false, this.status = 1, required this.paymentMethod, required final Map<String, dynamic>? paymentDetails, required this.basePrice, required this.couponId, required this.coupon, required this.renewalAt, required this.accountId, required this.account, this.isAvailable = true, required this.finalPrice, required this.createdAt, required this.updatedAt, required this.deletedAt}): _paymentDetails = paymentDetails;
|
||||
factory _SnWalletSubscription.fromJson(Map<String, dynamic> json) => _$SnWalletSubscriptionFromJson(json);
|
||||
|
||||
@override final String id;
|
||||
@override final DateTime begunAt;
|
||||
@override final DateTime endedAt;
|
||||
@override final DateTime? endedAt;
|
||||
@override final String identifier;
|
||||
@override final bool isActive;
|
||||
@override final bool isFreeTrial;
|
||||
@override final int status;
|
||||
@override final String paymentMethod;
|
||||
final Map<String, dynamic> _paymentDetails;
|
||||
@override Map<String, dynamic> get paymentDetails {
|
||||
@override@JsonKey() final bool isActive;
|
||||
@override@JsonKey() final bool isFreeTrial;
|
||||
@override@JsonKey() final int status;
|
||||
@override final String? paymentMethod;
|
||||
final Map<String, dynamic>? _paymentDetails;
|
||||
@override Map<String, dynamic>? get paymentDetails {
|
||||
final value = _paymentDetails;
|
||||
if (value == null) return null;
|
||||
if (_paymentDetails is EqualUnmodifiableMapView) return _paymentDetails;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableMapView(_paymentDetails);
|
||||
return EqualUnmodifiableMapView(value);
|
||||
}
|
||||
|
||||
@override final double basePrice;
|
||||
@override final double? basePrice;
|
||||
@override final String? couponId;
|
||||
@override final dynamic coupon;
|
||||
@override final DateTime renewalAt;
|
||||
@override final DateTime? renewalAt;
|
||||
@override final String accountId;
|
||||
@override final SnAccount? account;
|
||||
@override final bool isAvailable;
|
||||
@override final double finalPrice;
|
||||
@override@JsonKey() final bool isAvailable;
|
||||
@override final double? finalPrice;
|
||||
@override final DateTime createdAt;
|
||||
@override final DateTime updatedAt;
|
||||
@override final DateTime? deletedAt;
|
||||
@ -720,7 +722,7 @@ abstract mixin class _$SnWalletSubscriptionCopyWith<$Res> implements $SnWalletSu
|
||||
factory _$SnWalletSubscriptionCopyWith(_SnWalletSubscription value, $Res Function(_SnWalletSubscription) _then) = __$SnWalletSubscriptionCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, DateTime begunAt, DateTime endedAt, String identifier, bool isActive, bool isFreeTrial, int status, String paymentMethod, Map<String, dynamic> paymentDetails, double basePrice, String? couponId, dynamic coupon, DateTime renewalAt, String accountId, SnAccount? account, bool isAvailable, double finalPrice, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||
String id, DateTime begunAt, DateTime? endedAt, String identifier, bool isActive, bool isFreeTrial, int status, String? paymentMethod, Map<String, dynamic>? paymentDetails, double? basePrice, String? couponId, dynamic coupon, DateTime? renewalAt, String accountId, SnAccount? account, bool isAvailable, double? finalPrice, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||
});
|
||||
|
||||
|
||||
@ -737,26 +739,26 @@ class __$SnWalletSubscriptionCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of SnWalletSubscription
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? begunAt = null,Object? endedAt = null,Object? identifier = null,Object? isActive = null,Object? isFreeTrial = null,Object? status = null,Object? paymentMethod = null,Object? paymentDetails = null,Object? basePrice = null,Object? couponId = freezed,Object? coupon = freezed,Object? renewalAt = null,Object? accountId = null,Object? account = freezed,Object? isAvailable = null,Object? finalPrice = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? begunAt = null,Object? endedAt = freezed,Object? identifier = null,Object? isActive = null,Object? isFreeTrial = null,Object? status = null,Object? paymentMethod = freezed,Object? paymentDetails = freezed,Object? basePrice = freezed,Object? couponId = freezed,Object? coupon = freezed,Object? renewalAt = freezed,Object? accountId = null,Object? account = freezed,Object? isAvailable = null,Object? finalPrice = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||
return _then(_SnWalletSubscription(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,begunAt: null == begunAt ? _self.begunAt : begunAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,endedAt: null == endedAt ? _self.endedAt : endedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,identifier: null == identifier ? _self.identifier : identifier // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,endedAt: freezed == endedAt ? _self.endedAt : endedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,identifier: null == identifier ? _self.identifier : identifier // ignore: cast_nullable_to_non_nullable
|
||||
as String,isActive: null == isActive ? _self.isActive : isActive // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isFreeTrial: null == isFreeTrial ? _self.isFreeTrial : isFreeTrial // ignore: cast_nullable_to_non_nullable
|
||||
as bool,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
|
||||
as int,paymentMethod: null == paymentMethod ? _self.paymentMethod : paymentMethod // ignore: cast_nullable_to_non_nullable
|
||||
as String,paymentDetails: null == paymentDetails ? _self._paymentDetails : paymentDetails // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, dynamic>,basePrice: null == basePrice ? _self.basePrice : basePrice // ignore: cast_nullable_to_non_nullable
|
||||
as double,couponId: freezed == couponId ? _self.couponId : couponId // ignore: cast_nullable_to_non_nullable
|
||||
as int,paymentMethod: freezed == paymentMethod ? _self.paymentMethod : paymentMethod // ignore: cast_nullable_to_non_nullable
|
||||
as String?,paymentDetails: freezed == paymentDetails ? _self._paymentDetails : paymentDetails // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, dynamic>?,basePrice: freezed == basePrice ? _self.basePrice : basePrice // ignore: cast_nullable_to_non_nullable
|
||||
as double?,couponId: freezed == couponId ? _self.couponId : couponId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,coupon: freezed == coupon ? _self.coupon : coupon // ignore: cast_nullable_to_non_nullable
|
||||
as dynamic,renewalAt: null == renewalAt ? _self.renewalAt : renewalAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||
as dynamic,renewalAt: freezed == renewalAt ? _self.renewalAt : renewalAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||
as String,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
|
||||
as SnAccount?,isAvailable: null == isAvailable ? _self.isAvailable : isAvailable // ignore: cast_nullable_to_non_nullable
|
||||
as bool,finalPrice: null == finalPrice ? _self.finalPrice : finalPrice // ignore: cast_nullable_to_non_nullable
|
||||
as double,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as bool,finalPrice: freezed == finalPrice ? _self.finalPrice : finalPrice // ignore: cast_nullable_to_non_nullable
|
||||
as double?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
|
@ -106,24 +106,30 @@ _SnWalletSubscription _$SnWalletSubscriptionFromJson(
|
||||
) => _SnWalletSubscription(
|
||||
id: json['id'] as String,
|
||||
begunAt: DateTime.parse(json['begun_at'] as String),
|
||||
endedAt: DateTime.parse(json['ended_at'] as String),
|
||||
endedAt:
|
||||
json['ended_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['ended_at'] as String),
|
||||
identifier: json['identifier'] as String,
|
||||
isActive: json['is_active'] as bool,
|
||||
isFreeTrial: json['is_free_trial'] as bool,
|
||||
status: (json['status'] as num).toInt(),
|
||||
paymentMethod: json['payment_method'] as String,
|
||||
paymentDetails: json['payment_details'] as Map<String, dynamic>,
|
||||
basePrice: (json['base_price'] as num).toDouble(),
|
||||
isActive: json['is_active'] as bool? ?? true,
|
||||
isFreeTrial: json['is_free_trial'] as bool? ?? false,
|
||||
status: (json['status'] as num?)?.toInt() ?? 1,
|
||||
paymentMethod: json['payment_method'] as String?,
|
||||
paymentDetails: json['payment_details'] as Map<String, dynamic>?,
|
||||
basePrice: (json['base_price'] as num?)?.toDouble(),
|
||||
couponId: json['coupon_id'] as String?,
|
||||
coupon: json['coupon'],
|
||||
renewalAt: DateTime.parse(json['renewal_at'] as String),
|
||||
renewalAt:
|
||||
json['renewal_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['renewal_at'] as String),
|
||||
accountId: json['account_id'] as String,
|
||||
account:
|
||||
json['account'] == null
|
||||
? null
|
||||
: SnAccount.fromJson(json['account'] as Map<String, dynamic>),
|
||||
isAvailable: json['is_available'] as bool,
|
||||
finalPrice: (json['final_price'] as num).toDouble(),
|
||||
isAvailable: json['is_available'] as bool? ?? true,
|
||||
finalPrice: (json['final_price'] as num?)?.toDouble(),
|
||||
createdAt: DateTime.parse(json['created_at'] as String),
|
||||
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||
deletedAt:
|
||||
@ -137,7 +143,7 @@ Map<String, dynamic> _$SnWalletSubscriptionToJson(
|
||||
) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'begun_at': instance.begunAt.toIso8601String(),
|
||||
'ended_at': instance.endedAt.toIso8601String(),
|
||||
'ended_at': instance.endedAt?.toIso8601String(),
|
||||
'identifier': instance.identifier,
|
||||
'is_active': instance.isActive,
|
||||
'is_free_trial': instance.isFreeTrial,
|
||||
@ -147,7 +153,7 @@ Map<String, dynamic> _$SnWalletSubscriptionToJson(
|
||||
'base_price': instance.basePrice,
|
||||
'coupon_id': instance.couponId,
|
||||
'coupon': instance.coupon,
|
||||
'renewal_at': instance.renewalAt.toIso8601String(),
|
||||
'renewal_at': instance.renewalAt?.toIso8601String(),
|
||||
'account_id': instance.accountId,
|
||||
'account': instance.account?.toJson(),
|
||||
'is_available': instance.isAvailable,
|
||||
|
@ -9,6 +9,7 @@ import 'package:island/models/wallet.dart';
|
||||
import 'package:island/pods/network.dart';
|
||||
import 'package:island/pods/userinfo.dart';
|
||||
import 'package:island/services/responsive.dart';
|
||||
import 'package:island/services/time.dart';
|
||||
import 'package:island/widgets/account/leveling_progress.dart';
|
||||
import 'package:island/widgets/alert.dart';
|
||||
import 'package:island/widgets/app_scaffold.dart';
|
||||
@ -51,7 +52,7 @@ class LevelingScreen extends HookConsumerWidget {
|
||||
|
||||
// Level Stairs Graph
|
||||
Text(
|
||||
'Level Progress',
|
||||
'levelProgress'.tr(),
|
||||
style: Theme.of(
|
||||
context,
|
||||
).textTheme.headlineSmall?.copyWith(fontWeight: FontWeight.bold),
|
||||
@ -79,12 +80,12 @@ class LevelingScreen extends HookConsumerWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Unlocked Features',
|
||||
'unlockedFeatures'.tr(),
|
||||
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
||||
),
|
||||
const Gap(8),
|
||||
Text(
|
||||
'Features unlocked at your current level will be displayed here.',
|
||||
'unlockedFeaturesDescription'.tr(),
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
@ -252,7 +253,7 @@ class LevelingScreen extends HookConsumerWidget {
|
||||
),
|
||||
const Gap(8),
|
||||
Text(
|
||||
'Stellar Membership',
|
||||
'stellarMembership'.tr(),
|
||||
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
@ -265,7 +266,7 @@ class LevelingScreen extends HookConsumerWidget {
|
||||
],
|
||||
|
||||
Text(
|
||||
isActive ? 'Upgrade Your Plan' : 'Choose Your Plan',
|
||||
isActive ? 'upgradeYourPlan'.tr() : 'chooseYourPlan'.tr(),
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
|
||||
),
|
||||
const Gap(12),
|
||||
@ -299,19 +300,20 @@ class LevelingScreen extends HookConsumerWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Current: $tierName',
|
||||
'currentMembership'.tr(args: [tierName]),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: tierColor,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Expires: ${_formatDate(membership.endedAt)}',
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
if (membership.endedAt != null)
|
||||
Text(
|
||||
'membershipExpires'.tr(args: [membership.endedAt!.formatSystem()]),
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -328,31 +330,31 @@ class LevelingScreen extends HookConsumerWidget {
|
||||
final tiers = [
|
||||
{
|
||||
'id': 'solian.stellar.primary',
|
||||
'name': 'Stellar',
|
||||
'price': '10 NS\$ per month',
|
||||
'name': 'membershipTierStellar'.tr(),
|
||||
'price': 'membershipPriceStellar'.tr(),
|
||||
'features': [
|
||||
'Basic features',
|
||||
'Priority support',
|
||||
'Ad-free experience',
|
||||
'membershipFeatureBasic'.tr(),
|
||||
'membershipFeaturePrioritySupport'.tr(),
|
||||
'membershipFeatureAdFree'.tr(),
|
||||
],
|
||||
'color': Colors.blue,
|
||||
},
|
||||
{
|
||||
'id': 'solian.stellar.nova',
|
||||
'name': 'Nova',
|
||||
'price': '20 NS\$ per month',
|
||||
'name': 'membershipTierNova'.tr(),
|
||||
'price': 'membershipPriceNova'.tr(),
|
||||
'features': [
|
||||
'All Primary features',
|
||||
'Advanced customization',
|
||||
'Early access',
|
||||
'membershipFeatureAllPrimary'.tr(),
|
||||
'membershipFeatureAdvancedCustomization'.tr(),
|
||||
'membershipFeatureEarlyAccess'.tr(),
|
||||
],
|
||||
'color': Colors.purple,
|
||||
},
|
||||
{
|
||||
'id': 'solian.stellar.supernova',
|
||||
'name': 'Supernova',
|
||||
'price': '30 NS\$ per month',
|
||||
'features': ['All Nova features', 'Exclusive content', 'VIP support'],
|
||||
'name': 'membershipTierSupernova'.tr(),
|
||||
'price': 'membershipPriceSupernova'.tr(),
|
||||
'features': ['membershipFeatureAllNova'.tr(), 'membershipFeatureExclusiveContent'.tr(), 'membershipFeatureVipSupport'.tr()],
|
||||
'color': Colors.orange,
|
||||
},
|
||||
];
|
||||
@ -432,7 +434,7 @@ class LevelingScreen extends HookConsumerWidget {
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text(
|
||||
'CURRENT',
|
||||
'membershipCurrentBadge'.tr(),
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
@ -476,13 +478,13 @@ class LevelingScreen extends HookConsumerWidget {
|
||||
String _getMembershipTierName(String identifier) {
|
||||
switch (identifier) {
|
||||
case 'solian.stellar.primary':
|
||||
return 'Primary';
|
||||
return 'membershipTierStellar'.tr();
|
||||
case 'solian.stellar.nova':
|
||||
return 'Nova';
|
||||
return 'membershipTierNova'.tr();
|
||||
case 'solian.stellar.supernova':
|
||||
return 'Supernova';
|
||||
return 'membershipTierSupernova'.tr();
|
||||
default:
|
||||
return 'Unknown';
|
||||
return 'membershipTierUnknown'.tr();
|
||||
}
|
||||
}
|
||||
|
||||
@ -499,10 +501,6 @@ class LevelingScreen extends HookConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
String _formatDate(DateTime date) {
|
||||
return '${date.day}/${date.month}/${date.year}';
|
||||
}
|
||||
|
||||
Future<void> _purchaseMembership(
|
||||
BuildContext context,
|
||||
WidgetRef ref,
|
||||
@ -538,21 +536,23 @@ class LevelingScreen extends HookConsumerWidget {
|
||||
enableBiometric: true,
|
||||
);
|
||||
|
||||
if (context.mounted) showLoadingModal(context);
|
||||
|
||||
if (paidOrder != null) {
|
||||
// Payment successful, refresh user info or show success message
|
||||
ref.invalidate(userInfoProvider);
|
||||
await client.post(
|
||||
'/subscriptions/order/handle',
|
||||
data: {'order_id': paidOrder.id},
|
||||
);
|
||||
|
||||
ref.read(userInfoProvider.notifier).fetchUser();
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('membershipPurchaseSuccess'.tr()),
|
||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
);
|
||||
showSnackBar(context, 'membershipPurchaseSuccess'.tr());
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
if (context.mounted) hideLoadingModal(context);
|
||||
showErrorAlert(err);
|
||||
} finally {
|
||||
if (context.mounted) hideLoadingModal(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import 'package:dio/dio.dart';
|
||||
import 'package:local_auth/local_auth.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
class PaymentOverlay extends HookConsumerWidget {
|
||||
final SnWalletOrder order;
|
||||
@ -278,12 +279,7 @@ class _PaymentContentState extends ConsumerState<_PaymentContent> {
|
||||
_isPinMode = true;
|
||||
});
|
||||
if (message != null && message.isNotEmpty) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(message),
|
||||
backgroundColor: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
);
|
||||
showSnackBar(context, message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -423,21 +419,10 @@ class _PaymentContentState extends ConsumerState<_PaymentContent> {
|
||||
Widget _buildBiometricAuth() {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 120,
|
||||
height: 120,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
Symbols.fingerprint,
|
||||
size: 64,
|
||||
color: Theme.of(context).colorScheme.onPrimaryContainer,
|
||||
),
|
||||
),
|
||||
const Gap(24),
|
||||
Icon(Symbols.fingerprint, size: 48),
|
||||
const Gap(16),
|
||||
Text(
|
||||
'useBiometricToConfirm'.tr(),
|
||||
style: Theme.of(
|
||||
@ -445,15 +430,15 @@ class _PaymentContentState extends ConsumerState<_PaymentContent> {
|
||||
).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w500),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const Gap(16),
|
||||
Text(
|
||||
'touchSensorToAuthenticate'.tr(),
|
||||
'The biometric data will only be processed on your device',
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
fontSize: 11,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const Gap(32),
|
||||
).opacity(0.75),
|
||||
const Gap(28),
|
||||
ElevatedButton.icon(
|
||||
onPressed: _authenticateWithBiometric,
|
||||
icon: const Icon(Symbols.fingerprint),
|
||||
@ -462,13 +447,12 @@ class _PaymentContentState extends ConsumerState<_PaymentContent> {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
),
|
||||
),
|
||||
const Gap(16),
|
||||
TextButton(
|
||||
onPressed: () => _fallbackToPinMode(null),
|
||||
child: Text('usePinInstead'.tr()),
|
||||
),
|
||||
],
|
||||
);
|
||||
).center();
|
||||
}
|
||||
|
||||
Widget _buildActionButtons() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user