From d98873787ec40938a4fafdb9bee562b494428f71 Mon Sep 17 00:00:00 2001 From: Adam Mathes Date: Sun, 15 Feb 2026 20:17:51 -0800 Subject: Vanilla JS (v3): Add Logout button, 'neko' cat emoji toggle, and mobile responsiveness with backdrop --- frontend-vanilla/src/main.ts | 86 +++++++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 29 deletions(-) (limited to 'frontend-vanilla/src/main.ts') diff --git a/frontend-vanilla/src/main.ts b/frontend-vanilla/src/main.ts index c0a4e66..400bf7b 100644 --- a/frontend-vanilla/src/main.ts +++ b/frontend-vanilla/src/main.ts @@ -25,7 +25,9 @@ export function renderLayout() { if (!appEl) return; appEl.className = `theme-${store.theme} font-${store.fontTheme}`; appEl.innerHTML = ` -
+
+ + @@ -75,16 +77,23 @@ export function attachLayoutListeners() { const logoLink = document.getElementById('logo-link'); logoLink?.addEventListener('click', () => router.navigate('/')); - const logoutBtn = document.getElementById('logout-button'); - logoutBtn?.addEventListener('click', (e) => { + document.getElementById('logout-button')?.addEventListener('click', (e) => { e.preventDefault(); logout(); }); - const settingsLink = document.getElementById('settings-link'); - settingsLink?.addEventListener('click', (e) => { - e.preventDefault(); - router.navigate('/settings'); + document.getElementById('sidebar-toggle-btn')?.addEventListener('click', () => { + store.toggleSidebar(); + }); + + document.getElementById('sidebar-backdrop')?.addEventListener('click', () => { + store.setSidebarVisible(false); + }); + + window.addEventListener('resize', () => { + if (window.innerWidth > 768 && !store.sidebarVisible) { + store.setSidebarVisible(true); + } }); // Event delegation for filters, tags, and feeds in sidebar @@ -109,6 +118,14 @@ export function attachLayoutListeners() { e.preventDefault(); const feedId = link.getAttribute('data-value')!; router.navigate(`/feed/${feedId}`, currentQuery); + } else if (navType === 'settings') { + e.preventDefault(); + router.navigate('/settings', currentQuery); + } + + // Auto-close sidebar on mobile after clicking a link + if (window.innerWidth <= 768) { + store.setSidebarVisible(false); } }); @@ -143,8 +160,6 @@ export function attachLayoutListeners() { const itemTitle = target.closest('[data-action="open"]'); const itemRow = target.closest('.feed-item'); if (itemRow && !itemTitle) { // Clicking the row itself (but not the link) - // We can add "expand" logic here if we want but v2 shows it by default if loaded - // For now, let's just mark as read if it's unread const id = parseInt(itemRow.getAttribute('data-id')!); const item = store.items.find(i => i._id === id); if (item && !item.read) { @@ -229,26 +244,26 @@ export function renderSettings() { const contentArea = document.getElementById('content-area'); if (!contentArea) return; contentArea.innerHTML = ` -
-

Settings

-
-

Theme

-
- - -
-
-
-

Font

- -
+
+

Settings

+
+

Theme

+
+ +
- `; +
+
+

Font

+ +
+
+ `; // Attach settings listeners const themeOptions = document.getElementById('theme-options'); @@ -483,6 +498,19 @@ store.on('theme-updated', () => { } }); +store.on('sidebar-toggle', () => { + const layout = document.querySelector('.layout'); + if (layout) { + if (store.sidebarVisible) { + layout.classList.remove('sidebar-hidden'); + layout.classList.add('sidebar-visible'); + } else { + layout.classList.remove('sidebar-visible'); + layout.classList.add('sidebar-hidden'); + } + } +}); + store.on('items-updated', renderItems); store.on('loading-state-changed', renderItems); -- cgit v1.2.3