// What can be done with a library title, shared by Movies, Series, Library // and Calendar. import { app } from "../app.ts"; import type { Movie } from "../api/radarr.ts"; import type { Series } from "../api/sonarr.ts"; import { titleYear } from "../describe.ts"; import { h } from "../ui/dom.ts"; import { actionSheet, button, Dialog, run, Toggle, type Action } from "../ui/widgets.ts"; import { openEpisodes } from "./episodes.ts"; import { openReleases } from "./releases.ts"; export function movieReleases(m: Movie): void { openReleases("Releases for " + titleYear(m), (signal) => app.radarr.movieReleases(m.id, signal), (r) => app.radarr.grab(r)); } // movieActions: changed runs after something changed the movie (reload). export function movieActions(m: Movie, changed: () => void, removed?: () => void): Action[] { const name = titleYear(m); return [ { label: "Search releases", hint: "interactive", run: () => movieReleases(m) }, { label: "Automatic search", run: () => void run("Searching " + name, "Search started: " + name, () => app.radarr.searchMovie(m.id)) }, { label: m.monitored ? "Unmonitor" : "Monitor", run: () => void run(name + ": " + (m.monitored ? "unmonitoring" : "monitoring"), "Done: " + name, () => app.radarr.setMonitored(m.id, !m.monitored)).then((ok) => ok && changed()), }, { label: "Remove from library…", danger: true, run: () => removeDialog(name, false, (files, excl) => app.radarr.deleteMovie(m.id, files, excl), removed ?? changed) }, ]; } export function seriesActions(s: Series, changed: () => void, removed?: () => void): Action[] { const name = titleYear(s); return [ { label: "Seasons and episodes", run: () => openEpisodes(s, changed) }, { label: "Search all missing episodes", run: () => actionSheet(`Search all missing episodes of ${name}?`, [ { label: "Search", run: () => void run("Searching " + name, "Search started: " + name, () => app.sonarr.searchSeries(s.id)) }, ]), }, { label: s.monitored ? "Unmonitor" : "Monitor", run: () => void run(name + ": " + (s.monitored ? "unmonitoring" : "monitoring"), "Done: " + name, () => app.sonarr.setMonitored(s.id, !s.monitored)).then((ok) => ok && changed()), }, { label: "Remove from library…", danger: true, run: () => removeDialog(name, true, (files, excl) => app.sonarr.deleteSeries(s.id, files, excl), removed ?? changed) }, ]; } export function showMovieActions(m: Movie, changed: () => void, removed?: () => void): void { actionSheet(titleYear(m), movieActions(m, changed, removed)); } export function showSeriesActions(s: Series, changed: () => void, removed?: () => void): void { actionSheet(titleYear(s), seriesActions(s, changed, removed)); } // removeDialog asks before removing; files and the import exclusion are // separate choices, both off. function removeDialog(name: string, series: boolean, remove: (files: boolean, exclusion: boolean) => Promise, removed: () => void): void { const d = new Dialog("Remove " + name); const files = new Toggle(series ? "Delete all episode files" : "Delete the movie's files", false); const excl = new Toggle("Do not add again from import lists", false); const cancel = button("Cancel", () => d.close(), "ghost"); d.add( h("p.dialog-text", "The title leaves the library. Files stay on disk unless you tick the box."), files.el, excl.el, h("div.row-buttons", button("Remove", () => { d.close(); void run("Removing " + name, "Removed " + name, () => remove(files.value, excl.value)).then((ok) => ok && removed()); }, "danger"), cancel), ); d.open(cancel); }