Ajouter le scan camera du code-barres ISBN
Le decodage EAN-13/EAN-8 est fait en C# par ZXing.Net (IsbnScanner), conformement a la decision actee dans CLAUDE.md : le JavaScript ne fournit que les pixels de la camera, aucune logique de decodage ne lui est confiee. Le scan se greffe en amont du flux d'ajout par ISBN existant : des qu'un code est lu et reconnu comme ISBN-13 valide, la recherche de notices est declenchee sans que l'utilisateur ait a retaper quoi que ce soit. La saisie manuelle reste accessible en permanence, y compris quand la camera echoue. Points traites explicitement : - camera arriere par defaut (facingMode "environment", en "ideal" pour ne pas echouer sur un PC sans camera arriere) ; - liberation de la camera a l'annulation, au succes et au demontage du composant ; - cadence limitee a ~12 images/s et decodage restreint a la bande centrale reduite a 640 px de large : inutile de decoder chaque frame en pleine taille ; - messages distincts pour permission refusee, absence de camera, camera occupee et contexte non securise (getUserMedia exige HTTPS ou localhost : une IP de reseau local en http ne marchera jamais, c'est une source de confusion garantie). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
@if (_etape == Etape.Saisie)
|
||||
{
|
||||
<p class="message-discret">
|
||||
Saisissez l'ISBN imprimé sur le livre. Le scan par la caméra arrivera plus tard.
|
||||
Scannez le code-barres, ou saisissez l'ISBN imprimé sur le livre.
|
||||
</p>
|
||||
|
||||
<div class="barre-recherche">
|
||||
@@ -24,10 +24,20 @@
|
||||
@onclick="ChercherAsync">
|
||||
@(_chargement ? "Recherche…" : "Chercher")
|
||||
</button>
|
||||
@* La saisie manuelle reste le recours quand le code-barres est abîmé, absent,
|
||||
ou que la caméra est indisponible : elle ne disparaît jamais derrière le scan. *@
|
||||
<button type="button" class="bouton bouton-discret" @onclick="OuvrirScanner">
|
||||
Scanner
|
||||
</button>
|
||||
<a class="bouton bouton-discret" href="ajout/manuel">Saisir à la main</a>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (_etape == Etape.Scan)
|
||||
{
|
||||
<ScannerCodeBarres OnCodeDetecte="SurCodeDetecteAsync" OnAnnuler="Recommencer" />
|
||||
}
|
||||
|
||||
@if (_erreur is not null)
|
||||
{
|
||||
<p class="message-erreur" role="alert">@_erreur</p>
|
||||
@@ -103,7 +113,7 @@
|
||||
}
|
||||
|
||||
@code {
|
||||
private enum Etape { Saisie, Choix, Formulaire }
|
||||
private enum Etape { Saisie, Scan, Choix, Formulaire }
|
||||
|
||||
private Etape _etape = Etape.Saisie;
|
||||
private string _isbn = string.Empty;
|
||||
@@ -115,6 +125,22 @@
|
||||
private IReadOnlyList<string> _avertissements = [];
|
||||
private EnregistrementLivre _saisie = new();
|
||||
|
||||
private void OuvrirScanner()
|
||||
{
|
||||
_erreur = null;
|
||||
_avertissements = [];
|
||||
_etape = Etape.Scan;
|
||||
}
|
||||
|
||||
// Le scan enchaîne directement sur le flux de lookup existant : l'utilisateur
|
||||
// ne retape jamais ce qui vient d'être scanné.
|
||||
private async Task SurCodeDetecteAsync(string isbn)
|
||||
{
|
||||
_isbn = isbn;
|
||||
_etape = Etape.Saisie;
|
||||
await ChercherAsync();
|
||||
}
|
||||
|
||||
private async Task SurTouche(KeyboardEventArgs e)
|
||||
{
|
||||
if (e.Key == "Enter" && !string.IsNullOrWhiteSpace(_isbn))
|
||||
|
||||
Reference in New Issue
Block a user