Compare commits

..

No commits in common. "07b6bf33cb376e4ac6ff448a13c09ae577454488" and "b85c0eb95dd2a034dd3fe0172990669ccd64f9d6" have entirely different histories.

3 changed files with 38 additions and 61 deletions

View File

@ -1,8 +1,5 @@
# Changelog # Changelog
## 2024.3 (133)
- Add additional info to Tip Jar
## 2024.3 (132) ## 2024.3 (132)
- Add ToS nag before signing in - Add ToS nag before signing in

View File

@ -32,12 +32,12 @@ struct TipJarView: View {
@StateObject private var observer = UbiquitousKeyValueStoreObserver() @StateObject private var observer = UbiquitousKeyValueStoreObserver()
var body: some View { var body: some View {
List { ZStack {
productsOrLoading Color.appGroupedBackground
} .edgesIgnoringSafeArea(.all)
.listStyle(.insetGrouped)
.appGroupedListBackground(container: PreferencesNavigationController.self) productsView
.overlay {
if showConfetti { if showConfetti {
ConfettiView() ConfettiView()
.transition(.opacity.animation(.default)) .transition(.opacity.animation(.default))
@ -75,66 +75,46 @@ struct TipJarView: View {
.onDisappear { .onDisappear {
updatesObserver?.cancel() updatesObserver?.cancel()
} }
.onChange(of: showConfetti) { newValue in .onReceive(Just(showConfetti).filter { $0 }.delay(for: .seconds(5), scheduler: DispatchQueue.main)) { _ in
if newValue { showConfetti = false
Task {
try await Task.sleep(nanoseconds: 5 * NSEC_PER_SEC)
showConfetti = false
}
}
} }
} }
@ViewBuilder @ViewBuilder
private var productsOrLoading: some View { private var productsView: some View {
if isLoaded { if isLoaded {
productsSections VStack {
} else { if !supporterProducts.isEmpty {
ProgressView() supporterSubscriptions
.progressViewStyle(.circular) }
.frame(maxWidth: .infinity, alignment: .center)
.listRowBackground(Color.clear) tipPurchases
}
} if let tipStatus {
@ViewBuilder
private var productsSections: some View {
if let tipStatus {
Section {
VStack(alignment: .leading) {
tipStatus tipStatus
.multilineTextAlignment(.leading) .multilineTextAlignment(.center)
.padding(.horizontal)
.padding(.top, 16)
Text("Thank you!") Text("Thank you!")
} }
} }
.appGroupedListRowBackground() } else {
ProgressView()
.progressViewStyle(.circular)
} }
if !supporterProducts.isEmpty {
supporterSection
}
tipSection
} }
private var supporterSection: some View { @ViewBuilder
Section { private var supporterSubscriptions: some View {
Text("If you want to contribute Tusker's continued development, you can become a supporter and give a montly tip.") Text("If you want to contribute Tusker's continued development, you can become a supporter. Supporting Tusker is an auto-renewable monthly subscription.")
.multilineTextAlignment(.leading) .multilineTextAlignment(.center)
.padding(.horizontal)
VStack(alignment: .myAlignment) {
ForEach($supporterProducts, id: \.0.id) { $productAndPurchasing in ForEach($supporterProducts, id: \.0.id) { $productAndPurchasing in
TipRow(product: productAndPurchasing.0, buttonWidth: supporterButtonWidth, isPurchasing: $productAndPurchasing.1, showConfetti: $showConfetti) TipRow(product: productAndPurchasing.0, buttonWidth: supporterButtonWidth, isPurchasing: $productAndPurchasing.1, showConfetti: $showConfetti)
} }
} footer: {
VStack {
var privacyPolicy: AttributedString = "Privacy Policy"
let _ = privacyPolicy.link = URL(string: "https://vaccor.space/tusker#privacy")!
var eula: AttributedString = "EULA"
let _ = eula.link = URL(string: "https://www.apple.com/legal/internet-services/itunes/dev/stdeula/")!
Text(AttributedString("Supporting Tusker is an auto-renewable monthly subscription. Subscribing does not provide additional features or capabilities.\n") + privacyPolicy + AttributedString(" and ") + eula)
}
} }
.appGroupedListRowBackground()
.onPreferenceChange(ButtonWidthKey.self) { newValue in .onPreferenceChange(ButtonWidthKey.self) { newValue in
if let supporterButtonWidth { if let supporterButtonWidth {
self.supporterButtonWidth = max(supporterButtonWidth, newValue) self.supporterButtonWidth = max(supporterButtonWidth, newValue)
@ -144,16 +124,18 @@ struct TipJarView: View {
} }
} }
private var tipSection: some View { @ViewBuilder
Section { private var tipPurchases: some View {
Text("Or, you can choose to make a one-time tip to show your gratitutde or help support the app's development. It is greatly appreciated!") Text("Or, you can choose to make a one-time tip to show your gratitutde or help support the app's development. It is greatly appreciated!")
.multilineTextAlignment(.leading) .multilineTextAlignment(.center)
.padding(.horizontal)
.padding(.top, 16)
VStack(alignment: .myAlignment) {
ForEach($tipProducts, id: \.0.id) { $productAndPurchasing in ForEach($tipProducts, id: \.0.id) { $productAndPurchasing in
TipRow(product: productAndPurchasing.0, buttonWidth: tipButtonWidth, isPurchasing: $productAndPurchasing.1, showConfetti: $showConfetti) TipRow(product: productAndPurchasing.0, buttonWidth: tipButtonWidth, isPurchasing: $productAndPurchasing.1, showConfetti: $showConfetti)
} }
} }
.appGroupedListRowBackground()
.onPreferenceChange(ButtonWidthKey.self) { newValue in .onPreferenceChange(ButtonWidthKey.self) { newValue in
if let tipButtonWidth { if let tipButtonWidth {
self.tipButtonWidth = max(tipButtonWidth, newValue) self.tipButtonWidth = max(tipButtonWidth, newValue)
@ -249,8 +231,6 @@ private struct TipRow: View {
Text(product.displayName) Text(product.displayName)
.alignmentGuide(.myAlignment, computeValue: { context in context[.trailing] }) .alignmentGuide(.myAlignment, computeValue: { context in context[.trailing] })
Spacer()
if let subscription = product.subscription { if let subscription = product.subscription {
SubscriptionButton(product: product, subscriptionInfo: subscription, isPurchasing: $isPurchasing, buttonWidth: buttonWidth, purchase: purchase) SubscriptionButton(product: product, subscriptionInfo: subscription, isPurchasing: $isPurchasing, buttonWidth: buttonWidth, purchase: purchase)
} else { } else {

View File

@ -10,7 +10,7 @@
// https://help.apple.com/xcode/#/dev745c5c974 // https://help.apple.com/xcode/#/dev745c5c974
MARKETING_VERSION = 2024.3 MARKETING_VERSION = 2024.3
CURRENT_PROJECT_VERSION = 133 CURRENT_PROJECT_VERSION = 132
CURRENT_PROJECT_VERSION = $(inherited)$(CURRENT_PROJECT_VERSION_BUILD_SUFFIX_$(CONFIGURATION)) CURRENT_PROJECT_VERSION = $(inherited)$(CURRENT_PROJECT_VERSION_BUILD_SUFFIX_$(CONFIGURATION))
CURRENT_PROJECT_VERSION_BUILD_SUFFIX_Debug=-dev CURRENT_PROJECT_VERSION_BUILD_SUFFIX_Debug=-dev