diff --git a/IceCubesApp/App/IceCubesApp.swift b/IceCubesApp/App/IceCubesApp.swift index fd015eb3..cf3f4189 100644 --- a/IceCubesApp/App/IceCubesApp.swift +++ b/IceCubesApp/App/IceCubesApp.swift @@ -28,6 +28,7 @@ struct IceCubesApp: App { @State private var selectedTab: Tab = .timeline @State private var popToRootTab: Tab = .other @State private var sideBarLoadedTabs: Set = 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() { diff --git a/IceCubesApp/App/Tabs/Settings/SupportAppView.swift b/IceCubesApp/App/Tabs/Settings/SupportAppView.swift index 468e46aa..9bffe442 100644 --- a/IceCubesApp/App/Tabs/Settings/SupportAppView.swift +++ b/IceCubesApp/App/Tabs/Settings/SupportAppView.swift @@ -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() + } } diff --git a/IceCubesApp/Resources/Localization/be.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/be.lproj/Localizable.strings index 6c8d25bc..3dde5616 100644 --- a/IceCubesApp/Resources/Localization/be.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/be.lproj/Localizable.strings @@ -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"; diff --git a/IceCubesApp/Resources/Localization/ca.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/ca.lproj/Localizable.strings index cbe1a8ab..cdc76d72 100644 --- a/IceCubesApp/Resources/Localization/ca.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/ca.lproj/Localizable.strings @@ -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"; diff --git a/IceCubesApp/Resources/Localization/de.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/de.lproj/Localizable.strings index 4114b986..7b184302 100644 --- a/IceCubesApp/Resources/Localization/de.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/de.lproj/Localizable.strings @@ -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"; diff --git a/IceCubesApp/Resources/Localization/en-GB.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/en-GB.lproj/Localizable.strings index b8d3096a..672d0d17 100644 --- a/IceCubesApp/Resources/Localization/en-GB.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/en-GB.lproj/Localizable.strings @@ -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"; diff --git a/IceCubesApp/Resources/Localization/en.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/en.lproj/Localizable.strings index 6f45199f..07f99a55 100644 --- a/IceCubesApp/Resources/Localization/en.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/en.lproj/Localizable.strings @@ -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"; diff --git a/IceCubesApp/Resources/Localization/es.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/es.lproj/Localizable.strings index 9200b9c6..3d5e0d28 100644 --- a/IceCubesApp/Resources/Localization/es.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/es.lproj/Localizable.strings @@ -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"; diff --git a/IceCubesApp/Resources/Localization/eu.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/eu.lproj/Localizable.strings index 1620c8a9..5be8bc06 100644 --- a/IceCubesApp/Resources/Localization/eu.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/eu.lproj/Localizable.strings @@ -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"; diff --git a/IceCubesApp/Resources/Localization/fr.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/fr.lproj/Localizable.strings index 53b33dd6..fda15d6d 100644 --- a/IceCubesApp/Resources/Localization/fr.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/fr.lproj/Localizable.strings @@ -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"; diff --git a/IceCubesApp/Resources/Localization/it.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/it.lproj/Localizable.strings index 18a5a059..5f85cf2e 100644 --- a/IceCubesApp/Resources/Localization/it.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/it.lproj/Localizable.strings @@ -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"; diff --git a/IceCubesApp/Resources/Localization/ja.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/ja.lproj/Localizable.strings index fb20ca78..d27c068b 100644 --- a/IceCubesApp/Resources/Localization/ja.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/ja.lproj/Localizable.strings @@ -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を評価する"; diff --git a/IceCubesApp/Resources/Localization/ko.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/ko.lproj/Localizable.strings index 01905580..040cde42 100644 --- a/IceCubesApp/Resources/Localization/ko.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/ko.lproj/Localizable.strings @@ -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 평가 남기기"; diff --git a/IceCubesApp/Resources/Localization/nb.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/nb.lproj/Localizable.strings index 7a05e272..52b1a6b2 100644 --- a/IceCubesApp/Resources/Localization/nb.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/nb.lproj/Localizable.strings @@ -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"; diff --git a/IceCubesApp/Resources/Localization/nl.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/nl.lproj/Localizable.strings index 82e93eb6..a3d29db6 100644 --- a/IceCubesApp/Resources/Localization/nl.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/nl.lproj/Localizable.strings @@ -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"; diff --git a/IceCubesApp/Resources/Localization/pl.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/pl.lproj/Localizable.strings index 9e9c8d11..6ced9ed8 100644 --- a/IceCubesApp/Resources/Localization/pl.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/pl.lproj/Localizable.strings @@ -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"; diff --git a/IceCubesApp/Resources/Localization/pt-BR.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/pt-BR.lproj/Localizable.strings index 958834b6..235b544e 100644 --- a/IceCubesApp/Resources/Localization/pt-BR.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/pt-BR.lproj/Localizable.strings @@ -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"; diff --git a/IceCubesApp/Resources/Localization/tr.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/tr.lproj/Localizable.strings index 47ecc3f9..c73953db 100644 --- a/IceCubesApp/Resources/Localization/tr.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/tr.lproj/Localizable.strings @@ -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"; diff --git a/IceCubesApp/Resources/Localization/uk.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/uk.lproj/Localizable.strings index 8558e136..ff52a609 100644 --- a/IceCubesApp/Resources/Localization/uk.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/uk.lproj/Localizable.strings @@ -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"; diff --git a/IceCubesApp/Resources/Localization/zh-Hans.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/zh-Hans.lproj/Localizable.strings index 12862836..1fc5f7c2 100644 --- a/IceCubesApp/Resources/Localization/zh-Hans.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/zh-Hans.lproj/Localizable.strings @@ -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 评分"; diff --git a/Packages/Account/Sources/Account/AccountDetailHeaderView.swift b/Packages/Account/Sources/Account/AccountDetailHeaderView.swift index ce4be75c..da9f19f2 100644 --- a/Packages/Account/Sources/Account/AccountDetailHeaderView.swift +++ b/Packages/Account/Sources/Account/AccountDetailHeaderView.swift @@ -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 { diff --git a/Packages/Env/Sources/Env/CustomEnvValues.swift b/Packages/Env/Sources/Env/CustomEnvValues.swift index 528822b5..935ca262 100644 --- a/Packages/Env/Sources/Env/CustomEnvValues.swift +++ b/Packages/Env/Sources/Env/CustomEnvValues.swift @@ -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 } + } } diff --git a/TERMS.MD b/TERMS.MD new file mode 100644 index 00000000..c398a53c --- /dev/null +++ b/TERMS.MD @@ -0,0 +1,8 @@ +# Terms of Use +Use of Ice Cubes is governed by Apple’s 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 user’s 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