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>
27 lines
No EOL
1.1 KiB
Swift
27 lines
No EOL
1.1 KiB
Swift
import Foundation
|
|
|
|
/// Tracks content folders (`downloadDir/name`) already ingested into the library.
|
|
/// Without this, torrents that finished before the app launched never get a direct
|
|
/// scan — the first poll deliberately skips completion notifications for the backlog.
|
|
public enum IndexedFoldersStore {
|
|
private static let key = "tv-anarchy.indexed-content-folders"
|
|
|
|
public static func load() -> Set<String> {
|
|
Set(UserDefaults.standard.stringArray(forKey: key) ?? [])
|
|
}
|
|
|
|
public static func mark(_ folders: [String]) {
|
|
guard !folders.isEmpty else { return }
|
|
var known = load()
|
|
let before = known.count
|
|
folders.forEach { known.insert($0) }
|
|
guard known.count > before else { return }
|
|
UserDefaults.standard.set(Array(known), forKey: key)
|
|
}
|
|
|
|
/// Complete transfers whose `contentFolder` has never been incrementally indexed.
|
|
public static func unmarkedFolders(in transfers: [TorrentRow]) -> [String] {
|
|
let known = load()
|
|
return transfers.filter(\.isComplete).compactMap(\.contentFolder).filter { !known.contains($0) }
|
|
}
|
|
} |