feat(manga): implémenter la page Découvrir avec recommandations MangaDex
- Endpoint GET /api/manga-discover via DiscoverMangaStateProvider + DiscoverMangaHandler
- Algorithme : top 5 manga de la collection → appel /manga/{id}/recommendation
par source → agrégation avec système de votes (multi-sources = plus pertinent)
- Filtrage : tags exclus (Oneshot, Doujinshi, Self-Published), contentRating,
et suppression des manga déjà en bibliothèque
- Page Vue DiscoverPage.vue : chargement auto au montage, bouton Actualiser,
modal détail, ajout à la bibliothèque
- Adapteurs InMemory de test mis à jour (discover + getMangaRecommendations)
This commit is contained in:
parent
65453c87e5
commit
814fe46ce5
@@ -127,6 +127,35 @@ class MangadexClient implements MangadexClientInterface
|
||||
]);
|
||||
}
|
||||
|
||||
public function getMangaRecommendations(string $mangaId): array
|
||||
{
|
||||
// L'endpoint retourne des objets manga_recommendation avec des relationships
|
||||
// vers les manga (sans détails). Il faut d'abord récupérer les IDs, puis
|
||||
// fetcher les manga en batch avec leurs détails complets.
|
||||
$recommendations = $this->get('/manga/' . $mangaId . '/recommendation');
|
||||
|
||||
$recommendedIds = [];
|
||||
foreach ($recommendations['data'] ?? [] as $item) {
|
||||
foreach ($item['relationships'] ?? [] as $rel) {
|
||||
if ($rel['type'] === 'manga' && $rel['id'] !== $mangaId) {
|
||||
$recommendedIds[] = $rel['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($recommendedIds)) {
|
||||
return ['data' => []];
|
||||
}
|
||||
|
||||
return $this->get('/manga', [
|
||||
'ids' => $recommendedIds,
|
||||
'includes' => ['cover_art', 'author'],
|
||||
'contentRating' => ['safe', 'suggestive', 'erotica'],
|
||||
'excludedTags' => self::EXCLUDED_TAGS,
|
||||
'limit' => count($recommendedIds),
|
||||
]);
|
||||
}
|
||||
|
||||
private function get(string $endpoint, array $params = []): array
|
||||
{
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user