diff --git a/desktop/src/scripts/auth-guard.js b/desktop/src/scripts/auth-guard.js index ee3f277..4dd5548 100644 --- a/desktop/src/scripts/auth-guard.js +++ b/desktop/src/scripts/auth-guard.js @@ -1,6 +1,5 @@ ;(() => { const token = localStorage.getItem("token") - if (!token && window.location.pathname !== "/") { window.location.href = "/" } @@ -12,41 +11,61 @@ async function loadMeUI() { try { const res = await fetch("/api/me", { - headers: { - Authorization: `Bearer ${token}`, - }, + headers: { Authorization: `Bearer ${token}` }, }) if (!res.ok) return const user = await res.json() + const avatarUrl = user.avatar || "/public/assets/avatar.png" const navUser = document.getElementById("nav-user") const navUsername = document.getElementById("nav-username") const navAvatar = document.getElementById("nav-avatar") const dropdownAvatar = document.getElementById("dropdown-avatar") - if (!navUser || !navUsername || !navAvatar) return + if (navUser && navUsername && navAvatar) { + navUser.style.display = "flex" + navUsername.textContent = user.username + navAvatar.src = avatarUrl + if (dropdownAvatar) dropdownAvatar.src = avatarUrl + } - navUser.style.display = "flex" - navUsername.textContent = user.username + const titlebarUserBox = document.getElementById("titlebar-user-box") + const titlebarUsername = document.getElementById("titlebar-username") + const titlebarAvatar = document.getElementById("titlebar-avatar") + const titlebarDropdownAvatar = document.getElementById("titlebar-dropdown-avatar") + const titlebarDropdownUsername = document.getElementById("titlebar-dropdown-username") - const avatarUrl = user.avatar || "/public/assets/avatar.png" - navAvatar.src = avatarUrl - if (dropdownAvatar) { - dropdownAvatar.src = avatarUrl + if (titlebarUserBox && titlebarUsername && titlebarAvatar) { + titlebarUserBox.style.display = "flex" + + titlebarUsername.textContent = user.username + titlebarAvatar.src = avatarUrl + + if (titlebarDropdownAvatar) titlebarDropdownAvatar.src = avatarUrl + if (titlebarDropdownUsername) titlebarDropdownUsername.textContent = user.username } setupDropdown() + } catch (e) { console.error("Failed to load user UI:", e) } } -// Variable para saber si el modal ya fue cargado let settingsModalLoaded = false; -document.getElementById('nav-settings').addEventListener('click', openSettings) +const navSettingsBtn = document.getElementById('nav-settings'); +const titlebarSettingsBtn = document.getElementById('titlebar-settings'); + +if (navSettingsBtn) navSettingsBtn.addEventListener('click', openSettings); +if (titlebarSettingsBtn) titlebarSettingsBtn.addEventListener('click', (e) => { + e.stopPropagation(); + + openSettings(); + document.getElementById("titlebar-dropdown")?.classList.remove("active"); +}); async function openSettings() { if (!settingsModalLoaded) { @@ -55,63 +74,69 @@ async function openSettings() { const html = await res.text() document.body.insertAdjacentHTML('beforeend', html) settingsModalLoaded = true; - - // Esperar un momento para que el DOM se actualice await new Promise(resolve => setTimeout(resolve, 50)); - - // Ahora cargar los settings - if (window.toggleSettingsModal) { - await window.toggleSettingsModal(false); - } + if (window.toggleSettingsModal) await window.toggleSettingsModal(false); } catch (err) { console.error('Error loading settings modal:', err); } } else { - if (window.toggleSettingsModal) { - await window.toggleSettingsModal(false); - } - } -} - -function closeSettings() { - const modal = document.getElementById('settings-modal'); - if (modal) { - modal.classList.add('hidden'); + if (window.toggleSettingsModal) await window.toggleSettingsModal(false); } } function setupDropdown() { + const userAvatarBtn = document.querySelector(".user-avatar-btn") const navDropdown = document.getElementById("nav-dropdown") const navLogout = document.getElementById("nav-logout") - if (!userAvatarBtn || !navDropdown || !navLogout) return + if (userAvatarBtn && navDropdown) { + userAvatarBtn.addEventListener("click", (e) => { + e.stopPropagation() + navDropdown.classList.toggle("active") - userAvatarBtn.addEventListener("click", (e) => { - e.stopPropagation() - navDropdown.classList.toggle("active") - }) + document.getElementById("titlebar-dropdown")?.classList.remove("active") + }) + if (navLogout) { + navLogout.addEventListener("click", () => { + localStorage.removeItem("token") + window.location.href = "/" + }) + } + } + + const titlebarUserBox = document.getElementById("titlebar-user-box") + const titlebarDropdown = document.getElementById("titlebar-dropdown") + const titlebarLogout = document.getElementById("titlebar-logout") + + if (titlebarUserBox && titlebarDropdown) { + titlebarUserBox.addEventListener("click", (e) => { + e.stopPropagation() + titlebarDropdown.classList.toggle("active") + + document.getElementById("nav-dropdown")?.classList.remove("active") + }) + + if (titlebarLogout) { + titlebarLogout.addEventListener("click", (e) => { + e.stopPropagation() + localStorage.removeItem("token") + window.location.href = "/" + }) + } + + titlebarDropdown.addEventListener("click", (e) => { + e.stopPropagation() + }) + } document.addEventListener("click", (e) => { - if (!navDropdown.contains(e.target)) { + if (navDropdown && !navDropdown.contains(e.target)) { navDropdown.classList.remove("active") } - }) - - navDropdown.addEventListener("click", (e) => { - e.stopPropagation() - }) - - navLogout.addEventListener("click", () => { - localStorage.removeItem("token") - window.location.href = "/" - }) - - const dropdownLinks = navDropdown.querySelectorAll("a.dropdown-item") - dropdownLinks.forEach((link) => { - link.addEventListener("click", () => { - navDropdown.classList.remove("active") - }) + if (titlebarDropdown && !titlebarDropdown.contains(e.target)) { + titlebarDropdown.classList.remove("active") + } }) } @@ -159,7 +184,6 @@ searchWrapper.addEventListener('click', (e) => { } }); -// Cerrar el buscador si se hace clic fuera document.addEventListener('click', (e) => { if (!searchWrapper.contains(e.target)) { searchWrapper.classList.remove('active-mobile'); diff --git a/desktop/src/scripts/books/reader.js b/desktop/src/scripts/books/reader.js index 3ba5707..eb13cfd 100644 --- a/desktop/src/scripts/books/reader.js +++ b/desktop/src/scripts/books/reader.js @@ -1,7 +1,7 @@ const urlParams = new URLSearchParams(window.location.search); const reader = document.getElementById('reader'); const panel = document.getElementById('settings-panel'); -const overlay = document.getElementById('overlay'); +const overlay2 = document.getElementById('overlay'); const settingsBtn = document.getElementById('settings-btn'); const closePanel = document.getElementById('close-panel'); const chapterLabel = document.getElementById('chapter-label'); @@ -665,14 +665,14 @@ document.getElementById('back-btn').addEventListener('click', () => { // Panel de configuraciΓ³n settingsBtn.addEventListener('click', () => { panel.classList.add('open'); - overlay.classList.add('active'); + overlay2.classList.add('active'); }); closePanel.addEventListener('click', closeSettings); -overlay.addEventListener('click', closeSettings); +overlay2.addEventListener('click', closeSettings); function closeSettings() { panel.classList.remove('open'); - overlay.classList.remove('active'); + overlay2.classList.remove('active'); } document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && panel.classList.contains('open')) { diff --git a/desktop/src/scripts/gallery/gallery.js b/desktop/src/scripts/gallery/gallery.js index 8d9433e..340a4f8 100644 --- a/desktop/src/scripts/gallery/gallery.js +++ b/desktop/src/scripts/gallery/gallery.js @@ -1,5 +1,5 @@ const providerSelector = document.getElementById('provider-selector'); -const searchInput = document.getElementById('search-input'); +const searchInput2 = document.getElementById('search-input'); const resultsContainer = document.getElementById('gallery-results'); let currentPage = 1; @@ -231,7 +231,7 @@ function showSkeletons(count, append = false) { async function searchGallery(isLoadMore = false) { if (isLoading) return; - const query = searchInput.value.trim(); + const query = searchInput2.value.trim(); const provider = providerSelector.value; const page = isLoadMore ? currentPage + 1 : 1; @@ -351,22 +351,22 @@ async function loadExtensions() { providerSelector.addEventListener('change', () => { if (providerSelector.value === 'favorites') { - searchInput.placeholder = "Search in favorites..."; + searchInput2.placeholder = "Search in favorites..."; } else { - searchInput.placeholder = "Search in gallery..."; + searchInput2.placeholder = "Search in gallery..."; } searchGallery(false); }); let searchTimeout; -searchInput.addEventListener('input', () => { +searchInput2.addEventListener('input', () => { clearTimeout(searchTimeout); searchTimeout = setTimeout(() => { searchGallery(false); }, 500); }); -searchInput.addEventListener('keydown', e => { +searchInput2.addEventListener('keydown', e => { if (e.key === 'Enter') { clearTimeout(searchTimeout); searchGallery(false); diff --git a/desktop/src/views/views.routes.ts b/desktop/src/views/views.routes.ts index 57f50d2..c5ad3a4 100644 --- a/desktop/src/views/views.routes.ts +++ b/desktop/src/views/views.routes.ts @@ -1,7 +1,18 @@ -import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify'; +import {FastifyInstance, FastifyReply, FastifyRequest} from 'fastify'; import * as fs from 'fs'; import * as path from 'path'; +let cachedTitlebar: string | null = null; + +function getTitlebarHTML(): string { + if (!cachedTitlebar) { + + const titlebarPath = path.join(__dirname, '..', '..', 'views', 'components', 'titlebar.html'); + cachedTitlebar = fs.readFileSync(titlebarPath, 'utf-8'); + } + return cachedTitlebar; +} + let cachedNavbar: string | null = null; function getNavbarHTML(activePage: string, showSearch: boolean = true): string { @@ -14,6 +25,7 @@ function getNavbarHTML(activePage: string, showSearch: boolean = true): string { const pages = ['anime', 'books', 'gallery', 'schedule' , 'marketplace']; pages.forEach(page => { + const regex = new RegExp(`( - - - - -