fix(ui): stack episode title under the thumbnail on narrow rows
A fixed 160px thumbnail beside the title left phone-width rows cramped. A container query stacks a full-width thumbnail above the info block when the row is under 28rem, lets the title wrap to two lines there, and requests a 640px image so the wider thumbnail stays sharp.
This commit is contained in:
@@ -57,25 +57,29 @@
|
||||
const episodeNumber = $derived(episode.indexNumber || 0);
|
||||
</script>
|
||||
|
||||
<button
|
||||
<!-- Narrow rows stack the title under a full-width thumbnail instead of
|
||||
squeezing it beside a fixed 160px one. A container query, not a viewport
|
||||
breakpoint, so it follows the row's own width. -->
|
||||
<div class="@container">
|
||||
<button
|
||||
bind:this={buttonRef}
|
||||
type="button"
|
||||
class="group/row flex gap-4 w-full text-left p-3 rounded-lg hover:bg-[var(--color-surface-hover)] transition-colors {focused
|
||||
class="group/row flex flex-col @md:flex-row gap-3 @md:gap-4 w-full text-left p-3 rounded-lg hover:bg-[var(--color-surface-hover)] transition-colors {focused
|
||||
? 'ring-2 ring-[var(--color-jellyfin)] bg-[var(--color-surface)]'
|
||||
: current
|
||||
? 'ring-2 ring-yellow-400 bg-[var(--color-surface)]'
|
||||
: ''}"
|
||||
{onclick}
|
||||
>
|
||||
>
|
||||
<!-- Thumbnail -->
|
||||
<div
|
||||
class="relative flex-shrink-0 w-40 aspect-video rounded-lg overflow-hidden bg-[var(--color-surface)]"
|
||||
class="relative flex-shrink-0 w-full @md:w-40 aspect-video rounded-lg overflow-hidden bg-[var(--color-surface)]"
|
||||
>
|
||||
<CachedImage
|
||||
itemId={episode.id}
|
||||
imageType="Primary"
|
||||
tag={episode.imageId}
|
||||
maxWidth={320}
|
||||
maxWidth={640}
|
||||
alt={episode.name}
|
||||
class="w-full h-full object-cover transition-transform group-hover/row:scale-105"
|
||||
/>
|
||||
@@ -104,9 +108,14 @@
|
||||
|
||||
<!-- Download indicator -->
|
||||
{#if isDownloaded || isDownloading}
|
||||
<div class="absolute bottom-2 right-2" title={isDownloaded ? "Downloaded" : "Downloading..."}>
|
||||
<div
|
||||
class="absolute bottom-2 right-2"
|
||||
title={isDownloaded ? "Downloaded" : "Downloading..."}
|
||||
>
|
||||
{#if isDownloaded}
|
||||
<div class="w-5 h-5 rounded-full bg-green-600 flex items-center justify-center shadow-lg">
|
||||
<div
|
||||
class="w-5 h-5 rounded-full bg-green-600 flex items-center justify-center shadow-lg"
|
||||
>
|
||||
<svg
|
||||
class="w-3 h-3 text-white"
|
||||
fill="none"
|
||||
@@ -114,7 +123,11 @@
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="2.5"
|
||||
>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4v12m0 0l-4-4m4 4l4-4" />
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M12 4v12m0 0l-4-4m4 4l4-4"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
{:else if isDownloading}
|
||||
@@ -148,7 +161,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Episode info -->
|
||||
<div class="flex-1 min-w-0 py-1">
|
||||
<div class="flex-1 min-w-0 @md:py-1">
|
||||
<div class="flex items-start justify-between gap-4">
|
||||
<div class="min-w-0 flex-1">
|
||||
<!-- Episode number and title -->
|
||||
@@ -157,7 +170,7 @@
|
||||
{episodeNumber}.
|
||||
</span>
|
||||
<h3
|
||||
class="text-white font-medium truncate group-hover/row:text-[var(--color-jellyfin)] transition-colors"
|
||||
class="text-white font-medium line-clamp-2 @md:truncate group-hover/row:text-[var(--color-jellyfin)] transition-colors"
|
||||
>
|
||||
{truncateMiddle(episode.name, 56)}
|
||||
</h3>
|
||||
@@ -220,4 +233,5 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user