diff --git a/CHANGELOG.md b/CHANGELOG.md index cc6a5e2..5be0749 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG +## 1.1.0 - 2026-01-25 + +- **Added**: Support for YTPTube API changes where presets are returned in an "items" array. +- **Removed**: Output template and folder setting. You can set them via preset server-side. + ## 1.0.4 - 2025-11-01 - **Fixed**: Issue with saving options for firefox. diff --git a/src/background.js b/src/background.js index 90ed3cd..29462f2 100644 --- a/src/background.js +++ b/src/background.js @@ -1,6 +1,4 @@ -// noinspection JSUnresolvedReference - -const str_keys = ["instance_url", "preset", "template", "folder", "username", "password"] +const str_keys = ["instance_url", "preset", "username", "password"] const bool_keys = ["showContextMenu"] if (typeof chrome === 'undefined') { @@ -28,7 +26,7 @@ const shouldShowContextMenu = async () => { const syncContextMenu = async () => { let showContextMenu = await shouldShowContextMenu(); - chrome.contextMenus.update("send-to-ytptube", {visible: showContextMenu}); + chrome.contextMenus.update("send-to-ytptube", { visible: showContextMenu }); } chrome.contextMenus.create({ @@ -37,7 +35,7 @@ chrome.contextMenus.create({ contexts: ["link"] }, onMenuCreated); -const getCurrentUrl = async () => (await chrome.tabs.query({currentWindow: true, active: true}))[0].url +const getCurrentUrl = async () => (await chrome.tabs.query({ currentWindow: true, active: true }))[0].url const getOption = async key => { let item = await chrome.storage.sync.get(key); @@ -70,7 +68,7 @@ const sendRequest = async (path, data) => { const url = new URL(instanceUrl); url.pathname = path; - let opts = {method: Object.keys(data).length > 0 ? 'POST' : 'GET', headers: headers}; + let opts = { method: Object.keys(data).length > 0 ? 'POST' : 'GET', headers: headers }; if (data) { opts.headers['Content-Type'] = 'application/json'; @@ -80,38 +78,27 @@ const sendRequest = async (path, data) => { console.debug(`Sending to '${instanceUrl}'.`, opts, headers.length > 0 ? 'with auth header' : 'without auth header'); const req = await fetch(url, opts); - return {status: req.status, statusText: req.statusText, data: req}; + return { status: req.status, statusText: req.statusText, data: req }; }; const sendUrl = async (user_url, preset = null) => { try { - const requestData = {url: user_url}; + const requestData = { url: user_url }; if (preset) { requestData.preset = preset; } - - // Add template and folder if configured - const template = await getOption("template"); - if (template) { - requestData.template = template; - } - - const folder = await getOption("folder"); - if (folder) { - requestData.folder = folder; - } - + console.debug('Sending request data:', requestData); - + const data = await sendRequest('/api/history', requestData); - if (200 === data.status) { + if ([200, 201, 202].includes(data.status)) { notify('Request sent successfully.'); return { success: true, message: 'Request sent successfully.' }; } const errorMessage = `Failed to send request. '${data.status}: ${data.statusText}'.`; notify(errorMessage); return { success: false, message: errorMessage }; - }catch (e) { + } catch (e) { console.error(e); const errorMessage = `Failed to send request. '${e.message}'.`; notify(errorMessage); @@ -156,7 +143,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { } })(); - return true; // Keep the messaging channel open for async response + return true; }); diff --git a/src/manifest.json b/src/manifest.json index 2c291d3..08d8120 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -7,7 +7,7 @@ ] }, "name": "YTPTube Extension", - "version": "1.0.4", + "version": "1.1.0", "description": "Add URLs to YTPTube instance", "permissions": [ "activeTab", diff --git a/src/options.html b/src/options.html index cf6a3f7..b860fb6 100644 --- a/src/options.html +++ b/src/options.html @@ -27,24 +27,6 @@ Preset to use for the URL -
- -
- -
- Filename template to use for the output file. -
- -
- -
- -
- Where to save downloaded files. -
-
diff --git a/src/options.js b/src/options.js index f22b9c4..7544be2 100644 --- a/src/options.js +++ b/src/options.js @@ -1,6 +1,6 @@ // noinspection JSUnresolvedReference -const str_keys = ["instance_url", "preset", "template", "folder", "username", "password"] +const str_keys = ["instance_url", "preset", "username", "password"] let storedOriginPattern = null; if (typeof chrome === 'undefined') { @@ -38,7 +38,7 @@ const ensureOriginPermission = async (originPattern) => { return true; } - return await chrome.permissions.request({origins: [originPattern]}); + return await chrome.permissions.request({ origins: [originPattern] }); }; const removeOriginPermission = async (originPattern) => { @@ -46,16 +46,15 @@ const removeOriginPermission = async (originPattern) => { return; } - const hasPermission = await chrome.permissions.contains({origins: [originPattern]}); + const hasPermission = await chrome.permissions.contains({ origins: [originPattern] }); if (!hasPermission) { return; } - await chrome.permissions.remove({origins: [originPattern]}); + await chrome.permissions.remove({ origins: [originPattern] }); }; const testConfig = async () => { - document.querySelector('#error_msg').innerText = ""; let instance_url = document.querySelector("#instance_url").value.trim(); @@ -133,7 +132,7 @@ document.getElementById("ytptube_options").addEventListener("submit", async e => let showContextMenu = document.querySelector("#showContextMenu").checked; - let data = {presets: {presets: ['default'], last_updated: 0}} + let data = { presets: { presets: ['default'], last_updated: 0 } } str_keys.forEach(key => data[key] = document.querySelector(`#${key}`).value) data["showContextMenu"] = showContextMenu; @@ -147,7 +146,7 @@ document.getElementById("ytptube_options").addEventListener("submit", async e => storedOriginPattern = newOriginPattern; chrome.storage.sync.set(data); - chrome.contextMenus.update("send-to-ytptube", {visible: showContextMenu}); + chrome.contextMenus.update("send-to-ytptube", { visible: showContextMenu }); notify("Options saved.", true); diff --git a/src/popup.js b/src/popup.js index 4fe41ea..1f5c79f 100644 --- a/src/popup.js +++ b/src/popup.js @@ -20,7 +20,7 @@ const notify = message => chrome.notifications.create({ const showLoading = (isLoading) => { const submitBtn = $('#submit-btn') - + if (isLoading) { submitBtn.disabled = true submitBtn.classList.add('is-loading') @@ -35,7 +35,7 @@ const showStatusMessage = (message, isSuccess = true) => { statusDiv.textContent = message statusDiv.className = `notification ${isSuccess ? 'is-success' : 'is-danger'}` statusDiv.classList.remove('is-hidden') - + // Hide the message after 3 seconds setTimeout(() => { statusDiv.classList.add('is-hidden') @@ -52,10 +52,10 @@ $("#ytptube_popup").addEventListener("submit", async (e) => { } showLoading(true) - + try { - const response = await chrome.runtime.sendMessage({command: 'send-to-ytptube', url: url, preset: preset}) - + const response = await chrome.runtime.sendMessage({ command: 'send-to-ytptube', url: url, preset: preset }) + if (response && response.success) { showStatusMessage('Request sent successfully!', true) } else { @@ -69,7 +69,7 @@ $("#ytptube_popup").addEventListener("submit", async (e) => { } }) -const getCurrentUrl = async () => (await chrome.tabs.query({currentWindow: true, active: true}))[0].url +const getCurrentUrl = async () => (await chrome.tabs.query({ currentWindow: true, active: true }))[0].url addEventListener('DOMContentLoaded', async _ => { let url = await getCurrentUrl() @@ -90,7 +90,7 @@ addEventListener('DOMContentLoaded', async _ => { if (Date.now() - cache.last_updated > 1000 * 60 * 60) { cache.presets = await getPresets() cache.last_updated = Date.now() - await chrome.storage.sync.set({presets: cache}) + await chrome.storage.sync.set({ presets: cache }) } const s = $('#preset') @@ -120,7 +120,7 @@ $('#go-to-options').addEventListener('click', function () { } }); -$('#preset').addEventListener('change', async e => await chrome.storage.sync.set({preset: e.target.value})) +$('#preset').addEventListener('change', async e => await chrome.storage.sync.set({ preset: e.target.value })) const getPresets = async () => { let presets = [] @@ -143,13 +143,18 @@ const getPresets = async () => { url.pathname = '/api/presets'; url.search = 'filter=name'; - const req = await fetch(url, {method: 'GET', headers: {...headers, 'Accept': 'application/json'}}); + const req = await fetch(url, { method: 'GET', headers: { ...headers, 'Accept': 'application/json' } }); if (200 !== req.status) { presets.push('Error fetching presets from YTPTube.'); return presets } - (await req.json()).forEach(preset => presets.push(preset.name)) + const data = await req.json() + if (data.items && Array.isArray(data.items)) { + data.items.forEach(preset => presets.push(preset.name)) + } else { + data.forEach(preset => presets.push(preset.name)) + } return presets }; \ No newline at end of file