diff --git a/public/app.js b/public/app.js index b74af71..398a7a2 100644 --- a/public/app.js +++ b/public/app.js @@ -9,6 +9,10 @@ const linksContainer = document.getElementById('linksContainer'); const toastContainer = document.getElementById('toastContainer'); const archiveToggle = document.getElementById('archiveToggle'); const scrollToTopBtn = document.getElementById('scrollToTopBtn'); +const searchToggle = document.getElementById('searchToggle'); +const searchWrapper = document.getElementById('searchWrapper'); +const addLinkToggle = document.getElementById('addLinkToggle'); +const addLinkWrapper = document.getElementById('addLinkWrapper'); // State let allLinks = []; @@ -20,6 +24,8 @@ document.addEventListener('DOMContentLoaded', () => { loadLinks(); setupEventListeners(); setupScrollToTop(); + setupMobileSearch(); + setupMobileAddLink(); }); // Event listeners @@ -29,6 +35,80 @@ function setupEventListeners() { archiveToggle.addEventListener('click', handleToggleArchive); } +// Setup search toggle (works on both desktop and mobile) +function setupMobileSearch() { + if (!searchToggle || !searchWrapper) return; + + searchToggle.addEventListener('click', () => { + const isVisible = searchWrapper.classList.contains('show'); + + if (isVisible) { + // Hide search + searchWrapper.classList.remove('show'); + searchToggle.classList.remove('active'); + // Hide add link if visible + if (addLinkWrapper && addLinkWrapper.classList.contains('show')) { + addLinkWrapper.classList.remove('show'); + if (addLinkToggle) addLinkToggle.classList.remove('active'); + } + // Clear search and reset if needed + if (searchInput.value.trim()) { + searchInput.value = ''; + loadLinks(); + } + } else { + // Hide add link if visible + if (addLinkWrapper && addLinkWrapper.classList.contains('show')) { + addLinkWrapper.classList.remove('show'); + if (addLinkToggle) addLinkToggle.classList.remove('active'); + } + // Show search + searchWrapper.classList.add('show'); + searchToggle.classList.add('active'); + // Focus the input after a brief delay for animation + setTimeout(() => { + searchInput.focus(); + }, 100); + } + }); +} + +// Setup add link toggle (works on both desktop and mobile) +function setupMobileAddLink() { + if (!addLinkToggle || !addLinkWrapper) return; + + addLinkToggle.addEventListener('click', () => { + const isVisible = addLinkWrapper.classList.contains('show'); + + if (isVisible) { + // Hide add link + addLinkWrapper.classList.remove('show'); + addLinkToggle.classList.remove('active'); + // Clear input if needed + if (linkInput.value.trim()) { + linkInput.value = ''; + } + } else { + // Hide search if visible + if (searchWrapper && searchWrapper.classList.contains('show')) { + searchWrapper.classList.remove('show'); + if (searchToggle) searchToggle.classList.remove('active'); + if (searchInput.value.trim()) { + searchInput.value = ''; + loadLinks(); + } + } + // Show add link + addLinkWrapper.classList.add('show'); + addLinkToggle.classList.add('active'); + // Focus the input after a brief delay for animation + setTimeout(() => { + linkInput.focus(); + }, 100); + } + }); +} + // Setup scroll to top button function setupScrollToTop() { // Show/hide button based on scroll position @@ -158,9 +238,7 @@ function handleSearch(e) { // Handle archive toggle function handleToggleArchive() { showArchived = !showArchived; - const toggleWrapper = archiveToggle.closest('.archive-toggle-wrapper'); archiveToggle.classList.toggle('active', showArchived); - toggleWrapper.classList.toggle('active', showArchived); // Re-filter and display links const query = searchInput.value.trim(); diff --git a/public/index.html b/public/index.html index eaec726..b69e5c2 100644 --- a/public/index.html +++ b/public/index.html @@ -9,19 +9,61 @@