enhance stream view
This commit is contained in:
@@ -43,7 +43,6 @@ export default function ControlsIndicator({ type, children }: ControlsIndicatorP
|
||||
{children ? <div className="flex-1">{children}</div> :
|
||||
<div className="flex-1" />
|
||||
}
|
||||
{children && <span className="text-muted-foreground">·</span>}
|
||||
<div className="text-muted-foreground">
|
||||
Hold{" "}
|
||||
<kbd
|
||||
|
||||
@@ -29,14 +29,14 @@ export function PlaybackPageIndicator({
|
||||
{/* Dim track */}
|
||||
<div
|
||||
className={cn(
|
||||
"absolute inset-x-0 top-1 h-1 rounded-full bg-white/30",
|
||||
"absolute inset-x-0 top-0 h-1 bg-white/30 transition-all",
|
||||
"group-hover:h-1.5 group-hover:top-0.5",
|
||||
)}
|
||||
/>
|
||||
{/* Fill */}
|
||||
<div
|
||||
className={cn(
|
||||
"absolute left-0 top-1 h-1 rounded-full bg-white/90",
|
||||
"absolute left-0 top-0 h-1 bg-white/90 transition-all",
|
||||
"group-hover:h-1.5 group-hover:top-0.5",
|
||||
)}
|
||||
style={{
|
||||
|
||||
@@ -18,6 +18,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { Home, Settings } from "lucide-react";
|
||||
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from "@/components/ui/breadcrumb";
|
||||
import { WindowControls } from "@/components/window-controls";
|
||||
import { formatDistanceToNow } from "@/lib/time-utils";
|
||||
|
||||
function getParticleDisplayName(particle: Particle): string {
|
||||
switch (particle.type) {
|
||||
@@ -367,58 +368,7 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="z-10 absolute left-0 right-0 flex flex-row mt-3 px-2 gap-5 items-center">
|
||||
<WindowControls />
|
||||
|
||||
<Breadcrumb className="no-drag rounded-full bg-black/30 backdrop-blur-sm px-3 py-1 mx-auto">
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem className="text-xs">
|
||||
<BreadcrumbLink
|
||||
className="flex cursor-pointer items-center gap-1"
|
||||
onClick={() => navigate("/")}
|
||||
>
|
||||
<Home className="size-3.5" />
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem className="text-xs">
|
||||
<BreadcrumbLink
|
||||
className="cursor-pointer"
|
||||
onClick={() => navigate(`/${networkId}`)}
|
||||
>
|
||||
<NetworkBreadcrumbContent networkId={networkId} />
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
|
||||
{streamParticle && (
|
||||
<span key={path} className="contents">
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem className="text-xs">
|
||||
<BreadcrumbPage>{getParticleDisplayName(streamParticle)}</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</span>
|
||||
)}
|
||||
|
||||
{currentParticle && (
|
||||
<>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem className="text-xs">
|
||||
<BreadcrumbPage><ParticleBreadcrumbContent particle={currentParticle} /></BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</>
|
||||
)}
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="no-drag text-muted-foreground"
|
||||
onClick={() => navigate("/settings")}
|
||||
>
|
||||
<Settings className="size-3.5" />
|
||||
</Button>
|
||||
</div>
|
||||
<TopBar networkId={networkId} particle={currentParticle} streamParticle={streamParticle} />
|
||||
|
||||
{/* Main playback area */}
|
||||
<div className="flex-1 overflow-hidden">
|
||||
@@ -456,6 +406,65 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
|
||||
);
|
||||
}
|
||||
|
||||
function TopBar({ networkId, particle, streamParticle }: { networkId: string; particle: Particle; streamParticle: Particle & { type: "stream" } }) {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<div className="drag-region z-10 absolute left-0 right-0 flex flex-row mt-3 px-4 gap-5 items-center opacity-0 hover:opacity-100 transition-all">
|
||||
<WindowControls />
|
||||
|
||||
<Breadcrumb className="no-drag rounded-full bg-black/30 backdrop-blur-sm px-3 py-1 mx-auto">
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem className="text-xs">
|
||||
<BreadcrumbLink
|
||||
className="flex cursor-pointer items-center gap-1"
|
||||
onClick={() => navigate("/")}
|
||||
>
|
||||
<Home className="size-3.5" />
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem className="text-xs">
|
||||
<BreadcrumbLink
|
||||
className="cursor-pointer"
|
||||
onClick={() => navigate(`/${networkId}`)}
|
||||
>
|
||||
<NetworkBreadcrumbContent networkId={networkId} />
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
|
||||
{streamParticle && (
|
||||
<>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem className="text-xs">
|
||||
<BreadcrumbPage>{getParticleDisplayName(streamParticle)}</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</>
|
||||
)}
|
||||
|
||||
{particle && (
|
||||
<>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem className="text-xs">
|
||||
<BreadcrumbPage><ParticleBreadcrumbContent particle={particle} /></BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</>
|
||||
)}
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="no-drag text-muted-foreground"
|
||||
onClick={() => navigate("/settings")}
|
||||
>
|
||||
<Settings className="size-3.5" />
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function NetworkBreadcrumbContent({ networkId }: { networkId: string }) {
|
||||
const { data: networks } = useNetworks();
|
||||
const network = networks?.find((n) => n.id === networkId);
|
||||
@@ -480,13 +489,14 @@ function ParticleBreadcrumbContent({ particle }: { particle: Particle }) {
|
||||
const initials = createdByEmail.slice(0, 2).toUpperCase();
|
||||
|
||||
return (
|
||||
<span className="flex items-center gap-1.5">
|
||||
<span className="flex
|
||||
items-center gap-1.5">
|
||||
<Avatar size="sm">
|
||||
<AvatarFallback>
|
||||
{initials}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
{prefix}
|
||||
{prefix} - {formatDistanceToNow(particle.created_at.toISOString())}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user