diff --git a/shaarli-pro/css/style.css b/shaarli-pro/css/style.css index 640f63b..8ebec5b 100644 --- a/shaarli-pro/css/style.css +++ b/shaarli-pro/css/style.css @@ -3093,3 +3093,23 @@ select:focus { font-size: 14px; } + +/* Filter Badge Indicator */ +.filter-badge { + position: absolute; + top: 2px; + right: 2px; + width: 8px; + height: 8px; + background: #ef4444; + border-radius: 50%; + border: 2px solid var(--header-bg); +} + +.header-action-btn { + position: relative; +} + +.header-action-btn.has-active-filter { + background: rgba(239, 68, 68, 0.2); +} diff --git a/shaarli-pro/js/script.js b/shaarli-pro/js/script.js index 9250a32..177b0f6 100644 --- a/shaarli-pro/js/script.js +++ b/shaarli-pro/js/script.js @@ -410,15 +410,7 @@ document.addEventListener('DOMContentLoaded', () => { let basePath = (typeof shaarli !== 'undefined' && shaarli.basePath) ? shaarli.basePath : ''; let url = basePath + '/'; - // Save filter state to localStorage before navigation - const filterState = { - private: isPrivate, - public: isPublic, - untagged: isUntagged, - timestamp: Date.now() - }; - localStorage.setItem('shaarliFilterState', JSON.stringify(filterState)); - console.log('[Filter] Saved filter state:', filterState); + console.log('[Filter] Applying filters - private:', isPrivate, 'public:', isPublic, 'untagged:', isUntagged); // Build the URL based on selected filters using the correct Shaarli admin paths if (isPrivate && isUntagged) { @@ -430,22 +422,18 @@ document.addEventListener('DOMContentLoaded', () => { } else if (isPublic) { url = basePath + '/admin/visibility/public'; } else if (isUntagged) { - url = basePath + '/untagged-only'; - } else { - // No filter selected - clear the state - localStorage.removeItem('shaarliFilterState'); + url = basePath + '/?searchtags='; } + // else: no filter, url stays as basePath + '/' console.log('[Filter] Navigating to:', url); window.location.href = url; } - // Clear filters function - function clearFilters() { - localStorage.removeItem('shaarliFilterState'); - if (filterPrivate) filterPrivate.checked = false; - if (filterPublic) filterPublic.checked = false; - if (filterUntagged) filterUntagged.checked = false; + // Clear all filters and go to home + function clearAllFilters() { + const basePath = (typeof shaarli !== 'undefined' && shaarli.basePath) ? shaarli.basePath : ''; + window.location.href = basePath + '/'; } // Private and public are mutually exclusive @@ -467,34 +455,24 @@ document.addEventListener('DOMContentLoaded', () => { applyFilters(); }); - // Initialize filter states from localStorage (since Shaarli redirects after applying filters) + // Initialize filter states from URL (detect current filter state from page URL) (function initFilterStates() { console.log('[Filter Debug] ========================================'); - // Try to read filter state from localStorage - let savedState = null; - try { - const savedJson = localStorage.getItem('shaarliFilterState'); - if (savedJson) { - savedState = JSON.parse(savedJson); - console.log('[Filter Debug] Found saved filter state:', savedState); + // Detect filter state from current URL path + const currentPath = window.location.pathname; + const currentSearch = window.location.search; - // Check if state is not too old (30 seconds max) - const age = Date.now() - (savedState.timestamp || 0); - if (age > 30000) { - console.log('[Filter Debug] Saved state is too old, ignoring'); - localStorage.removeItem('shaarliFilterState'); - savedState = null; - } - } - } catch (e) { - console.log('[Filter Debug] Error reading saved state:', e); - } + // Detect visibility filter from URL path + let isPrivateActive = currentPath.includes('/visibility/private') || currentPath.includes('/admin/visibility/private'); + let isPublicActive = currentPath.includes('/visibility/public') || currentPath.includes('/admin/visibility/public'); - // Determine active filters from saved state - let isPrivateActive = savedState?.private || false; - let isPublicActive = savedState?.public || false; - let isUntaggedActive = savedState?.untagged || false; + // Detect untagged filter + let isUntaggedActive = currentPath.includes('/untagged-only') || + (currentSearch.includes('searchtags=') && !currentSearch.match(/searchtags=[^&]+/)); + + console.log('[Filter Debug] URL path:', currentPath); + console.log('[Filter Debug] URL search:', currentSearch); console.log('[Filter Debug] isPrivateActive:', isPrivateActive); console.log('[Filter Debug] isPublicActive:', isPublicActive); @@ -534,24 +512,31 @@ document.addEventListener('DOMContentLoaded', () => { // Create and display the filter info banner if (hasActiveFilter && !document.getElementById('filter-info-banner')) { - // Build the message - describe the active filter without count + // Get result count from page + let resultCount = ''; + const pagingStats = document.querySelector('.paging-stats strong:last-child'); + if (pagingStats) { + resultCount = pagingStats.textContent; + } + + // Build the message with result count like "X results with status private" let filterParts = []; if (isPrivateActive) { - filterParts.push('private links'); + filterParts.push('with status private'); } else if (isPublicActive) { - filterParts.push('public links'); + filterParts.push('with status public'); } if (isUntaggedActive) { if (filterParts.length > 0) { - filterParts.push('without tags'); + filterParts.push('and untagged'); } else { - filterParts.push('links without tags'); + filterParts.push('untagged'); } } - let message = 'Showing ' + filterParts.join(' '); + let message = resultCount ? resultCount + ' results ' + filterParts.join(' ') : 'Showing ' + filterParts.join(' ') + ' links'; console.log('[Filter Debug] filterParts:', filterParts); console.log('[Filter Debug] message:', message); @@ -599,8 +584,7 @@ document.addEventListener('DOMContentLoaded', () => { // Add click handler to clear button document.getElementById('filter-clear-btn')?.addEventListener('click', () => { - localStorage.removeItem('shaarliFilterState'); - console.log('[Filter] Cleared filter state from localStorage'); + console.log('[Filter] Clear button clicked, navigating to home'); window.location.href = basePath + '/'; }); }