优化缩略图

This commit is contained in:
truewhile
2026-09-20 14:13:49 +08:00
parent 9b2b592003
commit c24ebe181d
14 changed files with 119 additions and 43 deletions
+2 -2
View File
@@ -2,7 +2,7 @@ import { useEffect, useRef, useState, type DragEvent, type MouseEvent, type Reac
import { createPortal } from 'react-dom'
import { Folder, GripVertical, Image, MoreVertical, Plus, Power, PowerOff, RefreshCw, Save, Trash2 } from 'lucide-react'
import { imageURL } from '../api/client'
import { ARTWORK, imageURL } from '../api/client'
import { LocalDirBrowserDialog } from '../components/LocalDirBrowserDialog'
import type { Library, LibraryRoot } from '../types'
import type { RootDraft } from './adminLibraryPanelModel'
@@ -172,7 +172,7 @@ function LibraryTableRow({ library, dragging, dragOver, onDragStart, onDragOver,
<div className="flex items-center gap-2">
{library.cover_url && (
<img
src={imageURL(library.cover_url, library.updated_at)}
src={imageURL(library.cover_url, library.updated_at, ARTWORK.backdropStrip)}
alt=""
loading="lazy"
decoding="async"
+5 -5
View File
@@ -17,7 +17,7 @@ import {
Tv,
} from 'lucide-react'
import { imageURL } from '../api/client'
import { ARTWORK, imageURL } from '../api/client'
import { useInViewOnce } from '../hooks/useInViewOnce'
import { useLazyPreviewBatch } from '../hooks/useLazyPreviewBatch'
import { useRememberedListPosition } from '../hooks/useListPositionMemory'
@@ -171,7 +171,7 @@ export function HomeCarouselSection({
{visual && (
<img
key={visual + currentItem.id}
src={imageURL(visual, currentItem.updated_at, { maxWidth: 1920, maxHeight: 1080, quality: 78 })}
src={imageURL(visual, currentItem.updated_at, ARTWORK.backdropHero)}
alt=""
fetchPriority="high"
decoding="async"
@@ -283,7 +283,7 @@ export function HomeCarouselSection({
</div>
{poster && (
<img
src={imageURL(poster, currentItem.updated_at, { maxWidth: 560, quality: 84 })}
src={imageURL(poster, currentItem.updated_at, ARTWORK.posterDetail)}
alt={currentItem.title}
fetchPriority="high"
decoding="async"
@@ -516,7 +516,7 @@ export function HomeLibraryCard({
src={imageURL(
src,
version,
library.cover_url ? undefined : { maxWidth: 480, maxHeight: 320, quality: 78 },
library.cover_url ? undefined : ARTWORK.backdropStrip,
)}
alt=""
loading="lazy"
@@ -750,7 +750,7 @@ function ContinueCard({ media, progress }: { media: Media; progress: number }) {
<div className="relative h-20 w-14 shrink-0 overflow-hidden rounded-xl bg-[var(--app-panel-soft)]">
{media.poster_url ? (
<img
src={imageURL(media.poster_url, media.updated_at, { maxWidth: 180, maxHeight: 240, quality: 78 })}
src={imageURL(media.poster_url, media.updated_at, ARTWORK.posterCard)}
alt=""
className="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105"
loading="lazy"
+2 -2
View File
@@ -2,7 +2,7 @@ import { isRemoteEmbyID } from '../utils/remoteEmby'
import { Link } from 'react-router-dom'
import { ArrowLeft, Database, FileText, Film, FolderInput, Pencil, Play, Search, Sparkles, Trash2 } from 'lucide-react'
import { imageURL } from '../api/client'
import { ARTWORK, imageURL } from '../api/client'
import { ExternalPlayerButton } from '../components/ExternalPlayerButton'
import { MediaFavouriteButton } from '../components/MediaFavouriteButton'
import type { Media } from '../types'
@@ -70,7 +70,7 @@ export function LibrarySeriesDetailHeader({
<div className="w-40 shrink-0 overflow-hidden rounded-xl bg-sand-200 shadow-card">
{series.rep.poster_url ? (
<img
src={imageURL(series.rep.poster_url, series.rep.updated_at)}
src={imageURL(series.rep.poster_url, series.rep.updated_at, ARTWORK.posterDetail)}
alt={series.rep.title}
loading="lazy"
decoding="async"
+2 -6
View File
@@ -1,7 +1,7 @@
import { Link } from 'react-router-dom'
import { Play, Search } from 'lucide-react'
import { imageURL } from '../api/client'
import { ARTWORK, imageURL } from '../api/client'
import { ExternalPlayerButton } from '../components/ExternalPlayerButton'
import type { Media } from '../types'
import {
@@ -87,11 +87,7 @@ export function LibrarySeriesEpisodes({
>
{ep.backdrop_url || ep.poster_url ? (
<img
src={imageURL(ep.backdrop_url || ep.poster_url || '', ep.updated_at, {
maxWidth: 320,
maxHeight: 180,
quality: 76,
})}
src={imageURL(ep.backdrop_url || ep.poster_url || '', ep.updated_at, ARTWORK.backdropStrip)}
alt=""
loading="lazy"
decoding="async"
+3 -11
View File
@@ -2,7 +2,7 @@ import { motion } from 'framer-motion'
import { FileText, Play } from 'lucide-react'
import { Link } from 'react-router-dom'
import { imageURL } from '../api/client'
import { ARTWORK, imageURL } from '../api/client'
import type { Media } from '../types'
type MediaDetailArtworkProps = {
@@ -14,11 +14,7 @@ export function MediaDetailBackdrop({ media }: MediaDetailArtworkProps) {
<div className="absolute inset-0 h-[480px] z-0 overflow-hidden">
{media.backdrop_url || media.poster_url ? (
<img
src={imageURL(media.backdrop_url || media.poster_url || '', media.updated_at, {
maxWidth: 1920,
maxHeight: 1080,
quality: 76,
})}
src={imageURL(media.backdrop_url || media.poster_url || '', media.updated_at, ARTWORK.backdropHero)}
alt=""
decoding="async"
fetchPriority="low"
@@ -42,11 +38,7 @@ export function MediaDetailPoster({ media }: MediaDetailArtworkProps) {
>
{media.poster_url ? (
<img
src={imageURL(media.poster_url, media.updated_at, {
maxWidth: 560,
maxHeight: 840,
quality: 84,
})}
src={imageURL(media.poster_url, media.updated_at, ARTWORK.posterDetail)}
alt={media.title}
decoding="async"
fetchPriority="high"
+2 -2
View File
@@ -19,7 +19,7 @@ import {
X,
} from 'lucide-react'
import { imageURL } from '../api/client'
import { ARTWORK, imageURL } from '../api/client'
import { scraperAPI } from '../api/scraper'
import type { ScrapeQueueSnapshot, ScrapeTask, ScrapeTaskStatus } from '../types/scraper'
import { apiErrorMessage, formatTime, taskStatusMeta } from './StrmManagePage'
@@ -756,7 +756,7 @@ export function ScraperQueuePage({ embedded = false }: { embedded?: boolean }) {
<div className="flex items-center gap-2">
{task.poster_url ? (
<img
src={imageURL(task.poster_url)}
src={imageURL(task.poster_url, undefined, ARTWORK.posterTiny)}
alt=""
className="h-10 w-7 rounded object-cover border border-gray-200 shrink-0"
onError={(e) => {
+2 -2
View File
@@ -4,7 +4,7 @@ import { Clock, Play, Trash2 } from 'lucide-react'
import toast from 'react-hot-toast'
import { historyAPI } from '../api/history'
import { imageURL } from '../api/client'
import { ARTWORK, imageURL } from '../api/client'
import { confirmAction } from '../components/confirmAction'
import { isRemoteEmbyID } from '../utils/remoteEmby'
import type { HistoryItem, Media } from '../types'
@@ -117,7 +117,7 @@ export function WatchHistoryPage() {
<div className="h-16 w-12 shrink-0 overflow-hidden rounded-lg bg-surface-900">
{m.poster_url ? (
<img
src={imageURL(m.poster_url, m.updated_at)}
src={imageURL(m.poster_url, m.updated_at, ARTWORK.posterCard)}
alt={m.title}
className="h-full w-full object-cover"
referrerPolicy="no-referrer"
@@ -1,7 +1,7 @@
import { Link } from 'react-router-dom'
import { AlertCircle, Ban, Copy, ExternalLink, RefreshCw, Sparkles, Trash2, X } from 'lucide-react'
import { imageURL } from '../../api/client'
import { ARTWORK, imageURL } from '../../api/client'
import type { ScrapeTask } from '../../types/scraper'
import { formatTime, taskStatusMeta } from '../StrmManagePage'
import { PROVIDER_LABELS, TYPE_LABELS } from './scrapeLabels'
@@ -52,7 +52,7 @@ export function ScrapeDetailModal({
<div className="flex gap-4 rounded-2xl border border-brand-500/20 bg-primary-400/5 p-4">
{task.poster_url && (
<img
src={imageURL(task.poster_url)}
src={imageURL(task.poster_url, undefined, ARTWORK.posterTiny)}
alt=""
className="h-28 w-20 rounded-xl object-cover border border-brand-500/30 shadow-md shrink-0"
/>