Connect to notification filters V2

This commit is contained in:
Thomas Ricouard 2024-08-15 22:30:31 +02:00
parent dfbbb84e9d
commit 412f475d1d
2 changed files with 93 additions and 30 deletions

View file

@ -1,10 +1,15 @@
import Foundation import Foundation
public struct NotificationsPolicy: Codable, Sendable { public struct NotificationsPolicy: Codable, Sendable {
public var filterNotFollowing: Bool public enum Policy: String, Codable, Sendable, CaseIterable, Hashable {
public var filterNotFollowers: Bool case accept, filter, drop
public var filterNewAccounts: Bool }
public var filterPrivateMentions: Bool
public var forNotFollowing: Policy
public var forNotFollowers: Policy
public var forNewAccounts: Policy
public var forPrivateMentions: Policy
public var forLimitedAccounts: Policy
public let summary: Summary public let summary: Summary
public struct Summary: Codable, Sendable { public struct Summary: Codable, Sendable {

View file

@ -17,34 +17,85 @@ struct NotificationsPolicyView: View {
NavigationStack { NavigationStack {
Form { Form {
Section("notifications.content-filter.title-inline") { Section("notifications.content-filter.title-inline") {
Toggle(isOn: .init(get: { policy?.filterNotFollowing == true }, Picker(selection: .init(get: {
set: { newValue in policy?.forNotFollowing ?? .drop
policy?.filterNotFollowing = newValue }, set: { policy in
Task { await updatePolicy() } self.policy?.forNotFollowing = policy
}), label: { Task { await updatePolicy() }
})) {
pickerMenu
} label: {
VStack(alignment: .leading) {
Text("notifications.content-filter.peopleYouDontFollow") Text("notifications.content-filter.peopleYouDontFollow")
}) Text("Until you manually approve them")
Toggle(isOn: .init(get: { policy?.filterNotFollowers == true }, .foregroundStyle(.secondary)
set: { newValue in .font(.footnote)
policy?.filterNotFollowers = newValue }
Task { await updatePolicy() } }
}), label: {
Picker(selection: .init(get: {
policy?.forNotFollowers ?? .drop
}, set: { policy in
self.policy?.forNotFollowers = policy
Task { await updatePolicy() }
})) {
pickerMenu
} label: {
VStack(alignment: .leading) {
Text("notifications.content-filter.peopleNotFollowingYou") Text("notifications.content-filter.peopleNotFollowingYou")
}) Text("And following you for less than 3 days")
Toggle(isOn: .init(get: { policy?.filterNewAccounts == true }, .foregroundStyle(.secondary)
set: { newValue in .font(.footnote)
policy?.filterNewAccounts = newValue }
Task { await updatePolicy() } }
}), label: {
Picker(selection: .init(get: {
policy?.forNewAccounts ?? .drop
}, set: { policy in
self.policy?.forNewAccounts = policy
Task { await updatePolicy() }
})) {
pickerMenu
} label: {
VStack(alignment: .leading) {
Text("notifications.content-filter.newAccounts") Text("notifications.content-filter.newAccounts")
}) Text("Created within the past 30 days")
Toggle(isOn: .init(get: { policy?.filterPrivateMentions == true }, .foregroundStyle(.secondary)
set: { newValue in .font(.footnote)
policy?.filterPrivateMentions = newValue }
Task { await updatePolicy() } }
}), label: {
Picker(selection: .init(get: {
policy?.forPrivateMentions ?? .drop
}, set: { policy in
self.policy?.forPrivateMentions = policy
Task { await updatePolicy() }
})) {
pickerMenu
} label: {
VStack(alignment: .leading) {
Text("notifications.content-filter.privateMentions") Text("notifications.content-filter.privateMentions")
}) Text("Unless it's in reply to your own mention or if you follow the sender")
.foregroundStyle(.secondary)
.font(.footnote)
}
}
Picker(selection: .init(get: {
policy?.forLimitedAccounts ?? .drop
}, set: { policy in
self.policy?.forLimitedAccounts = policy
Task { await updatePolicy() }
})) {
pickerMenu
} label: {
VStack(alignment: .leading) {
Text("Moderated accounts")
Text("Limited by server moderators")
.foregroundStyle(.secondary)
.font(.footnote)
}
}
} }
#if !os(visionOS) #if !os(visionOS)
.listRowBackground(theme.primaryBackgroundColor.opacity(0.3)) .listRowBackground(theme.primaryBackgroundColor.opacity(0.3))
@ -59,18 +110,25 @@ struct NotificationsPolicyView: View {
.task { .task {
await getPolicy() await getPolicy()
} }
.redacted(reason: policy == nil ? .placeholder : [])
} }
.presentationDetents([.medium]) .presentationDetents([.medium])
.presentationBackground(.thinMaterial) .presentationBackground(.thinMaterial)
} }
private var pickerMenu: some View {
ForEach(NotificationsPolicy.Policy.allCases, id: \.self) { policy in
Text(policy.rawValue.capitalized)
}
}
private func getPolicy() async { private func getPolicy() async {
defer { defer {
isUpdating = false isUpdating = false
} }
do { do {
isUpdating = true isUpdating = true
policy = try await client.get(endpoint: Notifications.policy) policy = try await client.get(endpoint: Notifications.policy, forceVersion: .v2)
} catch { } catch {
dismiss() dismiss()
} }
@ -83,7 +141,7 @@ struct NotificationsPolicyView: View {
} }
do { do {
isUpdating = true isUpdating = true
self.policy = try await client.put(endpoint: Notifications.putPolicy(policy: policy)) self.policy = try await client.put(endpoint: Notifications.putPolicy(policy: policy), forceVersion: .v2)
} catch {} } catch {}
} }
} }