feat: show manga covers everywhere a manga is referenced
Every place that surfaced a manga title used to show *just* the title — the home page, the reader's back-to-manga link, and the chapter upload form's manga selector. Adding the cover image alongside makes the app feel like an actual manga library. - Home (`/`): manga list switched from a one-line `<a>` per item to a responsive grid of cards (`auto-fill, minmax(140px, 1fr)`), each card showing the cover (with 📖 placeholder when no cover is set), the title (line-clamped to 2 rows), and the author. - Reader (`/manga/[id]/chapter/[n]`): the back-to-manga link in the reader header now shows a 28×42 thumbnail of the manga's cover next to the title. Reuses the placeholder pattern for cover-less mangas. - Upload (`/upload`): the chapter form's manga `<select>` still uses a native dropdown (covers don't fit in `<option>`), but a preview pane below the select now shows the currently-selected manga's cover + title + author so the user can visually confirm which manga they're attaching the chapter to. No backend changes — `cover_image_path` was already in the Manga JSON; only the frontend needed to read it. Lockstep version bump to 0.12.0. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { ApiError } from '$lib/api/client';
|
||||
import { ApiError, fileUrl } from '$lib/api/client';
|
||||
import { createManga } from '$lib/api/mangas';
|
||||
import { request } from '$lib/api/client';
|
||||
import { session } from '$lib/session.svelte';
|
||||
@@ -74,6 +74,7 @@
|
||||
let chapterSuccess = $state<string | null>(null);
|
||||
let isDragOver = $state(false);
|
||||
|
||||
const selectedManga = $derived(mangas.find((m) => m.id === chapterMangaId) ?? null);
|
||||
const allChapterPagesValid = $derived(chapterPages.every((p) => !p.error));
|
||||
const canSubmitChapter = $derived(
|
||||
Boolean(chapterMangaId) &&
|
||||
@@ -276,10 +277,32 @@
|
||||
>
|
||||
<option value="">Choose…</option>
|
||||
{#each mangas as m (m.id)}
|
||||
<option value={m.id}>{m.title}</option>
|
||||
<option value={m.id}>
|
||||
{m.title}{#if m.author} — {m.author}{/if}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
</label>
|
||||
{#if selectedManga}
|
||||
<div class="manga-preview" data-testid="chapter-manga-preview">
|
||||
{#if selectedManga.cover_image_path}
|
||||
<img
|
||||
src={fileUrl(selectedManga.cover_image_path)}
|
||||
alt=""
|
||||
class="preview-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
{:else}
|
||||
<span class="preview-cover preview-cover-placeholder" aria-hidden="true">📖</span>
|
||||
{/if}
|
||||
<div class="preview-meta">
|
||||
<span class="preview-title">{selectedManga.title}</span>
|
||||
{#if selectedManga.author}
|
||||
<span class="preview-author">{selectedManga.author}</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<label>
|
||||
Chapter number <span aria-hidden="true">*</span>
|
||||
<input
|
||||
@@ -415,6 +438,42 @@
|
||||
.success {
|
||||
color: #0a7d2c;
|
||||
}
|
||||
.manga-preview {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 0.5rem;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 4px;
|
||||
background: #fafafa;
|
||||
}
|
||||
.preview-cover {
|
||||
width: 48px;
|
||||
height: 72px;
|
||||
object-fit: cover;
|
||||
border-radius: 3px;
|
||||
background: #f0f0f0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.preview-cover-placeholder {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.5rem;
|
||||
color: #999;
|
||||
}
|
||||
.preview-meta {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
}
|
||||
.preview-title {
|
||||
font-weight: 600;
|
||||
}
|
||||
.preview-author {
|
||||
color: #777;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
.drop-zone {
|
||||
border: 2px dashed #aaa;
|
||||
border-radius: 6px;
|
||||
|
||||
Reference in New Issue
Block a user