feat: implémenter système thèmes complet avec 14 thèmes prédéfinis (DEFAULT/GitHub/Linear/Spotify/Notion/Discord/Dracula/OneDark/TokyoNight/Nord/NightOwl/Anthracite/Cyberpunk/NavyElegance/Earthy), panel gestion thèmes dans tools.html avec grid previews et sélection interactive, synchronisation bidirectionnelle via bookmark shaarit_config (fetch/save JSON config), enforcement dark-only pour thèmes sans support light mode (disable toggle sidebar, auto-force dark), ajout data-theme-id attribute
This commit is contained in:
@@ -36,12 +36,26 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const themeIconLight = document.getElementById('theme-icon-light');
|
||||
const themeLabelSpan = document.querySelector('.theme-toggle-label span');
|
||||
|
||||
function checkThemeRestrictions() {
|
||||
const themeId = localStorage.getItem('shaarit_theme_id') || 'DEFAULT';
|
||||
const darkOnlyThemes = ['LINEAR', 'SPOTIFY', 'NOTION', 'DISCORD', 'DRACULA', 'ONE_DARK_PRO', 'TOKYO_NIGHT', 'NORD', 'NIGHT_OWL', 'ANTHRACITE', 'CYBERPUNK', 'NAVY_ELEGANCE', 'EARTHY'];
|
||||
return darkOnlyThemes.indexOf(themeId) !== -1;
|
||||
}
|
||||
|
||||
function updateTheme(theme) {
|
||||
// Enforce dark mode if the theme only supports dark
|
||||
if (checkThemeRestrictions()) {
|
||||
theme = 'dark';
|
||||
}
|
||||
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
localStorage.setItem('theme', theme);
|
||||
|
||||
if (themeCheckbox) {
|
||||
themeCheckbox.checked = theme === 'dark';
|
||||
// Disable the checkbox if restricted to dark mode
|
||||
themeCheckbox.disabled = checkThemeRestrictions();
|
||||
themeCheckbox.closest('.theme-switch').style.opacity = themeCheckbox.disabled ? '0.5' : '1';
|
||||
}
|
||||
if (themeIconLight) {
|
||||
themeIconLight.className = theme === 'dark' ? 'mdi mdi-weather-night' : 'mdi mdi-weather-sunny';
|
||||
@@ -51,13 +65,19 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle themeChanged event fired by tools.html
|
||||
window.addEventListener('themeChanged', () => {
|
||||
updateTheme(localStorage.getItem('theme') || 'dark');
|
||||
});
|
||||
|
||||
// Init Theme
|
||||
const savedTheme = localStorage.getItem('theme') ||
|
||||
let savedTheme = localStorage.getItem('theme') ||
|
||||
(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
|
||||
updateTheme(savedTheme);
|
||||
|
||||
if (themeCheckbox) {
|
||||
themeCheckbox.addEventListener('change', () => {
|
||||
if (checkThemeRestrictions()) return; // Extra safety
|
||||
const next = themeCheckbox.checked ? 'dark' : 'light';
|
||||
updateTheme(next);
|
||||
});
|
||||
@@ -3287,4 +3307,45 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
updateSummary();
|
||||
renderDays();
|
||||
})();
|
||||
|
||||
// ===== Sync Theme from Bookmark in Background =====
|
||||
setTimeout(() => {
|
||||
// Run sync after a slight delay to avoid blocking initial load
|
||||
if (!window.shaarli || !window.shaarli.basePath) return;
|
||||
|
||||
fetch(window.shaarli.basePath + '/?searchtags=shaarit_config')
|
||||
.then(res => res.text())
|
||||
.then(text => {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(text, 'text/html');
|
||||
const linkCard = doc.querySelector('.linklist-item');
|
||||
if (linkCard) {
|
||||
const descEl = linkCard.querySelector('.link-description p');
|
||||
if (descEl) {
|
||||
try {
|
||||
const config = JSON.parse(descEl.textContent.trim());
|
||||
const remoteThemeId = config.theme;
|
||||
const localThemeId = localStorage.getItem('shaarit_theme_id') || 'DEFAULT';
|
||||
|
||||
if (remoteThemeId && remoteThemeId !== localThemeId) {
|
||||
localStorage.setItem('shaarit_theme_id', remoteThemeId);
|
||||
document.documentElement.setAttribute('data-theme-id', remoteThemeId);
|
||||
|
||||
// Enforce light/dark constraints based on new theme
|
||||
const darkOnlyThemes = ['LINEAR', 'SPOTIFY', 'NOTION', 'DISCORD', 'DRACULA', 'ONE_DARK_PRO', 'TOKYO_NIGHT', 'NORD', 'NIGHT_OWL', 'ANTHRACITE', 'CYBERPUNK', 'NAVY_ELEGANCE', 'EARTHY'];
|
||||
if (darkOnlyThemes.indexOf(remoteThemeId) !== -1) {
|
||||
localStorage.setItem('theme', 'dark');
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
}
|
||||
|
||||
window.dispatchEvent(new Event('themeChanged'));
|
||||
console.log('[shaarit] Theme synced from bookmark:', remoteThemeId);
|
||||
}
|
||||
} catch(e) {}
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(err => console.log('[shaarit] Background theme sync failed:', err));
|
||||
}, 1500);
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user