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

153 lines
4.6 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 {
2023-02-21 18:52:30 +01:00
enum Tip: String, CaseIterable {
2023-01-22 12:27:00 +01:00
case one, two, three, four
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-22 06:38:30 +01:00
var title: LocalizedStringKey {
2023-01-07 13:44:13 +01:00
switch self {
case .one:
return "settings.support.one.title"
2023-01-07 13:44:13 +01:00
case .two:
return "settings.support.two.title"
2023-01-07 13:44:13 +01:00
case .three:
return "settings.support.three.title"
2023-01-22 12:27:00 +01:00
case .four:
return "settings.support.four.title"
2023-01-07 13:44:13 +01:00
}
}
2023-01-22 06:38:30 +01:00
var subtitle: LocalizedStringKey {
2023-01-07 13:44:13 +01:00
switch self {
case .one:
return "settings.support.one.subtitle"
2023-01-07 13:44:13 +01:00
case .two:
return "settings.support.two.subtitle"
2023-01-07 13:44:13 +01:00
case .three:
return "settings.support.three.subtitle"
2023-01-22 12:27:00 +01:00
case .four:
return "settings.support.four.subtitle"
2023-01-07 13:44:13 +01:00
}
}
}
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("settings.support.message-from-dev")
2023-01-07 13:44:13 +01:00
}
}
.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("placeholder.loading.short.")
.font(.scaledSubheadline)
Text("settings.support.placeholder.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
2023-02-21 18:52:30 +01:00
let tip = Tip(productId: product.productIdentifier)
2023-01-07 13:44:13 +01:00
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 {
if !isProcessingPurchase {
isProcessingPurchase = true
Task {
do {
let result = try await Purchases.shared.purchase(product: product)
if !result.userCancelled {
purchaseSuccessDisplayed = true
}
} catch {
purchaseErrorDisplayed = true
}
isProcessingPurchase = false
2023-01-07 13:44:13 +01:00
}
}
} label: {
if isProcessingPurchase {
ProgressView()
} else {
Text(product.localizedPriceString)
}
}
.buttonStyle(.bordered)
}
.padding(.vertical, 8)
}
}
}
.listRowBackground(theme.primaryBackgroundColor)
}
.navigationTitle("settings.support.navigation-title")
2023-01-07 13:44:13 +01:00
.scrollContentBackground(.hidden)
.background(theme.secondaryBackgroundColor)
.alert("settings.support.alert.title", isPresented: $purchaseSuccessDisplayed, actions: {
Button { purchaseSuccessDisplayed = false } label: { Text("alert.button.ok") }
2023-01-07 13:44:13 +01:00
}, message: {
Text("settings.support.alert.message")
2023-01-07 13:44:13 +01:00
})
.alert("alert.error", isPresented: $purchaseErrorDisplayed, actions: {
Button { purchaseErrorDisplayed = false } label: { Text("alert.button.ok") }
2023-01-07 13:44:13 +01:00
}, message: {
Text("settings.support.alert.error.message")
2023-01-07 13:44:13 +01:00
})
.onAppear {
loadingProducts = true
2023-02-21 18:52:30 +01:00
Purchases.shared.getProducts(Tip.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
}
}
}
}