book_generator/static/js/main.js

159 lines
No EOL
4.9 KiB
JavaScript

let enable_auto_update = false;
let previewTimeout = null;
let isScrolling = false;
// Gestion du thème
const themeSwitch = document.getElementById('theme-switch');
const htmlElement = document.documentElement;
// Charger le thème sauvegardé
const savedTheme = localStorage.getItem('theme') || 'light';
htmlElement.setAttribute('data-theme', savedTheme);
themeSwitch.checked = savedTheme === 'dark';
// Écouteur d'événements pour le switch de thème
themeSwitch.addEventListener('change', (e) => {
const theme = e.target.checked ? 'dark' : 'light';
htmlElement.setAttribute('data-theme', theme);
localStorage.setItem('theme', theme);
});
// Fonction pour convertir le texte org en HTML
function orgToHtml(text) {
// Conversion des titres
text = text.replace(/^\*+ (.*)$/gm, (match, content) => {
const level = match.match(/^\*+/)[0].length;
return `<h${level} class="org-heading">${content}</h${level}>`;
});
// Conversion des listes
text = text.replace(/^- (.*)$/gm, '<li>$1</li>');
text = text.replace(/(<li>.*<\/li>\n?)+/g, '<ul>$&</ul>');
// Conversion des citations
text = text.replace(/^#\+BEGIN_QUOTE\n(.*?)\n#\+END_QUOTE$/gs, '<blockquote>$1</blockquote>');
// Conversion du code
text = text.replace(/^#\+BEGIN_SRC.*\n(.*?)\n#\+END_SRC$/gs, '<pre><code>$1</code></pre>');
text = text.replace(/`([^`]+)`/g, '<code>$1</code>');
// Conversion des paragraphes
text = text.split('\n\n').map(para => {
if (!para.trim()) return '';
if (!para.match(/^<[hul]|^<blockquote|^<pre/)) {
return `<p>${para}</p>`;
}
return para;
}).join('\n');
return text;
}
// Fonction pour mettre à jour la prévisualisation
function updatePreview() {
const content = document.getElementById('editor-content').value;
const previewContent = document.getElementById('preview-content');
previewContent.innerHTML = orgToHtml(content);
}
// Synchronisation du défilement
function syncScroll(source, target) {
if (isScrolling) return;
isScrolling = true;
const sourceScrollPercent = source.scrollTop / (source.scrollHeight - source.clientHeight);
const targetScrollTop = sourceScrollPercent * (target.scrollHeight - target.clientHeight);
target.scrollTop = targetScrollTop;
setTimeout(() => {
isScrolling = false;
}, 100);
}
// Écouteurs d'événements pour la synchronisation du défilement
const editor = document.getElementById('editor-content');
const preview = document.getElementById('preview-content');
editor.addEventListener('scroll', () => {
syncScroll(editor, preview);
});
preview.addEventListener('scroll', () => {
syncScroll(preview, editor);
});
// Écouteur d'événements pour la mise à jour automatique de la prévisualisation
editor.addEventListener('input', () => {
if (document.getElementById('auto-preview').checked) {
clearTimeout(previewTimeout);
previewTimeout = setTimeout(updatePreview, 500);
}
});
// Écouteur d'événements pour le switch de mise à jour automatique
document.getElementById('auto-preview').addEventListener('change', (e) => {
if (e.target.checked) {
updatePreview();
}
});
// Sauvegarde automatique si activée
if (enable_auto_update) {
setInterval(async () => {
const content = document.getElementById('editor-content').value;
try {
const response = await fetch('/update', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `content=${encodeURIComponent(content)}`
});
const data = await response.json();
if (response.ok) {
document.getElementById('words-today').textContent = data.words_today;
console.log('Sauvegarde automatique effectuée');
}
} catch (error) {
console.error('Erreur lors de la sauvegarde automatique');
}
}, 20000); // 20 secondes
}
// Mise à jour du contenu
document.getElementById('update-btn').addEventListener('click', async () => {
const content = document.getElementById('editor-content').value;
try {
const response = await fetch('/update', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `content=${encodeURIComponent(content)}`
});
const data = await response.json();
if (response.ok) {
document.getElementById('words-today').textContent = data.words_today;
alert('Contenu mis à jour avec succès !');
}
} catch (error) {
alert('Erreur lors de la mise à jour');
}
});
// Mise à jour automatique du compteur de mots
async function updateWordCount() {
try {
const response = await fetch('/words_today');
const data = await response.json();
document.getElementById('words-today').textContent = data.words;
} catch (error) {
console.error('Erreur lors de la mise à jour du compteur de mots');
}
}
// Mise à jour toutes les 30 secondes
setInterval(updateWordCount, 30000);
// Initialisation de la prévisualisation
updatePreview();