783cd0e1f2
Settings → Danger zone → Delete account. For vfile accounts the host file is removed via POST /delete; for every method local credentials, follows, drafts, blocked accounts and muted words are wiped and the app returns to the Welcome screen. Required by App Review guideline 5.1.1(v).
66 lines
2.0 KiB
Swift
66 lines
2.0 KiB
Swift
import Foundation
|
|
import Observation
|
|
|
|
/// User-managed list of blocked feed URLs. UGC guideline 1.2 requires a
|
|
/// per-user block mechanism that hides the blocked author's content
|
|
/// instantly across the app; this is the single source of truth that
|
|
/// every feed-rendering view reads.
|
|
///
|
|
/// Persisted as a JSON-encoded `[String]` under `blockedFeedURLs` in
|
|
/// `UserDefaults`. Each entry is the FollowCoordinator-normalised URL
|
|
/// (lowercased scheme/host, trailing slash stripped) so the same feed
|
|
/// can't be blocked twice via two slightly different spellings.
|
|
@Observable @MainActor
|
|
final class BlockList {
|
|
|
|
static let shared = BlockList()
|
|
|
|
private(set) var blocked: [String]
|
|
|
|
private let defaultsKey = "blockedFeedURLs"
|
|
|
|
private init() {
|
|
if let raw = UserDefaults.standard.data(forKey: defaultsKey),
|
|
let decoded = try? JSONDecoder().decode([String].self, from: raw) {
|
|
self.blocked = decoded
|
|
} else {
|
|
self.blocked = []
|
|
}
|
|
}
|
|
|
|
func isBlocked(_ url: URL) -> Bool {
|
|
blocked.contains(FollowCoordinator.normalize(url))
|
|
}
|
|
|
|
func block(_ url: URL) {
|
|
let key = FollowCoordinator.normalize(url)
|
|
guard !blocked.contains(key) else { return }
|
|
blocked.append(key)
|
|
persist()
|
|
}
|
|
|
|
func unblock(_ raw: String) {
|
|
guard let idx = blocked.firstIndex(of: raw) else { return }
|
|
blocked.remove(at: idx)
|
|
persist()
|
|
}
|
|
|
|
func unblock(_ url: URL) {
|
|
unblock(FollowCoordinator.normalize(url))
|
|
}
|
|
|
|
/// Drops the in-memory list and clears the persisted entry. Called by
|
|
/// account deletion so a subsequent signup does not inherit the previous
|
|
/// user's blocked accounts from the singleton.
|
|
func reset() {
|
|
blocked = []
|
|
UserDefaults.standard.removeObject(forKey: defaultsKey)
|
|
}
|
|
|
|
private func persist() {
|
|
if let data = try? JSONEncoder().encode(blocked) {
|
|
UserDefaults.standard.set(data, forKey: defaultsKey)
|
|
}
|
|
}
|
|
}
|