Add supporter subscription + supporter badge

This commit is contained in:
Thomas Ricouard 2023-03-01 20:07:40 +01:00
parent a9e935016f
commit 81f3db733b
23 changed files with 382 additions and 84 deletions

View file

@ -28,6 +28,7 @@ struct IceCubesApp: App {
@State private var selectedTab: Tab = .timeline
@State private var popToRootTab: Tab = .other
@State private var sideBarLoadedTabs: Set<Tab> = Set()
@State private var isSupporter: Bool = false
private var availableTabs: [Tab] {
appAccountsManager.currentClient.isAuth ? Tab.loggedInTabs() : Tab.loggedOutTab()
@ -51,6 +52,7 @@ struct IceCubesApp: App {
.environmentObject(theme)
.environmentObject(watcher)
.environmentObject(pushNotificationsService)
.environment(\.isSupporter, isSupporter)
.fullScreenCover(item: $quickLook.url, content: { url in
QuickLookPreview(selectedURL: url, urls: quickLook.urls)
.edgesIgnoringSafeArea(.bottom)
@ -225,6 +227,11 @@ struct IceCubesApp: App {
private func setupRevenueCat() {
Purchases.logLevel = .error
Purchases.configure(withAPIKey: "appl_JXmiRckOzXXTsHKitQiicXCvMQi")
Purchases.shared.getCustomerInfo { info, _ in
if info?.entitlements.active.isEmpty == false {
isSupporter = true
}
}
}
private func refreshPushSubs() {

View file

@ -6,7 +6,7 @@ import SwiftUI
struct SupportAppView: View {
enum Tip: String, CaseIterable {
case one, two, three, four
case one, two, three, four, supporter
init(productId: String) {
self = .init(rawValue: String(productId.split(separator: ".")[2]))!
@ -26,6 +26,8 @@ struct SupportAppView: View {
return "settings.support.three.title"
case .four:
return "settings.support.four.title"
case .supporter:
return "settings.support.supporter.title"
}
}
@ -39,92 +41,31 @@ struct SupportAppView: View {
return "settings.support.three.subtitle"
case .four:
return "settings.support.four.subtitle"
case .supporter:
return "settings.support.supporter.subtitle"
}
}
}
@EnvironmentObject private var theme: Theme
@Environment(\.openURL) private var openURL
@State private var loadingProducts: Bool = false
@State private var products: [StoreProduct] = []
@State private var subscription: StoreProduct?
@State private var customerInfo: CustomerInfo?
@State private var isProcessingPurchase: Bool = false
@State private var purchaseSuccessDisplayed: Bool = false
@State private var purchaseErrorDisplayed: Bool = false
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")
}
}
.listRowBackground(theme.primaryBackgroundColor)
Section {
if loadingProducts {
HStack {
VStack(alignment: .leading) {
Text("placeholder.loading.short.")
.font(.scaledSubheadline)
Text("settings.support.placeholder.loading-subtitle")
.font(.scaledFootnote)
.foregroundColor(.gray)
}
.padding(.vertical, 8)
}
.redacted(reason: .placeholder)
.shimmering()
} else {
ForEach(products, id: \.productIdentifier) { product in
let tip = Tip(productId: product.productIdentifier)
HStack {
VStack(alignment: .leading) {
Text(tip.title)
.font(.scaledSubheadline)
Text(tip.subtitle)
.font(.scaledFootnote)
.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
}
}
} label: {
if isProcessingPurchase {
ProgressView()
} else {
Text(product.localizedPriceString)
}
}
.buttonStyle(.bordered)
}
.padding(.vertical, 8)
}
}
}
.listRowBackground(theme.primaryBackgroundColor)
aboutSection
subscriptionSection
tipsSection
restorePurchase
linksSection
}
.navigationTitle("settings.support.navigation-title")
.scrollContentBackground(.hidden)
@ -141,12 +82,191 @@ struct SupportAppView: View {
})
.onAppear {
loadingProducts = true
Purchases.shared.getProducts(Tip.allCases.map { $0.productId }) { products in
self.products = products.sorted(by: { $0.price < $1.price })
withAnimation {
loadingProducts = false
fetchStoreProducts()
refreshUserInfo()
}
}
private func purchase(product: StoreProduct) async {
if !isProcessingPurchase {
isProcessingPurchase = true
do {
let result = try await Purchases.shared.purchase(product: product)
if !result.userCancelled {
purchaseSuccessDisplayed = true
}
} catch {
purchaseErrorDisplayed = true
}
isProcessingPurchase = false
}
}
private func fetchStoreProducts() {
Purchases.shared.getProducts(Tip.allCases.map { $0.productId }) { products in
self.subscription = products.first(where: { $0.productIdentifier == Tip.supporter.productId })
self.products = products.filter{ $0.productIdentifier != Tip.supporter.productId}.sorted(by: { $0.price < $1.price })
withAnimation {
loadingProducts = false
}
}
}
private func refreshUserInfo() {
Purchases.shared.getCustomerInfo { info, _ in
self.customerInfo = info
}
}
private func makePurchaseButton(product: StoreProduct) -> some View {
Button {
Task {
await purchase(product: product)
refreshUserInfo()
}
} label: {
if isProcessingPurchase {
ProgressView()
} else {
Text(product.localizedPriceString)
}
}
.buttonStyle(.bordered)
}
private var aboutSection: some View {
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")
}
}
.listRowBackground(theme.primaryBackgroundColor)
}
private var subscriptionSection: some View {
Section {
if loadingProducts {
loadingPlaceholder
} else if let subscription {
HStack {
if customerInfo?.entitlements.active.isEmpty == false {
Text(Image(systemName: "checkmark.seal.fill"))
.foregroundColor(theme.tintColor)
.baselineOffset(-1) +
Text("settings.support.supporter.subscribed")
.font(.scaledSubheadline)
} else {
VStack(alignment: .leading) {
Text(Image(systemName: "checkmark.seal.fill"))
.foregroundColor(theme.tintColor)
.baselineOffset(-1) +
Text(Tip.supporter.title)
.font(.scaledSubheadline)
Text(Tip.supporter.subtitle)
.font(.scaledFootnote)
.foregroundColor(.gray)
}
Spacer()
makePurchaseButton(product: subscription)
}
}
.padding(.vertical, 8)
}
} footer: {
if customerInfo?.entitlements.active.isEmpty == true {
Text("settings.support.supporter.subscription-info")
}
}
.listRowBackground(theme.primaryBackgroundColor)
}
private var tipsSection: some View {
Section {
if loadingProducts {
loadingPlaceholder
} else {
ForEach(products, id: \.productIdentifier) { product in
let tip = Tip(productId: product.productIdentifier)
HStack {
VStack(alignment: .leading) {
Text(tip.title)
.font(.scaledSubheadline)
Text(tip.subtitle)
.font(.scaledFootnote)
.foregroundColor(.gray)
}
Spacer()
makePurchaseButton(product: product)
}
.padding(.vertical, 8)
}
}
}
.listRowBackground(theme.primaryBackgroundColor)
}
private var restorePurchase: some View {
Section {
HStack {
Spacer()
Button {
Purchases.shared.restorePurchases { info, _ in
self.customerInfo = info
}
} label: {
Text("settings.support.restore-purchase.button")
}.buttonStyle(.bordered)
Spacer()
}
} footer: {
Text("settings.support.restore-purchase.explanation")
}
.listRowBackground(theme.secondaryBackgroundColor)
}
private var linksSection: some View {
Section {
VStack(alignment: .leading, spacing: 16) {
Button {
openURL(URL(string: "https://github.com/Dimillian/IceCubesApp/blob/main/PRIVACY.MD")!)
} label: {
Text("settings.support.privacy-policy")
}
.buttonStyle(.borderless)
Button {
openURL(URL(string: "https://github.com/Dimillian/IceCubesApp/blob/main/TERMS.MD")!)
} label: {
Text("settings.support.terms-of-use")
}
.buttonStyle(.borderless)
}
}
.listRowBackground(theme.secondaryBackgroundColor)
}
private var loadingPlaceholder: some View {
HStack {
VStack(alignment: .leading) {
Text("placeholder.loading.short.")
.font(.scaledSubheadline)
Text("settings.support.placeholder.loading-subtitle")
.font(.scaledFootnote)
.foregroundColor(.gray)
}
.padding(.vertical, 8)
}
.redacted(reason: .placeholder)
.shimmering()
}
}

View file

@ -146,6 +146,14 @@
"settings.support.two.title" = "☕️ Прыемны Гасцінец";
"settings.support.four.title" = "👽 Хто ты Гасцінец";
"settings.support.four.subtitle" = "Гэта вельмі дапаможа Ice Cubes працаваць!";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "Дадайце мясцовую шкалу часу";
"settings.title" = "Налады";
"settings.rate" = "Ацаніце Ice Cubes";

View file

@ -141,6 +141,14 @@
"settings.support.two.title" = "☕️ Bona propina";
"settings.support.four.title" = "👽 Propina d'un altre món";
"settings.support.four.subtitle" = "Ajudarà molt a mantenir Ice Cubes en funcionament!";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "Afegeix una línia de temps local";
"settings.title" = "Configuració";
"settings.rate" = "Valora Ice Cubes";

View file

@ -122,6 +122,14 @@
"settings.support.two.title" = "☕️ Schönes Trinkgeld";
"settings.support.four.title" = "👽 Wahnsinns-Trinkgeld";
"settings.support.four.subtitle" = "Das wird eine große Hilfe sein, Ice Cubes am Laufen zu halten!";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "Lokale Timeline hinzufügen";
"settings.title" = "Einstellungen";
"settings.rate" = "Bewerte Ice Cubes";

View file

@ -147,6 +147,14 @@
"settings.support.two.title" = "☕️ Nice Tip";
"settings.support.four.title" = "👽 Who are you Tip";
"settings.support.four.subtitle" = "It'll go a long way to keep Ice Cubes running!";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "Add a Local Timeline";
"settings.title" = "Settings";
"settings.rate" = "Rate Ice Cubes";

View file

@ -146,6 +146,14 @@
"settings.support.two.title" = "☕️ Nice Tip";
"settings.support.four.title" = "👽 Who are you Tip";
"settings.support.four.subtitle" = "It'll go a long way to keep Ice Cubes running!";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "Add a Local Timeline";
"settings.title" = "Settings";
"settings.rate" = "Rate Ice Cubes";

View file

@ -122,6 +122,14 @@
"settings.support.two.title" = "☕️ Buena propina";
"settings.support.four.title" = "👽 Propina de otro mundo";
"settings.support.four.subtitle" = "¡Será de gran ayuda para que Ice Cubes siga funcionando!";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "Añadir cronología local";
"settings.title" = "Ajustes";
"settings.rate" = "Valora Ice Cubes";

View file

@ -122,6 +122,14 @@
"settings.support.two.title" = "☕️ Eskupeko ona";
"settings.support.four.title" = "👽 Nor zara zu, Tip";
"settings.support.four.subtitle" = "Askorako emango du eta Ice Cubes mantentzen lagunduko du!";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "Gehitu denbora-lerro lokal bat";
"settings.title" = "Ezarpenak";
"settings.rate" = "Baloratu Ice Cubes";

View file

@ -142,6 +142,14 @@
"settings.support.two.title" = "☕️ Belle contribution";
"settings.support.four.title" = "👽 Contribution Qui êtes-vous";
"settings.support.four.subtitle" = "Cela ira loin pour maintenir Ice Cubes en marche !";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "Ajouter une chronologie locale";
"settings.title" = "Réglages";
"settings.rate" = "Noter Ice Cubes";

View file

@ -122,6 +122,14 @@
"settings.support.two.title" = "☕️ Contributo carino";
"settings.support.four.title" = "👽 Contributo fuori dal mondo";
"settings.support.four.subtitle" = "Sarà di grande aiuto per mantenere Ice Cubes in funzione!";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "Aggiungi una timeline locale";
"settings.title" = "Impostazioni";
"settings.rate" = "Valuta Ice Cubes";

View file

@ -146,6 +146,14 @@
"settings.support.two.title" = "☕️ ナイスチップ";
"settings.support.four.title" = "👽 お前は一体誰なんだ";
"settings.support.four.subtitle" = "Ice Cubesの運営に大きく貢献することでしょう";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "ローカルタイムラインの追加";
"settings.title" = "設定";
"settings.rate" = "Ice Cubesを評価する";

View file

@ -142,6 +142,14 @@
"settings.support.two.title" = "☕️ 기분 좋아지는 기부금";
"settings.support.four.title" = "👽 엄청난 기부금";
"settings.support.four.subtitle" = "Ice Cubes가 계속 발전하는 데 정말 많은 도움이 될 거에요!";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "원격 로컬 타임라인 추가";
"settings.title" = "설정";
"settings.rate" = "Ice Cubes 평가 남기기";

View file

@ -146,6 +146,14 @@
"settings.support.two.title" = "☕️ Godt tips";
"settings.support.four.title" = "👽 Hvem er du tips";
"settings.support.four.subtitle" = "Det vil gå en lang vei å holde Ice Cubes i gang!";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "Legg til en lokal tidslinje";
"settings.title" = "Innstillinger";
"settings.rate" = "Vurder Ice Cubes";

View file

@ -123,6 +123,14 @@
"settings.support.two.title" = "☕️ Goeie fooi";
"settings.support.four.title" = "👽 Wie ben jij-fooi";
"settings.support.four.subtitle" = "Daarmee kan Ice Cubes nog een tijdje vooruit!";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "Lokale tijdlijn toevoegen";
"settings.title" = "Instellingen";
"settings.section.other" = "Overig";

View file

@ -142,6 +142,14 @@
"settings.support.two.title" = "☕️ Miły napiwek";
"settings.support.four.title" = "👽 Kim jesteś?";
"settings.support.four.subtitle" = "To pozwoli na utrzymywanie Ice Cubes w działaniu przez długi czas!";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "Dodaj strumień lokalny";
"settings.title" = "Ustawienia";
"settings.rate" = "Oceń Ice Cubes";

View file

@ -142,6 +142,14 @@
"settings.support.two.title" = "☕️ Corgeta legal";
"settings.support.four.title" = "👽 Quem é você Gorgeta";
"settings.support.four.subtitle" = "Percorrerá um longo caminho para manter o Ice Cubes funcionando!";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "Adicionar uma timeline local";
"settings.title" = "Configurações";
"settings.rate" = "Avalie o Ice Cubes";

View file

@ -142,6 +142,14 @@
"settings.support.two.title" = "☕️ Hoş Bağış";
"settings.support.four.title" = "👽 Sen de kimsin Bağışı";
"settings.support.four.subtitle" = "Bu, Ice Cubes'u daha uzun süre devam ettirmemize yardımcı olacak!";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "Yerel bir zaman dilimi ekleyin";
"settings.title" = "Ayarlar";
"settings.rate" = "Ice Cubes'u puanlayın";

View file

@ -146,6 +146,14 @@
"settings.support.two.title" = "☕️ Nice Tip";
"settings.support.four.title" = "👽 Who are you Tip";
"settings.support.four.subtitle" = "It'll go a long way to keep Ice Cubes running!";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "Додати локальну стрічку";
"settings.title" = "Налаштування";
"settings.rate" = "Оцінити Ice Cubes";

View file

@ -122,6 +122,14 @@
"settings.support.two.title" = "☕️ 很不错的捐赠";
"settings.support.four.title" = "👽 神秘人的捐赠";
"settings.support.four.subtitle" = "这将大大有助于 Ice Cubes 的持续运行!";
"settings.support.supporter.title" = " Become a supporter!";
"settings.support.supporter.subtitle" = "By giving a monthly tip to Ice Cubes, you become a supporter, you'll even get verified badge on your profile. For your 👀 only.";
"settings.support.supporter.subscribed" = " Thanks for being an Ice Cubes supporter!";
"settings.support.supporter.subscription-info"= "Subscription are automatically renewed unless you cancel them a day before the next renewal cycle.";
"settings.support.restore-purchase.button" = "Restore purchase";
"settings.support.restore-purchase.explanation" = "Restore your supporter subscription if it's haven't been automatically synced.";
"settings.support.privacy-policy" = "Privacy Policy";
"settings.support.terms-of-use" = "Terms";
"settings.timeline.add" = "添加远程时间线";
"settings.title" = "设置";
"settings.rate" = "给 Ice Cubes 评分";

View file

@ -16,6 +16,7 @@ struct AccountDetailHeaderView: View {
@EnvironmentObject private var routerPath: RouterPath
@EnvironmentObject private var currentAccount: CurrentAccount
@Environment(\.redactionReasons) private var reasons
@Environment(\.isSupporter) private var isSupporter: Bool
@ObservedObject var viewModel: AccountDetailViewModel
let account: Account
@ -85,15 +86,24 @@ struct AccountDetailHeaderView: View {
private var accountAvatarView: some View {
HStack {
AvatarView(url: account.avatar, size: .account)
.onTapGesture {
guard account.haveAvatar else {
return
}
Task {
await quickLook.prepareFor(urls: [account.avatar], selectedURL: account.avatar)
ZStack(alignment: .topTrailing) {
AvatarView(url: account.avatar, size: .account)
.onTapGesture {
guard account.haveAvatar else {
return
}
Task {
await quickLook.prepareFor(urls: [account.avatar], selectedURL: account.avatar)
}
}
if viewModel.isCurrentUser, isSupporter {
Image(systemName: "checkmark.seal.fill")
.resizable()
.frame(width: 25, height: 25)
.foregroundColor(theme.tintColor)
.offset(x: 10, y: -10)
}
}
Spacer()
Group {
Button {

View file

@ -17,6 +17,10 @@ private struct IsInCaptureMode: EnvironmentKey {
static let defaultValue: Bool = false
}
private struct IsSupporter: EnvironmentKey {
static let defaultValue: Bool = false
}
public extension EnvironmentValues {
var isSecondaryColumn: Bool {
get { self[SecondaryColumnKey.self] }
@ -37,4 +41,9 @@ public extension EnvironmentValues {
get { self[IsInCaptureMode.self] }
set { self[IsInCaptureMode.self] = newValue }
}
var isSupporter: Bool {
get { self[IsSupporter.self] }
set { self[IsSupporter.self] = newValue }
}
}

8
TERMS.MD Normal file
View file

@ -0,0 +1,8 @@
# Terms of Use
Use of Ice Cubes is governed by Apples Standard EULA for apps.
Tips provided in Ice Cubes do no unlock any additional content in the app.
Subscriptions will automatically renew unless canceled within 24-hours before the end of the current period. You can cancel anytime with your iTunes account settings. Any unused portion of a free trial will be forfeited if you purchase a subscription. Auto-renewal may be turned off by the user, by going to the users Account Settings after purchase. The duration and price of each subscription is displayed on the purchase screen, and updated at the time of purchase.
If you have any questions about Ice Cubes Terms of Use, please reach out to me at ricouard77@gmail.com