diff --git a/client/src/routes/Settings.svelte b/client/src/routes/Settings.svelte index 52e7c05..080b5b5 100644 --- a/client/src/routes/Settings.svelte +++ b/client/src/routes/Settings.svelte @@ -13,6 +13,11 @@ let cookiesUpdatedAt = null; let loadingCookies = false; let savingCookies = false; + let loadingYtSettings = false; + let savingYtSettings = false; + let selectedResolution = "1080p"; + let onlyAudio = false; + const resolutionOptions = ["1080p", "720p", "480p", "360p", "240p", "144p"]; let error = null; let success = null; @@ -64,8 +69,51 @@ } } + async function loadYoutubeSettings() { + loadingYtSettings = true; + error = null; + try { + const resp = await apiFetch("/api/youtube/settings"); + if (!resp.ok) throw new Error(`HTTP ${resp.status}`); + const data = await resp.json(); + if (data?.resolution) selectedResolution = data.resolution; + if (typeof data?.onlyAudio === "boolean") onlyAudio = data.onlyAudio; + } catch (err) { + error = err?.message || "YouTube ayarları alınamadı."; + } finally { + loadingYtSettings = false; + } + } + + async function saveYoutubeSettings() { + if (savingYtSettings) return; + savingYtSettings = true; + error = null; + success = null; + try { + const resp = await apiFetch("/api/youtube/settings", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + resolution: selectedResolution, + onlyAudio + }) + }); + const data = await resp.json().catch(() => ({})); + if (!resp.ok || !data?.ok) { + throw new Error(data?.error || `HTTP ${resp.status}`); + } + success = "YouTube indirme ayarları kaydedildi."; + } catch (err) { + error = err?.message || "YouTube ayarları kaydedilemedi."; + } finally { + savingYtSettings = false; + } + } + onMount(() => { loadCookies(); + loadYoutubeSettings(); }); function formatDate(ts) { @@ -98,6 +146,47 @@ {#if activeTab === "youtube"} +
+
+
+ + YouTube Download +
+
+ +
+
+ + +
+ +
+ +
+ + +
+
+
@@ -238,6 +327,46 @@ font-weight: 600; } + .field.inline { + display: flex; + align-items: center; + gap: 16px; + flex-wrap: wrap; + } + + .field.inline.compact { + align-items: flex-end; + } + + .field.inline.left-align { + flex-direction: column; + align-items: flex-start; + justify-content: flex-start; + gap: 10px; + } + + .inline-field { + display: flex; + flex-direction: column; + gap: 6px; + } + + .field select { + min-width: 180px; + max-width: 240px; + padding: 8px 10px; + border: 1px solid var(--border, #dcdcdc); + border-radius: 8px; + background: #fff; + } + + .checkbox-row { + display: inline-flex; + align-items: center; + gap: 8px; + font-weight: 600; + } + .field textarea { min-height: 180px; padding: 10px; @@ -258,6 +387,16 @@ justify-content: flex-end; } + .actions.left { + justify-content: flex-start; + } + + .divider { + height: 1px; + background: #eee; + margin: 6px 0; + } + .btn { display: inline-flex; align-items: center;