Progress percentage is now visible on the files screen.

This commit is contained in:
2025-10-24 21:50:21 +03:00
parent ba51482d07
commit 6282d83351
3 changed files with 73 additions and 21 deletions

View File

@@ -223,10 +223,9 @@
} }
} }
onMount(() => { onMount(async () => {
loadFiles(); await loadFiles(); // önce dosyaları getir
// 🔄 WebSocket ile anlık dosya güncellemelerini dinle
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
const wsUrl = `${API.replace("http", "ws")}?token=${token}`; const wsUrl = `${API.replace("http", "ws")}?token=${token}`;
const ws = new WebSocket(wsUrl); const ws = new WebSocket(wsUrl);
@@ -234,16 +233,37 @@
ws.onmessage = async (event) => { ws.onmessage = async (event) => {
try { try {
const msg = JSON.parse(event.data); const msg = JSON.parse(event.data);
if (msg.type === "fileUpdate") { if (msg.type === "fileUpdate") {
console.log("📸 Yeni thumbnail bildirimi alındı:", msg.path); console.log("📸 Yeni thumbnail bildirimi:", msg.path);
await loadFiles(); // 🔄 anında dosya listesini yenile await loadFiles();
}
if (msg.type === "progress" && msg.torrents) {
for (const t of msg.torrents) {
const savePath = t.savePath || "";
const folderId = savePath.split("/").pop();
files = files.map((f) => {
const fileFolder = f.name.split("/")[0];
if (fileFolder === folderId) {
return t.progress < 1
? {
...f,
progressText: `${Math.floor(t.progress * 100)}%`
}
: { ...f, progressText: null };
}
return f;
});
}
files = [...files];
} }
} catch (err) { } catch (err) {
console.warn("WebSocket mesajı çözümlenemedi:", err); console.warn("WebSocket mesajı çözümlenemedi:", err);
} }
}; };
// ✅ Tek event handler içinde hem Esc hem ok tuşlarını kontrol et
function handleKey(e) { function handleKey(e) {
if (e.key === "Escape") { if (e.key === "Escape") {
if (showModal) closeModal(); if (showModal) closeModal();
@@ -255,9 +275,7 @@
} }
window.addEventListener("keydown", handleKey); window.addEventListener("keydown", handleKey);
return () => { return () => window.removeEventListener("keydown", handleKey);
window.removeEventListener("keydown", handleKey);
};
}); });
</script> </script>
@@ -289,7 +307,13 @@
{/if} {/if}
<div class="info"> <div class="info">
<div class="name">{cleanFileName(f.name)}</div> <div class="name">{cleanFileName(f.name)}</div>
<div class="size">{formatSize(f.size)}</div> <div class="size">
{#if f.progressText}
<span class="progress-text">{f.progressText}</span>
{:else}
{formatSize(f.size)}
{/if}
</div>
</div> </div>
<div class="media-type-icon"> <div class="media-type-icon">
{#if f.type?.startsWith("video/")} {#if f.type?.startsWith("video/")}
@@ -600,6 +624,25 @@
opacity: 1; opacity: 1;
} }
.progress-text {
color: #666; /* gri */
font-weight: 600;
font-size: 12px;
animation: pulse 1.2s infinite ease-in-out;
}
@keyframes pulse {
0% {
opacity: 0.7;
}
50% {
opacity: 1;
}
100% {
opacity: 0.7;
}
}
/* 🗑️ ikonu hover efekti */ /* 🗑️ ikonu hover efekti */
.delete-overlay i { .delete-overlay i {
background: rgba(255, 255, 255, 0.2); background: rgba(255, 255, 255, 0.2);

View File

@@ -453,16 +453,16 @@ body,
/* 🌫️ Thumbnail fade-in + blur efekti */ /* 🌫️ Thumbnail fade-in + blur efekti */
/* 🌫️ Fade-in thumbnail efekti — sadece img'ler için geçerli */ /* 🌫️ Fade-in thumbnail efekti — sadece img'ler için geçerli */
img.thumb { img.thumb {
opacity: 0; opacity: 1;
filter: blur(10px) brightness(0.9); filter: none;
transform: scale(1.03); transform: none;
transition: opacity 0.6s ease, filter 1s ease, transform 0.6s ease; transition: none;
} }
img.thumb.loaded { img.thumb.loaded {
opacity: 1; opacity: 1;
filter: blur(0) brightness(1); filter: none;
transform: scale(1); transform: none;
} }
/* 🪄 Placeholder her zaman görünür */ /* 🪄 Placeholder her zaman görünür */

View File

@@ -54,8 +54,9 @@ function snapshot() {
downloadSpeed: torrent.downloadSpeed, downloadSpeed: torrent.downloadSpeed,
uploadSpeed: torrent.uploadSpeed, uploadSpeed: torrent.uploadSpeed,
numPeers: torrent.numPeers, numPeers: torrent.numPeers,
tracker: torrent.announce?.[0] || null, // 🆕 ilk tracker tracker: torrent.announce?.[0] || null,
added, // 🆕 eklenme zamanı added,
savePath, // 🆕 BURASI!
files: torrent.files.map((f, i) => ({ files: torrent.files.map((f, i) => ({
index: i, index: i,
name: f.name, name: f.name,
@@ -155,6 +156,11 @@ app.post("/api/transfer", requireAuth, upload.single("torrent"), (req, res) => {
length: f.length length: f.length
})) }))
}); });
const data = JSON.stringify({
type: "progress",
torrents: snapshot()
});
wss.clients.forEach((c) => c.readyState === 1 && c.send(data));
}); });
// --- İndirme tamamlandığında thumbnail oluştur --- // --- İndirme tamamlandığında thumbnail oluştur ---
@@ -526,10 +532,13 @@ wss.on("connection", (ws) => {
ws.send(JSON.stringify({ type: "progress", torrents: snapshot() })); ws.send(JSON.stringify({ type: "progress", torrents: snapshot() }));
}); });
// --- ⏱️ Her 2 saniyede bir aktif torrent durumu yayınla ---
setInterval(() => { setInterval(() => {
const data = JSON.stringify({ type: "progress", torrents: snapshot() }); if (torrents.size > 0) {
wss.clients.forEach((c) => c.readyState === 1 && c.send(data)); const data = JSON.stringify({ type: "progress", torrents: snapshot() });
}, 1000); wss.clients.forEach((c) => c.readyState === 1 && c.send(data));
}
}, 2000);
client.on("error", (err) => { client.on("error", (err) => {
if (!String(err).includes("uTP")) if (!String(err).includes("uTP"))