feat: ajouter ShaaritThemeConfig.load() pour lecture config bookmark et refactorer sync thème background avec IIFE async au lieu de setTimeout, éliminer fetch/parsing HTML manuel au profit de load() unifié, appliquer remote theme/mode uniquement si différents de localStorage, dispatch themeChanged seulement si changements effectués, et cleanup code dupliqué avec gestion erreurs try/catch centralisée

This commit is contained in:
Bruno Charest 2026-04-20 22:24:38 -04:00
parent aaf8e902a1
commit 7621eeef7a

View File

@ -139,7 +139,18 @@
return inflight;
}
window.ShaaritThemeConfig = { save, findCandidates };
// Reads the current persisted config from the bookmark (no write).
// Returns null when no bookmark exists yet or JSON is invalid.
async function load() {
try {
const { existing } = await readEditForm(CONFIG_URL);
return existing || null;
} catch (e) {
return null;
}
}
window.ShaaritThemeConfig = { save, load, findCandidates };
})();
document.addEventListener('DOMContentLoaded', () => {
@ -3556,54 +3567,53 @@ document.addEventListener('DOMContentLoaded', () => {
})();
// ===== 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=themes')
.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) {
// On every page load (including hard refresh): fetch the single config
// bookmark and apply {default, mode} if they differ from localStorage.
// This makes the bookmark the source of truth across devices/sessions.
(async function syncFromBookmark() {
try {
const config = JSON.parse(descEl.textContent.trim());
if (!window.ShaaritThemeConfig) return;
const config = await window.ShaaritThemeConfig.load();
if (!config) return;
const remoteThemeId = config.default;
const remoteMode = config.mode;
const localThemeId = localStorage.getItem('shaarit_theme_id') || 'DEFAULT';
const localMode = localStorage.getItem('theme') || (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
const localMode = localStorage.getItem('theme')
|| (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
// Sync theme if different
let changed = false;
if (remoteThemeId && remoteThemeId !== localThemeId) {
localStorage.setItem('shaarit_theme_id', remoteThemeId);
document.documentElement.setAttribute('data-theme-id', remoteThemeId);
console.log('[shaarit] Theme synced from bookmark:', remoteThemeId);
changed = true;
}
// Sync mode if different
if (remoteMode && remoteMode !== localMode) {
localStorage.setItem('theme', remoteMode);
document.documentElement.setAttribute('data-theme', remoteMode);
console.log('[shaarit] Mode synced from bookmark:', remoteMode);
changed = true;
}
// Enforce light/dark constraints based on synced theme
const darkOnlyThemes = ['LINEAR', 'SPOTIFY', 'NOTION', 'DISCORD', 'DRACULA', 'ONE_DARK_PRO', 'TOKYO_NIGHT', 'NORD', 'NIGHT_OWL', 'ANTHRACITE', 'CYBERPUNK', 'NAVY_ELEGANCE', 'EARTHY'];
const syncedThemeId = remoteThemeId || localThemeId;
if (darkOnlyThemes.indexOf(syncedThemeId) !== -1) {
// Enforce dark-only theme constraints after remote apply
const darkOnlyThemes = ['LINEAR', 'SPOTIFY', 'NOTION', 'DISCORD', 'DRACULA',
'ONE_DARK_PRO', 'TOKYO_NIGHT', 'NORD', 'NIGHT_OWL', 'ANTHRACITE',
'CYBERPUNK', 'NAVY_ELEGANCE', 'EARTHY'];
const effectiveThemeId = remoteThemeId || localThemeId;
if (darkOnlyThemes.indexOf(effectiveThemeId) !== -1
&& localStorage.getItem('theme') !== 'dark') {
localStorage.setItem('theme', 'dark');
document.documentElement.setAttribute('data-theme', 'dark');
changed = true;
}
if (changed) {
window.dispatchEvent(new Event('themeChanged'));
} catch(e) {}
}
} catch (err) {
console.log('[shaarit] Background theme sync failed:', err);
}
})
.catch(err => console.log('[shaarit] Background theme sync failed:', err));
}, 1500);
})();
});