From e3d0eaf8cf1913cab6d1b58da658db475cfe9ab4 Mon Sep 17 00:00:00 2001 From: szbk Date: Sun, 14 Dec 2025 21:05:10 +0300 Subject: [PATCH] =?UTF-8?q?feat(settings):=20YouTube=20indirme=20ayarlar?= =?UTF-8?q?=C4=B1=20ekle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Kullanıcıların YouTube indirme tercihlerini yapılandırabilmesi için ayarlar arayüzüne yeni kontroller eklendi: - Video çözünürlüğü seçimi (1080p, 720p, 480p, 360p, 240p, 144p) - Sadece ses indirme seçeneği - Ayarları kaydetme/yenileme butonları - API ile entegrasyon için load/save fonksiyonları --- client/src/routes/Settings.svelte | 139 ++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) 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;