mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2025-03-28 04:25:28 +00:00
Use SubClub API for Subscription info
This commit is contained in:
parent
86c0b66777
commit
759ec6a002
4 changed files with 88 additions and 10 deletions
|
@ -4,6 +4,7 @@ import Env
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
import WrappingHStack
|
import WrappingHStack
|
||||||
import AppAccount
|
import AppAccount
|
||||||
|
import Network
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
struct PremiumAcccountSubsciptionSheetView: View {
|
struct PremiumAcccountSubsciptionSheetView: View {
|
||||||
|
@ -21,8 +22,10 @@ struct PremiumAcccountSubsciptionSheetView: View {
|
||||||
|
|
||||||
@State private var state: SheetState = .selection
|
@State private var state: SheetState = .selection
|
||||||
@State private var animationsending: Bool = false
|
@State private var animationsending: Bool = false
|
||||||
|
@State private var subClubUser: SubClubUser?
|
||||||
|
|
||||||
let account: Account
|
let account: Account
|
||||||
|
let subClubClient = SubClubClient()
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
|
@ -40,6 +43,14 @@ struct PremiumAcccountSubsciptionSheetView: View {
|
||||||
.presentationBackground(.thinMaterial)
|
.presentationBackground(.thinMaterial)
|
||||||
.presentationCornerRadius(8)
|
.presentationCornerRadius(8)
|
||||||
.presentationDetents([.height(330)])
|
.presentationDetents([.height(330)])
|
||||||
|
.task {
|
||||||
|
if let premiumUsername = account.premiumUsername {
|
||||||
|
let user = await subClubClient.getUser(username: premiumUsername)
|
||||||
|
withAnimation {
|
||||||
|
subClubUser = user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
|
@ -59,15 +70,21 @@ struct PremiumAcccountSubsciptionSheetView: View {
|
||||||
Text("Subscribe")
|
Text("Subscribe")
|
||||||
.font(.title2)
|
.font(.title2)
|
||||||
Text("Subscribe to @\(account.username) to get access to exclusive content!")
|
Text("Subscribe to @\(account.username) to get access to exclusive content!")
|
||||||
Button {
|
if let subscription = subClubUser?.subscription {
|
||||||
withAnimation(.easeInOut(duration: 0.5)) {
|
Button {
|
||||||
isSubscibeSelected = true
|
withAnimation(.easeInOut(duration: 0.5)) {
|
||||||
|
isSubscibeSelected = true
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
Text("\(subscription.formattedAmount) / month")
|
||||||
}
|
}
|
||||||
} label: {
|
.buttonStyle(.borderedProminent)
|
||||||
Text("$5 / month")
|
.padding(.vertical, 8)
|
||||||
|
} else {
|
||||||
|
ProgressView()
|
||||||
|
.foregroundStyle(theme.labelColor)
|
||||||
|
.padding(.vertical, 8)
|
||||||
}
|
}
|
||||||
.buttonStyle(.borderedProminent)
|
|
||||||
.padding(.vertical, 8)
|
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
.padding(12)
|
.padding(12)
|
||||||
|
@ -122,9 +139,10 @@ struct PremiumAcccountSubsciptionSheetView: View {
|
||||||
.fontWeight(.bold)
|
.fontWeight(.bold)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
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 premiumUsername = account.premiumUsername,
|
||||||
let url = URL(string: "https://\(AppInfo.premiumInstance)/@\(premiumUsername)/subscribe?callback=icecubesapp://subclub&id=@\(accountName)&amount=\(500)¤cy=USD&theme=\(colorScheme)") {
|
let url = URL(string: "https://\(AppInfo.premiumInstance)/@\(premiumUsername)/subscribe?callback=icecubesapp://subclub&id=@\(accountName)&amount=\(subscription.unitAmount)¤cy=\(subscription.currency)&theme=\(colorScheme)") {
|
||||||
openURL(url)
|
openURL(url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,7 +202,9 @@ extension Account {
|
||||||
}
|
}
|
||||||
|
|
||||||
public var premiumAcct: String? {
|
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
|
return field.value.asRawText
|
||||||
} else if let field = fields.first(where: { $0.value.asRawText.hasPrefix("https://\(AppInfo.premiumInstance)") }),
|
} else if let field = fields.first(where: { $0.value.asRawText.hasPrefix("https://\(AppInfo.premiumInstance)") }),
|
||||||
let url = URL(string: field.value.asRawText) {
|
let url = URL(string: field.value.asRawText) {
|
||||||
|
|
22
Packages/Models/Sources/Models/SubClubUser.swift
Normal file
22
Packages/Models/Sources/Models/SubClubUser.swift
Normal 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?
|
||||||
|
}
|
36
Packages/Network/Sources/Network/SubClubClient.swift
Normal file
36
Packages/Network/Sources/Network/SubClubClient.swift
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue