feat: refactorer l'interface avec système de vues grid/list/compact, toolbar moderne avec toggle de vue et pagination intégrée, styles hover unifiés pour header-nav-link avec état active, suppression des pills Notes obsolètes, ajout content-container responsive, link cards avec sélection visuelle et checkbox repositionné, badges visibility/readlater optimisés, et restructuration majeure du CSS avec 2500+ lignes de nouveaux styles pour grilles adaptatives, modales, formulaires, et compos
This commit is contained in:
+60
-40
@@ -85,20 +85,21 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
|
||||
// ===== Search Overlay (Spotlight Style) =====
|
||||
const searchOverlay = document.getElementById('search-overlay');
|
||||
const searchToggleBtns = document.querySelectorAll('[data-search-toggle]');
|
||||
const searchModalInput = document.getElementById('search-modal-input');
|
||||
const searchResults = document.getElementById('search-results');
|
||||
const searchTagsBtn = document.getElementById('search-tags-btn');
|
||||
const searchAllBtn = document.getElementById('search-all-btn');
|
||||
const searchNotesBtn = document.getElementById('search-notes-btn');
|
||||
const searchForm = document.getElementById('search-form');
|
||||
try {
|
||||
const searchOverlay = document.getElementById('search-overlay');
|
||||
const searchToggleBtns = document.querySelectorAll('[data-search-toggle]');
|
||||
const searchModalInput = document.getElementById('search-modal-input');
|
||||
const searchResults = document.getElementById('search-results');
|
||||
const searchTagsBtn = document.getElementById('search-tags-btn');
|
||||
const searchAllBtn = document.getElementById('search-all-btn');
|
||||
const searchNotesBtn = document.getElementById('search-notes-btn');
|
||||
const searchForm = document.getElementById('search-form');
|
||||
|
||||
let searchMode = 'search'; // 'search' | 'tags' | 'notes'
|
||||
let selectedIndex = -1;
|
||||
let searchTimeout = null;
|
||||
let cachedBookmarks = null;
|
||||
let cachedTags = null;
|
||||
let searchMode = 'search'; // 'search' | 'tags' | 'notes'
|
||||
let selectedIndex = -1;
|
||||
let searchTimeout = null;
|
||||
let cachedBookmarks = null;
|
||||
let cachedTags = null;
|
||||
|
||||
// Escape HTML to prevent XSS
|
||||
function escapeHtml(text) {
|
||||
@@ -185,12 +186,12 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
function getSearchHint(mode) {
|
||||
if (mode === 'tags') {
|
||||
return 'Type to search in tags...';
|
||||
return 'Rechercher dans les tags...';
|
||||
}
|
||||
if (mode === 'notes') {
|
||||
return 'Type to search in notes...';
|
||||
return 'Rechercher dans les notes...';
|
||||
}
|
||||
return 'Type to search in bookmarks and notes...';
|
||||
return 'Rechercher dans les bookmarks et notes...';
|
||||
}
|
||||
|
||||
// Render search results (tags, global bookmarks, or notes)
|
||||
@@ -375,6 +376,36 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
selectedIndex = -1;
|
||||
}
|
||||
|
||||
function submitSearchByMode() {
|
||||
const basePath = (typeof shaarli !== 'undefined' && shaarli.basePath) ? shaarli.basePath : '';
|
||||
const query = (searchModalInput?.value || '').trim();
|
||||
|
||||
if (selectedIndex >= 0 && navigateToSelected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!query) {
|
||||
if (searchMode === 'tags') {
|
||||
window.location.href = `${basePath}/tags/cloud`;
|
||||
return;
|
||||
}
|
||||
window.location.href = `${basePath}/`;
|
||||
return;
|
||||
}
|
||||
|
||||
if (searchMode === 'tags') {
|
||||
window.location.href = `${basePath}/?searchtags=${encodeURIComponent(query)}`;
|
||||
return;
|
||||
}
|
||||
|
||||
if (searchMode === 'notes') {
|
||||
window.location.href = `${basePath}/?searchterm=${encodeURIComponent(query)}&searchtags=note`;
|
||||
return;
|
||||
}
|
||||
|
||||
window.location.href = `${basePath}/?searchterm=${encodeURIComponent(query)}`;
|
||||
}
|
||||
|
||||
// Toggle search mode (tags vs search)
|
||||
function setSearchMode(mode) {
|
||||
if (!['search', 'tags', 'notes'].includes(mode)) {
|
||||
@@ -391,6 +422,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
searchTagsBtn?.setAttribute('aria-pressed', String(mode === 'tags'));
|
||||
searchNotesBtn?.setAttribute('aria-pressed', String(mode === 'notes'));
|
||||
|
||||
searchAllBtn?.setAttribute('aria-selected', String(mode === 'search'));
|
||||
searchTagsBtn?.setAttribute('aria-selected', String(mode === 'tags'));
|
||||
searchNotesBtn?.setAttribute('aria-selected', String(mode === 'notes'));
|
||||
|
||||
if (searchModalInput) {
|
||||
searchModalInput.name = mode === 'tags' ? 'searchtags' : 'searchterm';
|
||||
searchModalInput.placeholder = getSearchHint(mode);
|
||||
@@ -427,19 +462,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
|
||||
searchForm?.addEventListener('submit', (e) => {
|
||||
if (searchMode === 'notes') {
|
||||
e.preventDefault();
|
||||
if (selectedIndex < 0) {
|
||||
updateSelection(0);
|
||||
}
|
||||
navigateToSelected();
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedIndex >= 0) {
|
||||
e.preventDefault();
|
||||
navigateToSelected();
|
||||
}
|
||||
e.preventDefault();
|
||||
submitSearchByMode();
|
||||
});
|
||||
|
||||
// Live search on input
|
||||
@@ -455,7 +479,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
|
||||
// Keyboard shortcuts
|
||||
document.addEventListener('keydown', (e) => {
|
||||
document.addEventListener('keydown', (e) => {
|
||||
const isSearchOpen = searchOverlay?.classList.contains('show');
|
||||
const target = e.target;
|
||||
const isTyping = Boolean(
|
||||
@@ -490,15 +514,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
updateSelection(selectedIndex - 1);
|
||||
break;
|
||||
case 'Enter':
|
||||
// If an item is selected, navigate to it
|
||||
if (selectedIndex >= 0 && navigateToSelected()) {
|
||||
e.preventDefault();
|
||||
} else if (searchMode === 'notes') {
|
||||
e.preventDefault();
|
||||
updateSelection(0);
|
||||
navigateToSelected();
|
||||
}
|
||||
// Otherwise, submit the form normally
|
||||
e.preventDefault();
|
||||
submitSearchByMode();
|
||||
break;
|
||||
}
|
||||
return;
|
||||
@@ -521,7 +538,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
e.preventDefault();
|
||||
openSearch('notes');
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Search overlay initialization failed:', error);
|
||||
}
|
||||
|
||||
// ===== Filter Panel =====
|
||||
const filterToggleBtn = document.getElementById('filter-toggle-btn');
|
||||
|
||||
Reference in New Issue
Block a user