mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-07-12 21:02:17 +02:00
remove headphone mode
This commit is contained in:
parent
e9ee8fd975
commit
47941e31b4
4 changed files with 11 additions and 88 deletions
|
|
@ -50,11 +50,12 @@ avatar while off, no webcam frames captured), screen share toggle, mascot ⇄
|
|||
assistant's spoken line run along the bottom. Typing in the composer still
|
||||
works mid-call; frames ride along with typed messages too.
|
||||
|
||||
Outside calls the composer keeps exactly two voice affordances: the **mic
|
||||
button** (push-to-talk dictation, untouched) and the **read-aloud toggle**
|
||||
(headphones; summary-style for typed chat — calls force full read-aloud and
|
||||
restore the prior setting on hang-up). The old video dropdown, talking-head
|
||||
toggle, and summary/full TTS dropdown are retired.
|
||||
Outside calls the composer keeps exactly one voice affordance: the **mic
|
||||
button** (push-to-talk dictation, untouched). Spoken responses exist only
|
||||
inside calls (forced full read-aloud, off on hang-up). The old video
|
||||
dropdown, talking-head toggle, read-aloud headphones toggle, and summary/full
|
||||
TTS dropdown are all retired — a per-message "read aloud" action on assistant
|
||||
messages is the planned replacement for text-in/voice-out.
|
||||
|
||||
The call button is disabled unless both voice input (Deepgram) and voice
|
||||
output (TTS) are configured. `call_started` (with `preset`) is captured in
|
||||
|
|
|
|||
|
|
@ -970,7 +970,8 @@ function App() {
|
|||
// Voice mode state
|
||||
const [voiceAvailable, setVoiceAvailable] = useState(false)
|
||||
const [ttsAvailable, setTtsAvailable] = useState(false)
|
||||
const [ttsEnabled, setTtsEnabled] = useState(false)
|
||||
// TTS plays only during calls now (the standing read-aloud toggle was
|
||||
// retired; a per-message "read aloud" action may replace it later).
|
||||
const ttsEnabledRef = useRef(false)
|
||||
// Read-aloud style: 'summary' for typed chat, forced to 'full' during a
|
||||
// call and restored after. Context decides — the user never picks it.
|
||||
|
|
@ -1032,8 +1033,6 @@ function App() {
|
|||
// Practice preset: adds the coaching persona to the system prompt.
|
||||
const [practiceMode, setPracticeMode] = useState(false)
|
||||
const practiceModeRef = useRef(false)
|
||||
// TTS settings to restore when a call ends (a call forces full read-aloud).
|
||||
const preCallTtsRef = useRef<{ enabled: boolean; mode: 'summary' | 'full' } | null>(null)
|
||||
|
||||
const handleToggleMeetingRef = useRef<(() => void) | undefined>(undefined)
|
||||
const meetingTranscription = useMeetingTranscription(() => {
|
||||
|
|
@ -1119,17 +1118,6 @@ function App() {
|
|||
}
|
||||
}, [voice])
|
||||
|
||||
const handleToggleTts = useCallback(() => {
|
||||
setTtsEnabled(prev => {
|
||||
const next = !prev
|
||||
ttsEnabledRef.current = next
|
||||
if (!next) {
|
||||
ttsRef.current.cancel()
|
||||
}
|
||||
return next
|
||||
})
|
||||
}, [])
|
||||
|
||||
const handleCancelRecording = useCallback(() => {
|
||||
voice.cancel()
|
||||
setIsRecording(false)
|
||||
|
|
@ -1169,8 +1157,6 @@ function App() {
|
|||
setIsRecording(false)
|
||||
isRecordingRef.current = false
|
||||
}
|
||||
preCallTtsRef.current = { enabled: ttsEnabledRef.current, mode: ttsModeRef.current }
|
||||
setTtsEnabled(true)
|
||||
ttsEnabledRef.current = true
|
||||
ttsModeRef.current = 'full'
|
||||
void voiceRef.current.startContinuous((text) => {
|
||||
|
|
@ -1190,15 +1176,9 @@ function App() {
|
|||
const endCall = useCallback(() => {
|
||||
if (!inCallRef.current) return
|
||||
voiceRef.current.cancel()
|
||||
const saved = preCallTtsRef.current
|
||||
preCallTtsRef.current = null
|
||||
const restoreEnabled = saved?.enabled ?? false
|
||||
setTtsEnabled(restoreEnabled)
|
||||
ttsEnabledRef.current = restoreEnabled
|
||||
if (saved) {
|
||||
ttsModeRef.current = saved.mode
|
||||
}
|
||||
if (!restoreEnabled) ttsRef.current.cancel()
|
||||
ttsEnabledRef.current = false
|
||||
ttsModeRef.current = 'summary'
|
||||
ttsRef.current.cancel()
|
||||
video.stop()
|
||||
setPracticeMode(false)
|
||||
practiceModeRef.current = false
|
||||
|
|
@ -6553,9 +6533,6 @@ function App() {
|
|||
onSubmitRecording={isActive ? handleSubmitRecording : undefined}
|
||||
onCancelRecording={isActive ? handleCancelRecording : undefined}
|
||||
voiceAvailable={isActive && voiceAvailable}
|
||||
ttsAvailable={isActive && ttsAvailable}
|
||||
ttsEnabled={ttsEnabled}
|
||||
onToggleTts={isActive ? handleToggleTts : undefined}
|
||||
inCall={inCall}
|
||||
onStartCall={isActive ? startCall : undefined}
|
||||
onEndCall={isActive ? endCall : undefined}
|
||||
|
|
@ -6666,9 +6643,6 @@ function App() {
|
|||
onSubmitRecording={handleSubmitRecording}
|
||||
onCancelRecording={handleCancelRecording}
|
||||
voiceAvailable={voiceAvailable}
|
||||
ttsAvailable={ttsAvailable}
|
||||
ttsEnabled={ttsEnabled}
|
||||
onToggleTts={handleToggleTts}
|
||||
inCall={inCall}
|
||||
onStartCall={startCall}
|
||||
onEndCall={endCall}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import {
|
|||
FolderCog,
|
||||
FolderOpen,
|
||||
Globe,
|
||||
Headphones,
|
||||
ImagePlus,
|
||||
LoaderIcon,
|
||||
Lock,
|
||||
|
|
@ -246,9 +245,6 @@ interface ChatInputInnerProps {
|
|||
onSubmitRecording?: () => void | Promise<void>
|
||||
onCancelRecording?: () => void
|
||||
voiceAvailable?: boolean
|
||||
ttsAvailable?: boolean
|
||||
ttsEnabled?: boolean
|
||||
onToggleTts?: () => void
|
||||
/** A call is live (hands-free voice loop + spoken responses). */
|
||||
inCall?: boolean
|
||||
/** Start a call with the given preset's device defaults. */
|
||||
|
|
@ -289,9 +285,6 @@ function ChatInputInner({
|
|||
onSubmitRecording,
|
||||
onCancelRecording,
|
||||
voiceAvailable,
|
||||
ttsAvailable,
|
||||
ttsEnabled,
|
||||
onToggleTts,
|
||||
inCall,
|
||||
onStartCall,
|
||||
onEndCall,
|
||||
|
|
@ -1294,33 +1287,6 @@ function ChatInputInner({
|
|||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
) : null}
|
||||
{onToggleTts && ttsAvailable && (
|
||||
<Tooltip delayDuration={CHAT_INPUT_TOOLTIP_DELAY_MS}>
|
||||
<TooltipTrigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onToggleTts}
|
||||
className={cn(
|
||||
'relative flex h-7 w-7 shrink-0 items-center justify-center rounded-full transition-colors',
|
||||
ttsEnabled
|
||||
? 'text-foreground hover:bg-muted'
|
||||
: 'text-muted-foreground hover:bg-muted hover:text-foreground'
|
||||
)}
|
||||
aria-label={ttsEnabled ? 'Disable read-aloud' : 'Enable read-aloud'}
|
||||
>
|
||||
<Headphones className="h-4 w-4" />
|
||||
{!ttsEnabled && (
|
||||
<span className="absolute inset-0 flex items-center justify-center pointer-events-none">
|
||||
<span className="block h-[1.5px] w-5 -rotate-45 rounded-full bg-muted-foreground" />
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="top">
|
||||
{ttsEnabled ? 'Read responses aloud: on' : 'Read responses aloud: off'}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
)}
|
||||
{onStartCall && (
|
||||
<div className="flex shrink-0 items-center">
|
||||
<Tooltip delayDuration={CHAT_INPUT_TOOLTIP_DELAY_MS}>
|
||||
|
|
@ -1555,9 +1521,6 @@ export interface ChatInputWithMentionsProps {
|
|||
onSubmitRecording?: () => void | Promise<void>
|
||||
onCancelRecording?: () => void
|
||||
voiceAvailable?: boolean
|
||||
ttsAvailable?: boolean
|
||||
ttsEnabled?: boolean
|
||||
onToggleTts?: () => void
|
||||
inCall?: boolean
|
||||
onStartCall?: (preset: CallPreset) => void
|
||||
onEndCall?: () => void
|
||||
|
|
@ -1591,9 +1554,6 @@ export function ChatInputWithMentions({
|
|||
onSubmitRecording,
|
||||
onCancelRecording,
|
||||
voiceAvailable,
|
||||
ttsAvailable,
|
||||
ttsEnabled,
|
||||
onToggleTts,
|
||||
inCall,
|
||||
onStartCall,
|
||||
onEndCall,
|
||||
|
|
@ -1624,9 +1584,6 @@ export function ChatInputWithMentions({
|
|||
onSubmitRecording={onSubmitRecording}
|
||||
onCancelRecording={onCancelRecording}
|
||||
voiceAvailable={voiceAvailable}
|
||||
ttsAvailable={ttsAvailable}
|
||||
ttsEnabled={ttsEnabled}
|
||||
onToggleTts={onToggleTts}
|
||||
inCall={inCall}
|
||||
onStartCall={onStartCall}
|
||||
onEndCall={onEndCall}
|
||||
|
|
|
|||
|
|
@ -187,9 +187,6 @@ interface ChatSidebarProps {
|
|||
onSubmitRecording?: () => void | Promise<void>
|
||||
onCancelRecording?: () => void
|
||||
voiceAvailable?: boolean
|
||||
ttsAvailable?: boolean
|
||||
ttsEnabled?: boolean
|
||||
onToggleTts?: () => void
|
||||
inCall?: boolean
|
||||
onStartCall?: (preset: CallPreset) => void
|
||||
onEndCall?: () => void
|
||||
|
|
@ -253,9 +250,6 @@ export function ChatSidebar({
|
|||
onSubmitRecording,
|
||||
onCancelRecording,
|
||||
voiceAvailable,
|
||||
ttsAvailable,
|
||||
ttsEnabled,
|
||||
onToggleTts,
|
||||
inCall,
|
||||
onStartCall,
|
||||
onEndCall,
|
||||
|
|
@ -829,9 +823,6 @@ export function ChatSidebar({
|
|||
onSubmitRecording={isActive ? onSubmitRecording : undefined}
|
||||
onCancelRecording={isActive ? onCancelRecording : undefined}
|
||||
voiceAvailable={isActive && voiceAvailable}
|
||||
ttsAvailable={isActive && ttsAvailable}
|
||||
ttsEnabled={ttsEnabled}
|
||||
onToggleTts={isActive ? onToggleTts : undefined}
|
||||
inCall={inCall}
|
||||
onStartCall={isActive ? onStartCall : undefined}
|
||||
onEndCall={isActive ? onEndCall : undefined}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue