- cards com moldura de navegador (endereco real) e brilho na cor do site no card que toca - um video por vez: o do card sob o mouse/foco, ou o mais perto do centro da tela; nada baixa antes de tocar, e um botao pausa os videos que se mexem sozinhos - janela ampliada em <dialog> nativo: troca computador/celular mantendo o ponto do site, capitulos clicaveis, controles proprios, setas entre projetos e foco devolvido ao fechar - dados e capitulos de cada projeto em lib/project-showcase.ts (substitui project-videos.ts) Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
80 lines
2.4 KiB
TypeScript
80 lines
2.4 KiB
TypeScript
"use client";
|
|
|
|
import type { CSSProperties } from "react";
|
|
import { useReducedMotion } from "@/app/hooks/useReducedMotion";
|
|
import { getProjectVideo, getShowcaseConfig } from "@/lib/project-showcase";
|
|
import { ProjectVideo } from "../ProjectVideo";
|
|
import { BrowserFrame, displayUrl } from "./BrowserFrame";
|
|
import { useShowcaseCard } from "./ShowcaseProvider";
|
|
|
|
/**
|
|
* Capa do card com vídeo: o vídeo dentro de uma moldura de navegador, com brilho da cor do site quando é o
|
|
* card que toca, e o botão que amplia (a tela inteira é o botão).
|
|
*/
|
|
export function ProjectMedia({
|
|
project,
|
|
}: {
|
|
project: {
|
|
id: string;
|
|
title: string;
|
|
demoUrl?: string | null;
|
|
githubUrl?: string | null;
|
|
};
|
|
}) {
|
|
const { frameRef, active, open, userPaused, toggleAutoplay } =
|
|
useShowcaseCard(project.id);
|
|
const reducedMotion = useReducedMotion();
|
|
const video = getProjectVideo(project.id);
|
|
const config = getShowcaseConfig(project.id);
|
|
if (!video || !config) return null;
|
|
|
|
return (
|
|
<div
|
|
ref={frameRef}
|
|
className="ds-frame"
|
|
data-active={active}
|
|
style={{ "--accent": config.accent } as CSSProperties}
|
|
>
|
|
<BrowserFrame url={displayUrl(project)}>
|
|
<div
|
|
className="ds-frame-screen"
|
|
style={{ backgroundImage: `url(${video.poster})` }}
|
|
>
|
|
<ProjectVideo video={video} title={project.title} active={active} />
|
|
<button
|
|
type="button"
|
|
className="ds-frame-expand"
|
|
onClick={open}
|
|
aria-haspopup="dialog"
|
|
aria-label={`Ampliar o vídeo de ${project.title}`}
|
|
>
|
|
<span className="ds-frame-chip" aria-hidden="true">
|
|
Ampliar
|
|
</span>
|
|
</button>
|
|
{!reducedMotion && (
|
|
<button
|
|
type="button"
|
|
className="ds-frame-pause"
|
|
onClick={toggleAutoplay}
|
|
aria-label={
|
|
userPaused
|
|
? "Retomar os vídeos dos projetos"
|
|
: "Pausar os vídeos dos projetos"
|
|
}
|
|
>
|
|
<svg viewBox="0 0 16 16" aria-hidden="true">
|
|
{userPaused ? (
|
|
<path d="M4 2.5v11l9-5.5z" />
|
|
) : (
|
|
<path d="M4 3h3v10H4zM9 3h3v10H9z" />
|
|
)}
|
|
</svg>
|
|
</button>
|
|
)}
|
|
</div>
|
|
</BrowserFrame>
|
|
</div>
|
|
);
|
|
}
|