diff --git a/web/sections/CarouselItems.tsx b/web/sections/CarouselItems.tsx index c818c9d..b600dbf 100644 --- a/web/sections/CarouselItems.tsx +++ b/web/sections/CarouselItems.tsx @@ -5,7 +5,7 @@ import { Input } from '@/components/ui/input'; import { useClient } from 'hooks/useClient'; import { MediaPicker } from '../MediaPicker'; import { readableError } from '../errors'; -import { thumbUrl } from '../thumbnail'; +import { mediaThumbUrl } from '../thumbnail'; /** * One carousel's contents: what is in it, in what order, and what each picture is called. @@ -151,7 +151,7 @@ export const CarouselItems = ({ carouselId, onChanged }: { carouselId: number; o and a browser cannot show the original at all. */} ({ section }: { section: Su {photos.map((photo) => (
  • - +

    {photo.name}

  • diff --git a/web/thumbnail.ts b/web/thumbnail.ts index f2112b1..c2529b9 100644 --- a/web/thumbnail.ts +++ b/web/thumbnail.ts @@ -48,3 +48,20 @@ export const originalUrl = (path: string, width: number): string => { const encoded = path.split('/').map(encodeURIComponent).join('/'); return `/api/fofos-admin/original/${encoded}?width=${Math.round(width)}&token=${encodeURIComponent(token)}`; }; + +/** Extensions av-club treats as video. The same list the site's own `kindFor` uses. */ +const VIDEO = /\.(mp4|mov|webm|m4v|avi|mkv)$/i; + +/** + * A thumbnail for anything in the media store, picture or video. + * + * A video has no width rungs — `poster-448.webp` and friends are cut from a still, and asking for + * `320.webp` gets a 404 and a broken image. Every grid in this panel was doing exactly that, so a + * carousel holding a video showed a broken tile with no clue why. + * + * `posterUrl` already existed for this and nothing called it. One helper that decides from the + * extension, so a screen showing mixed media does not have to know the difference — which is the + * whole point, since a carousel is explicitly allowed to hold both. + */ +export const mediaThumbUrl = (path: string, width: 256 | 320 | 480 | 640 | 960 | 1280 = 320): string => + VIDEO.test(path) ? posterUrl(path) : thumbUrl(path, width);