import { getHeaders } from 'hooks/useClient'; /** * A thumbnail URL for something under `originals/`, authenticated by `?token=`. * * ── Why the token is in the query ── * * An `` cannot send an Authorization header. `user-middleware` and the permission gate both accept * the token in the query string for exactly this, and the platform's own file browser does the same. * Built without it first, and every picture 401s while the layout looks perfectly correct. * * ── Why this is a module ── * * It was copied into CarouselsPanel and again into RecordsPanel, and a third copy was about to go into * MediaField. Three copies of a URL shape is three places to be wrong about the rung when the ladder * changes — which it did, four times in a day. */ export const thumbUrl = (path: string, width: 256 | 320 | 480 | 640 | 960 | 1280 = 320): string => { const token = getHeaders()['Authorization']?.replace('Bearer ', '') ?? ''; const encoded = path.split('/').map(encodeURIComponent).join('/'); return `/api/fofos-admin/derived/${encoded}/${width}.webp?token=${encodeURIComponent(token)}`; }; /** * A video's poster, for the same reason. * * A video has no width rungs — `poster-448.webp` and friends are cut from its still — so a slot showing * one asks for the poster rather than a width that does not exist. */ export const posterUrl = (path: string): string => { const token = getHeaders()['Authorization']?.replace('Bearer ', '') ?? ''; const encoded = path.split('/').map(encodeURIComponent).join('/'); return `/api/fofos-admin/derived/${encoded}/poster-512.webp?token=${encodeURIComponent(token)}`; }; /** * An ORIGINAL, rendered at a width, for something drawn at size. * * The derived ladder is right for a row thumbnail and wrong for a framing slot: that is most of a panel * wide and can be zoomed on top of it, so a rung chosen in advance is a rung that is wrong. This asks * for the width the slot actually draws, from the file that has every pixel. * * `width` is a hint the server clamps to 256..4096. Ask for what will be drawn — twice it, on a screen * that is worth it — rather than a round number. */ export const originalUrl = (path: string, width: number): string => { const token = getHeaders()['Authorization']?.replace('Bearer ', '') ?? ''; const encoded = path.split('/').map(encodeURIComponent).join('/'); return `/api/fofos-admin/original/${encoded}?width=${Math.round(width)}&token=${encodeURIComponent(token)}`; };