Refactor and add legal links to payment pages, change contribute view's layout

This commit is contained in:
maddiebaka 2024-01-20 23:50:07 -05:00
parent 32b3ab5ee1
commit 0f2cf4af04
6 changed files with 154 additions and 50 deletions

View File

@ -497,7 +497,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.2; MARKETING_VERSION = 1.3;
PRODUCT_BUNDLE_IDENTIFIER = "info.maddie.Toki-Trainer.Toki-Trainer-Widgets"; PRODUCT_BUNDLE_IDENTIFIER = "info.maddie.Toki-Trainer.Toki-Trainer-Widgets";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
@ -524,7 +524,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.2; MARKETING_VERSION = 1.3;
PRODUCT_BUNDLE_IDENTIFIER = "info.maddie.Toki-Trainer.Toki-Trainer-Widgets"; PRODUCT_BUNDLE_IDENTIFIER = "info.maddie.Toki-Trainer.Toki-Trainer-Widgets";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
@ -678,7 +678,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.2; MARKETING_VERSION = 1.3;
PRODUCT_BUNDLE_IDENTIFIER = "info.maddie.Toki-Trainer"; PRODUCT_BUNDLE_IDENTIFIER = "info.maddie.Toki-Trainer";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_EMIT_LOC_STRINGS = YES;
@ -713,7 +713,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.2; MARKETING_VERSION = 1.3;
PRODUCT_BUNDLE_IDENTIFIER = "info.maddie.Toki-Trainer"; PRODUCT_BUNDLE_IDENTIFIER = "info.maddie.Toki-Trainer";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_EMIT_LOC_STRINGS = YES;

View File

@ -25,7 +25,14 @@
}, },
"Contribute" : { "Contribute" : {
"localizations" : {
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Contribuer"
}
}
}
}, },
"Correct" : { "Correct" : {
"localizations" : { "localizations" : {
@ -58,10 +65,24 @@
} }
}, },
"Donate Monthly" : { "Donate Monthly" : {
"localizations" : {
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Faire un don mensuel"
}
}
}
}, },
"Donate Once" : { "Donate Once" : {
"localizations" : {
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Don unique"
}
}
}
}, },
"Enter Toki Pona Word or Phrase" : { "Enter Toki Pona Word or Phrase" : {
"localizations" : { "localizations" : {
@ -124,7 +145,14 @@
} }
}, },
"One-Time Donation" : { "One-Time Donation" : {
"localizations" : {
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Don unique"
}
}
}
}, },
"Parts of Speech" : { "Parts of Speech" : {
"localizations" : { "localizations" : {
@ -155,6 +183,9 @@
} }
} }
} }
},
"Privacy Policy" : {
}, },
"Results" : { "Results" : {
"localizations" : { "localizations" : {
@ -186,8 +217,21 @@
} }
} }
}, },
"Thank you for donating!" : { "Source Code" : {
},
"Terms of Use" : {
},
"Thank you for donating!" : {
"localizations" : {
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Merci pour votre don !"
}
}
}
}, },
"Words" : { "Words" : {
"localizations" : { "localizations" : {
@ -200,7 +244,14 @@
} }
}, },
"Write Review" : { "Write Review" : {
"localizations" : {
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ecrire une critique"
}
}
}
} }
}, },
"version" : "1.0" "version" : "1.0"

View File

@ -1,5 +1,5 @@
// //
// Store.swift // TransactionObserver.swift
// Toki Trainer // Toki Trainer
// //
// Created by Madeline Pace on 12/18/23. // Created by Madeline Pace on 12/18/23.
@ -82,7 +82,6 @@ final class TransactionObserver: ObservableObject {
} }
func processSubscription(_ productID: String) { func processSubscription(_ productID: String) {
// TODO: Write function
print("Subscription ID: \(productID)") print("Subscription ID: \(productID)")
switch productID { switch productID {
case K.MonthlyTransactions.TierOne: case K.MonthlyTransactions.TierOne:

View File

@ -36,6 +36,7 @@ Please also consider donating financially if you can. 💕
private var recurringIAPs = ["TierThree"] private var recurringIAPs = ["TierThree"]
@EnvironmentObject var transactions: TransactionObserver @EnvironmentObject var transactions: TransactionObserver
@ -49,8 +50,16 @@ Please also consider donating financially if you can. 💕
Text(supportString) Text(supportString)
.padding(16) .padding(16)
Spacer() Spacer()
// Link("Source Code", destination: URL(string: "https://git.corrupt.link/maddiefuzz/TokiTrainer")!)
// .padding(12)
// .padding([.bottom], 12)
HStack { HStack {
ReviewButton() ReviewButton()
SourceCodeButton()
}
HStack {
SingleDonationButton() SingleDonationButton()
RecurringDonationButton() RecurringDonationButton()
} }
@ -82,6 +91,21 @@ struct ThankYouBannerView: View {
} }
} }
struct SourceCodeButton: View {
var body: some View {
Link(destination: URL(string: "https://git.corrupt.link/maddiefuzz/TokiTrainer")!) {
VStack {
Image(systemName: "apple.terminal")
.font(.system(size: 24, weight: .regular))
.padding(2)
Text("Source Code")
}
}
.frame(width: 100)
.padding(8)
}
}
// MARK: ReviewButton // MARK: ReviewButton
struct ReviewButton: View { struct ReviewButton: View {
@Environment(\.requestReview) private var requestReview @Environment(\.requestReview) private var requestReview
@ -98,7 +122,7 @@ struct ReviewButton: View {
Text("Write Review") Text("Write Review")
} }
}) })
.frame(width: 80) .frame(width: 100)
.padding(8) .padding(8)
} }
@ -144,42 +168,51 @@ struct SingleDonationButton: View {
Text("Donate Once") Text("Donate Once")
} }
} }
.frame(width: 80) .frame(width: 100)
.padding(8) .padding(8)
.sheet(item: self.$IAPs) { IAPs in .sheet(item: self.$IAPs) { IAPs in
if(productsFetched) { if(productsFetched) {
Text("One-Time Donation") VStack {
.font(.largeTitle) Spacer()
ForEach(IAPs.products) { product in Text("One-Time Donation")
HStack { .font(.largeTitle)
VStack { Spacer()
Text(product.displayName) ForEach(IAPs.products) { product in
.font(.title) HStack {
.frame(maxWidth: .infinity, alignment: .leading) VStack {
Text(product.description) Text(product.displayName)
.frame(maxWidth: .infinity, alignment: .leading) .font(.title)
} .frame(maxWidth: .infinity, alignment: .leading)
.padding(.leading, 12) Text(product.description)
Spacer() .frame(maxWidth: .infinity, alignment: .leading)
Button {
print("Purchase this one: \(product)")
disabledPurchaseButtons = true
Task {
let _ = try? await purchase(product)
disabledPurchaseButtons = false
} }
} label: { .padding(.leading, 12)
Text(product.displayPrice) Spacer()
.frame(minWidth: 50) Button {
.padding(8) print("Purchase this one: \(product)")
.fontWeight(/*@START_MENU_TOKEN@*/.bold/*@END_MENU_TOKEN@*/) disabledPurchaseButtons = true
Task {
let _ = try? await purchase(product)
disabledPurchaseButtons = false
}
} label: {
Text(product.displayPrice)
.frame(minWidth: 50)
.padding(8)
.fontWeight(/*@START_MENU_TOKEN@*/.bold/*@END_MENU_TOKEN@*/)
}
.padding(.trailing, 12)
.buttonStyle(.bordered)
.disabled(disabledPurchaseButtons)
} }
.padding(.trailing, 12) .padding(12)
.buttonStyle(.bordered)
.disabled(disabledPurchaseButtons)
} }
.padding(12) Spacer()
LegalLinksView()
.padding(16)
.padding([.bottom], 20)
} }
//.padding([.top], 60)
} else { } else {
ProgressView() ProgressView()
} }
@ -244,14 +277,35 @@ struct RecurringDonationButton: View {
Text("Donate Monthly") Text("Donate Monthly")
} }
} }
.frame(width: 80) .frame(width: 100)
.padding(8) .padding(8)
.sheet(isPresented: $toggleSheet, content: { .sheet(isPresented: $toggleSheet, content: {
SubscriptionStoreView(groupID: self.groupID) VStack {
SubscriptionStoreView(groupID: self.groupID)
// HStack {
// Link("Terms of Use", destination: URL(string: "https://www.apple.com/legal/internet-services/itunes/dev/stdeula/")!)
// .padding(12)
// Link("Privacy Policy", destination: URL(string: "https://maddie.info/null_privacy_policy")!)
// }
LegalLinksView()
.padding(16)
.padding([.bottom], 20)
}
}) })
} }
} }
struct LegalLinksView: View {
var body: some View {
HStack {
Link("Terms of Use", destination: URL(string: "https://www.apple.com/legal/internet-services/itunes/dev/stdeula/")!)
.padding(12)
Link("Privacy Policy", destination: URL(string: "https://maddie.info/null_privacy_policy")!)
}
}
}
#Preview { #Preview {
ContributeView().environmentObject(TransactionObserver()) ContributeView().environmentObject(TransactionObserver())
} }

View File

@ -52,7 +52,7 @@ struct DictionaryView: View {
}) })
.buttonStyle(.bordered) .buttonStyle(.bordered)
} }
.padding([.top, .leading, .trailing], 8) .padding([.top, .leading, .trailing], 16)
if advancedSearchEnabled == true { if advancedSearchEnabled == true {
VStack { VStack {
Text("Search for:") Text("Search for:")
@ -88,7 +88,7 @@ struct DictionaryView: View {
.sheet(isPresented: $showGenericLegend, content: { .sheet(isPresented: $showGenericLegend, content: {
PartsOfSpeechView(selectedPartOfSpeech: nil) PartsOfSpeechView(selectedPartOfSpeech: nil)
}) })
.onChange(of: tokiInput) { newValue in .onChange(of: tokiInput) {
filterByInput() filterByInput()
//tokiDictViewModel.filterDictionaryEnglishMode(newValue) //tokiDictViewModel.filterDictionaryEnglishMode(newValue)
} }

View File

@ -31,8 +31,8 @@ struct TranslatorView: View {
} }
.buttonStyle(.borderedProminent) .buttonStyle(.borderedProminent)
} }
.padding([.top, .leading, .trailing], 8) .padding([.top, .leading, .trailing], 16)
if tokiInput.count == 0 { if tokiInput.count == 0 {
List(tokiDictViewModel.dictionary, id: \.word) { entry in List(tokiDictViewModel.dictionary, id: \.word) { entry in
TokiWordsListEntryView(entry: entry, selectedPartOfSpeech: $selectedPartOfSpeech) TokiWordsListEntryView(entry: entry, selectedPartOfSpeech: $selectedPartOfSpeech)
@ -52,8 +52,8 @@ struct TranslatorView: View {
.sheet(item: $selectedPartOfSpeech) { selectedPOS in .sheet(item: $selectedPartOfSpeech) { selectedPOS in
PartsOfSpeechView(selectedPartOfSpeech: selectedPOS) PartsOfSpeechView(selectedPartOfSpeech: selectedPOS)
} }
.onChange(of: tokiInput) { newValue in .onChange(of: tokiInput) {
tokiDictViewModel.translatePhrase(newValue) tokiDictViewModel.translatePhrase(tokiInput)
} }
.onTapGesture { .onTapGesture {
hideKeyboard() hideKeyboard()