Files
llink/js/src/features/streams/particle-preview.tsx
T

94 lines
2.8 KiB
TypeScript

import type { StreamParticle } from "@/api/types";
import { getParticleData } from "@/api/types";
import {
MessageSquare,
Video,
Mic,
ScrollText,
BookOpen,
FileIcon,
FolderIcon,
} from "lucide-react";
interface ParticlePreviewProps {
particle: StreamParticle;
}
export function ParticlePreview({ particle }: ParticlePreviewProps) {
switch (particle.type) {
case "text": {
const data = getParticleData(particle, "text");
return (
<div className="flex items-start gap-2">
<MessageSquare className="text-muted-foreground mt-0.5 h-3.5 w-3.5 shrink-0" />
<p className="text-muted-foreground line-clamp-2 text-xs">
{data.content}
</p>
</div>
);
}
case "media": {
const data = getParticleData(particle, "media");
const isVideo = data.mime_type.startsWith("video");
const Icon = isVideo ? Video : Mic;
const label = isVideo ? "Video" : "Audio";
const seconds = Math.round(data.duration_ms / 1000);
return (
<div className="flex items-center gap-2">
<Icon className="text-muted-foreground h-3.5 w-3.5 shrink-0" />
<span className="text-muted-foreground text-xs">
{label} · {seconds}s
</span>
</div>
);
}
case "quest": {
const data = getParticleData(particle, "quest");
return (
<div className="flex items-center gap-2">
<ScrollText className="text-muted-foreground h-3.5 w-3.5 shrink-0" />
<span className="text-muted-foreground truncate text-xs">
{data.title}
{data.status && ` · ${data.status}`}
</span>
</div>
);
}
case "paper": {
const data = getParticleData(particle, "paper");
return (
<div className="flex items-center gap-2">
<BookOpen className="text-muted-foreground h-3.5 w-3.5 shrink-0" />
<span className="text-muted-foreground truncate text-xs">
{data.title}
</span>
</div>
);
}
case "file": {
const data = getParticleData(particle, "file");
return (
<div className="flex items-center gap-2">
<FileIcon className="text-muted-foreground h-3.5 w-3.5 shrink-0" />
<span className="text-muted-foreground truncate text-xs">
{data.filename}
</span>
</div>
);
}
case "folder": {
const data = getParticleData(particle, "folder");
return (
<div className="flex items-center gap-2">
<FolderIcon className="text-muted-foreground h-3.5 w-3.5 shrink-0" />
<span className="text-muted-foreground truncate text-xs">
{data.name}
</span>
</div>
);
}
default:
return null;
}
}