Mini menu client + luminosite impression + endpoints systeme
- Menu client coin haut-gauche : WiFi, luminosite, relancer, redemarrer, eteindre - Popup WiFi : scan, statut, connexion (reutilise les endpoints existants) - Popup luminosite : slider -50% a +50%, ajuste la luminosite avant impression (ImageEnhance.Brightness dans _preparer_image) - Endpoints systeme : /api/systeme/eteindre, redemarrer, redemarrer-app - Endpoint exposition Canon : /api/camera/exposition (GET choix + POST valeur) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -157,6 +157,107 @@ html, body {
|
||||
color: rgba(255,255,255,0.4);
|
||||
}
|
||||
|
||||
/* Mini menu client */
|
||||
.btn-menu-client {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
left: 12px;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.3rem;
|
||||
color: rgba(255,255,255,0.2);
|
||||
cursor: pointer;
|
||||
border-radius: 50%;
|
||||
transition: color 0.3s;
|
||||
z-index: 60;
|
||||
}
|
||||
.btn-menu-client:active {
|
||||
color: rgba(255,255,255,0.5);
|
||||
}
|
||||
.menu-client {
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
left: 12px;
|
||||
background: rgba(0,0,0,0.92);
|
||||
border-radius: 16px;
|
||||
padding: 16px;
|
||||
z-index: 200;
|
||||
min-width: 220px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
.menu-client button {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 14px 16px;
|
||||
font-size: 1rem;
|
||||
text-align: left;
|
||||
background: rgba(255,255,255,0.08);
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.menu-client button:active {
|
||||
background: rgba(255,255,255,0.2);
|
||||
}
|
||||
.menu-client-titre {
|
||||
font-size: .85rem;
|
||||
font-weight: 600;
|
||||
color: rgba(255,255,255,0.5);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
padding: 0 4px 8px;
|
||||
}
|
||||
.popup-wifi {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0,0,0,0.85);
|
||||
z-index: 300;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.popup-wifi-inner {
|
||||
background: rgba(30,30,30,0.98);
|
||||
border-radius: 20px;
|
||||
padding: 24px;
|
||||
width: 90%;
|
||||
max-width: 400px;
|
||||
}
|
||||
.popup-wifi-inner button {
|
||||
padding: 12px;
|
||||
font-size: 1rem;
|
||||
background: rgba(255,255,255,0.1);
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.popup-wifi-inner button:active {
|
||||
background: rgba(255,255,255,0.2);
|
||||
}
|
||||
.wifi-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px;
|
||||
margin: 4px 0;
|
||||
background: rgba(255,255,255,0.06);
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.wifi-item:active {
|
||||
background: rgba(255,255,255,0.15);
|
||||
}
|
||||
.wifi-item.actif {
|
||||
border-left: 3px solid #4caf50;
|
||||
}
|
||||
|
||||
/* Popup mot de passe */
|
||||
.popup-overlay {
|
||||
position: fixed;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
||||
<meta name="google" content="notranslate">
|
||||
<meta http-equiv="Content-Language" content="fr">
|
||||
<link rel="stylesheet" href="/css/style.css?v=16">
|
||||
<link rel="stylesheet" href="/css/style.css?v=17">
|
||||
<link rel="stylesheet" href="/css/themes.css?v=2">
|
||||
</head>
|
||||
<body>
|
||||
@@ -59,6 +59,38 @@
|
||||
<div id="btn-admin" class="btn-admin" onclick="ouvrirAdmin()">⚙</div>
|
||||
<!-- Icone photostation coin bas-gauche (visible seulement si installée) -->
|
||||
<div id="btn-photostation" class="btn-photostation cache" onclick="ouvrirPhotostation()">🖼</div>
|
||||
<!-- Mini menu client coin haut-gauche -->
|
||||
<div id="btn-menu-client" class="btn-menu-client" onclick="toggleMenuClient()">☰</div>
|
||||
<div id="menu-client" class="menu-client cache">
|
||||
<div class="menu-client-titre">Maintenance</div>
|
||||
<button onclick="menuClientAction('wifi')">📶 WiFi</button>
|
||||
<button onclick="menuClientAction('exposition')">☀ Luminosite</button>
|
||||
<button onclick="menuClientAction('restart-app')">🔄 Relancer l'appli</button>
|
||||
<button onclick="menuClientAction('reboot')">🔃 Redemarrer</button>
|
||||
<button onclick="menuClientAction('shutdown')">⏻ Eteindre</button>
|
||||
<button onclick="toggleMenuClient()" style="background:transparent;color:var(--text2)">Fermer</button>
|
||||
</div>
|
||||
<!-- Popup WiFi -->
|
||||
<div id="popup-wifi" class="popup-wifi cache">
|
||||
<div class="popup-wifi-inner">
|
||||
<div class="menu-client-titre">WiFi</div>
|
||||
<div id="wifi-status"></div>
|
||||
<div id="wifi-list" style="max-height:300px;overflow-y:auto"></div>
|
||||
<button onclick="scanWifi()" style="margin-top:8px;width:100%">Actualiser</button>
|
||||
<button onclick="document.getElementById('popup-wifi').classList.add('cache')" style="margin-top:4px;width:100%;background:transparent;color:var(--text2)">Fermer</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Popup Exposition -->
|
||||
<div id="popup-exposition" class="popup-wifi cache">
|
||||
<div class="popup-wifi-inner">
|
||||
<div class="menu-client-titre">Luminosite photo</div>
|
||||
<div id="expo-status" style="text-align:center;margin:12px 0;font-size:1.5rem;font-weight:700"></div>
|
||||
<input type="range" id="expo-slider" min="-9" max="9" value="0" style="width:100%" oninput="updateExpoLabel(this.value)">
|
||||
<div id="expo-label" style="text-align:center;margin:8px 0;font-size:.9rem;color:var(--text2)">0</div>
|
||||
<button onclick="appliquerExpo()" style="width:100%">Appliquer</button>
|
||||
<button onclick="document.getElementById('popup-exposition').classList.add('cache')" style="margin-top:4px;width:100%;background:transparent;color:var(--text2)">Fermer</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Choix du mode -->
|
||||
@@ -1145,7 +1177,7 @@
|
||||
</style>
|
||||
|
||||
<script src="/js/websocket.js?v=16"></script>
|
||||
<script src="/js/app.js?v=25"></script>
|
||||
<script src="/js/app.js?v=26"></script>
|
||||
<script src="/js/camera.js?v=26"></script>
|
||||
<script src="/js/effects.js?v=4"></script>
|
||||
<script src="/js/gallery.js?v=5"></script>
|
||||
|
||||
@@ -707,6 +707,91 @@ function eteindreSpots() {
|
||||
fetch('/api/relais/veille', { method: 'POST' }).catch(() => {});
|
||||
}
|
||||
|
||||
// --- Mini menu client ---
|
||||
|
||||
function toggleMenuClient() {
|
||||
document.getElementById('menu-client').classList.toggle('cache');
|
||||
}
|
||||
|
||||
async function menuClientAction(action) {
|
||||
document.getElementById('menu-client').classList.add('cache');
|
||||
if (action === 'wifi') {
|
||||
document.getElementById('popup-wifi').classList.remove('cache');
|
||||
scanWifi();
|
||||
} else if (action === 'exposition') {
|
||||
document.getElementById('popup-exposition').classList.remove('cache');
|
||||
chargerExposition();
|
||||
} else if (action === 'shutdown') {
|
||||
if (confirm('Eteindre la borne ?')) apiPost('/api/systeme/eteindre');
|
||||
} else if (action === 'reboot') {
|
||||
if (confirm('Redemarrer la borne ?')) apiPost('/api/systeme/redemarrer');
|
||||
} else if (action === 'restart-app') {
|
||||
apiPost('/api/systeme/redemarrer-app');
|
||||
setTimeout(() => location.reload(), 3000);
|
||||
}
|
||||
}
|
||||
|
||||
async function scanWifi() {
|
||||
const list = document.getElementById('wifi-list');
|
||||
const status = document.getElementById('wifi-status');
|
||||
list.innerHTML = '<div style="text-align:center;padding:16px;color:var(--text2)">Scan en cours...</div>';
|
||||
try {
|
||||
const s = await apiGet('/api/wifi/status');
|
||||
status.innerHTML = s.connecte
|
||||
? `<div style="padding:8px;color:#4caf50">Connecte a <b>${s.ssid}</b> (${s.signal || '?'}%)</div>`
|
||||
: '<div style="padding:8px;color:#f44336">Non connecte</div>';
|
||||
const nets = await apiGet('/api/wifi/scan');
|
||||
if (!nets.length) { list.innerHTML = '<div style="padding:12px;color:var(--text2)">Aucun reseau</div>'; return; }
|
||||
list.innerHTML = nets.map(n => `
|
||||
<div class="wifi-item${n.actif ? ' actif' : ''}" onclick="connecterWifi('${n.ssid.replace(/'/g,"\\'")}', ${n.enregistre})">
|
||||
<div>
|
||||
<div style="font-weight:600">${n.ssid}</div>
|
||||
<div style="font-size:.75rem;color:var(--text2)">${n.signal}% ${n.securise ? '🔒' : ''} ${n.enregistre ? '(enregistre)' : ''}</div>
|
||||
</div>
|
||||
${n.actif ? '<span style="color:#4caf50;font-weight:700">✓</span>' : ''}
|
||||
</div>
|
||||
`).join('');
|
||||
} catch(e) { list.innerHTML = '<div style="padding:12px;color:#f44336">Erreur: ' + e + '</div>'; }
|
||||
}
|
||||
|
||||
async function connecterWifi(ssid, enregistre) {
|
||||
if (enregistre) {
|
||||
const r = await apiPost('/api/wifi/connect', {ssid});
|
||||
alert(r.message || (r.succes ? 'Connecte' : 'Erreur'));
|
||||
scanWifi();
|
||||
return;
|
||||
}
|
||||
const mdp = prompt('Mot de passe WiFi pour ' + ssid + ' :');
|
||||
if (mdp === null) return;
|
||||
const r = await apiPost('/api/wifi/connect', {ssid, password: mdp});
|
||||
alert(r.message || (r.succes ? 'Connecte' : 'Erreur'));
|
||||
scanWifi();
|
||||
}
|
||||
|
||||
async function chargerExposition() {
|
||||
const cfg = charger_config ? charger_config() : config;
|
||||
const luminosite = (cfg || config).impression?.luminosite_impression || 0;
|
||||
document.getElementById('expo-slider').value = luminosite;
|
||||
document.getElementById('expo-slider').min = -50;
|
||||
document.getElementById('expo-slider').max = 50;
|
||||
document.getElementById('expo-slider').step = 5;
|
||||
updateExpoLabel(luminosite);
|
||||
}
|
||||
|
||||
function updateExpoLabel(val) {
|
||||
const signe = val > 0 ? '+' : '';
|
||||
document.getElementById('expo-label').textContent = `${signe}${val}%`;
|
||||
document.getElementById('expo-status').textContent = val == 0 ? 'Normal' : `${signe}${val}%`;
|
||||
}
|
||||
|
||||
async function appliquerExpo() {
|
||||
const val = parseInt(document.getElementById('expo-slider').value);
|
||||
await apiPost('/api/config', {impression: {luminosite_impression: val}});
|
||||
document.getElementById('popup-exposition').classList.add('cache');
|
||||
afficherStatut('Luminosite impression : ' + (val > 0 ? '+' : '') + val + '%', 'succes');
|
||||
config = await apiGet('/api/config');
|
||||
}
|
||||
|
||||
// Demarrage
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
init().then(() => {
|
||||
|
||||
Reference in New Issue
Block a user