mirror of
https://github.com/yattee/yattee.git
synced 2026-10-26 14:42:53 +00:00
Give remote playlist rows a name of their own
Playlist fetches threw away the only handle a row could be removed by: Invidious hands out an index/indexId pair per entry and both were dropped on conversion, so nothing downstream could say which row it meant. Both authenticated fetches now also return a snapshot — the playlist plus its addressable entries. Invidious entries carry the server's indexId and survive refetches; Piped has no such token, so its entries are addressed by position and are only valid inside the snapshot that minted them. The entry id carries the playlist id in both cases, so position 3 of one playlist can never be mistaken for position 3 of another. A row needs both an indexId and an index to be a target: rows missing either are still displayed but never appear in entries, so no removal can be aimed at a row the server refuses to name. Page-overlap dedupe stays keyed on index and never on videoId — the same video may sit in a playlist twice, and each copy is its own removable row.
This commit is contained in:
@@ -28,9 +28,23 @@ actor HTTPClient {
|
||||
self.session = session
|
||||
self.decoder = decoder
|
||||
|
||||
// Configure decoder for common API patterns
|
||||
self.decoder.keyDecodingStrategy = .convertFromSnakeCase
|
||||
self.decoder.dateDecodingStrategy = .iso8601
|
||||
Self.configureForAPIs(self.decoder)
|
||||
}
|
||||
|
||||
/// Applies the decoding rules every instance API response is parsed with.
|
||||
///
|
||||
/// Exposed so code that parses an already-fetched payload — a merged page
|
||||
/// set, say — decodes it exactly the way the network path would.
|
||||
nonisolated static func configureForAPIs(_ decoder: JSONDecoder) {
|
||||
decoder.keyDecodingStrategy = .convertFromSnakeCase
|
||||
decoder.dateDecodingStrategy = .iso8601
|
||||
}
|
||||
|
||||
/// A decoder configured the way this client decodes API responses.
|
||||
nonisolated static func makeAPIDecoder() -> JSONDecoder {
|
||||
let decoder = JSONDecoder()
|
||||
configureForAPIs(decoder)
|
||||
return decoder
|
||||
}
|
||||
|
||||
// MARK: - Configuration
|
||||
|
||||
Reference in New Issue
Block a user