- Preview thread : poll uniquement quand ecran capture actif, keepalive 30s sinon - Sequence boot Canon : power cycle relais si absent USB au demarrage - Veille auto 30min : Canon coupe par relais apres inactivite, reveil au preview_start - Stats diagnostic /api/canon/stats : keepalive, preview, captures, connexions - Escalade reconnexion adoucie : pas d'USB reset les 2 premieres tentatives - Hard reset relais 10s (resistance decharge 990ohm sur dummy battery 8V) - Gestion fin evenement : date_fin + bouton terminer + guard 403 impression - Compteur base sur min(papier, ruban) avec cap evenement optionnel - Pre-eclairage countdown : projecteurs ON 3s avant capture pour mesure expo - Canon _configurer_init() : ISO 800, drivemode Single, viewfinder, EXIF preserve - Admin : detail evenement, compteur consommables, galerie impression Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WyN9xFp84P9VaWT3Qe2DXu
123 lines
3.8 KiB
JavaScript
123 lines
3.8 KiB
JavaScript
/* Module galerie */
|
|
|
|
async function chargerGalerie() {
|
|
const photos = await apiGet('/api/galerie');
|
|
const grille = document.getElementById('grille-galerie');
|
|
grille.innerHTML = '';
|
|
|
|
if (photos.length === 0) {
|
|
grille.innerHTML = '<p style="color:var(--texte-secondaire);grid-column:1/-1;text-align:center">Aucune photo pour le moment</p>';
|
|
return;
|
|
}
|
|
|
|
for (const photo of photos) {
|
|
const img = document.createElement('img');
|
|
img.src = '/' + photo.chemin;
|
|
img.alt = photo.nom;
|
|
img.loading = 'lazy';
|
|
img.addEventListener('click', () => voirPhoto(photo));
|
|
grille.appendChild(img);
|
|
}
|
|
}
|
|
|
|
function voirPhoto(photo) {
|
|
photoFinale = photo.nom;
|
|
document.getElementById('photo-partage').src = '/' + photo.chemin;
|
|
allerA('partage');
|
|
}
|
|
|
|
/* --- Admin gallery --- */
|
|
|
|
let adminGaleriePhotos = [];
|
|
let adminGalerieSelection = new Set();
|
|
|
|
async function chargerAdminGalerie() {
|
|
const photos = await apiGet('/api/galerie');
|
|
adminGaleriePhotos = photos;
|
|
adminGalerieSelection.clear();
|
|
const grille = document.getElementById('admin-galerie-grille');
|
|
grille.innerHTML = '';
|
|
|
|
if (photos.length === 0) {
|
|
grille.innerHTML = '<p style="color:var(--texte-secondaire);grid-column:1/-1;text-align:center">Aucune photo</p>';
|
|
majAdminGalerieSelection();
|
|
return;
|
|
}
|
|
|
|
for (const photo of photos) {
|
|
const wrap = document.createElement('div');
|
|
wrap.style.cssText = 'position:relative;cursor:pointer';
|
|
wrap.dataset.nom = photo.nom;
|
|
|
|
const img = document.createElement('img');
|
|
img.src = '/' + photo.chemin;
|
|
img.alt = photo.nom;
|
|
img.loading = 'lazy';
|
|
img.style.cssText = 'width:100%;border-radius:8px;display:block';
|
|
|
|
const check = document.createElement('div');
|
|
check.className = 'admin-galerie-check';
|
|
check.textContent = '✓';
|
|
|
|
wrap.appendChild(img);
|
|
wrap.appendChild(check);
|
|
wrap.addEventListener('click', () => toggleAdminGaleriePhoto(photo.nom, wrap));
|
|
grille.appendChild(wrap);
|
|
}
|
|
majAdminGalerieSelection();
|
|
}
|
|
|
|
function toggleAdminGaleriePhoto(nom, wrap) {
|
|
if (adminGalerieSelection.has(nom)) {
|
|
adminGalerieSelection.delete(nom);
|
|
wrap.querySelector('.admin-galerie-check').classList.remove('visible');
|
|
} else {
|
|
adminGalerieSelection.add(nom);
|
|
wrap.querySelector('.admin-galerie-check').classList.add('visible');
|
|
}
|
|
majAdminGalerieSelection();
|
|
}
|
|
|
|
function adminGalerieSelectAll() {
|
|
const grille = document.getElementById('admin-galerie-grille');
|
|
for (const photo of adminGaleriePhotos) {
|
|
adminGalerieSelection.add(photo.nom);
|
|
}
|
|
grille.querySelectorAll('.admin-galerie-check').forEach(c => c.classList.add('visible'));
|
|
majAdminGalerieSelection();
|
|
}
|
|
|
|
function adminGalerieDeselectAll() {
|
|
adminGalerieSelection.clear();
|
|
const grille = document.getElementById('admin-galerie-grille');
|
|
grille.querySelectorAll('.admin-galerie-check').forEach(c => c.classList.remove('visible'));
|
|
majAdminGalerieSelection();
|
|
}
|
|
|
|
function majAdminGalerieSelection() {
|
|
const span = document.getElementById('admin-galerie-selection');
|
|
const n = adminGalerieSelection.size;
|
|
span.textContent = n > 0 ? n + ' selectionnee' + (n > 1 ? 's' : '') : '';
|
|
}
|
|
|
|
async function adminGalerieImprimer() {
|
|
const noms = [...adminGalerieSelection];
|
|
if (noms.length === 0) return;
|
|
if (!confirm('Imprimer ' + noms.length + ' photo' + (noms.length > 1 ? 's' : '') + ' ?')) return;
|
|
|
|
let ok = 0, fail = 0, termine = false;
|
|
for (const nom of noms) {
|
|
try {
|
|
const r = await apiPost('/api/imprimer', { photo: nom });
|
|
if (r && r.succes) ok++;
|
|
else if (r && r.erreur === 'evenement_termine') { termine = true; break; }
|
|
else fail++;
|
|
} catch { fail++; }
|
|
}
|
|
if (termine) {
|
|
alert('Evenement termine — impression desactivee. Les photos ne seront pas imprimees.');
|
|
} else {
|
|
alert('Impression : ' + ok + ' OK' + (fail > 0 ? ', ' + fail + ' echec' : ''));
|
|
}
|
|
}
|