Add search action mode selector
This commit is contained in:
+50
-24
@@ -508,17 +508,25 @@ INDEX_HTML = r"""<!doctype html>
|
||||
</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Download mode
|
||||
<select id="selectionMode">
|
||||
<option value="sub">Subbed</option>
|
||||
<option value="dub">Dubbed</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>Library name
|
||||
<input id="animeNameInput" placeholder="Anime name">
|
||||
</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Season
|
||||
<input id="seasonInput" inputmode="numeric" pattern="[0-9]*" value="1">
|
||||
</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Episodes
|
||||
<input id="episodesInput" placeholder="1-12">
|
||||
</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Download folder
|
||||
<input id="jobFolder" placeholder="/home/me/Downloads/Anime">
|
||||
</label>
|
||||
@@ -653,32 +661,23 @@ INDEX_HTML = r"""<!doctype html>
|
||||
$("resultsMeta").textContent = `${results.length} matching anime`;
|
||||
}
|
||||
|
||||
async function selectResult(item, button) {
|
||||
function modeAvailable(item, mode) {
|
||||
return Boolean(item && item[`has_${mode}`]);
|
||||
}
|
||||
|
||||
async function loadSelectedEpisodes(mode) {
|
||||
const requestId = ++state.episodeRequestId;
|
||||
document.querySelectorAll(".result-card").forEach((node) => node.classList.remove("active"));
|
||||
button.classList.add("active");
|
||||
state.selected = item;
|
||||
state.episodes = [];
|
||||
const preferredMode = state.config.mode === "dub" ? "dub" : "sub";
|
||||
const selectedMode = item[`has_${preferredMode}`]
|
||||
? preferredMode
|
||||
: item.has_sub
|
||||
? "sub"
|
||||
: item.has_dub
|
||||
? "dub"
|
||||
: preferredMode;
|
||||
const selectedMode = mode === "dub" ? "dub" : "sub";
|
||||
state.config.mode = selectedMode;
|
||||
$("selectedTitle").textContent = item.title;
|
||||
$("animeNameInput").value = item.title;
|
||||
$("seasonInput").value = $("seasonInput").value || "1";
|
||||
$("selectedMeta").textContent = "Loading episodes...";
|
||||
$("selectionMode").value = selectedMode;
|
||||
$("selectedMeta").textContent = `Loading ${selectedMode.toUpperCase()} episodes...`;
|
||||
$("episodeChips").innerHTML = "";
|
||||
$("episodesInput").value = "";
|
||||
$("addBtn").disabled = true;
|
||||
$("trackBtn").disabled = false;
|
||||
openSelectionModal();
|
||||
try {
|
||||
const data = await api(`/api/anime/${encodeURIComponent(item.id)}/episodes?mode=${selectedMode}`);
|
||||
if (requestId !== state.episodeRequestId || state.selected !== item) return;
|
||||
const data = await api(`/api/anime/${encodeURIComponent(state.selected.id)}/episodes?mode=${selectedMode}`);
|
||||
if (requestId !== state.episodeRequestId || !state.selected) return;
|
||||
state.episodes = data.episodes;
|
||||
const first = state.episodes[0] || "";
|
||||
const last = state.episodes[state.episodes.length - 1] || "";
|
||||
@@ -687,11 +686,34 @@ INDEX_HTML = r"""<!doctype html>
|
||||
renderEpisodeChips();
|
||||
$("addBtn").disabled = !state.episodes.length;
|
||||
} catch (error) {
|
||||
if (requestId !== state.episodeRequestId || state.selected !== item) return;
|
||||
if (requestId !== state.episodeRequestId || !state.selected) return;
|
||||
$("selectedMeta").textContent = error.message;
|
||||
}
|
||||
}
|
||||
|
||||
async function selectResult(item, button) {
|
||||
document.querySelectorAll(".result-card").forEach((node) => node.classList.remove("active"));
|
||||
button.classList.add("active");
|
||||
state.selected = item;
|
||||
const preferredMode = state.config.mode === "dub" ? "dub" : "sub";
|
||||
const selectedMode = item[`has_${preferredMode}`]
|
||||
? preferredMode
|
||||
: item.has_sub
|
||||
? "sub"
|
||||
: item.has_dub
|
||||
? "dub"
|
||||
: preferredMode;
|
||||
$("selectionMode").value = selectedMode;
|
||||
$("selectionMode").querySelector('option[value="sub"]').disabled = !modeAvailable(item, "sub");
|
||||
$("selectionMode").querySelector('option[value="dub"]').disabled = !modeAvailable(item, "dub");
|
||||
$("selectedTitle").textContent = item.title;
|
||||
$("animeNameInput").value = item.title;
|
||||
$("seasonInput").value = $("seasonInput").value || "1";
|
||||
$("trackBtn").disabled = false;
|
||||
openSelectionModal();
|
||||
await loadSelectedEpisodes(selectedMode);
|
||||
}
|
||||
|
||||
function renderEpisodeChips() {
|
||||
const el = $("episodeChips");
|
||||
el.innerHTML = "";
|
||||
@@ -743,6 +765,7 @@ INDEX_HTML = r"""<!doctype html>
|
||||
title: state.selected.title,
|
||||
category: $("trackCategory").value,
|
||||
media_type: $("trackMediaType").value,
|
||||
auto_download_mode: $("selectionMode").value,
|
||||
auto_download_series: $("seasonInput").value || "1"
|
||||
})
|
||||
});
|
||||
@@ -764,7 +787,7 @@ INDEX_HTML = r"""<!doctype html>
|
||||
anime_name: $("animeNameInput").value || state.selected.title,
|
||||
media_type: $("trackMediaType").value,
|
||||
season: $("seasonInput").value || "1",
|
||||
mode: state.config.mode,
|
||||
mode: $("selectionMode").value,
|
||||
quality: state.config.quality,
|
||||
episodes: $("episodesInput").value,
|
||||
download_dir: $("jobFolder").value || state.config.download_dir
|
||||
@@ -793,6 +816,9 @@ INDEX_HTML = r"""<!doctype html>
|
||||
$("trackBtn").addEventListener("click", addSelectedToWatchlist);
|
||||
$("addBtn").addEventListener("click", addSelected);
|
||||
$("closeSelectionBtn").addEventListener("click", closeSelectionModal);
|
||||
$("selectionMode").addEventListener("change", () => {
|
||||
if (state.selected) loadSelectedEpisodes($("selectionMode").value);
|
||||
});
|
||||
selectionModal.addEventListener("click", (event) => {
|
||||
if (event.target === selectionModal) closeSelectionModal();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user