feat: ajout de la gestion des chapitres dans le store Manga avec des actions pour charger et mettre à jour la disponibilité des chapitres, intégration d'un écouteur Mercure pour les mises à jour en temps réel, et amélioration des composants d'interface utilisateur pour gérer les états de chargement et d'erreur.

This commit is contained in:
ext.jeremy.guillot@maxicoffee.domains
2025-04-04 16:06:32 +02:00
parent e51712a800
commit 5928cfd5f0
11 changed files with 539 additions and 39 deletions

View File

@@ -29,6 +29,7 @@ readonly class FetchMangaChaptersHandler
$limit = 500;
$hasMore = true;
$chaptersByNumber = [];
$chapterLanguages = []; // Pour stocker la langue de chaque chapitre
$chapterNumbers = [];
while ($hasMore) {
@@ -41,27 +42,40 @@ readonly class FetchMangaChaptersHandler
foreach ($feed['data'] as $chapterData) {
$chapterNumber = (float) $chapterData['attributes']['chapter'];
$language = $chapterData['attributes']['translatedLanguage'];
$title = $chapterData['attributes']['title'];
// On ne traite que les chapitres en français ou en anglais
// Pour les langues autres que français et anglais, on utilise un titre générique
if (!in_array($language, ['fr', 'en'])) {
continue;
$title = "Chapter {$chapterNumber}";
}
// Si le chapitre n'existe pas encore ou si c'est une version française
if (!isset($chaptersByNumber[$chapterNumber]) || $language === 'fr') {
$chapter = new Chapter(
// Définir les règles de priorité des langues (fr > en > autres)
$shouldReplaceChapter = false;
if (!isset($chaptersByNumber[$chapterNumber])) {
// Si c'est le premier chapitre avec ce numéro qu'on rencontre
$shouldReplaceChapter = true;
$chapterNumbers[] = $chapterNumber;
} else if ($language === 'fr') {
// Le français est toujours prioritaire
$shouldReplaceChapter = true;
} else if ($language === 'en' && $chapterLanguages[$chapterNumber] !== 'fr') {
// L'anglais est prioritaire sur les autres langues, sauf le français
$shouldReplaceChapter = true;
}
if ($shouldReplaceChapter) {
$chaptersByNumber[$chapterNumber] = new Chapter(
new ChapterId((string) Uuid::uuid4()),
$manga->getId()->getValue(),
$chapterNumber,
$chapterData['attributes']['title'],
$title,
isset($chapterData['attributes']['volume']) ? (int) $chapterData['attributes']['volume'] : null,
true,
false,
new \DateTimeImmutable()
);
$chaptersByNumber[$chapterNumber] = $chapter;
$chapterNumbers[] = $chapterNumber;
$chapterLanguages[$chapterNumber] = $language;
}
}
@@ -69,6 +83,9 @@ readonly class FetchMangaChaptersHandler
$hasMore = count($feed['data']) === $limit;
}
// Harmonisation des volumes: si le chapitre précédent et suivant ont un volume null, alors le chapitre actuel aussi
$this->harmonizeVolumes($chaptersByNumber);
// Récupère les chapitres existants
$existingChapters = $this->mangaRepository->findExistingChaptersByNumbers(
$manga->getId()->getValue(),
@@ -82,4 +99,56 @@ readonly class FetchMangaChaptersHandler
}
}
}
/**
* Harmonise les volumes des chapitres:
* - Si le chapitre précédent et suivant ont un volume null, alors le chapitre actuel aussi
* - Si le chapitre précédent et suivant ont le même volume, alors le chapitre actuel aura ce volume
*/
private function harmonizeVolumes(array &$chaptersByNumber): void
{
// Trie les chapitres par numéro pour faciliter la recherche des adjacents
ksort($chaptersByNumber);
$chapterNumbers = array_keys($chaptersByNumber);
$count = count($chapterNumbers);
for ($i = 1; $i < $count - 1; $i++) {
$prevChapterNum = $chapterNumbers[$i - 1];
$currentChapterNum = $chapterNumbers[$i];
$nextChapterNum = $chapterNumbers[$i + 1];
$prevChapter = $chaptersByNumber[$prevChapterNum];
$currentChapter = $chaptersByNumber[$currentChapterNum];
$nextChapter = $chaptersByNumber[$nextChapterNum];
$shouldUpdateVolume = false;
$newVolume = $currentChapter->getVolume();
// Si les chapitres adjacents ont un volume null, alors le chapitre actuel aussi
if ($prevChapter->getVolume() === null && $nextChapter->getVolume() === null && $currentChapter->getVolume() !== null) {
$shouldUpdateVolume = true;
$newVolume = null;
}
// Si les chapitres adjacents ont le même volume non-null, alors le chapitre actuel aura ce volume
else if ($prevChapter->getVolume() !== null && $prevChapter->getVolume() === $nextChapter->getVolume() && $currentChapter->getVolume() !== $prevChapter->getVolume()) {
$shouldUpdateVolume = true;
$newVolume = $prevChapter->getVolume();
}
if ($shouldUpdateVolume) {
// On doit créer un nouveau chapitre car les objets sont immuables
$chaptersByNumber[$currentChapterNum] = new Chapter(
id: new ChapterId($currentChapter->getId()),
mangaId: $currentChapter->getMangaId(),
number: $currentChapter->getNumber(),
title: $currentChapter->getTitle(),
volume: $newVolume, // On met à jour le volume
isVisible: $currentChapter->isVisible(),
isAvailable: $currentChapter->isAvailable(),
createdAt: $currentChapter->getCreatedAt()
);
}
}
}
}