Naut-Plugin-WebUI/public/js/api.js
ookami125 d55fc35c72 webui: edit-category modal + dropdown dedupe
Add an "Edit category…" context-menu item and modal that renames a
category and/or changes its save path (Uncategorized: path only).
Filter empty-named categories out of the add/set-category dropdowns so
the stored Uncategorized save-path entry doesn't double the option.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 00:29:16 -04:00

59 lines
2.3 KiB
JavaScript

// Thin API client + SSE live stream.
async function jget(url) {
const r = await fetch(url);
if (!r.ok) throw new Error(`${url}${r.status}`);
return r.json();
}
async function jpost(url, body) {
const r = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body || {}),
});
if (!r.ok) throw new Error(`${url}${r.status}`);
return r.json();
}
export const api = {
authStatus: () => jget('/api/auth/status'),
login: (username, password) => jpost('/api/login', { username, password }),
logout: () => jpost('/api/logout', {}),
plugins: () => jget('/api/plugins'),
meta: () => jget('/api/meta'),
snapshot: () => jget('/api/snapshot'),
torrent: (hash) => jget(`/api/torrents/${hash}`),
trackers: (hash) => jget(`/api/torrents/${hash}/trackers`),
peers: (hash) => jget(`/api/torrents/${hash}/peers`),
files: (hash) => jget(`/api/torrents/${hash}/files`),
pieces: (hash) => jget(`/api/torrents/${hash}/pieces`),
action: (action, hashes, params) => jpost('/api/action', { action, hashes, params }),
remove: (hashes, deleteFiles) => jpost('/api/delete', { hashes, deleteFiles }),
add: (opts) => jpost('/api/add', opts),
toggleAltSpeed: () => jpost('/api/altspeed', {}),
createCategory: (name, savePath) => jpost('/api/categories', { name, savePath }),
deleteCategory: (name) => jpost('/api/categories/delete', { name }),
editCategory: (name, newName, savePath) =>
jpost('/api/categories/edit', { name, newName, savePath }),
createTag: (name) => jpost('/api/tags', { name }),
deleteTag: (name) => jpost('/api/tags/delete', { name }),
rss: () => jget('/api/rss'),
rssRules: () => jget('/api/rss/rules'),
script: () => jget('/api/script'),
saveScript: (source) => jpost('/api/script', { source }),
saveScriptSettings: (settings) => jpost('/api/script/settings', { settings }),
search: (q) => jget(`/api/search?q=${encodeURIComponent(q)}`),
// Live snapshot stream. onSnapshot(snapshot) called ~1/s.
stream(onSnapshot, onStatus) {
const es = new EventSource('/api/stream');
es.addEventListener('snapshot', (e) => onSnapshot(JSON.parse(e.data)));
es.onopen = () => onStatus && onStatus('connected');
es.onerror = () => onStatus && onStatus('reconnecting');
return es;
},
};