Add watchlist source name override for ani-cli queries
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## 0.45.18 - 2026-06-13
|
||||
|
||||
- Added a `Source name` field to the watchlist auto-download editor so per-show jobs can send a more specific anime title to `ani-cli` when provider searches return multiple similarly named results.
|
||||
- Migrated existing watchlist databases by adding an `auto_download_source_name` column and defaulting stored entries to the tracked title, preserving current behavior until you override it.
|
||||
- Changed both watchlist `Download all` and automatic watchlist episode queueing to use the saved `Source name` for the `ani-cli` query while keeping the separate library `Name` field for folder and file naming.
|
||||
|
||||
## 0.45.17 - 2026-06-07
|
||||
|
||||
- Added a lightweight `/api/watchlist/homepage` endpoint for Homepage's Custom API widget, returning simple watchlist category counts for `watchlist`, `planned`, `finished`, `dropped`, and `total`.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Local web UI for a system-wide `ani-cli` install.
|
||||
|
||||
Current version: `0.45.17`
|
||||
Current version: `0.45.18`
|
||||
|
||||
## What it does
|
||||
|
||||
@@ -11,7 +11,7 @@ Current version: `0.45.17`
|
||||
- Track shows in a watchlist with `Watching`, `Planned`, `Finished`, and `Dropped` categories
|
||||
- Expose a small JSON summary endpoint for Homepage dashboard widgets
|
||||
- Refresh watchlist episode counts manually or on a schedule
|
||||
- Auto-download missing episodes for `Watching` entries after later refreshes
|
||||
- Auto-download missing episodes for `Watching` entries after later refreshes, with a per-show `Source name` override for `ani-cli` search
|
||||
- Move fully completed libraries into Jellyfin TV or movie folders
|
||||
- Send optional Discord webhook notifications
|
||||
|
||||
@@ -19,7 +19,7 @@ Current version: `0.45.17`
|
||||
|
||||
- `/`: Search and queue downloads, with poster-card search results below the selection box and alternate English titles under the main name when available
|
||||
- `/queue`: Monitor jobs, inspect logs, retry failed jobs, remove finished jobs
|
||||
- `/watchlist`: Track shows, refresh them, download all available episodes, manage auto-download settings
|
||||
- `/watchlist`: Track shows, refresh them, download all available episodes, and manage auto-download settings such as `Source name`, library `Name`, season, and episode offset
|
||||
- `/config`: Save defaults, schedule refreshes, configure Jellyfin and Discord, view runtime info and the changelog
|
||||
|
||||
## Quick start
|
||||
@@ -96,7 +96,7 @@ Docker notes:
|
||||
### Auto-download
|
||||
|
||||
- Runs only for entries in `Watching`
|
||||
- Uses the per-show language, quality, season, library name, and optional episode offset settings
|
||||
- Uses the per-show language, quality, `Source name` search override, season, library name, and optional episode offset settings
|
||||
- Can queue backlog episodes that were already available before the show was first tracked
|
||||
|
||||
### Jellyfin handoff
|
||||
|
||||
@@ -1338,10 +1338,12 @@ class WatchlistStore:
|
||||
|
||||
def _auto_download_defaults(self, title):
|
||||
config = self.config_getter() or {}
|
||||
normalized_title = str(title or "").strip() or "Anime"
|
||||
return {
|
||||
"auto_download_mode": str(config.get("auto_download_mode") or "dub").strip().lower() or "dub",
|
||||
"auto_download_quality": str(config.get("auto_download_quality") or "best").strip().lower() or "best",
|
||||
"auto_download_name": sanitize_path_component(title, "Anime"),
|
||||
"auto_download_name": sanitize_path_component(normalized_title, "Anime"),
|
||||
"auto_download_source_name": normalized_title,
|
||||
"auto_download_series": "1",
|
||||
"auto_download_offset": None,
|
||||
"media_type": "tv",
|
||||
@@ -1422,6 +1424,7 @@ class WatchlistStore:
|
||||
auto_download_mode TEXT,
|
||||
auto_download_quality TEXT,
|
||||
auto_download_name TEXT,
|
||||
auto_download_source_name TEXT,
|
||||
auto_download_series TEXT,
|
||||
auto_download_offset TEXT,
|
||||
downloaded_sub_episodes_json TEXT,
|
||||
@@ -1468,6 +1471,8 @@ class WatchlistStore:
|
||||
conn.execute("ALTER TABLE watchlist ADD COLUMN auto_download_quality TEXT")
|
||||
if "auto_download_name" not in columns:
|
||||
conn.execute("ALTER TABLE watchlist ADD COLUMN auto_download_name TEXT")
|
||||
if "auto_download_source_name" not in columns:
|
||||
conn.execute("ALTER TABLE watchlist ADD COLUMN auto_download_source_name TEXT")
|
||||
if "auto_download_series" not in columns:
|
||||
conn.execute("ALTER TABLE watchlist ADD COLUMN auto_download_series TEXT")
|
||||
if "auto_download_offset" not in columns:
|
||||
@@ -1548,6 +1553,7 @@ class WatchlistStore:
|
||||
item["auto_download_mode"] = mode if mode in MODE_CHOICES else defaults["auto_download_mode"]
|
||||
item["auto_download_quality"] = quality if quality in QUALITY_CHOICES else defaults["auto_download_quality"]
|
||||
item["auto_download_name"] = sanitize_path_component(item.get("auto_download_name") or defaults["auto_download_name"], defaults["auto_download_name"])
|
||||
item["auto_download_source_name"] = str(item.get("auto_download_source_name") or defaults["auto_download_source_name"]).strip() or defaults["auto_download_source_name"]
|
||||
item["auto_download_series"] = normalize_season(item.get("auto_download_series") or defaults["auto_download_series"])
|
||||
item["auto_download_offset"] = normalize_episode_offset(item.get("auto_download_offset"))
|
||||
item["downloaded_sub_episodes"] = decode_episode_values(item.get("downloaded_sub_episodes_json"))
|
||||
@@ -1574,10 +1580,10 @@ class WatchlistStore:
|
||||
animeschedule_route, animeschedule_title,
|
||||
anilist_id, anilist_title, anilist_site_url, alternative_titles_json,
|
||||
anidb_aid, anidb_title, media_type,
|
||||
auto_download_mode, auto_download_quality, auto_download_name, auto_download_series, auto_download_offset,
|
||||
auto_download_mode, auto_download_quality, auto_download_name, auto_download_source_name, auto_download_series, auto_download_offset,
|
||||
downloaded_sub_episodes_json, downloaded_dub_episodes_json,
|
||||
thumbnail_path, thumbnail_checked_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(show_id) DO UPDATE SET
|
||||
title = excluded.title,
|
||||
category = excluded.category,
|
||||
@@ -1604,6 +1610,7 @@ class WatchlistStore:
|
||||
auto_download_mode = excluded.auto_download_mode,
|
||||
auto_download_quality = excluded.auto_download_quality,
|
||||
auto_download_name = excluded.auto_download_name,
|
||||
auto_download_source_name = excluded.auto_download_source_name,
|
||||
auto_download_series = excluded.auto_download_series,
|
||||
auto_download_offset = excluded.auto_download_offset,
|
||||
downloaded_sub_episodes_json = excluded.downloaded_sub_episodes_json,
|
||||
@@ -1639,6 +1646,7 @@ class WatchlistStore:
|
||||
item.get("auto_download_mode"),
|
||||
item.get("auto_download_quality"),
|
||||
item.get("auto_download_name"),
|
||||
str(item.get("auto_download_source_name") or "").strip() or str(item["title"]).strip(),
|
||||
item.get("auto_download_series"),
|
||||
normalize_episode_offset(item.get("auto_download_offset")),
|
||||
item.get("downloaded_sub_episodes_json"),
|
||||
@@ -1696,6 +1704,7 @@ class WatchlistStore:
|
||||
"auto_download_mode": None,
|
||||
"auto_download_quality": None,
|
||||
"auto_download_name": None,
|
||||
"auto_download_source_name": None,
|
||||
"auto_download_series": None,
|
||||
"auto_download_offset": None,
|
||||
"downloaded_sub_episodes_json": None,
|
||||
@@ -1867,6 +1876,9 @@ class WatchlistStore:
|
||||
}
|
||||
item["auto_download_series"] = normalize_season(payload.get("auto_download_series") or item.get("auto_download_series") or "1")
|
||||
item["auto_download_offset"] = normalize_episode_offset(payload.get("auto_download_offset"))
|
||||
item["auto_download_source_name"] = (
|
||||
str(payload.get("auto_download_source_name") or item.get("auto_download_source_name") or title).strip() or title
|
||||
)
|
||||
self._upsert_conn(conn, item)
|
||||
self._clear_removal_conn(conn, show_id)
|
||||
|
||||
@@ -2196,6 +2208,7 @@ class WatchlistStore:
|
||||
"anidb_aid": None,
|
||||
"anidb_title": None,
|
||||
"media_type": normalized_media_type,
|
||||
"auto_download_source_name": None,
|
||||
"auto_download_series": None,
|
||||
"downloaded_sub_episodes_json": encode_episode_values(downloaded_episode_values) if normalized_mode == "sub" else None,
|
||||
"downloaded_dub_episodes_json": encode_episode_values(downloaded_episode_values) if normalized_mode == "dub" else None,
|
||||
@@ -2206,7 +2219,7 @@ class WatchlistStore:
|
||||
self.schedule_refresh(normalized_show_id, source="sync")
|
||||
return self.get(normalized_show_id)
|
||||
|
||||
def update_auto_download_settings(self, show_id, mode=None, quality=None, name=None, series=None, episode_offset=None):
|
||||
def update_auto_download_settings(self, show_id, mode=None, quality=None, name=None, source_name=None, series=None, episode_offset=None):
|
||||
existing = self.get(show_id)
|
||||
defaults = self._auto_download_defaults(existing["title"])
|
||||
normalized_mode = str(mode or defaults["auto_download_mode"]).strip().lower()
|
||||
@@ -2216,6 +2229,9 @@ class WatchlistStore:
|
||||
if normalized_quality not in QUALITY_CHOICES:
|
||||
raise ValueError("Unknown auto-download quality.")
|
||||
normalized_name = sanitize_path_component(name or defaults["auto_download_name"], defaults["auto_download_name"])
|
||||
normalized_source_name = str(source_name or existing.get("auto_download_source_name") or defaults["auto_download_source_name"]).strip()
|
||||
if not normalized_source_name:
|
||||
normalized_source_name = defaults["auto_download_source_name"]
|
||||
normalized_series = normalize_season(series or existing.get("auto_download_series") or defaults["auto_download_series"])
|
||||
normalized_offset = (
|
||||
normalize_episode_offset(existing.get("auto_download_offset"))
|
||||
@@ -2226,10 +2242,19 @@ class WatchlistStore:
|
||||
conn.execute(
|
||||
"""
|
||||
UPDATE watchlist
|
||||
SET auto_download_mode = ?, auto_download_quality = ?, auto_download_name = ?, auto_download_series = ?, auto_download_offset = ?, updated_at = ?
|
||||
SET auto_download_mode = ?, auto_download_quality = ?, auto_download_name = ?, auto_download_source_name = ?, auto_download_series = ?, auto_download_offset = ?, updated_at = ?
|
||||
WHERE show_id = ?
|
||||
""",
|
||||
(normalized_mode, normalized_quality, normalized_name, normalized_series, normalized_offset, now_iso(), existing["show_id"]),
|
||||
(
|
||||
normalized_mode,
|
||||
normalized_quality,
|
||||
normalized_name,
|
||||
normalized_source_name,
|
||||
normalized_series,
|
||||
normalized_offset,
|
||||
now_iso(),
|
||||
existing["show_id"],
|
||||
),
|
||||
)
|
||||
return self.get(show_id)
|
||||
|
||||
@@ -2442,7 +2467,7 @@ def download_watchlist_item(show_id, mode):
|
||||
if normalized_mode not in MODE_CHOICES:
|
||||
raise ValueError("Mode must be sub or dub")
|
||||
|
||||
query = str(item.get("title") or item.get("show_id") or "").strip()
|
||||
query = str(item.get("auto_download_source_name") or item.get("title") or item.get("show_id") or "").strip()
|
||||
if not query:
|
||||
raise ValueError("Watchlist item is missing a searchable title.")
|
||||
|
||||
@@ -2502,7 +2527,7 @@ def queue_watchlist_auto_download(item, refresh_source="manual"):
|
||||
if not specs:
|
||||
return {"queued": False, "reason": "nothing_missing"}
|
||||
|
||||
query = str(item.get("title") or item.get("show_id") or "").strip()
|
||||
query = str(item.get("auto_download_source_name") or item.get("title") or item.get("show_id") or "").strip()
|
||||
if not query:
|
||||
return {"queued": False, "reason": "missing_title"}
|
||||
|
||||
@@ -2619,13 +2644,14 @@ def update_watchlist_media_type(show_id, media_type):
|
||||
return {"message": f"Saved {item['title']} as {item['media_type_label']}.", "item": item}
|
||||
|
||||
|
||||
def update_watchlist_auto_download(show_id, mode=None, quality=None, name=None, series=None, episode_offset=None):
|
||||
def update_watchlist_auto_download(show_id, mode=None, quality=None, name=None, source_name=None, series=None, episode_offset=None):
|
||||
ensure_runtime()
|
||||
item = WATCHLIST.update_auto_download_settings(
|
||||
show_id,
|
||||
mode=mode,
|
||||
quality=quality,
|
||||
name=name,
|
||||
source_name=source_name,
|
||||
series=series,
|
||||
episode_offset=episode_offset,
|
||||
)
|
||||
|
||||
@@ -729,6 +729,7 @@ class Handler(BaseHTTPRequestHandler):
|
||||
payload.get("mode"),
|
||||
payload.get("quality"),
|
||||
payload.get("name"),
|
||||
payload.get("source_name"),
|
||||
payload.get("series"),
|
||||
payload.get("episode_offset"),
|
||||
)
|
||||
|
||||
+15
-7
@@ -1598,6 +1598,7 @@ class WatchlistCompletionTests(unittest.TestCase):
|
||||
"show_id": "show-42",
|
||||
"title": "Queue Show",
|
||||
"auto_download_name": "Queue Show Library",
|
||||
"auto_download_source_name": "Queue Show Source",
|
||||
"auto_download_series": "4",
|
||||
"auto_download_quality": "720",
|
||||
"media_type": "movie",
|
||||
@@ -1613,7 +1614,7 @@ class WatchlistCompletionTests(unittest.TestCase):
|
||||
runtime["download_queue"].add.assert_called_once_with(
|
||||
{
|
||||
"show_id": "show-42",
|
||||
"query": "Queue Show",
|
||||
"query": "Queue Show Source",
|
||||
"title": "Queue Show",
|
||||
"anime_name": "Queue Show Library",
|
||||
"media_type": "movie",
|
||||
@@ -1656,6 +1657,7 @@ class WatchlistCompletionTests(unittest.TestCase):
|
||||
"show_id": "show-42",
|
||||
"title": "Queue Show",
|
||||
"auto_download_name": "Queue Show",
|
||||
"auto_download_source_name": "Queue Show Alt Search",
|
||||
"auto_download_series": "1",
|
||||
"media_type": "tv",
|
||||
}
|
||||
@@ -2339,6 +2341,7 @@ class AutoDownloadQueueTests(unittest.TestCase):
|
||||
"auto_download_mode": "dub",
|
||||
"auto_download_quality": "best",
|
||||
"auto_download_name": 'Queue Show: Alt/Name',
|
||||
"auto_download_source_name": "Queue Show Source",
|
||||
"auto_download_series": "3",
|
||||
"auto_download_offset": "13",
|
||||
"downloaded_dub_episodes": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
|
||||
@@ -2370,7 +2373,7 @@ class AutoDownloadQueueTests(unittest.TestCase):
|
||||
download_queue.add.assert_called_once_with(
|
||||
{
|
||||
"show_id": "show-42",
|
||||
"query": "Queue Show",
|
||||
"query": "Queue Show Source",
|
||||
"title": "Queue Show",
|
||||
"anime_name": "Queue Show- Alt-Name",
|
||||
"media_type": "tv",
|
||||
@@ -2395,6 +2398,7 @@ class AutoDownloadQueueTests(unittest.TestCase):
|
||||
"auto_download_mode": "dub",
|
||||
"auto_download_quality": "best",
|
||||
"auto_download_name": "Backlog Show",
|
||||
"auto_download_source_name": "Backlog Show Search",
|
||||
"auto_download_series": "1",
|
||||
"auto_download_offset": None,
|
||||
"downloaded_dub_episodes": [],
|
||||
@@ -2424,7 +2428,7 @@ class AutoDownloadQueueTests(unittest.TestCase):
|
||||
download_queue.add.assert_called_once_with(
|
||||
{
|
||||
"show_id": "show-99",
|
||||
"query": "Backlog Show",
|
||||
"query": "Backlog Show Search",
|
||||
"title": "Backlog Show",
|
||||
"anime_name": "Backlog Show",
|
||||
"media_type": "tv",
|
||||
@@ -2449,6 +2453,7 @@ class AutoDownloadQueueTests(unittest.TestCase):
|
||||
"auto_download_mode": "dub",
|
||||
"auto_download_quality": "best",
|
||||
"auto_download_name": "First Refresh Show",
|
||||
"auto_download_source_name": "First Refresh Source",
|
||||
"auto_download_series": "1",
|
||||
"auto_download_offset": None,
|
||||
"downloaded_dub_episodes": [],
|
||||
@@ -2478,7 +2483,7 @@ class AutoDownloadQueueTests(unittest.TestCase):
|
||||
download_queue.add.assert_called_once_with(
|
||||
{
|
||||
"show_id": "show-first-refresh",
|
||||
"query": "First Refresh Show",
|
||||
"query": "First Refresh Source",
|
||||
"title": "First Refresh Show",
|
||||
"anime_name": "First Refresh Show",
|
||||
"media_type": "tv",
|
||||
@@ -2503,6 +2508,7 @@ class AutoDownloadQueueTests(unittest.TestCase):
|
||||
"auto_download_mode": "dub",
|
||||
"auto_download_quality": "best",
|
||||
"auto_download_name": "Split Season Show",
|
||||
"auto_download_source_name": "Split Season Search",
|
||||
"auto_download_series": "2",
|
||||
"auto_download_offset": "13",
|
||||
"downloaded_dub_episodes": [],
|
||||
@@ -2531,7 +2537,7 @@ class AutoDownloadQueueTests(unittest.TestCase):
|
||||
download_queue.add.assert_called_once_with(
|
||||
{
|
||||
"show_id": "show-77",
|
||||
"query": "Split Season Show",
|
||||
"query": "Split Season Search",
|
||||
"title": "Split Season Show",
|
||||
"anime_name": "Split Season Show",
|
||||
"media_type": "tv",
|
||||
@@ -3089,7 +3095,7 @@ class HandlerRouteTests(unittest.TestCase):
|
||||
self.assertEqual(handler.json_status, HTTPStatus.CREATED)
|
||||
|
||||
def test_watchlist_auto_download_settings_post_returns_updated_item(self):
|
||||
body = b'{"show_id":"show-1","mode":"dub","quality":"best","name":"Example Name","series":"2","episode_offset":"13"}'
|
||||
body = b'{"show_id":"show-1","mode":"dub","quality":"best","name":"Example Name","source_name":"Example Source","series":"2","episode_offset":"13"}'
|
||||
handler = DummyHandler("/api/watchlist/update-auto-download", body=body, content_length=len(body))
|
||||
payload = {"message": "Saved auto-download settings for Show 1.", "item": {"show_id": "show-1"}}
|
||||
handler.handler_context = mock.Mock(update_watchlist_auto_download=mock.Mock(return_value=payload))
|
||||
@@ -3097,7 +3103,7 @@ class HandlerRouteTests(unittest.TestCase):
|
||||
self.assertEqual(handler.json_payload, payload)
|
||||
self.assertEqual(handler.json_status, HTTPStatus.OK)
|
||||
handler.handler_context.update_watchlist_auto_download.assert_called_once_with(
|
||||
"show-1", "dub", "best", "Example Name", "2", "13"
|
||||
"show-1", "dub", "best", "Example Name", "Example Source", "2", "13"
|
||||
)
|
||||
|
||||
def test_watchlist_media_type_post_returns_updated_item(self):
|
||||
@@ -3316,6 +3322,8 @@ class TemplateHelperTests(unittest.TestCase):
|
||||
self.assertIn("closeAutoDownloadOverlay()", APP.WATCHLIST_HTML)
|
||||
self.assertIn("Save auto-download", APP.WATCHLIST_HTML)
|
||||
self.assertIn("Manual add does not trigger it", APP.WATCHLIST_HTML)
|
||||
self.assertIn("Source name", APP.WATCHLIST_HTML)
|
||||
self.assertIn('id="autoDownloadSourceName"', APP.WATCHLIST_HTML)
|
||||
self.assertIn("Name source", APP.WATCHLIST_HTML)
|
||||
self.assertIn('class="wide-half">Name source', APP.WATCHLIST_HTML)
|
||||
self.assertIn('class="wide-half">Name', APP.WATCHLIST_HTML)
|
||||
|
||||
@@ -833,6 +833,9 @@ WATCHLIST_HTML = r"""<!doctype html>
|
||||
<label>Episode offset
|
||||
<input class="auto-download-offset" id="autoDownloadOffset" type="number" min="1" step="1" placeholder="Optional">
|
||||
</label>
|
||||
<label class="wide-half">Source name
|
||||
<input class="auto-download-source-name" id="autoDownloadSourceName" type="text">
|
||||
</label>
|
||||
<label class="wide-half">Name source
|
||||
<select class="auto-download-name-select" id="autoDownloadNameSelect"></select>
|
||||
</label>
|
||||
@@ -887,6 +890,7 @@ WATCHLIST_HTML = r"""<!doctype html>
|
||||
const autoDownloadQuality = document.getElementById("autoDownloadQuality");
|
||||
const autoDownloadSeries = document.getElementById("autoDownloadSeries");
|
||||
const autoDownloadOffset = document.getElementById("autoDownloadOffset");
|
||||
const autoDownloadSourceName = document.getElementById("autoDownloadSourceName");
|
||||
const autoDownloadNameSelect = document.getElementById("autoDownloadNameSelect");
|
||||
const autoDownloadName = document.getElementById("autoDownloadName");
|
||||
const autoDownloadSaveBtn = document.getElementById("autoDownloadSaveBtn");
|
||||
@@ -1088,6 +1092,7 @@ WATCHLIST_HTML = r"""<!doctype html>
|
||||
autoDownloadQuality.value = item.auto_download_quality || "best";
|
||||
autoDownloadSeries.value = item.auto_download_series || "1";
|
||||
autoDownloadOffset.value = item.auto_download_offset || "";
|
||||
autoDownloadSourceName.value = item.auto_download_source_name || item.title || "";
|
||||
populateAutoDownloadNameChoices(item);
|
||||
autoDownloadOverlay.hidden = false;
|
||||
}
|
||||
@@ -1123,6 +1128,7 @@ WATCHLIST_HTML = r"""<!doctype html>
|
||||
mode: autoDownloadMode.value,
|
||||
quality: autoDownloadQuality.value,
|
||||
name: autoDownloadName.value,
|
||||
source_name: autoDownloadSourceName.value,
|
||||
series: autoDownloadSeries.value,
|
||||
episode_offset: autoDownloadOffset.value
|
||||
})
|
||||
@@ -1133,12 +1139,14 @@ WATCHLIST_HTML = r"""<!doctype html>
|
||||
auto_download_mode: savedItem.auto_download_mode || autoDownloadMode.value,
|
||||
auto_download_quality: savedItem.auto_download_quality || autoDownloadQuality.value,
|
||||
auto_download_name: savedItem.auto_download_name || autoDownloadName.value,
|
||||
auto_download_source_name: savedItem.auto_download_source_name || autoDownloadSourceName.value,
|
||||
auto_download_series: savedItem.auto_download_series || autoDownloadSeries.value,
|
||||
auto_download_offset: savedItem.auto_download_offset || ""
|
||||
};
|
||||
populateAutoDownloadNameChoices(state.autoDownloadDraft);
|
||||
autoDownloadSeries.value = state.autoDownloadDraft.auto_download_series || autoDownloadSeries.value;
|
||||
autoDownloadOffset.value = state.autoDownloadDraft.auto_download_offset || "";
|
||||
autoDownloadSourceName.value = state.autoDownloadDraft.auto_download_source_name || autoDownloadSourceName.value;
|
||||
autoDownloadStatus.textContent = data.message || "Auto-download settings saved.";
|
||||
setNotice(data.message || "Auto-download settings saved.");
|
||||
closeAutoDownloadOverlay();
|
||||
|
||||
Reference in New Issue
Block a user