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

@@ -32,8 +32,14 @@
<!-- Actions du volume -->
<div class="flex space-x-2 text-xl text-bold">
<button class="w-8 text-center" @click="handleSearch">
<MagnifyingGlassIcon class="h-6 w-6 text-gray-500 hover:text-green-500" />
<button
class="w-8 text-center"
@click="handleSearch"
:class="{
'text-yellow-500 cursor-wait': isSearching,
'text-gray-500 hover:text-green-500': !isSearching
}">
<MagnifyingGlassIcon class="h-6 w-6" />
</button>
<button class="w-8 text-center" @click="handleDownload">
<ArrowDownTrayIcon class="h-6 w-6 text-gray-500 hover:text-green-500" />
@@ -54,16 +60,16 @@
</template>
<script setup>
import { ref } from 'vue';
import {
ArrowDownTrayIcon,
BookmarkIcon,
ChevronUpIcon,
ChevronDownIcon,
MagnifyingGlassIcon,
ArrowDownTrayIcon
ChevronUpIcon,
MagnifyingGlassIcon
} from '@heroicons/vue/24/outline';
import MangaChapterList from './MangaChapterList.vue';
import { ref } from 'vue';
import { useMangaStore } from '../../application/store/mangaStore';
import MangaChapterList from './MangaChapterList.vue';
const props = defineProps({
volume: {
@@ -82,14 +88,48 @@
const store = useMangaStore();
const isOpen = ref(props.isOpen);
const isSearching = ref(false);
const toggleVolume = () => {
isOpen.value = !isOpen.value;
};
const handleSearch = async () => {
// TODO: Implémenter la recherche du volume
console.log('Recherche du volume:', props.volume.number);
if (isSearching.value) return; // Éviter les clicks multiples
try {
isSearching.value = true;
console.log(
`Recherche du volume ${props.volume.number} - Lancement du scraping de ${props.volume.chapters.length} chapitres`
);
// Récupérer tous les chapitres non disponibles du volume
const chaptersToSearch = props.volume.chapters
.filter(chapter => !chapter.isAvailable)
.map(chapter => chapter.id);
if (chaptersToSearch.length === 0) {
console.log('Tous les chapitres sont déjà disponibles !');
isSearching.value = false;
return;
}
console.log(`Chapitres à scraper: ${chaptersToSearch.length}`);
// Lancer le scraping de chaque chapitre non disponible en séquentiel
for (const chapterId of chaptersToSearch) {
console.log(`Scraping du chapitre ${chapterId}...`);
await store.searchChapter(chapterId);
// Petite pause entre chaque requête pour éviter de surcharger le serveur
await new Promise(resolve => setTimeout(resolve, 500));
}
console.log(`Scraping des chapitres du volume ${props.volume.number} terminé`);
} catch (error) {
console.error(`Erreur lors du scraping du volume ${props.volume.number}:`, error);
} finally {
isSearching.value = false;
}
};
const handleDownload = async () => {