@page "/auteurs/{AuteurId:int}/bibliographie"
@inject ServiceLivresApi Api
@inject EtatReseau Reseau
MaBibli — bibliographie
@if (_bibliographie is null && _erreur is null)
{
Bibliographie
Interrogation de la BnF…
}
else if (_erreur is not null)
{
Bibliographie
@_erreur
@* Une panne de réseau est le plus souvent passagère : sans ce bouton, il fallait
recharger la page entière pour retenter. *@
@if (_reessayable)
{
}
}
else if (_bibliographie is { } biblio)
{
@biblio.Auteur.Nom
@*
⚠️ Les deux cas ci-dessous s'excluent, et c'est TOUT l'objet de ce bloc.
Avant correction, une BnF muette produisait une liste vide, que l'écran commentait
d'un rassurant « la BnF ne connaît aucun livre de cet auteur » — affiché juste sous
l'avertissement qui disait le contraire. On affirmait une absence qu'on n'avait pas
pu constater, ce qui est la pire des deux erreurs possibles ici : elle ferme la
question au lieu de la laisser ouverte.
La règle : on n'explique une absence de résultats QUE si la source a répondu.
*@
@if (biblio.SourceMuette)
{
@biblio.Avertissement
La bibliographie n'a donc pas pu être établie : cet écran ne dit
rien de ce que cet auteur a écrit.
}
else if (biblio.Oeuvres.Count == 0)
{
@* La source a répondu, et elle ne connaît rien : là, et là seulement, on peut
l'expliquer. Le cas est fréquent et n'a rien d'anormal. *@
La BnF ne connaît aucun livre de cet auteur. C'est le cas attendu pour les auteurs
étrangers : le dépôt légal français ne couvre que l'édition francophone, et un
auteur traduit n'y a souvent pas de notice à son nom.
}
else if (biblio.Avertissement is not null)
{
@* Source répondue mais bancale (une page sur deux, par exemple) : la liste vaut
quelque chose, on la montre en disant qu'elle est peut-être incomplète. *@
@biblio.Avertissement
}
else
{
@* Ces compteurs disent à l'utilisateur CE QU'IL REGARDE. Sur un auteur très réédité,
la liste n'est qu'un extrait : le taire ferait croire qu'un livre absent n'existe pas. *@
@biblio.Oeuvres.Count œuvre@(biblio.Oeuvres.Count > 1 ? "s" : "")
— @_possedees déjà chez vous
@* Deux phrases distinctes plutôt qu'une seule à trous : enchaîner des fragments
conditionnels dans une même phrase produit une ponctuation bancale dès qu'un des
fragments manque (« exister. .34 notices ont été écartées »). *@
@if (biblio.Tronquee)
{
D'après le catalogue de la BnF, à partir de @biblio.NoticesLues notices
sur les @biblio.NoticesAnnoncees qu'elle annonce :
cette liste est un extrait, classé par pertinence.
Un livre absent d'ici peut très bien exister.
}
else
{
D'après le catalogue de la BnF, sur
@biblio.NoticesLues notice@(biblio.NoticesLues > 1 ? "s" : "").
}
@if (biblio.NoticesEcartees > 0)
{
@biblio.NoticesEcartees notice@(biblio.NoticesEcartees > 1 ? "s ont" : " a")
été écartée@(biblio.NoticesEcartees > 1 ? "s" : "") : autre support (livre audio,
jeu) ou ouvrage signé de quelqu'un d'autre.
}
@if (_message is not null)
{
@_message
}
@* Filtre sur une seule question : « qu'est-ce qui me manque ? ». Les livres possédés ne
sont jamais masqués par défaut — le grisage est l'information principale de l'écran. *@
@foreach (var oeuvre in Affichees(biblio))
{
@* La classe « oeuvre-possedee » grise la ligne : le livre est déjà sur l'étagère. *@
@if (!string.IsNullOrWhiteSpace(oeuvre.Annee))
{
@oeuvre.Annee
}
@if (!string.IsNullOrWhiteSpace(oeuvre.Editeur))
{
@oeuvre.Editeur
}
@if (oeuvre.NombreEditions > 1)
{
@oeuvre.NombreEditions éditions
}
@if (oeuvre.Possede)
{
Déjà chez vous
}
else if (oeuvre.Souhaite)
{
Dans vos envies
}
@if (oeuvre.ADecouvrir)
{
}
}
@* Le rapprochement est fait par titre, et il rate des choses (voir CleOeuvre). Le dire
franchement vaut mieux que laisser l'utilisateur découvrir seul qu'un livre qu'il
possède n'est pas grisé. *@
Le rapprochement avec votre bibliothèque se fait par titre. Un livre
que vous possédez sous un titre différent (traduction, intégrale, édition retitrée)
n'apparaîtra donc pas comme possédé. Rien n'est masqué : à vous de trancher.
}
}
@* « Retour aux auteurs » est parti : l'onglet Auteurs fait exactement cela, en permanence.
Ne reste que ce qu'aucun onglet ne sait faire — le catalogue restreint à cet auteur. *@
@if (_bibliographie is { } b)
{
}
@code {
[Parameter]
public int AuteurId { get; set; }
private BibliographieDto? _bibliographie;
private bool _seulementManquants;
private bool _enCours;
private bool _chargement;
/// Vrai quand l'échec vient du réseau, donc qu'une nouvelle tentative a un sens.
private bool _reessayable;
private string? _erreur;
private string? _message;
private int _possedees;
protected override async Task OnParametersSetAsync() => await ChargerAsync();
private IEnumerable Affichees(BibliographieDto biblio) =>
_seulementManquants ? biblio.Oeuvres.Where(o => o.ADecouvrir) : biblio.Oeuvres;
private async Task ChargerAsync()
{
_erreur = null;
_reessayable = false;
_chargement = true;
try
{
_bibliographie = await Api.ObtenirBibliographieAsync(AuteurId);
if (_bibliographie is null)
{
// Celui-là ne se retente pas : l'auteur n'existe pas, réessayer ne le fera
// pas apparaître.
_erreur = "Cet auteur n'existe pas dans votre bibliothèque.";
return;
}
_possedees = _bibliographie.Oeuvres.Count(o => o.Possede);
}
catch (Exception)
{
// ⚠️ Jamais le message brut de l'exception : hors-ligne, c'est un « 404 Not Found »
// du service worker que l'utilisateur n'a aucun moyen d'interpréter. La
// bibliographie interroge la BnF, elle ne peut PAS venir du cache — il n'y a rien
// à réparer, seulement à dire.
//
// Ce chemin-ci est l'échec de l'appel à NOTRE serveur (délai du navigateur compris) ;
// une BnF muette, elle, revient en 200 avec un état, et se traite plus haut.
_erreur = Reseau.EnLigne
? "La bibliographie n'a pas pu être obtenue. La BnF est parfois lente à répondre."
: "La bibliographie vient de la BnF : indisponible hors ligne.";
_reessayable = true;
}
finally
{
_chargement = false;
}
}
///
/// Ajoute une œuvre à la liste d'envies, en emportant ce que la BnF en sait.
///
///
/// L'auteur enregistré est celui de l'écran, pas celui de la notice : c'est lui que
/// l'utilisateur a en tête, et c'est sous ce nom qu'il retrouvera l'envie dans l'export.
///
/// Après l'ajout, la bibliographie est relue plutôt que corrigée en mémoire : c'est
/// le serveur qui sait rapprocher l'envie de l'œuvre, et refaire ce calcul ici le
/// dupliquerait — avec le risque qu'il diverge.
///
///
private async Task SouhaiterAsync(OeuvreBibliographie oeuvre)
{
if (_bibliographie is null)
{
return;
}
_enCours = true;
_message = null;
var resultat = await Api.AjouterSouhaitAsync(new EnregistrementSouhait
{
Titre = oeuvre.Titre,
Auteur = _bibliographie.Auteur.Nom,
Editeur = oeuvre.Editeur,
Annee = oeuvre.Annee,
// L'ISBN de la BnF est celui d'UNE édition relevée, souvent à 10 chiffres et parfois
// épuisée. Il est repris tel quel : il aide à commander, sans engager le choix.
Isbn = oeuvre.Isbn,
});
_enCours = false;
if (!resultat.EstOk)
{
_message = resultat.Erreur;
return;
}
await ChargerAsync();
}
}