feat(channels): фон комнаты и статичные превью при reduced-motion
- миграция 00014: background_file_id у комнаты (AGENT.md 7.5, 7.7)
- API: POST/DELETE /channels/{id}/background под MANAGE_CHANNEL_BACKGROUND,
фон отдаётся в списке комнат и рассылается событием CHANNEL_UPDATE
- клиент: фон рисуется за лентой с затемнением, блок «Фон комнаты» в настройках
комнаты (загрузка, замена, удаление)
- AnimatedImage: при «уменьшить движение» показывает статичный первый кадр,
нарисованный на canvas, вместо анимации
- тесты: Go (загрузка, права, снятие) и Vitest (лента, настройки, reduced-motion)
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
import { useReducedMotion, useStaticFrame } from '@/lib/reducedMotion';
|
||||
|
||||
/**
|
||||
* Картинка, которая при «уменьшить движение» показывает статичный первый кадр
|
||||
* вместо анимации (AGENT.md 7.2, 7.7). Используется для фонов, рамок, аватаров
|
||||
* и баннеров — везде, где может лежать GIF или анимированный WebP.
|
||||
*/
|
||||
|
||||
interface AnimatedImageProps {
|
||||
src: string;
|
||||
alt?: string;
|
||||
className?: string;
|
||||
loading?: 'lazy' | 'eager';
|
||||
}
|
||||
|
||||
/** Картинка, уважающая настройку «уменьшить движение». */
|
||||
export function AnimatedImage({ src, alt = '', className, loading }: AnimatedImageProps) {
|
||||
const reduced = useReducedMotion();
|
||||
const frame = useStaticFrame(src, reduced);
|
||||
return (
|
||||
<img
|
||||
src={frame ?? src}
|
||||
alt={alt}
|
||||
{...(className === undefined ? {} : { className })}
|
||||
{...(loading === undefined ? {} : { loading })}
|
||||
data-animated={frame !== undefined && frame !== src ? 'static' : 'animated'}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user