diff --git a/src/components/ComicCard.astro b/src/components/ComicCard.astro index 25598e8..248dc30 100644 --- a/src/components/ComicCard.astro +++ b/src/components/ComicCard.astro @@ -1,13 +1,15 @@ --- -// Import the necessary types and assets -import type { Comic } from '../lib/types'; +import type { Comic, Genre } from '../lib/types'; import { Image } from 'astro:assets'; +import { getGenreNames } from '../lib/api'; interface Props { comic: Comic; + genres: Genre[]; } -const { comic } = Astro.props; +const { comic, genres } = Astro.props; +const genreNames = getGenreNames(comic.md_comics.genres, genres); // Determine if the file is AVIF based on the URL const isAvif = comic.md_comics.md_covers[0]?.b2key.endsWith('.avif'); @@ -19,21 +21,28 @@ const coverUrl = comic.md_comics.md_covers[0]
{!isAvif ? ( - // Infer size only for non-AVIF files {comic.md_comics.title} ) : ( - // Provide fallback handling for AVIF files {comic.md_comics.title} )}

{comic.md_comics.title}

-

Chapter {comic.chap}

+

Chapter {comic.chap}

+ {genreNames.length > 0 && ( +
+ {genreNames.map(genre => ( + + {genre} + + ))} +
+ )}

{new Date(comic.updated_at).toLocaleString(undefined, { timeStyle: "short" })}

@@ -42,13 +51,15 @@ const coverUrl = comic.md_comics.md_covers[0] \ No newline at end of file diff --git a/src/lib/api.ts b/src/lib/api.ts index 544e1d7..4dd9ea6 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -1,4 +1,4 @@ -import type { Comic } from './types'; +import type { Comic, Genre } from './types'; const languageMap = { "en": "English", @@ -16,6 +16,28 @@ const languages = new Set(Object.keys(languageMap)); const contentTypes = new Set(["sfw", "nsfw"]); const urlBase = "https://api.comick.fun/chapter"; +let genreCache: Genre[] = []; + +export async function fetchGenres(): Promise { + if (genreCache.length > 0) return genreCache; + + try { + const response = await fetch('https://api.comick.fun/genre'); + if (!response.ok) throw new Error(`Failed to fetch genres: ${response.status}`); + genreCache = await response.json(); + return genreCache; + } catch (error) { + console.error('Error fetching genres:', error); + return []; + } +} + +export function getGenreNames(genreIds: number[], genres: Genre[]): string[] { + return genreIds + .map(id => genres.find(g => g.id === id)?.name ?? '') + .filter(name => name !== ''); +} + export async function fetchComics(language: string = 'en', contentType: string = 'sfw'): Promise { try { const apiUrl = `${urlBase}?lang=${language}&page=1&order=new&accept_erotic_content=${contentType === 'nsfw'}`; diff --git a/src/pages/[lang]/[type].astro b/src/pages/[lang]/[type].astro index fcc8942..970bfbc 100644 --- a/src/pages/[lang]/[type].astro +++ b/src/pages/[lang]/[type].astro @@ -3,7 +3,7 @@ import Layout from '../../layouts/Layout.astro'; import ComicCard from '../../components/ComicCard.astro'; import LanguageSelector from '../../components/LanguageSelector.astro'; import RSSLink from '../../components/RSSLink.astro'; -import { fetchComics, isValidLanguage, isValidContentType } from '../../lib/api'; +import { fetchComics, isValidLanguage, isValidContentType, fetchGenres } from '../../lib/api'; import type { Comic } from '../../lib/types'; export async function getStaticPaths() { @@ -25,6 +25,7 @@ if (!isValidLanguage(lang!) || !isValidContentType(type!)) { let comics: Comic[] = []; let error: string | null = null; +const genres = await fetchGenres(); try { comics = await fetchComics(lang, type); @@ -52,7 +53,7 @@ try { {comics.length > 0 ? (
{comics.map(comic => ( - + ))}
) : ( diff --git a/src/pages/rss/[lang]/[type].xml.ts b/src/pages/rss/[lang]/[type].xml.ts index 7a62464..f188eba 100644 --- a/src/pages/rss/[lang]/[type].xml.ts +++ b/src/pages/rss/[lang]/[type].xml.ts @@ -3,6 +3,8 @@ import { fetchComics, isValidLanguage, isValidContentType, + fetchGenres, + getGenreNames, } from "../../../lib/api"; import type { APIRoute } from "astro"; @@ -13,28 +15,38 @@ export const GET: APIRoute = async ({ params, request }) => { return new Response("Invalid language or content type", { status: 400 }); } - const comics = await fetchComics(lang, type); + const [comics, genres] = await Promise.all([ + fetchComics(lang, type), + fetchGenres(), + ]); + const siteURL = new URL(request.url).origin; return rss({ title: `ComicK - ${lang.toUpperCase()} ${type.toUpperCase()}`, description: `A simple RSS feed for ComicK!`, site: "https://github.com/ld3z/manga-rss", - items: comics.map((comic) => ({ - title: `${comic.md_comics.title} - Chapter ${comic.chap}`, - link: `https://comick.io/comic/${comic.md_comics.slug}`, - pubDate: new Date(comic.updated_at), - description: `Chapter ${comic.chap} of ${ - comic.md_comics.title - } is now available on ComicK! - ${ - comic.md_comics.md_covers[0] - ? `Cover` - : "" - } - `, - })), + items: comics.map((comic) => { + const genreNames = getGenreNames(comic.md_comics.genres, genres); + const genresHtml = genreNames.length > 0 + ? `

Genres: ${genreNames.join(', ')}

` + : ''; + + return { + title: `${comic.md_comics.title} - Chapter ${comic.chap}`, + link: `https://comick.io/comic/${comic.md_comics.slug}`, + pubDate: new Date(comic.updated_at), + description: `Chapter ${comic.chap} of ${comic.md_comics.title} is now available on ComicK! + ${genresHtml} + ${ + comic.md_comics.md_covers[0] + ? `Cover` + : "" + } + `, + }; + }), }); }; @@ -58,6 +70,5 @@ export function getStaticPaths() { { params: { lang: "zh", type: "nsfw" } }, { params: { lang: "sv", type: "sfw" } }, { params: { lang: "sv", type: "nsfw" } }, - // Add other combinations as needed ]; -} +} \ No newline at end of file