215 lines
6.1 KiB
Svelte
215 lines
6.1 KiB
Svelte
<script>
|
||
import { Link } from "svelte-routing";
|
||
import { createEventDispatcher, onDestroy, onMount, tick } from "svelte";
|
||
import { movieCount } from "../stores/movieStore.js";
|
||
import { tvShowCount } from "../stores/tvStore.js";
|
||
import { apiFetch } from "../utils/api.js";
|
||
|
||
export let menuOpen = false;
|
||
const dispatch = createEventDispatcher();
|
||
let hasMovies = false;
|
||
let hasShows = false;
|
||
// Svelte store kullanarak reaktivite sağla
|
||
import { writable } from 'svelte/store';
|
||
const diskSpaceStore = writable({ totalGB: '0', usedGB: '0', usedPercent: 0 });
|
||
let diskSpace;
|
||
|
||
// Store subscription'ı temizlemek için
|
||
let unsubscribeDiskSpace;
|
||
|
||
// Store'u değişkene bağla
|
||
unsubscribeDiskSpace = diskSpaceStore.subscribe(value => {
|
||
diskSpace = value;
|
||
console.log('🔄 Disk space updated from store:', diskSpace);
|
||
});
|
||
|
||
// Disk space'i reaktif olarak güncellemek için bir fonksiyon
|
||
function updateDiskSpace(newData) {
|
||
diskSpaceStore.update(current => Object.assign({}, current, newData));
|
||
console.log('🔄 Disk space update called with:', newData);
|
||
}
|
||
|
||
const unsubscribeMovie = movieCount.subscribe((count) => {
|
||
hasMovies = (count ?? 0) > 0;
|
||
});
|
||
|
||
const unsubscribeTv = tvShowCount.subscribe((count) => {
|
||
hasShows = (count ?? 0) > 0;
|
||
});
|
||
|
||
onDestroy(() => {
|
||
unsubscribeMovie();
|
||
unsubscribeTv();
|
||
if (unsubscribeDiskSpace) {
|
||
unsubscribeDiskSpace();
|
||
}
|
||
});
|
||
|
||
// Menü öğesine tıklanınca sidebar'ı kapat
|
||
function handleLinkClick() {
|
||
dispatch("closeMenu");
|
||
}
|
||
|
||
// Disk space bilgilerini al
|
||
async function fetchDiskSpace() {
|
||
try {
|
||
const response = await apiFetch('/api/disk-space');
|
||
if (response.ok) {
|
||
const data = await response.json();
|
||
console.log('Disk space data received:', data);
|
||
updateDiskSpace(data);
|
||
} else {
|
||
console.error('Disk space API error:', response.status, response.statusText);
|
||
}
|
||
} catch (error) {
|
||
console.error('Disk space fetch error:', error);
|
||
}
|
||
}
|
||
|
||
// Component yüklendiğinde disk space bilgilerini al
|
||
onMount(() => {
|
||
console.log('🔌 Sidebar component mounted');
|
||
fetchDiskSpace();
|
||
|
||
// WebSocket bağlantısı kur
|
||
const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||
// Server port'unu doğru almak için
|
||
const currentHost = window.location.host;
|
||
// Eğer client farklı portta çalışıyorsa, server port'unu manuel belirt
|
||
const wsHost = currentHost.includes(':3000') ? currentHost.replace(':3000', ':3001') : currentHost;
|
||
const wsUrl = `${wsProtocol}//${wsHost}`;
|
||
console.log('🔌 Connecting to WebSocket at:', wsUrl);
|
||
|
||
// WebSocket bağlantısını global olarak saklayalım
|
||
window.diskSpaceWs = new WebSocket(wsUrl);
|
||
|
||
window.diskSpaceWs.onmessage = (event) => {
|
||
try {
|
||
const data = JSON.parse(event.data);
|
||
console.log('WebSocket message received:', data);
|
||
if (data.type === 'diskSpace') {
|
||
console.log('Disk space update received:', data.data);
|
||
updateDiskSpace(data.data);
|
||
}
|
||
} catch (err) {
|
||
console.error('WebSocket message parse error:', err);
|
||
}
|
||
};
|
||
|
||
window.diskSpaceWs.onopen = () => {
|
||
console.log('WebSocket connected for disk space updates');
|
||
};
|
||
|
||
window.diskSpaceWs.onerror = (error) => {
|
||
console.error('WebSocket error:', error);
|
||
};
|
||
|
||
window.diskSpaceWs.onclose = () => {
|
||
console.log('WebSocket disconnected');
|
||
};
|
||
|
||
onDestroy(() => {
|
||
if (window.diskSpaceWs && (window.diskSpaceWs.readyState === WebSocket.OPEN || window.diskSpaceWs.readyState === WebSocket.CONNECTING)) {
|
||
window.diskSpaceWs.close();
|
||
}
|
||
});
|
||
});
|
||
</script>
|
||
|
||
<div class="sidebar" class:open={menuOpen}>
|
||
<div class="logo">du.pe</div>
|
||
|
||
<div class="menu">
|
||
<Link
|
||
to="/"
|
||
class="item"
|
||
getProps={({ isCurrent }) => ({
|
||
class: isCurrent ? "item active" : "item",
|
||
})}
|
||
on:click={handleLinkClick}
|
||
>
|
||
<i class="fa-solid fa-folder icon"></i>
|
||
Files
|
||
</Link>
|
||
|
||
{#if hasMovies}
|
||
<Link
|
||
to="/movies"
|
||
class="item"
|
||
getProps={({ isCurrent }) => ({
|
||
class: isCurrent ? "item active" : "item",
|
||
})}
|
||
on:click={handleLinkClick}
|
||
>
|
||
<i class="fa-solid fa-film icon"></i>
|
||
Movies
|
||
</Link>
|
||
{/if}
|
||
|
||
{#if hasShows}
|
||
<Link
|
||
to="/tv"
|
||
class="item"
|
||
getProps={({ isCurrent }) => ({
|
||
class: isCurrent ? "item active" : "item",
|
||
})}
|
||
on:click={handleLinkClick}
|
||
>
|
||
<i class="fa-solid fa-tv icon"></i>
|
||
Tv Shows
|
||
</Link>
|
||
{/if}
|
||
|
||
<Link
|
||
to="/transfers"
|
||
class="item"
|
||
getProps={({ isCurrent }) => ({
|
||
class: isCurrent ? "item active" : "item",
|
||
})}
|
||
on:click={handleLinkClick}
|
||
>
|
||
<i class="fa-solid fa-arrow-down icon"></i>
|
||
Transfers
|
||
</Link>
|
||
|
||
<Link
|
||
to="/trash"
|
||
class="item"
|
||
getProps={({ isCurrent }) => ({
|
||
class: isCurrent ? "item active" : "item",
|
||
})}
|
||
on:click={handleLinkClick}
|
||
>
|
||
<i class="fa-solid fa-trash icon"></i>
|
||
Trash
|
||
</Link>
|
||
</div>
|
||
|
||
<!-- Disk Space Alanı - Sidebar'ın en altında -->
|
||
<div class="disk-space">
|
||
<div class="disk-space-header">
|
||
<i class="fa-solid fa-hard-drive icon"></i>
|
||
<span class="disk-space-title">Disk Space</span>
|
||
</div>
|
||
<div class="disk-space-info">
|
||
<div class="disk-space-text">
|
||
<span class="disk-space-values">
|
||
{#if diskSpace.usedFormatted && diskSpace.totalFormatted}
|
||
{diskSpace.usedFormatted} / {diskSpace.totalFormatted}
|
||
{:else}
|
||
{diskSpace.usedGB} GB / {diskSpace.totalGB} GB
|
||
{/if}
|
||
</span>
|
||
</div>
|
||
<div class="disk-space-bar-container">
|
||
<div class="disk-space-bar">
|
||
<div
|
||
class="disk-space-bar-fill {diskSpace.usedPercent < 50 ? 'low' : diskSpace.usedPercent < 80 ? 'medium' : 'high'}"
|
||
style="width: {diskSpace.usedPercent}%"
|
||
></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|