180 lines
5.1 KiB
Svelte
180 lines
5.1 KiB
Svelte
<script>
|
||
import { Router, Route } from "svelte-routing";
|
||
import { onMount } from "svelte";
|
||
import Sidebar from "./components/Sidebar.svelte";
|
||
import Topbar from "./components/Topbar.svelte";
|
||
import Files from "./routes/Files.svelte";
|
||
import Transfers from "./routes/Transfers.svelte";
|
||
import Trash from "./routes/Trash.svelte";
|
||
import Movies from "./routes/Movies.svelte";
|
||
import TvShows from "./routes/TvShows.svelte";
|
||
import Music from "./routes/Music.svelte";
|
||
import Profile from "./routes/Profile.svelte";
|
||
import Settings from "./routes/Settings.svelte";
|
||
import Login from "./routes/Login.svelte";
|
||
import { API, getAccessToken } from "./utils/api.js";
|
||
import { refreshMovieCount } from "./stores/movieStore.js";
|
||
import { refreshTvShowCount } from "./stores/tvStore.js";
|
||
import { refreshMusicCount } from "./stores/musicStore.js";
|
||
import { fetchTrashItems } from "./stores/trashStore.js";
|
||
import { setAvatarUrl } from "./stores/avatarStore.js";
|
||
|
||
const token = getAccessToken();
|
||
|
||
let menuOpen = false;
|
||
let wsCounts;
|
||
let refreshTimer = null;
|
||
|
||
const scheduleMediaRefresh = () => {
|
||
if (refreshTimer) return;
|
||
refreshTimer = setTimeout(async () => {
|
||
refreshTimer = null;
|
||
try {
|
||
await Promise.all([
|
||
refreshMovieCount(),
|
||
refreshTvShowCount(),
|
||
refreshMusicCount(),
|
||
fetchTrashItems()
|
||
]);
|
||
} catch (err) {
|
||
console.warn("Medya sayacı yenileme başarısız:", err);
|
||
}
|
||
}, 400);
|
||
};
|
||
|
||
const loadUserProfile = async () => {
|
||
try {
|
||
const response = await fetch(`${API}/api/profile`, {
|
||
method: 'GET',
|
||
headers: {
|
||
'Authorization': `Bearer ${getAccessToken()}`,
|
||
'Content-Type': 'application/json'
|
||
}
|
||
});
|
||
|
||
if (response.ok) {
|
||
const profileData = await response.json();
|
||
if (profileData?.avatarExists) {
|
||
const token = getAccessToken();
|
||
if (token) {
|
||
const avatarUrl = `${API}/api/profile/avatar?token=${token}&v=${Date.now()}`;
|
||
setAvatarUrl(avatarUrl);
|
||
}
|
||
} else {
|
||
setAvatarUrl(null);
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.warn('Profil bilgileri yüklenemedi:', error);
|
||
setAvatarUrl(null);
|
||
}
|
||
};
|
||
|
||
// Menü aç/kapat (hamburger butonuyla)
|
||
const toggleMenu = () => {
|
||
menuOpen = !menuOpen;
|
||
};
|
||
|
||
// 🔹 Sidebar'ı kapatma fonksiyonu
|
||
function closeSidebar() {
|
||
menuOpen = false;
|
||
}
|
||
|
||
onMount(() => {
|
||
if (token) {
|
||
refreshMovieCount();
|
||
refreshTvShowCount();
|
||
refreshMusicCount();
|
||
fetchTrashItems();
|
||
loadUserProfile();
|
||
const authToken = getAccessToken();
|
||
if (authToken) {
|
||
const wsUrl = `${API.replace("http", "ws")}?token=${authToken}`;
|
||
try {
|
||
wsCounts = new WebSocket(wsUrl);
|
||
wsCounts.onmessage = (event) => {
|
||
try {
|
||
const msg = JSON.parse(event.data);
|
||
if (msg.type === "fileUpdate") {
|
||
scheduleMediaRefresh();
|
||
} else if (
|
||
msg.type === "progress" &&
|
||
Array.isArray(msg.torrents) &&
|
||
msg.torrents.some(
|
||
(t) =>
|
||
Number(t.progress) >= 1 ||
|
||
(t.type && String(t.type).toLowerCase() === "youtube")
|
||
)
|
||
) {
|
||
scheduleMediaRefresh();
|
||
}
|
||
} catch (err) {
|
||
console.warn("WS mesajı çözümlenemedi:", err);
|
||
}
|
||
};
|
||
wsCounts.onerror = () => scheduleMediaRefresh();
|
||
} catch (err) {
|
||
console.warn("WS bağlantısı kurulamadı:", err);
|
||
}
|
||
}
|
||
}
|
||
return () => {
|
||
if (wsCounts) {
|
||
try {
|
||
wsCounts.close();
|
||
} catch (err) {
|
||
/* no-op */
|
||
}
|
||
wsCounts = null;
|
||
}
|
||
if (refreshTimer) {
|
||
clearTimeout(refreshTimer);
|
||
refreshTimer = null;
|
||
}
|
||
};
|
||
});
|
||
</script>
|
||
|
||
{#if token}
|
||
<Router>
|
||
<div class="app">
|
||
<!-- Sidebar -->
|
||
<Sidebar {menuOpen} on:closeMenu={closeSidebar} />
|
||
|
||
<!-- İçerik -->
|
||
<div class="content">
|
||
<Topbar on:toggleMenu={toggleMenu} />
|
||
|
||
<Route path="/" component={Files} />
|
||
<Route path="/files" component={Files} />
|
||
<Route path="/movies" component={Movies} />
|
||
<Route path="/tv" component={TvShows} />
|
||
<Route path="/music" component={Music} />
|
||
<Route path="/profile" component={Profile} />
|
||
<Route path="/settings" component={Settings} />
|
||
<Route path="/transfers" component={Transfers} />
|
||
<Route path="/trash" component={Trash} />
|
||
</div>
|
||
|
||
<!-- Sidebar dışına tıklayınca kapanma -->
|
||
{#if menuOpen}
|
||
<div
|
||
class="backdrop show"
|
||
role="button"
|
||
tabindex="0"
|
||
aria-label="Menüyü kapat"
|
||
on:click={closeSidebar}
|
||
on:keydown={(event) => {
|
||
if (event.key === "Enter" || event.key === " ") {
|
||
event.preventDefault();
|
||
closeSidebar();
|
||
}
|
||
}}
|
||
></div>
|
||
{/if}
|
||
</div>
|
||
</Router>
|
||
{:else}
|
||
<Login />
|
||
{/if}
|