IceCubes/IceCubesApp/App/Tabs/Settings/SupportAppView.swift

145 lines
4.5 KiB
Swift
Raw Normal View History

2023-01-07 13:44:13 +01:00
import DesignSystem
2023-01-17 11:36:01 +01:00
import Env
2023-01-07 13:44:13 +01:00
import RevenueCat
2023-01-10 08:24:05 +01:00
import Shimmer
2023-01-17 11:36:01 +01:00
import SwiftUI
2023-01-07 13:44:13 +01:00
struct SupportAppView: View {
enum Tips: String, CaseIterable {
case one, two, three
2023-01-17 11:36:01 +01:00
2023-01-07 13:44:13 +01:00
init(productId: String) {
self = .init(rawValue: String(productId.split(separator: ".")[2]))!
}
2023-01-17 11:36:01 +01:00
2023-01-07 13:44:13 +01:00
var productId: String {
"icecubes.tipjar.\(rawValue)"
}
2023-01-17 11:36:01 +01:00
2023-01-07 13:44:13 +01:00
var title: String {
switch self {
case .one:
return "🍬 Small Tip"
case .two:
return "☕️ Nice Tip"
case .three:
return "🤯 Generous Tip"
}
}
2023-01-17 11:36:01 +01:00
2023-01-07 13:44:13 +01:00
var subtitle: String {
switch self {
case .one:
return "Small, but cute, and it taste good!"
case .two:
return "I love the taste of a fancy coffee ❤️"
case .three:
return "You're insane, thank you so much!"
}
}
}
2023-01-17 11:36:01 +01:00
2023-01-07 13:44:13 +01:00
@EnvironmentObject private var theme: Theme
2023-01-17 11:36:01 +01:00
2023-01-07 13:44:13 +01:00
@State private var loadingProducts: Bool = false
@State private var products: [StoreProduct] = []
@State private var isProcessingPurchase: Bool = false
@State private var purchaseSuccessDisplayed: Bool = false
@State private var purchaseErrorDisplayed: Bool = false
2023-01-17 11:36:01 +01:00
2023-01-07 13:44:13 +01:00
var body: some View {
Form {
Section {
HStack(alignment: .top, spacing: 12) {
VStack(spacing: 18) {
Image("avatar")
.resizable()
.frame(width: 50, height: 50)
.cornerRadius(4)
Image("icon0")
.resizable()
.frame(width: 50, height: 50)
.cornerRadius(4)
}
Text("Hi there! My name is Thomas and I absolutely love creating open source apps. Ice Cubes is definitely one of my proudest projects to date - and let's be real, it's also the one that requires the most maintenance due to the ever-changing world of Mastodon and social media. If you're having a blast using Ice Cubes, consider tossing a little tip my way. It'll make my day (and help keep the app running smoothly for you). 🚀")
}
}
.listRowBackground(theme.primaryBackgroundColor)
2023-01-17 11:36:01 +01:00
2023-01-07 13:44:13 +01:00
Section {
if loadingProducts {
2023-01-10 08:24:05 +01:00
HStack {
VStack(alignment: .leading) {
Text("Loading ...")
.font(.scaledSubheadline)
2023-01-10 08:24:05 +01:00
Text("Loading subtitle...")
.font(.scaledFootnote)
2023-01-10 08:24:05 +01:00
.foregroundColor(.gray)
}
.padding(.vertical, 8)
}
.redacted(reason: .placeholder)
.shimmering()
2023-01-07 13:44:13 +01:00
} else {
ForEach(products, id: \.productIdentifier) { product in
let tip = Tips(productId: product.productIdentifier)
HStack {
VStack(alignment: .leading) {
Text(tip.title)
.font(.scaledSubheadline)
2023-01-07 13:44:13 +01:00
Text(tip.subtitle)
.font(.scaledFootnote)
2023-01-07 13:44:13 +01:00
.foregroundColor(.gray)
}
Spacer()
Button {
isProcessingPurchase = true
2023-01-07 14:06:40 +01:00
Task {
do {
_ = try await Purchases.shared.purchase(product: product)
2023-01-07 13:44:13 +01:00
purchaseSuccessDisplayed = true
2023-01-07 14:06:40 +01:00
} catch {
2023-01-07 13:44:13 +01:00
purchaseErrorDisplayed = true
}
isProcessingPurchase = false
}
} label: {
if isProcessingPurchase {
ProgressView()
} else {
Text(product.localizedPriceString)
}
}
.buttonStyle(.bordered)
}
.padding(.vertical, 8)
}
}
}
.listRowBackground(theme.primaryBackgroundColor)
}
.navigationTitle("Support Ice Cubes")
.scrollContentBackground(.hidden)
.background(theme.secondaryBackgroundColor)
.alert("Thanks!", isPresented: $purchaseSuccessDisplayed, actions: {
Button { purchaseSuccessDisplayed = false } label: { Text("Ok") }
}, message: {
Text("Thanks you so much for your tip! It's greatly appreciated!")
})
.alert("Error!", isPresented: $purchaseErrorDisplayed, actions: {
Button { purchaseErrorDisplayed = false } label: { Text("Ok") }
}, message: {
Text("Error processing your in app purchase, please try again.")
})
.onAppear {
loadingProducts = true
2023-01-17 11:36:01 +01:00
Purchases.shared.getProducts(Tips.allCases.map { $0.productId }) { products in
2023-01-07 13:44:13 +01:00
self.products = products.sorted(by: { $0.price < $1.price })
2023-01-10 08:24:05 +01:00
withAnimation {
loadingProducts = false
}
2023-01-07 13:44:13 +01:00
}
}
}
}