diff --git a/src/components/ComicCard.astro b/src/components/ComicCard.astro index e504109..543bb63 100644 --- a/src/components/ComicCard.astro +++ b/src/components/ComicCard.astro @@ -9,28 +9,47 @@ interface Props { const { comic } = Astro.props; -// Determine if the file is AVIF based on the URL -const isAvif = comic.md_comics.md_covers[0]?.b2key.endsWith('.avif'); - const coverUrl = comic.md_comics.md_covers[0] ? `https://meo.comick.pictures/${comic.md_comics.md_covers[0].b2key}` : '/placeholder.png'; + +// Determine if the file is AVIF based on the URL +const isAvif = comic.md_comics.md_covers[0]?.b2key.endsWith('.avif'); + +// Define standard image dimensions +const IMG_WIDTH = 250; +const IMG_HEIGHT = 350; + +// Generate optimized image URL with dimensions +const optimizedCoverUrl = coverUrl.includes('meo.comick.pictures') + ? `${coverUrl}?width=${IMG_WIDTH}&quality=80` + : coverUrl; --- +
- {!isAvif ? ( - // Infer size only for non-AVIF files - {comic.md_comics.title} - ) : ( - // Provide fallback handling for AVIF files - {comic.md_comics.title} - )} +
+ {!isAvif ? ( + {comic.md_comics.title} + ) : ( + {comic.md_comics.title} { + e.currentTarget.src = '/placeholder.png'; + }} + /> + )} +

{comic.md_comics.title}

Chapter {comic.chap}

@@ -39,12 +58,13 @@ const coverUrl = comic.md_comics.md_covers[0]
- + \ No newline at end of file diff --git a/src/components/LanguageSelector.astro b/src/components/LanguageSelector.astro index 8afd65c..d5e0606 100644 --- a/src/components/LanguageSelector.astro +++ b/src/components/LanguageSelector.astro @@ -1,5 +1,5 @@ --- -import { availableLanguages, availableContentTypes } from '../lib/api'; +import { availableLanguages, availableContentTypes, getLanguageName } from '../lib/api'; interface Props { currentLang: string; @@ -12,13 +12,17 @@ const { currentLang, currentType } = Astro.props;
@@ -47,9 +51,9 @@ const { currentLang, currentType } = Astro.props; select { padding: 0.5rem 1rem; border-radius: 4px; - background: #23262d; - color: white; - border: 1px solid #444; + background: var(--bg-secondary); + color: var(--text-color); + border: 1px solid var(--bg-hover); } select:focus { diff --git a/src/components/RSSLink.astro b/src/components/RSSLink.astro index 9e39621..38cf224 100644 --- a/src/components/RSSLink.astro +++ b/src/components/RSSLink.astro @@ -21,9 +21,9 @@ const { lang, type } = Astro.props; display: flex; align-items: center; gap: 0.5rem; - color: white; + color: var(--text-color); text-decoration: none; - background: #23262d; + background: var(--bg-secondary); padding: 0.5rem 1rem; border-radius: 4px; transition: all 0.2s; @@ -31,6 +31,7 @@ const { lang, type } = Astro.props; .rss-link:hover { background: rgb(var(--accent)); + color: white; } svg { diff --git a/src/components/ThemeToggle.astro b/src/components/ThemeToggle.astro new file mode 100644 index 0000000..d8dcead --- /dev/null +++ b/src/components/ThemeToggle.astro @@ -0,0 +1,82 @@ +--- +--- + + + + + \ No newline at end of file diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index 1810971..369e761 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -1,4 +1,6 @@ --- +import ThemeToggle from '../components/ThemeToggle.astro'; + interface Props { title: string; } @@ -17,6 +19,7 @@ const { title } = Astro.props; {title} + @@ -32,10 +35,48 @@ const { title } = Astro.props; white 60% ); } + + /* Light theme */ + :root[data-theme="light"] { + --bg-primary: #ffffff; + --bg-secondary: #f0f0f0; + --bg-hover: #e0e0e0; + --text-color: #13151a; + --card-bg: #f5f5f5; + } + + /* Dark theme */ + :root[data-theme="dark"] { + --bg-primary: #13151a; + --bg-secondary: #23262d; + --bg-hover: #2a2d35; + --text-color: #ffffff; + --card-bg: #23262d; + } + + /* Default to dark theme if no data-theme is set */ + :root:not([data-theme]) { + --bg-primary: #13151a; + --bg-secondary: #23262d; + --bg-hover: #2a2d35; + --text-color: #ffffff; + --card-bg: #23262d; + } + html { font-family: system-ui, sans-serif; - background: #13151a; + background-color: var(--bg-primary); + color: var(--text-color); } + + body { + margin: 0; + min-height: 100vh; + background-color: var(--bg-primary); + color: var(--text-color); + transition: background-color 0.3s ease, color 0.3s ease; + } + code { font-family: Menlo, @@ -47,4 +88,4 @@ const { title } = Astro.props; Courier New, monospace; } - + \ No newline at end of file diff --git a/src/lib/api.ts b/src/lib/api.ts index 83c3dca..544e1d7 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -1,13 +1,24 @@ import type { Comic } from './types'; -const languages = new Set(["en", "fr", "es", "it", "pl", "tr", "ja", "zh", "sv"]); +const languageMap = { + "en": "English", + "fr": "French", + "es": "Spanish", + "it": "Italian", + "pl": "Polish", + "tr": "Turkish", + "ja": "Japanese", + "zh": "Chinese", + "sv": "Swedish" +} as const; + +const languages = new Set(Object.keys(languageMap)); const contentTypes = new Set(["sfw", "nsfw"]); -const urlBase = "https://api.comick.fun/chapter"; // Removed trailing slash +const urlBase = "https://api.comick.fun/chapter"; 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'}`; - // console.log('Fetching from:', apiUrl); // Debug log const response = await fetch(apiUrl, { headers: { @@ -21,7 +32,6 @@ export async function fetchComics(language: string = 'en', contentType: string = } const data = await response.json(); - // console.log('API response:', data); // Debug log if (!Array.isArray(data)) { console.error('Unexpected API response format:', data); @@ -43,5 +53,10 @@ export function isValidContentType(type: string): boolean { return contentTypes.has(type); } +export function getLanguageName(code: string): string { + return languageMap[code as keyof typeof languageMap] || code.toUpperCase(); +} + export const availableLanguages = Array.from(languages); -export const availableContentTypes = Array.from(contentTypes); \ No newline at end of file +export const availableContentTypes = Array.from(contentTypes); +export { languageMap }; \ No newline at end of file diff --git a/src/pages/[lang]/[type].astro b/src/pages/[lang]/[type].astro index 6969515..fcc8942 100644 --- a/src/pages/[lang]/[type].astro +++ b/src/pages/[lang]/[type].astro @@ -28,7 +28,7 @@ let error: string | null = null; try { comics = await fetchComics(lang, type); - console.log(`Fetched ${comics.length} comics`); // Debug log + console.log(`Fetched ${comics.length} comics`); } catch (e) { console.error('Failed to fetch comics:', e); error = e instanceof Error ? e.message : 'Failed to fetch comics'; @@ -70,7 +70,7 @@ try { padding: 1rem; width: 1200px; max-width: calc(100% - 2rem); - color: white; + color: var(--text-color); font-size: 20px; line-height: 1.6; } @@ -105,7 +105,7 @@ try { .no-comics { text-align: center; padding: 2rem; - background: #23262d; + background: var(--bg-secondary); border-radius: 8px; } @@ -119,7 +119,8 @@ try { .debug-info { font-size: 0.8rem; - color: #666; + color: var(--text-color); + opacity: 0.7; margin-top: 1rem; } \ No newline at end of file