Surface the existing pin (keep-from-cull) and per-file delete actions as visible inline buttons on each offline cache row instead of context-menu-only: a star toggles protection from auto-cull (and restore-if-missing), a trash culls that file early. Aligns wording/icons to the star metaphor. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
49 lines
2.3 KiB
Swift
49 lines
2.3 KiB
Swift
import Foundation
|
|
|
|
/// The three data classes the system keeps strictly separated, each with its own
|
|
/// storage root, sharing policy, and trust boundary:
|
|
///
|
|
/// - `.tvanarchy` — app/mesh metadata that is NOT private: cover art, and the
|
|
/// canonical shared catalog ("media definitions" like the Matrix collection).
|
|
/// Shareable across the mesh (signed by anchors); safe to replicate publicly
|
|
/// within an install.
|
|
/// - `.user` — the person's PRIVATE data: their library index (what they have),
|
|
/// watch history + resume positions, playlists, play queue, device config,
|
|
/// settings, franchise/track prefs. Never shared with friends; syncs only across
|
|
/// the user's OWN devices (their install).
|
|
/// - `.publicMedia` — the bulk media files themselves (torrent downloads).
|
|
/// Swarm-distributed; this is what the upload-bandwidth tiers arbitrate over.
|
|
public enum DataDomain: String, Sendable, CaseIterable {
|
|
case tvanarchy
|
|
case user
|
|
case publicMedia
|
|
|
|
/// Whether this domain may leave the user's own install (be shared with friends /
|
|
/// the public mesh). Only catalog/art and the media swarm; never user-private data.
|
|
public var shareableBeyondOwnFleet: Bool {
|
|
switch self {
|
|
case .tvanarchy: true // signed catalog + art
|
|
case .user: false // private — own install only
|
|
case .publicMedia: true // the swarm
|
|
}
|
|
}
|
|
|
|
/// Classify a state/config store by its filename or path. Defaults to `.user`
|
|
/// (the safe default: treat unknown app state as PRIVATE, never accidentally
|
|
/// shareable).
|
|
public static func classify(path: String) -> DataDomain {
|
|
let p = (path as NSString).lastPathComponent.lowercased()
|
|
let full = path.lowercased()
|
|
// Media files (the public swarm) — under a media root or the offline cache.
|
|
if full.contains("/media/") || full.contains("/bigdisk") || full.contains("tv-anarchy-offline") {
|
|
return .publicMedia
|
|
}
|
|
// Shareable app/mesh metadata: artwork + the (future) canonical catalog.
|
|
if full.contains("/posters/") || full.contains("/previews/")
|
|
|| full.contains("/meta/") || p == "catalog.json" {
|
|
return .tvanarchy
|
|
}
|
|
// Everything else the app persists is the user's private data.
|
|
return .user
|
|
}
|
|
}
|