From a8b95aa7520f863d2a3e7700be2e5fe7be519508 Mon Sep 17 00:00:00 2001
From: ld3zian <42660576+ld3z@users.noreply.github.com>
Date: Wed, 15 Jan 2025 15:50:26 -0700
Subject: [PATCH] add genre tags
---
src/components/ComicCard.astro | 104 +++++++++++++++++++++++++----
src/lib/api.ts | 24 ++++++-
src/pages/[lang]/[type].astro | 5 +-
src/pages/rss/[lang]/[type].xml.ts | 47 ++++++++-----
4 files changed, 145 insertions(+), 35 deletions(-)
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
) : (
- // Provide fallback handling for AVIF files
)}
{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]
- ? `
`
- : ""
- }
- `,
- })),
+ 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]
+ ? `
`
+ : ""
+ }
+ `,
+ };
+ }),
});
};
@@ -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