| 1 | import { useSearchParams } from "@solidjs/router"; |
| 2 | import { parseResponse } from "hono/client"; |
| 3 | import { createSignal, Show } from "solid-js"; |
| 4 | import { api, queries, reason } from "../api.ts"; |
| 5 | import { Explorer } from "../components/Explorer.tsx"; |
| 6 | import { ListPage } from "../components/ListPage.tsx"; |
| 7 | import { lastGood } from "../components/Loaded.tsx"; |
| 8 | import { OpenApp } from "../components/OpenApp.tsx"; |
| 9 | import { toast } from "../components/Toast.tsx"; |
| 10 | |
| 11 | export function Media() { |
| 12 | const [params] = useSearchParams<{ path?: string }>(); |
| 13 | const here = () => params.path ?? ""; |
| 14 | const apps = lastGood(queries.launcher.use()[0]); |
| 15 | /** Jellyfin has no page per folder, so a show, movie or artist folder opens a search for its title. */ |
| 16 | const jellyfin = () => { |
| 17 | const found = apps()?.find((app) => app.id === "jellyfin"); |
| 18 | const [top, , title] = here().split("/"); |
| 19 | if (!found) return null; |
| 20 | return { |
| 21 | ...found, |
| 22 | href: top === "jellyfin" && title |
| 23 | ? `${found.url}/web/#/search?query=${encodeURIComponent(title.replace(/ \(\d{4}\)$/, ""))}` |
| 24 | : `${found.url}/web/`, |
| 25 | }; |
| 26 | }; |
| 27 | const [refreshing, setRefreshing] = createSignal(false); |
| 28 | const refresh = async () => { |
| 29 | setRefreshing(true); |
| 30 | try { |
| 31 | await parseResponse(api.media.refresh.$post()); |
| 32 | toast("Jellyfin started scanning all libraries."); |
| 33 | } catch (failure) { |
| 34 | toast(reason(failure)); |
| 35 | } finally { |
| 36 | setRefreshing(false); |
| 37 | } |
| 38 | }; |
| 39 | |
| 40 | return ( |
| 41 | <ListPage id="media" flush head={ |
| 42 | <div class="page-head"> |
| 43 | <h1>media</h1> |
| 44 | <Show when={jellyfin()}>{(link) => <OpenApp app={link()} href={link().href} />}</Show> |
| 45 | <span class="spacer" /> |
| 46 | <button class="button" disabled={refreshing()} aria-busy={refreshing()} onClick={refresh} |
| 47 | data-tip="scans all Jellyfin libraries">scan jellyfin</button> |
| 48 | </div> |
| 49 | }> |
| 50 | <Explorer id="media" client={api.media} root="library" /> |
| 51 | </ListPage> |
| 52 | ); |
| 53 | } |