188 lines
6.5 KiB
JavaScript
188 lines
6.5 KiB
JavaScript
/*
|
|
SETTINGS — source provider toggles, API server base URL, TMDB key, local data.
|
|
*/
|
|
(function () {
|
|
'use strict';
|
|
|
|
SR.app.initChrome();
|
|
|
|
const providerList = document.getElementById('providerList');
|
|
const providersStatus = document.getElementById('providersStatus');
|
|
const apiBaseInput = document.getElementById('apiBaseInput');
|
|
const connStatus = document.getElementById('connStatus');
|
|
const tmdbKeyInput = document.getElementById('tmdbKeyInput');
|
|
const tmdbStatus = document.getElementById('tmdbStatus');
|
|
const dataStatus = document.getElementById('dataStatus');
|
|
|
|
/* ---- nav --------------------------------------------------------------------- */
|
|
|
|
const navlinks = Array.from(document.querySelectorAll('.settings__navlink'));
|
|
navlinks.forEach((link) => {
|
|
link.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
const target = document.querySelector(link.getAttribute('href'));
|
|
if (target) target.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
navlinks.forEach((l) => l.classList.toggle('is-active', l === link));
|
|
history.replaceState(null, '', link.getAttribute('href'));
|
|
});
|
|
});
|
|
|
|
/* ---- sources ------------------------------------------------------------------- */
|
|
|
|
let allProviders = [];
|
|
let serverEnabled = [];
|
|
const boxes = new Map(); // provider name -> checkbox
|
|
|
|
function setStatus(el, message, kind) {
|
|
el.textContent = message || '';
|
|
el.className =
|
|
kind === 'ok' ? 'settings__status settings__status--ok'
|
|
: kind === 'err' ? 'settings__status settings__status--err'
|
|
: 'settings__status';
|
|
}
|
|
|
|
function currentMap() {
|
|
const map = {};
|
|
for (const [name, box] of boxes) map[name] = box.checked;
|
|
return map;
|
|
}
|
|
|
|
function persist(map, message) {
|
|
SR.config.setProviders(map);
|
|
if (message) setStatus(providersStatus, message);
|
|
}
|
|
|
|
function renderProviders() {
|
|
providerList.replaceChildren();
|
|
boxes.clear();
|
|
const overrides = SR.config.getProviders();
|
|
const enabled = SR.config.enabledProviders(allProviders, serverEnabled);
|
|
for (const name of allProviders) {
|
|
const checked = enabled.includes(name);
|
|
const label = document.createElement('label');
|
|
label.className = 'provider';
|
|
const input = document.createElement('input');
|
|
input.type = 'checkbox';
|
|
input.checked = !!checked;
|
|
const nameEl = document.createElement('span');
|
|
nameEl.className = 'provider__name';
|
|
nameEl.textContent = name;
|
|
label.append(input, nameEl);
|
|
input.addEventListener('change', () =>
|
|
persist(currentMap(), input.checked ? `${name} enabled` : `${name} disabled`));
|
|
boxes.set(name, input);
|
|
providerList.appendChild(label);
|
|
}
|
|
const on = boxes.size ? Array.from(boxes.values()).filter((b) => b.checked).length : 0;
|
|
const source = overrides ? 'your selection' : 'default sources';
|
|
let host;
|
|
try { host = new URL(SR.config.getBase()).host; } catch (e) { host = SR.config.getBase(); }
|
|
setStatus(providersStatus, `${on} of ${allProviders.length} enabled — ${source} · ${host}`);
|
|
}
|
|
|
|
function resetProviders(message) {
|
|
SR.config.clearProviders();
|
|
renderProviders();
|
|
if (message) setStatus(providersStatus, message);
|
|
}
|
|
|
|
document.getElementById('allOn').addEventListener('click', () => {
|
|
if (!boxes.size) return;
|
|
for (const box of boxes.values()) box.checked = true;
|
|
persist(currentMap(), 'All sources enabled');
|
|
});
|
|
|
|
document.getElementById('allOff').addEventListener('click', () => {
|
|
if (!boxes.size) return;
|
|
for (const box of boxes.values()) box.checked = false;
|
|
persist(currentMap(), 'All sources disabled');
|
|
});
|
|
|
|
document.getElementById('providersReset').addEventListener('click', () =>
|
|
resetProviders('Using default sources'));
|
|
|
|
async function initSources() {
|
|
try {
|
|
const data = await SR.api.providers();
|
|
allProviders = data.all || [];
|
|
serverEnabled = data.enabled || [];
|
|
renderProviders();
|
|
} catch (e) {
|
|
setStatus(providersStatus, `Could not load the provider list: ${e.message}`, 'err');
|
|
}
|
|
}
|
|
|
|
/* ---- server ----------------------------------------------------------------------- */
|
|
|
|
apiBaseInput.value = SR.config.getBase();
|
|
|
|
async function testConnection() {
|
|
try {
|
|
const data = await SR.api.providers();
|
|
setStatus(connStatus, `Connected — ${data.all ? data.all.length : 0} provider(s) known.`, 'ok');
|
|
return true;
|
|
} catch (e) {
|
|
setStatus(connStatus, `Not reachable: ${e.message}`, 'err');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
document.getElementById('apiBaseSave').addEventListener('click', async () => {
|
|
SR.config.setBase(apiBaseInput.value);
|
|
apiBaseInput.value = SR.config.getBase();
|
|
SR.app.initChrome(); // refresh the footer label
|
|
if (await testConnection()) SR.app.toast('API base URL saved');
|
|
});
|
|
|
|
document.getElementById('apiBaseReset').addEventListener('click', async () => {
|
|
SR.config.clearBase();
|
|
apiBaseInput.value = SR.config.getBase();
|
|
SR.app.initChrome();
|
|
await testConnection();
|
|
});
|
|
|
|
/* ---- TMDB key ------------------------------------------------------------------- */
|
|
|
|
tmdbKeyInput.value = SR.config.getTmdbKey();
|
|
|
|
async function testTmdbKey(key) {
|
|
setStatus(tmdbStatus, 'Testing TMDB key…');
|
|
try {
|
|
await SR.api.tmdb('/search/movie', { query: 'The Matrix', page: 1 }, key);
|
|
setStatus(tmdbStatus, 'TMDB key works — search, details and images load directly from TMDB.', 'ok');
|
|
} catch (e) {
|
|
setStatus(tmdbStatus, e.message, 'err');
|
|
}
|
|
}
|
|
|
|
document.getElementById('tmdbKeySave').addEventListener('click', async () => {
|
|
SR.config.setTmdbKey(tmdbKeyInput.value);
|
|
tmdbKeyInput.value = SR.config.getTmdbKey();
|
|
await testTmdbKey(SR.config.getTmdbKey());
|
|
});
|
|
|
|
document.getElementById('tmdbKeyTest').addEventListener('click', async () => {
|
|
await testTmdbKey(tmdbKeyInput.value.trim());
|
|
});
|
|
|
|
document.getElementById('tmdbKeyReset').addEventListener('click', async () => {
|
|
SR.config.clearTmdbKey();
|
|
tmdbKeyInput.value = SR.config.getTmdbKey();
|
|
await testTmdbKey(SR.config.getTmdbKey());
|
|
});
|
|
|
|
/* ---- data ---------------------------------------------------------------------------- */
|
|
|
|
document.getElementById('clearHistory').addEventListener('click', () => {
|
|
SR.storage.clear();
|
|
setStatus(dataStatus, 'Continue-watching history cleared.');
|
|
});
|
|
|
|
document.getElementById('resetProviders').addEventListener('click', () => {
|
|
resetProviders('');
|
|
setStatus(dataStatus, 'Source toggles reset to default sources.');
|
|
});
|
|
|
|
initSources();
|
|
})();
|