Use SubClub API for Subscription info

This commit is contained in:
Thomas Ricouard 2024-07-05 09:30:48 +02:00
parent 86c0b66777
commit 759ec6a002
4 changed files with 88 additions and 10 deletions

View file

@ -4,6 +4,7 @@ import Env
import DesignSystem
import WrappingHStack
import AppAccount
import Network
@MainActor
struct PremiumAcccountSubsciptionSheetView: View {
@ -21,8 +22,10 @@ struct PremiumAcccountSubsciptionSheetView: View {
@State private var state: SheetState = .selection
@State private var animationsending: Bool = false
@State private var subClubUser: SubClubUser?
let account: Account
let subClubClient = SubClubClient()
var body: some View {
VStack {
@ -40,6 +43,14 @@ struct PremiumAcccountSubsciptionSheetView: View {
.presentationBackground(.thinMaterial)
.presentationCornerRadius(8)
.presentationDetents([.height(330)])
.task {
if let premiumUsername = account.premiumUsername {
let user = await subClubClient.getUser(username: premiumUsername)
withAnimation {
subClubUser = user
}
}
}
}
@ViewBuilder
@ -59,15 +70,21 @@ struct PremiumAcccountSubsciptionSheetView: View {
Text("Subscribe")
.font(.title2)
Text("Subscribe to @\(account.username) to get access to exclusive content!")
Button {
withAnimation(.easeInOut(duration: 0.5)) {
isSubscibeSelected = true
if let subscription = subClubUser?.subscription {
Button {
withAnimation(.easeInOut(duration: 0.5)) {
isSubscibeSelected = true
}
} label: {
Text("\(subscription.formattedAmount) / month")
}
} label: {
Text("$5 / month")
.buttonStyle(.borderedProminent)
.padding(.vertical, 8)
} else {
ProgressView()
.foregroundStyle(theme.labelColor)
.padding(.vertical, 8)
}
.buttonStyle(.borderedProminent)
.padding(.vertical, 8)
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(12)
@ -122,9 +139,10 @@ struct PremiumAcccountSubsciptionSheetView: View {
.fontWeight(.bold)
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
if let accountName = appAccount.currentAccount.accountName,
if let subscription = subClubUser?.subscription,
let accountName = appAccount.currentAccount.accountName,
let premiumUsername = account.premiumUsername,
let url = URL(string: "https://\(AppInfo.premiumInstance)/@\(premiumUsername)/subscribe?callback=icecubesapp://subclub&id=@\(accountName)&amount=\(500)&currency=USD&theme=\(colorScheme)") {
let url = URL(string: "https://\(AppInfo.premiumInstance)/@\(premiumUsername)/subscribe?callback=icecubesapp://subclub&id=@\(accountName)&amount=\(subscription.unitAmount)&currency=\(subscription.currency)&theme=\(colorScheme)") {
openURL(url)
}
}

View file

@ -202,7 +202,9 @@ extension Account {
}
public var premiumAcct: String? {
if let field = fields.first(where: { $0.value.asRawText.hasSuffix(AppInfo.premiumInstance) }) {
if isPremiumAccount {
return "@\(acct)"
} else if let field = fields.first(where: { $0.value.asRawText.hasSuffix(AppInfo.premiumInstance) }) {
return field.value.asRawText
} else if let field = fields.first(where: { $0.value.asRawText.hasPrefix("https://\(AppInfo.premiumInstance)") }),
let url = URL(string: field.value.asRawText) {

View file

@ -0,0 +1,22 @@
import Foundation
public struct SubClubUser: Sendable, Identifiable, Decodable {
public struct Subscription: Sendable, Decodable {
public let paymentType: String
public let currency: String
public let interval: String
public let intervalCount: Int
public let unitAmount: Int
public var formattedAmount: String {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.locale = Locale(identifier: "en_US")
formatter.maximumFractionDigits = 0
return formatter.string(from: .init(integerLiteral: unitAmount / 100)) ?? "$NaN"
}
}
public let id: String
public let subscription: Subscription?
}

View file

@ -0,0 +1,36 @@
import Foundation
import Models
public struct SubClubClient: Sendable {
public enum Endpoint {
case user(username: String)
var path: String {
switch self {
case .user(let username):
return "users/\(username)"
}
}
}
public init() { }
private var url: String {
"https://sub.club/"
}
public func getUser(username: String) async -> SubClubUser? {
guard let url = URL(string: url.appending(Endpoint.user(username: username).path)) else {
return nil
}
let request = URLRequest(url: url)
do {
let (result, _) = try await URLSession.shared.data(for: request)
let decoder = JSONDecoder()
let user = try decoder.decode(SubClubUser.self, from: result)
return user
} catch {
return nil
}
}
}