fix(offline): one server-only rule for both library views
Two defects with one cause: "server only" was a private $derived inside MediaCard. The list view (what LibraryGrid renders when the stored view preference is list) had no notion of it at all, so a library browsed as a list offline showed every revealed item as an ordinary tappable row that plays nothing, with no way to queue it. And the rule asked the downloads store whether *this item id* was downloaded — but only a playable leaf (Audio, Movie, Episode) ever has a download row. An album's tracks carry them, the album does not, so a fully downloaded album greyed itself out and offered to queue what was already on the device. The rule moves to the pure $lib/utils/serverOnly and both views call it. The container half is answered by the backend rather than guessed at: get_download_disk_usage().sizes already carries container subtotals beside leaf sizes (DR-085), so deviceContentIds is membership in a Rust-computed map, not a frontend list of which item types are containers. That map was loaded only by the Downloads page, so the shell primes it at startup and re-reads it whenever the offline gate settles. Queueing is shared too, since the list view had no copy to diverge from. TRACES: UR-052, UR-055 | DR-292 | UT-257, UT-258
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Is a card "server only" — revealed by the offline "Show all server media"
|
||||
* toggle, but with nothing on the device behind it?
|
||||
*
|
||||
* Such cards render greyed out, are inert to tap (there is nothing to play),
|
||||
* and offer to queue a download for the next reconnect instead.
|
||||
*
|
||||
* This lives in its own module because two surfaces answer the question — the
|
||||
* grid (`MediaCard`) and the list (`LibraryListView`) — and they disagreed:
|
||||
* the list had no notion of server-only at all, so switching a library to list
|
||||
* view offline turned every non-downloaded item back into a normal, tappable
|
||||
* row that plays nothing.
|
||||
*
|
||||
* `hasDeviceContent` is the fix for the second half of that defect. An item's
|
||||
* *own* download row only ever exists for a playable leaf (Audio, Movie,
|
||||
* Episode); an album or a season never has one, so a fully downloaded album
|
||||
* greyed itself out and offered to queue what was already on the device. The
|
||||
* caller passes the backend's answer — `get_download_disk_usage().sizes`
|
||||
* carries container subtotals as well as leaf sizes — rather than the frontend
|
||||
* deciding which item types are containers, which is taxonomy that belongs in
|
||||
* Rust.
|
||||
*
|
||||
* TRACES: UR-052 | DR-292 | UT-257
|
||||
*/
|
||||
|
||||
export interface ServerOnlyInput {
|
||||
/** False for a `Library` tile — a library is never queued or greyed. */
|
||||
isMediaItem: boolean;
|
||||
/** Server reachability (`$isConnected`). */
|
||||
isConnected: boolean;
|
||||
/** The offline banner's "Show all server media" toggle. */
|
||||
revealServerCatalog: boolean;
|
||||
/** This item's own download row is `completed`. */
|
||||
isDownloaded: boolean;
|
||||
/** This item's own download row is actively transferring. */
|
||||
isActivelyDownloading: boolean;
|
||||
/** The device holds bytes at or under this item (leaf file or container). */
|
||||
hasDeviceContent: boolean;
|
||||
}
|
||||
|
||||
export function isServerOnly({
|
||||
isMediaItem,
|
||||
isConnected,
|
||||
revealServerCatalog,
|
||||
isDownloaded,
|
||||
isActivelyDownloading,
|
||||
hasDeviceContent,
|
||||
}: ServerOnlyInput): boolean {
|
||||
if (!isMediaItem) return false;
|
||||
if (isConnected || !revealServerCatalog) return false;
|
||||
return !isDownloaded && !isActivelyDownloading && !hasDeviceContent;
|
||||
}
|
||||
Reference in New Issue
Block a user