From 279adf12e9ae8a8a55431d8cda287fca93790caf Mon Sep 17 00:00:00 2001 From: szbk Date: Wed, 29 Oct 2025 12:26:25 +0300 Subject: [PATCH] =?UTF-8?q?Men=C3=BC=20eklendi.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/routes/Files.svelte | 225 ++++++++++++++++++++++++++++++++- 1 file changed, 224 insertions(+), 1 deletion(-) diff --git a/client/src/routes/Files.svelte b/client/src/routes/Files.svelte index 6e45798..ae8e248 100644 --- a/client/src/routes/Files.svelte +++ b/client/src/routes/Files.svelte @@ -21,6 +21,7 @@ if (typeof window !== "undefined") { let selectedItems = new Set(); let allSelected = false; let pendingPlayTarget = null; +let activeMenu = null; // Aktif menünün dosya adını tutar if (typeof window !== "undefined") { const params = new URLSearchParams(window.location.search); const playParam = params.get("play"); @@ -340,6 +341,69 @@ let isPlaying = false; allSelected = failed.length > 0 && failed.length === files.length; await Promise.all([refreshMovieCount(), refreshTvShowCount()]); } + + // Menü fonksiyonları + function toggleMenu(fileName, event) { + event.stopPropagation(); + activeMenu = activeMenu === fileName ? null : fileName; + } + + function closeMenu() { + activeMenu = null; + } + + async function downloadFile(file) { + const token = localStorage.getItem("token"); + const link = document.createElement('a'); + link.href = `${API}/downloads/${file.name}?token=${token}`; + link.download = file.name; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + closeMenu(); + } + + function matchFile(file) { + // Eşleşme işlevi - buraya özel mantık eklenebilir + console.log("Eşleşme:", file.name); + closeMenu(); + } + + async function deleteFile(file) { + if (!confirm(`"${cleanFileName(file.name)}" dosyasını silmek istediğinizden emin misiniz?`)) + return; + + const token = localStorage.getItem("token"); + try { + const resp = await fetch( + `${API}/api/file?path=${encodeURIComponent(file.name)}`, + { + method: "DELETE", + headers: { Authorization: `Bearer ${token}` }, + }, + ); + + if (!resp.ok) { + const data = await resp.json().catch(() => ({})); + alert("Silme hatası: " + (data.error || resp.statusText)); + return; + } + + files = files.filter((f) => f.name !== file.name); + + const hash = file.name.split("/")[0]; + await fetch(`${API}/api/torrents/${hash}`, { + method: "DELETE", + headers: { Authorization: `Bearer ${token}` }, + }); + + await Promise.all([refreshMovieCount(), refreshTvShowCount()]); + } catch (err) { + console.warn("⚠️ Silme işlemi başarısız:", err); + alert("Silme işlemi başarısız oldu."); + } + closeMenu(); + } onMount(async () => { await loadFiles(); // önce dosyaları getir const token = localStorage.getItem("token"); @@ -420,7 +484,20 @@ let isPlaying = false; } } window.addEventListener("keydown", handleKey); - return () => window.removeEventListener("keydown", handleKey); + + // Menüyü kapatmak için dışarı tıklama olayı + function handleClickOutside(event) { + if (activeMenu && !event.target.closest('.media-card')) { + activeMenu = null; + } + } + + window.addEventListener("click", handleClickOutside); + + return () => { + window.removeEventListener("keydown", handleKey); + window.removeEventListener("click", handleClickOutside); + }; }); @@ -566,6 +643,40 @@ let isPlaying = false; {/if} + + {#if activeMenu === f.name} + + {/if} {/each} @@ -1623,4 +1734,116 @@ let isPlaying = false; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); } } + /* Menü düğmesi ve dropdown stilleri */ + .menu-toggle { + position: absolute; + top: 12px; + right: 12px; + width: 34px; + height: 34px; + border-radius: 50%; + border: none; + background: rgba(0, 0, 0, 0.45); + color: #f5f5f5; + display: inline-flex; + align-items: center; + justify-content: center; + opacity: 0; + outline: none; + transform: scale(0.88); + transition: + opacity 0.2s ease, + transform 0.2s ease, + background 0.2s ease; + cursor: pointer; + pointer-events: none; + z-index: 2; + } + + .menu-toggle i { + font-size: 14px; + } + + .media-card:hover .menu-toggle, + .media-card.is-selected .menu-toggle { + opacity: 1; + transform: scale(1); + pointer-events: auto; + } + + .menu-toggle:hover { + background: rgba(0, 0, 0, 0.65); + } + + .media-card.list-view .menu-toggle { + top: 16px; + right: 16px; + } + + .dropdown-menu { + position: absolute; + top: 52px; + right: 12px; + background: #ffffff; + border-radius: 8px; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15); + min-width: 160px; + z-index: 100; + overflow: hidden; + animation: fadeIn 0.2s ease; + } + + .media-card.list-view .dropdown-menu { + top: 56px; + right: 16px; + } + + @keyframes fadeIn { + from { + opacity: 0; + transform: translateY(-8px); + } + to { + opacity: 1; + transform: translateY(0); + } + } + + .menu-item { + display: flex; + align-items: center; + gap: 12px; + width: 100%; + padding: 12px 16px; + border: none; + background: transparent; + color: #333; + font-size: 14px; + cursor: pointer; + transition: background-color 0.2s ease; + } + + .menu-item:hover { + background-color: #f5f5f5; + } + + .menu-item.delete { + color: #e53935; + } + + .menu-item.delete:hover { + background-color: #ffebee; + } + + .menu-item i { + font-size: 14px; + width: 16px; + text-align: center; + } + + .menu-divider { + height: 1px; + background-color: #e0e0e0; + margin: 4px 0; + }