Files
llink/js/src/features/compose/controls-indicator.tsx
T
Arjun PatelandGitHub 4b66d8e185 feat: initial conversational flow (#37)
* chore: only set visibility for container particles

* create reusable controls indicator for reply or new

* compress the size of top bar

* refactor: restructure state, routing, and more

* introduce stream compose flow

* feat: compose new stream full flow

* implement stream player

* fix: prevent redirect for signed object urls

* fix: implement stream playback cleaner structure

* refactor: layout file name

* feat: show stream name in breadcrumbs

* chore: tweak padding

* chore: adjust position of audio bars

* feat: show latest particle preview in stream list

* fix: remove console log

* refactor: reorder classes

* fix: avoid passing in updated_at to firestore particle

* refactor: extract properties for container particles to flat fields in firestore

* make the stream previews look alive

* feat: show audio bars during audio clip playback

* feat: order streams by last child creation

* feat: playback where I left off

* chore: remove unused store

* fix: recording mode not using shared state

* chore: clean unused variable

* remove unused imports

* fix: improve controls indicator immersion

* feat: show playback progress in bar & auto-play text

* feat: auto-exit stream on playback completion

* fix: jittery media playback progress

* fix: navigate during state change is invalid with react router

* fix: buggy exit progress when changing clips

* feat: add app icon

* update package.json info

* feat: only show streams visible to me

* feat: show seen indicator on particles

* fix: prevent unnecessary effects

* fix: play new particle after playback is ended

* use contols indicator for exit timer
2026-03-19 16:29:40 -07:00

70 lines
2.0 KiB
TypeScript

import { Video, Mic } from "lucide-react";
import { cn } from "@/lib/utils";
import { useMediaSettingsStore } from "@/stores/media-settings-store";
import { Button } from "@/components/ui/button";
import { PropsWithChildren } from "react";
interface ControlsIndicatorProps extends PropsWithChildren {
type: "reply" | "new";
}
export default function ControlsIndicator({ type, children }: ControlsIndicatorProps) {
const recordingMode = useMediaSettingsStore((s) => s.recordingMode);
const setRecordingMode = useMediaSettingsStore((s) => s.setRecordingMode);
return (
<div className="flex items-center gap-2 text-xs rounded-full pl-1 pr-3 py-1 bg-black/30 backdrop-blur-sm m-2">
<Button
onClick={() =>
setRecordingMode(recordingMode === "video" ? "audio" : "video")
}
title={
recordingMode === "video"
? "Switch to audio-only"
: "Switch to video"
}
variant="secondary"
className={cn(
"text-xs rounded-full",
"text-muted-foreground hover:text-white/90",
)}
>
{recordingMode === "video" ? (
<>
<Video className="h-3.5 w-3.5" />
<p>Video</p>
</>
) : (
<>
<Mic className="h-3.5 w-3.5" />
<span>Audio</span>
</>
)}
</Button>
{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
className={cn(
"bg-muted rounded px-1.5 py-0.5 font-mono",
)}
>
`
</kbd>{" "}
to {type === "reply" ? "reply " : "start "}
· Press{" "}
<kbd
className={cn(
"bg-muted rounded px-1.5 py-0.5 font-mono",
)}
>
T
</kbd>{" "}
for text
</div>
</div>
);
}