From db585307f55334a2116571a5437b7fbfa08b0971 Mon Sep 17 00:00:00 2001 From: ld3zian <42660576+ld3z@users.noreply.github.com> Date: Sun, 26 Jan 2025 11:04:32 -0700 Subject: [PATCH 01/10] fix light mode by changing css --- src/components/TypeFilter.astro | 4 ++-- src/layouts/Layout.astro | 15 +++++++++++++++ src/pages/[lang]/[contentType]/[type].astro | 8 ++++---- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/components/TypeFilter.astro b/src/components/TypeFilter.astro index 8ea63d3..edd2cbe 100644 --- a/src/components/TypeFilter.astro +++ b/src/components/TypeFilter.astro @@ -21,8 +21,8 @@ const types = [ href={`/${lang}/${contentType}/${type.id}`} class={`px-4 py-2 rounded-lg text-sm font-medium transition-colors ${ currentType === type.id - ? 'bg-accent text-white' - : 'bg-secondary text-primary/80 hover:bg-hover' + ? 'bg-[rgb(var(--accent-bg))] text-[rgb(var(--accent-text))]' + : 'bg-secondary text-primary hover:bg-hover' }`} > {type.label} diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index 9d812e1..a3a3968 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -66,6 +66,11 @@ const canonicalURL = new URL(Astro.url.pathname, Astro.site ?? 'https://comick-r --bg-secondary: #f0f0f0; --bg-hover: #e0e0e0; --text-color: #13151a; + --accent: 89, 0, 255; /* Brighter, more saturated purple */ + --accent-light: 124, 58, 237; + --accent-dark: 76, 29, 149; + --accent-bg: 89, 0, 255; /* Same as accent for bg */ + --accent-text: 255, 255, 255; /* White text for contrast */ } /* Dark theme */ @@ -74,6 +79,11 @@ const canonicalURL = new URL(Astro.url.pathname, Astro.site ?? 'https://comick-r --bg-secondary: #23262d; --bg-hover: #2a2d35; --text-color: #ffffff; + --accent: 136, 58, 234; + --accent-light: 224, 204, 250; + --accent-dark: 49, 10, 101; + --accent-bg: 136, 58, 234; /* Same as accent for bg */ + --accent-text: 255, 255, 255; /* White text for contrast */ } /* Default to dark theme if no data-theme is set */ @@ -82,6 +92,11 @@ const canonicalURL = new URL(Astro.url.pathname, Astro.site ?? 'https://comick-r --bg-secondary: #23262d; --bg-hover: #2a2d35; --text-color: #ffffff; + --accent: 136, 58, 234; + --accent-light: 224, 204, 250; + --accent-dark: 49, 10, 101; + --accent-bg: 136, 58, 234; + --accent-text: 255, 255, 255; } html { diff --git a/src/pages/[lang]/[contentType]/[type].astro b/src/pages/[lang]/[contentType]/[type].astro index 0eca550..8b2b16c 100644 --- a/src/pages/[lang]/[contentType]/[type].astro +++ b/src/pages/[lang]/[contentType]/[type].astro @@ -44,8 +44,8 @@ const title = `ComicK - ${getLanguageName(lang!)} ${contentType?.toUpperCase()} href={`/${lang}/sfw/${type}`} class={`px-4 py-2 rounded-lg text-sm font-medium transition-colors ${ contentType === 'sfw' - ? 'bg-accent text-white' - : 'bg-secondary text-primary/80 hover:bg-hover' + ? 'bg-[rgb(var(--accent-bg))] text-[rgb(var(--accent-text))]' + : 'bg-secondary text-primary hover:bg-hover' }`} > SFW @@ -54,8 +54,8 @@ const title = `ComicK - ${getLanguageName(lang!)} ${contentType?.toUpperCase()} href={`/${lang}/nsfw/${type}`} class={`px-4 py-2 rounded-lg text-sm font-medium transition-colors ${ contentType === 'nsfw' - ? 'bg-accent text-white' - : 'bg-secondary text-primary/80 hover:bg-hover' + ? 'bg-[rgb(var(--accent-bg))] text-[rgb(var(--accent-text))]' + : 'bg-secondary text-primary hover:bg-hover' }`} > NSFW From 007ec1856fb4f335a2c78c50f44904aa5cebb88f Mon Sep 17 00:00:00 2001 From: ld3zian <42660576+ld3z@users.noreply.github.com> Date: Sun, 26 Jan 2025 11:10:05 -0700 Subject: [PATCH 02/10] added timer to the comic card --- src/components/ComicCard.astro | 59 +++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/src/components/ComicCard.astro b/src/components/ComicCard.astro index 1c55285..deba8ea 100644 --- a/src/components/ComicCard.astro +++ b/src/components/ComicCard.astro @@ -97,14 +97,21 @@ const isNSFW = comic.md_comics.content_rating === 'erotica';
- +
+ + {comic.publish_at && ( +
+ Publishing in: calculating... +
+ )} +
Read Now →
@@ -176,5 +183,41 @@ const isNSFW = comic.md_comics.content_rating === 'erotica'; } }); }); + + // Add countdown timer functionality + const countdownTimers = document.querySelectorAll('.countdown-timer'); + + function updateTimer(element: Element) { + const publishAt = new Date(element.getAttribute('data-publish-at') || '').getTime(); + const now = new Date().getTime(); + const distance = publishAt - now; + + const timerSpan = element.querySelector('span'); + if (!timerSpan) return; + + if (distance < 0) { + timerSpan.textContent = 'Published'; + return; + } + + const days = Math.floor(distance / (1000 * 60 * 60 * 24)); + const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); + const seconds = Math.floor((distance % (1000 * 60)) / 1000); + + let timeString = ''; + if (days > 0) timeString += `${days}d `; + if (hours > 0 || days > 0) timeString += `${hours}h `; + if (minutes > 0 || hours > 0 || days > 0) timeString += `${minutes}m `; + timeString += `${seconds}s`; + + timerSpan.textContent = timeString; + } + + countdownTimers.forEach(timer => { + updateTimer(timer); + // Update every second + setInterval(() => updateTimer(timer), 1000); + }); }); \ No newline at end of file From 8c634a381aafa5c17cec1da46404e3871e6dbf86 Mon Sep 17 00:00:00 2001 From: ld3zian <42660576+ld3z@users.noreply.github.com> Date: Sun, 26 Jan 2025 11:50:58 -0700 Subject: [PATCH 03/10] search pt 1 --- src/components/SlugInput.astro | 282 ++++++++++++++++++++------------- src/lib/api.ts | 3 +- src/pages/custom.astro | 4 +- 3 files changed, 174 insertions(+), 115 deletions(-) diff --git a/src/components/SlugInput.astro b/src/components/SlugInput.astro index f680986..94db311 100644 --- a/src/components/SlugInput.astro +++ b/src/components/SlugInput.astro @@ -6,74 +6,78 @@ interface Props { const { currentSlugs = [] } = Astro.props; import { availableLanguages, languageMap } from '../lib/api'; + +const languages = [ + { value: 'en', label: 'English' }, + { value: 'ja', label: 'Japanese' }, + { value: 'ko', label: 'Korean' }, + { value: 'zh', label: 'Chinese' }, + { value: 'fr', label: 'French' }, + { value: 'es', label: 'Spanish' }, + { value: 'it', label: 'Italian' }, + { value: 'de', label: 'German' }, + { value: 'tr', label: 'Turkish' }, + { value: 'pl', label: 'Polish' }, +]; --- -
-
- +
+
- -
+
-
-
- - +
{currentSlugs.map(slug => ( -
+
{slug}
))}
-
+ \ No newline at end of file diff --git a/src/lib/api.ts b/src/lib/api.ts index 131f8ec..d566cbe 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -11,7 +11,8 @@ const languageMap = { "zh": "Chinese", "sv": "Swedish", "ar": "Arabic", - "de": "German" + "de": "German", + "ko": "Korean" } as const; const languages = new Set(Object.keys(languageMap)); diff --git a/src/pages/custom.astro b/src/pages/custom.astro index a893396..87f97a8 100644 --- a/src/pages/custom.astro +++ b/src/pages/custom.astro @@ -15,8 +15,8 @@ const description = "Create a custom RSS feed for your favorite comics";
-

Add the comic slugs from the URLs of your favorite comics on ComicK.

-

Example: For https://comick.io/comic/01-one-piece, the slug is "01-one-piece"

+

Search for your favorite comics using the search box above, or add their slugs manually.

+

Manual example: For https://comick.io/comic/01-one-piece, the slug is "01-one-piece"

\ No newline at end of file From cc173b66bd76566baf1056515dcb193b6760c735 Mon Sep 17 00:00:00 2001 From: ld3zian <42660576+ld3z@users.noreply.github.com> Date: Sun, 26 Jan 2025 11:55:50 -0700 Subject: [PATCH 04/10] forgo abt cors --- src/components/SlugInput.astro | 30 ++++++++++++++++++++++++++++-- src/pages/api/search.ts | 31 +++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 src/pages/api/search.ts diff --git a/src/components/SlugInput.astro b/src/components/SlugInput.astro index 94db311..c295713 100644 --- a/src/components/SlugInput.astro +++ b/src/components/SlugInput.astro @@ -145,11 +145,37 @@ const languages = [ } try { - const response = await fetch(`https://api.comick.io/v1.0/search/?page=1&limit=5&q=${encodeURIComponent(query)}`); + searchResults!.innerHTML = ` +
+ Searching... +
+ `; + searchResults!.classList.remove('hidden'); + + const response = await fetch('/api/search', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ query }) + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + if (!data || !Array.isArray(data) || data.length === 0) { + searchResults!.innerHTML = ` +
+ No comics found +
+ `; + return; + } + searchResults!.innerHTML = ''; - searchResults!.classList.remove('hidden'); data.forEach((comic: any) => { const div = document.createElement('div'); diff --git a/src/pages/api/search.ts b/src/pages/api/search.ts new file mode 100644 index 0000000..bccfc41 --- /dev/null +++ b/src/pages/api/search.ts @@ -0,0 +1,31 @@ +import type { APIRoute } from "astro"; + +export const POST: APIRoute = async ({ request }) => { + const { query } = await request.json(); + + try { + const response = await fetch( + `https://api.comick.io/v1.0/search/?page=1&limit=5&q=${encodeURIComponent(query)}` + ); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + return new Response(JSON.stringify(data), { + status: 200, + headers: { + 'Content-Type': 'application/json' + } + }); + } catch (error) { + console.error('Search error:', error); + return new Response(JSON.stringify({ error: 'Failed to search comics' }), { + status: 500, + headers: { + 'Content-Type': 'application/json' + } + }); + } +}; \ No newline at end of file From 86fa1d5a649c5c757121b787284b278c9836135f Mon Sep 17 00:00:00 2001 From: ld3zian <42660576+ld3z@users.noreply.github.com> Date: Sun, 26 Jan 2025 12:04:01 -0700 Subject: [PATCH 05/10] search pt 2 --- src/components/SlugInput.astro | 160 ++++++++++++++++++++++++++++----- 1 file changed, 136 insertions(+), 24 deletions(-) diff --git a/src/components/SlugInput.astro b/src/components/SlugInput.astro index c295713..860454c 100644 --- a/src/components/SlugInput.astro +++ b/src/components/SlugInput.astro @@ -105,32 +105,144 @@ const languages = [ renderSlugs(); } - function renderSlugs() { + async function renderSlugs() { if (!slugList) return; - slugList.innerHTML = ''; - [...slugs].forEach(slug => { - const div = document.createElement('div'); - div.className = 'flex items-center justify-between p-3 bg-primary rounded-lg border border-hover/30'; - - const text = document.createElement('span'); - text.textContent = slug; - - const removeBtn = document.createElement('button'); - removeBtn.className = 'text-red-500 hover:text-red-600 transition-colors'; - removeBtn.innerHTML = ` - - - - `; - removeBtn.onclick = () => { - slugs.delete(slug); - updateSlugs(); - }; - - div.appendChild(text); - div.appendChild(removeBtn); - slugList.appendChild(div); + // Show loading state + slugList.innerHTML = ` +
+ ${[...slugs].map(() => ` +
+
+
+
+
+
+
+ `).join('')} +
+ `; + + const promises = [...slugs].map(async (slug) => { + try { + // Updated API endpoint to match ComicK's current structure + const response = await fetch(`https://api.comick.fun/comic/${encodeURIComponent(slug)}`); + if (!response.ok) throw new Error('Comic not found'); + + const data = await response.json(); + + const div = document.createElement('div'); + div.className = 'flex items-center gap-4 p-4 bg-primary rounded-lg border border-hover/30 hover:border-accent/50 transition-all duration-300 group relative'; + + // Add a link to the comic + const link = document.createElement('a'); + link.href = `https://comick.io/comic/${slug}`; + link.target = '_blank'; + link.rel = 'noopener noreferrer'; + link.className = 'flex items-center gap-4 flex-1'; + + // Handle cover image + if (data.comic?.md_covers?.[0]?.b2key) { + const img = document.createElement('img'); + img.src = `https://meo.comick.pictures/${data.comic.md_covers[0].b2key}`; + img.className = 'w-16 h-24 object-cover rounded shadow-md group-hover:scale-105 transition-transform duration-300'; + img.alt = data.comic.title || slug; + img.onerror = () => { + img.src = '/placeholder.png'; // Fallback image + img.onerror = null; + }; + link.appendChild(img); + } else { + // Placeholder if no image + const placeholder = document.createElement('div'); + placeholder.className = 'w-16 h-24 bg-hover/30 rounded flex items-center justify-center text-primary/30'; + placeholder.innerHTML = ''; + link.appendChild(placeholder); + } + + const info = document.createElement('div'); + info.className = 'flex-1 min-w-0'; + info.innerHTML = ` +
+ ${data.comic?.title || slug} +
+
${slug}
+ ${data.comic?.last_chapter ? ` +
+ Latest: Chapter ${data.comic.last_chapter} +
+ ` : ''} + `; + + link.appendChild(info); + div.appendChild(link); + + const removeBtn = document.createElement('button'); + removeBtn.className = 'text-red-500 hover:text-red-600 transition-colors p-2 hover:bg-red-500/10 rounded-full flex-shrink-0 relative z-10'; + removeBtn.innerHTML = ` + + + + `; + removeBtn.onclick = (e) => { + e.preventDefault(); + e.stopPropagation(); + div.classList.add('scale-95', 'opacity-0'); + setTimeout(() => { + slugs.delete(slug); + updateSlugs(); + }, 200); + }; + + div.appendChild(removeBtn); + return div; + } catch (error) { + console.error(`Failed to fetch comic info for ${slug}:`, error); + // Improved error state + const div = document.createElement('div'); + div.className = 'flex items-center justify-between p-4 bg-primary rounded-lg border border-red-500/30 group'; + div.innerHTML = ` +
+
+ + + +
+
+
Failed to load details
+
${slug}
+
+
+ + `; + + const removeButton = div.querySelector('button'); + if (removeButton) { + removeButton.onclick = (e) => { + e.preventDefault(); + e.stopPropagation(); + div.classList.add('scale-95', 'opacity-0'); + setTimeout(() => { + slugs.delete(slug); + updateSlugs(); + }, 200); + }; + } + return div; + } + }); + + Promise.all(promises).then(elements => { + slugList.innerHTML = ''; + elements.forEach(element => slugList.appendChild(element)); + }).catch(error => { + console.error('Failed to render slugs:', error); }); } From daa059e667c55146a5622dafcb816daffec19d90 Mon Sep 17 00:00:00 2001 From: ld3zian <42660576+ld3z@users.noreply.github.com> Date: Sun, 26 Jan 2025 12:09:10 -0700 Subject: [PATCH 06/10] fix search --- src/components/SlugInput.astro | 4 ++-- src/pages/api/comic/[slug].ts | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 src/pages/api/comic/[slug].ts diff --git a/src/components/SlugInput.astro b/src/components/SlugInput.astro index 860454c..f33b2b4 100644 --- a/src/components/SlugInput.astro +++ b/src/components/SlugInput.astro @@ -125,8 +125,8 @@ const languages = [ const promises = [...slugs].map(async (slug) => { try { - // Updated API endpoint to match ComicK's current structure - const response = await fetch(`https://api.comick.fun/comic/${encodeURIComponent(slug)}`); + // Use our API endpoint instead of direct ComicK API call + const response = await fetch(`/api/comic/${encodeURIComponent(slug)}`); if (!response.ok) throw new Error('Comic not found'); const data = await response.json(); diff --git a/src/pages/api/comic/[slug].ts b/src/pages/api/comic/[slug].ts new file mode 100644 index 0000000..3989c4a --- /dev/null +++ b/src/pages/api/comic/[slug].ts @@ -0,0 +1,31 @@ +import type { APIRoute } from "astro"; + +export const GET: APIRoute = async ({ params }) => { + const { slug } = params; + + try { + const response = await fetch( + `https://api.comick.fun/comic/${encodeURIComponent(slug!)}/` + ); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + return new Response(JSON.stringify(data), { + status: 200, + headers: { + 'Content-Type': 'application/json' + } + }); + } catch (error) { + console.error('Comic fetch error:', error); + return new Response(JSON.stringify({ error: 'Failed to fetch comic details' }), { + status: 500, + headers: { + 'Content-Type': 'application/json' + } + }); + } +}; \ No newline at end of file From f9fc2c4cb070b0ece32cef264ed4d26ab74c6872 Mon Sep 17 00:00:00 2001 From: ld3zian <42660576+ld3z@users.noreply.github.com> Date: Sun, 26 Jan 2025 12:55:16 -0700 Subject: [PATCH 07/10] add credits --- src/components/ThemeToggle.astro | 2 +- src/layouts/Layout.astro | 128 +++++++++++++++++++++++++- src/pages/credits.astro | 152 +++++++++++++++++++++++++++++++ 3 files changed, 278 insertions(+), 4 deletions(-) create mode 100644 src/pages/credits.astro diff --git a/src/components/ThemeToggle.astro b/src/components/ThemeToggle.astro index a63a6eb..96a3644 100644 --- a/src/components/ThemeToggle.astro +++ b/src/components/ThemeToggle.astro @@ -2,7 +2,7 @@ --- + + +
+
+ )} +
+ +
+ +