Aller au contenu

Exemple complet

Un bouton torche et un scanner, de bout en bout.

Une épicerie solidaire affiche sa page de passage en caisse dans l’application de la commune. Le bénévole scanne la carte d’un adhérent avec la caméra du téléphone ; dans une réserve mal éclairée, il allume la lampe.

La carte lien est configurée avec les cases « Torche » et « Caméra ». La page doit :

  • afficher le bouton de lampe seulement si la torche est autorisée et disponible ;
  • démarrer la caméra arrière pour le scan ;
  • continuer de piloter la lampe pendant le scan, y compris sur Android où la caméra est alors occupée ;
  • rester utilisable dans un navigateur classique, avec une saisie manuelle.
<button id="torch" type="button" hidden aria-pressed="false">Allumer la lampe</button>
<button id="scan" type="button">Scanner une carte</button>
<video id="scanner" playsinline muted hidden></video>
<p id="fallback" hidden>
<label for="code">Numéro de carte</label>
<input id="code" inputmode="numeric" autocomplete="off" />
</p>
<script>
const torchButton = document.getElementById('torch');
const video = document.getElementById('scanner');
let stream = null;
// Torche : n’afficher le bouton que si elle est utilisable
async function setupTorch() {
const m = window.mairies;
if (!m || !m.commands.includes('torch')) return; // hors application ou non autorisée
const { available } = await m.torch.isAvailable();
if (!available) return;
const { on } = await m.torch.getState();
render(on);
torchButton.hidden = false;
}
function render(on) {
torchButton.setAttribute('aria-pressed', String(on));
torchButton.textContent = on ? 'Éteindre la lampe' : 'Allumer la lampe';
}
torchButton.addEventListener('click', async () => {
const next = torchButton.getAttribute('aria-pressed') !== 'true';
try {
const { on } = await window.mairies.torch.toggle();
render(on);
} catch (error) {
if (error.code === 'UNAVAILABLE' && stream) {
// Android : caméra occupée par le scan, on passe par la contrainte web
const [track] = stream.getVideoTracks();
if (track.getCapabilities?.().torch) {
await track.applyConstraints({ advanced: [{ torch: next }] });
render(next);
}
} else if (error.code !== 'RATE_LIMITED') {
console.warn('Torche indisponible :', error.code);
}
}
});
// Caméra : scan, avec saisie manuelle en repli
document.getElementById('scan').addEventListener('click', async () => {
try {
stream = await navigator.mediaDevices.getUserMedia({
video: { facingMode: 'environment' },
audio: false,
});
video.srcObject = stream;
video.hidden = false;
await video.play();
// Android : l’ouverture de la caméra éteint la lampe allumée par mairies.torch
if (window.mairies?.platform === 'android') render(false);
// … brancher ici votre bibliothèque de lecture de code-barres
} catch (error) {
document.getElementById('fallback').hidden = false;
document.getElementById('code').focus();
}
});
function stopScan() {
if (!stream) return;
stream.getTracks().forEach((track) => track.stop());
stream = null;
video.hidden = true;
}
if (window.mairies) setupTorch();
else window.addEventListener('mairies:ready', setupTorch, { once: true });
</script>

Quelques remarques :

  • Le bouton de lampe est masqué par défaut (hidden) : dans un navigateur classique, il n’apparaît jamais.
  • aria-pressed et le texte du bouton suivent l’état renvoyé par l’application, pas l’état attendu.
  • Un RATE_LIMITED (double clic rapide) est ignoré sans message : la lampe n’a simplement pas changé.
  • Appelez stopScan() dès qu’une carte est lue, pour libérer la caméra.
  1. Hébergez la page en HTTPS, sur l’origine exacte qui sera configurée dans la carte lien.

  2. Demandez à un agent de la commune de créer ou modifier la carte lien, d’activer « WebApp avancée » et de cocher « Torche » et « Caméra », puis de publier. Voir Activer la WebApp avancée.

  3. Sur un iPhone et sur un téléphone Android, mettez à jour l’application de la commune, puis ouvrez la carte lien.

  4. Vérifiez le bouton de lampe : allumage, extinction, et refus d’un double clic rapide.

  5. Lancez le scan, acceptez l’accès à la caméra, puis rallumez la lampe pendant le scan.

  6. Mettez l’application en arrière-plan : la lampe doit s’éteindre.

  7. Ouvrez la même page dans un navigateur classique : le bouton de lampe ne doit pas apparaître, et la saisie manuelle doit rester possible.

Pendant la mise au point, affichez dans la page le contenu de window.mairies et les codes d’erreur reçus : c’est le moyen le plus simple de voir ce que l’application autorise. Voir Dépannage.