mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2025-01-11 00:25:35 +00:00
Merge branch 'main' into iOS-18
This commit is contained in:
commit
3f6c3a024a
5 changed files with 77 additions and 39 deletions
|
@ -30,19 +30,19 @@ struct AboutView: View {
|
||||||
#if !targetEnvironment(macCatalyst) && !os(visionOS)
|
#if !targetEnvironment(macCatalyst) && !os(visionOS)
|
||||||
HStack {
|
HStack {
|
||||||
Spacer()
|
Spacer()
|
||||||
Image(uiImage: .init(named: "AppIconAlternate0")!)
|
Image(uiImage: .init(named: "AppIconAlternate0") ?? .init())
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(width: 50, height: 50)
|
.frame(width: 50, height: 50)
|
||||||
.cornerRadius(4)
|
.cornerRadius(4)
|
||||||
Image(uiImage: .init(named: "AppIconAlternate4")!)
|
Image(uiImage: .init(named: "AppIconAlternate4") ?? .init())
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(width: 50, height: 50)
|
.frame(width: 50, height: 50)
|
||||||
.cornerRadius(4)
|
.cornerRadius(4)
|
||||||
Image(uiImage: .init(named: "AppIconAlternate17")!)
|
Image(uiImage: .init(named: "AppIconAlternate17") ?? .init())
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(width: 50, height: 50)
|
.frame(width: 50, height: 50)
|
||||||
.cornerRadius(4)
|
.cornerRadius(4)
|
||||||
Image(uiImage: .init(named: "AppIconAlternate23")!)
|
Image(uiImage: .init(named: "AppIconAlternate23") ?? .init())
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(width: 50, height: 50)
|
.frame(width: 50, height: 50)
|
||||||
.cornerRadius(4)
|
.cornerRadius(4)
|
||||||
|
@ -64,6 +64,15 @@ struct AboutView: View {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
followAccountsSection
|
followAccountsSection
|
||||||
|
|
||||||
|
Section("Telemetry") {
|
||||||
|
Link(destination: .init(string: "https://telemetrydeck.com")!) {
|
||||||
|
Label("Telemetry by TelemtryDeck", systemImage: "link")
|
||||||
|
}
|
||||||
|
Link(destination: .init(string: "https://telemetrydeck.com/privacy/")!) {
|
||||||
|
Label("Privacy Policy", systemImage: "checkmark.shield")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Section {
|
Section {
|
||||||
Text("""
|
Text("""
|
||||||
|
|
|
@ -41802,6 +41802,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"Privacy Policy" : {
|
||||||
|
|
||||||
},
|
},
|
||||||
"Private" : {
|
"Private" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
|
@ -78620,6 +78623,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"Telemetry" : {
|
||||||
|
|
||||||
|
},
|
||||||
|
"Telemetry by TelemtryDeck" : {
|
||||||
|
|
||||||
},
|
},
|
||||||
"The DeepL API Key is still stored!" : {
|
"The DeepL API Key is still stored!" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
|
|
|
@ -4,21 +4,25 @@ import Env
|
||||||
import Models
|
import Models
|
||||||
import NukeUI
|
import NukeUI
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import AppAccount
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
struct AccountDetailHeaderView: View {
|
struct AccountDetailHeaderView: View {
|
||||||
enum Constants {
|
enum Constants {
|
||||||
static let headerHeight: CGFloat = 200
|
static let headerHeight: CGFloat = 200
|
||||||
}
|
}
|
||||||
|
|
||||||
@Environment(\.openWindow) private var openWindow
|
@Environment(\.openWindow) private var openWindow
|
||||||
@Environment(Theme.self) private var theme
|
@Environment(Theme.self) private var theme
|
||||||
@Environment(QuickLook.self) private var quickLook
|
@Environment(QuickLook.self) private var quickLook
|
||||||
@Environment(RouterPath.self) private var routerPath
|
@Environment(RouterPath.self) private var routerPath
|
||||||
@Environment(CurrentAccount.self) private var currentAccount
|
@Environment(CurrentAccount.self) private var currentAccount
|
||||||
@Environment(StreamWatcher.self) private var watcher
|
@Environment(StreamWatcher.self) private var watcher
|
||||||
|
@Environment(AppAccountsManager.self) private var appAccount
|
||||||
@Environment(\.redactionReasons) private var reasons
|
@Environment(\.redactionReasons) private var reasons
|
||||||
@Environment(\.isSupporter) private var isSupporter: Bool
|
@Environment(\.isSupporter) private var isSupporter: Bool
|
||||||
|
@Environment(\.openURL) private var openURL
|
||||||
|
@Environment(\.colorScheme) private var colorScheme
|
||||||
|
|
||||||
var viewModel: AccountDetailViewModel
|
var viewModel: AccountDetailViewModel
|
||||||
let account: Account
|
let account: Account
|
||||||
|
@ -241,7 +245,7 @@ struct AccountDetailHeaderView: View {
|
||||||
movedToView
|
movedToView
|
||||||
joinedAtView
|
joinedAtView
|
||||||
if viewModel.account?.isPremiumAccount == true && viewModel.relationship?.following == false || viewModel.account?.isLinkedToPremiumAccount == true && viewModel.premiumRelationship?.following == false {
|
if viewModel.account?.isPremiumAccount == true && viewModel.relationship?.following == false || viewModel.account?.isLinkedToPremiumAccount == true && viewModel.premiumRelationship?.following == false {
|
||||||
tipView
|
subscribeButton
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.accessibilityElement(children: .contain)
|
.accessibilityElement(children: .contain)
|
||||||
|
@ -342,18 +346,31 @@ struct AccountDetailHeaderView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var tipView: some View {
|
private var subscribeButton: some View {
|
||||||
Button {
|
Button {
|
||||||
isTipSheetPresented = true
|
if let subscription = viewModel.subClubUser?.subscription,
|
||||||
shouldListenToPremiumTimer = true
|
let accountName = appAccount.currentAccount.accountName,
|
||||||
|
let premiumUsername = account.premiumUsername,
|
||||||
|
let url = URL(string: "https://\(AppInfo.premiumInstance)/@\(premiumUsername)/subscribe?callback=icecubesapp://subclub&id=@\(accountName)&amount=\(subscription.unitAmount)¤cy=\(subscription.currency)&theme=\(colorScheme)") {
|
||||||
|
openURL(url)
|
||||||
|
} else {
|
||||||
|
isTipSheetPresented = true
|
||||||
|
shouldListenToPremiumTimer = true
|
||||||
|
}
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
if viewModel.account?.isLinkedToPremiumAccount == true {
|
if viewModel.account?.isLinkedToPremiumAccount == true {
|
||||||
try? await viewModel.followPremiumAccount()
|
try? await viewModel.followPremiumAccount()
|
||||||
}
|
}
|
||||||
try? await viewModel.followButtonViewModel?.follow()
|
try? await viewModel.followButtonViewModel?.follow()
|
||||||
}
|
}
|
||||||
|
|
||||||
} label: {
|
} label: {
|
||||||
Text("$ Subscribe")
|
if let subscription = viewModel.subClubUser?.subscription {
|
||||||
|
Text("Subscribe \(subscription.formattedAmount) / month")
|
||||||
|
} else {
|
||||||
|
Text("$ Subscribe")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.buttonStyle(.bordered)
|
.buttonStyle(.bordered)
|
||||||
.padding(.top, 8)
|
.padding(.top, 8)
|
||||||
|
|
|
@ -79,8 +79,11 @@ import SwiftUI
|
||||||
var fields: [Account.Field] = []
|
var fields: [Account.Field] = []
|
||||||
var familiarFollowers: [Account] = []
|
var familiarFollowers: [Account] = []
|
||||||
|
|
||||||
|
// Sub.club stuff
|
||||||
var premiumAccount: Account?
|
var premiumAccount: Account?
|
||||||
var premiumRelationship: Relationship?
|
var premiumRelationship: Relationship?
|
||||||
|
var subClubUser: SubClubUser?
|
||||||
|
private let subClubClient = SubClubClient()
|
||||||
|
|
||||||
var selectedTab = Tab.statuses {
|
var selectedTab = Tab.statuses {
|
||||||
didSet {
|
didSet {
|
||||||
|
@ -333,9 +336,12 @@ extension AccountDetailViewModel {
|
||||||
forceVersion: .v2)
|
forceVersion: .v2)
|
||||||
if let premiumAccount = results?.accounts.first {
|
if let premiumAccount = results?.accounts.first {
|
||||||
self.premiumAccount = premiumAccount
|
self.premiumAccount = premiumAccount
|
||||||
|
await fetchSubClubAccount(premiumUsername: premiumAccount.username)
|
||||||
let relationships: [Relationship] = try await client.get(endpoint: Accounts.relationships(ids: [premiumAccount.id]))
|
let relationships: [Relationship] = try await client.get(endpoint: Accounts.relationships(ids: [premiumAccount.id]))
|
||||||
self.premiumRelationship = relationships.first
|
self.premiumRelationship = relationships.first
|
||||||
}
|
}
|
||||||
|
} else if fromAccount.isPremiumAccount {
|
||||||
|
await fetchSubClubAccount(premiumUsername: fromAccount.username)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,4 +352,9 @@ extension AccountDetailViewModel {
|
||||||
reblogs: true))
|
reblogs: true))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func fetchSubClubAccount(premiumUsername: String) async {
|
||||||
|
let user = await subClubClient.getUser(username: premiumUsername)
|
||||||
|
subClubUser = user
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,8 @@ struct NotificationsPolicyView: View {
|
||||||
})) {
|
})) {
|
||||||
pickerMenu
|
pickerMenu
|
||||||
} label: {
|
} label: {
|
||||||
VStack(alignment: .leading) {
|
makePickerLabel(title: "notifications.content-filter.peopleYouDontFollow",
|
||||||
Text("notifications.content-filter.peopleYouDontFollow")
|
subtitle: "Until you manually approve them")
|
||||||
Text("Until you manually approve them")
|
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
.font(.footnote)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Picker(selection: .init(get: {
|
Picker(selection: .init(get: {
|
||||||
|
@ -41,12 +37,8 @@ struct NotificationsPolicyView: View {
|
||||||
})) {
|
})) {
|
||||||
pickerMenu
|
pickerMenu
|
||||||
} label: {
|
} label: {
|
||||||
VStack(alignment: .leading) {
|
makePickerLabel(title: "notifications.content-filter.peopleNotFollowingYou",
|
||||||
Text("notifications.content-filter.peopleNotFollowingYou")
|
subtitle: "And following you for less than 3 days")
|
||||||
Text("And following you for less than 3 days")
|
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
.font(.footnote)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Picker(selection: .init(get: {
|
Picker(selection: .init(get: {
|
||||||
|
@ -57,12 +49,8 @@ struct NotificationsPolicyView: View {
|
||||||
})) {
|
})) {
|
||||||
pickerMenu
|
pickerMenu
|
||||||
} label: {
|
} label: {
|
||||||
VStack(alignment: .leading) {
|
makePickerLabel(title: "notifications.content-filter.newAccounts",
|
||||||
Text("notifications.content-filter.newAccounts")
|
subtitle: "Created within the past 30 days")
|
||||||
Text("Created within the past 30 days")
|
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
.font(.footnote)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Picker(selection: .init(get: {
|
Picker(selection: .init(get: {
|
||||||
|
@ -73,12 +61,8 @@ struct NotificationsPolicyView: View {
|
||||||
})) {
|
})) {
|
||||||
pickerMenu
|
pickerMenu
|
||||||
} label: {
|
} label: {
|
||||||
VStack(alignment: .leading) {
|
makePickerLabel(title: "notifications.content-filter.privateMentions",
|
||||||
Text("notifications.content-filter.privateMentions")
|
subtitle: "Unless it's in reply to your own mention or if you follow the sender")
|
||||||
Text("Unless it's in reply to your own mention or if you follow the sender")
|
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
.font(.footnote)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Picker(selection: .init(get: {
|
Picker(selection: .init(get: {
|
||||||
|
@ -90,10 +74,8 @@ struct NotificationsPolicyView: View {
|
||||||
pickerMenu
|
pickerMenu
|
||||||
} label: {
|
} label: {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
Text("Moderated accounts")
|
makePickerLabel(title: "Moderated accounts",
|
||||||
Text("Limited by server moderators")
|
subtitle: "Limited by server moderators")
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
.font(.footnote)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +94,7 @@ struct NotificationsPolicyView: View {
|
||||||
}
|
}
|
||||||
.redacted(reason: policy == nil ? .placeholder : [])
|
.redacted(reason: policy == nil ? .placeholder : [])
|
||||||
}
|
}
|
||||||
.presentationDetents([.medium])
|
.presentationDetents([.height(500)])
|
||||||
.presentationBackground(.thinMaterial)
|
.presentationBackground(.thinMaterial)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,6 +103,16 @@ struct NotificationsPolicyView: View {
|
||||||
Text(policy.rawValue.capitalized)
|
Text(policy.rawValue.capitalized)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func makePickerLabel(title: LocalizedStringKey, subtitle: LocalizedStringKey) -> some View {
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
Text(title)
|
||||||
|
.font(.callout)
|
||||||
|
Text(subtitle)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
.font(.footnote)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func getPolicy() async {
|
private func getPolicy() async {
|
||||||
defer {
|
defer {
|
||||||
|
|
Loading…
Reference in a new issue