104 lines
3.0 KiB
TypeScript
104 lines
3.0 KiB
TypeScript
"use client";
|
|
|
|
// Press-to-play / press-to-view preview for uploaded assets.
|
|
// - audio: a play button that toggles a compact inline <audio> player.
|
|
// - video: a button that opens the video in a modal player.
|
|
// - image: a thumbnail that opens the full image in a modal.
|
|
// Renders a muted dash when no source is available.
|
|
|
|
import { useState } from "react";
|
|
import { Modal } from "./ui";
|
|
import { PlayIcon, PauseIcon, EyeIcon } from "./icons";
|
|
|
|
type Kind = "audio" | "video" | "image";
|
|
|
|
export function MediaPreview({
|
|
src,
|
|
kind,
|
|
label,
|
|
}: {
|
|
src?: string | null;
|
|
kind: Kind;
|
|
label?: string;
|
|
}) {
|
|
const [audioOpen, setAudioOpen] = useState(false);
|
|
const [modalOpen, setModalOpen] = useState(false);
|
|
|
|
if (!src) return <span className="text-muted">—</span>;
|
|
|
|
if (kind === "audio") {
|
|
return (
|
|
<div className="flex items-center gap-2">
|
|
<button
|
|
type="button"
|
|
onClick={() => setAudioOpen((v) => !v)}
|
|
className="inline-flex h-8 w-8 items-center justify-center rounded-full bg-primary-soft text-primary transition hover:bg-primary hover:text-white"
|
|
aria-label={audioOpen ? "توقف" : "پخش"}
|
|
>
|
|
{audioOpen ? (
|
|
<PauseIcon className="h-4 w-4" />
|
|
) : (
|
|
<PlayIcon className="h-4 w-4" />
|
|
)}
|
|
</button>
|
|
{audioOpen && (
|
|
// eslint-disable-next-line jsx-a11y/media-has-caption
|
|
<audio
|
|
src={src}
|
|
controls
|
|
autoPlay
|
|
className="h-8 max-w-[220px]"
|
|
onEnded={() => setAudioOpen(false)}
|
|
/>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (kind === "image") {
|
|
return (
|
|
<>
|
|
<button
|
|
type="button"
|
|
onClick={() => setModalOpen(true)}
|
|
className="block overflow-hidden rounded-lg border border-border transition hover:opacity-80"
|
|
aria-label="نمایش تصویر"
|
|
>
|
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
<img src={src} alt={label ?? ""} className="h-12 w-12 object-cover" />
|
|
</button>
|
|
<Modal
|
|
open={modalOpen}
|
|
onClose={() => setModalOpen(false)}
|
|
title={label ?? "تصویر"}
|
|
>
|
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
<img src={src} alt={label ?? ""} className="mx-auto max-h-[70vh] rounded-lg" />
|
|
</Modal>
|
|
</>
|
|
);
|
|
}
|
|
|
|
// video
|
|
return (
|
|
<>
|
|
<button
|
|
type="button"
|
|
onClick={() => setModalOpen(true)}
|
|
className="inline-flex h-8 w-8 items-center justify-center rounded-full bg-primary-soft text-primary transition hover:bg-primary hover:text-white"
|
|
aria-label="نمایش ویدیو"
|
|
>
|
|
<EyeIcon className="h-4 w-4" />
|
|
</button>
|
|
<Modal
|
|
open={modalOpen}
|
|
onClose={() => setModalOpen(false)}
|
|
title={label ?? "ویدیو"}
|
|
>
|
|
{/* eslint-disable-next-line jsx-a11y/media-has-caption */}
|
|
<video src={src} controls autoPlay className="w-full rounded-lg" />
|
|
</Modal>
|
|
</>
|
|
);
|
|
}
|