mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
feat(dictation): ⌘D push-to-talk, stop button icon when recording
- ⌘D is now push-to-talk: hold to record, release to stop. AppShell dispatches keydown/keyup events; useComposerDictation starts on keydown and stops on keyup. - Button click still toggles (click mic to start, click stop to end). - Mic icon swaps to a filled stop square while recording. - Shortcut description updated to reflect hold-to-talk behavior.
This commit is contained in:
@@ -597,7 +597,7 @@ export function AppShell() {
|
||||
|
||||
if (key === "d" && !event.shiftKey) {
|
||||
event.preventDefault();
|
||||
window.dispatchEvent(new CustomEvent("buzz:toggle-dictation"));
|
||||
window.dispatchEvent(new CustomEvent("buzz:dictation-key-down"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -608,9 +608,17 @@ export function AppShell() {
|
||||
}
|
||||
}
|
||||
|
||||
function handleKeyUp(event: KeyboardEvent) {
|
||||
if (event.key.toLowerCase() === "d") {
|
||||
window.dispatchEvent(new CustomEvent("buzz:dictation-key-up"));
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
window.addEventListener("keyup", handleKeyUp);
|
||||
return () => {
|
||||
window.removeEventListener("keydown", handleKeyDown);
|
||||
window.removeEventListener("keyup", handleKeyUp);
|
||||
};
|
||||
}, [
|
||||
handleOpenBrowseChannels,
|
||||
|
||||
@@ -71,16 +71,31 @@ export function useComposerDictation({
|
||||
}
|
||||
}, [disabled, dictation.isRecording, dictation.cancelRecording]);
|
||||
|
||||
// ⌘D global shortcut — dispatched from AppShell's keydown handler.
|
||||
// ⌘D push-to-talk — hold to record, release to stop.
|
||||
// Dispatched from AppShell's keydown/keyup handlers.
|
||||
useEffect(() => {
|
||||
function handleToggle() {
|
||||
dictation.toggleRecording();
|
||||
function handleKeyDown() {
|
||||
if (!dictation.isRecording && !dictation.isStarting) {
|
||||
dictation.startRecording();
|
||||
}
|
||||
}
|
||||
window.addEventListener("buzz:toggle-dictation", handleToggle);
|
||||
function handleKeyUp() {
|
||||
if (dictation.isRecording || dictation.isStarting) {
|
||||
dictation.stopRecording();
|
||||
}
|
||||
}
|
||||
window.addEventListener("buzz:dictation-key-down", handleKeyDown);
|
||||
window.addEventListener("buzz:dictation-key-up", handleKeyUp);
|
||||
return () => {
|
||||
window.removeEventListener("buzz:toggle-dictation", handleToggle);
|
||||
window.removeEventListener("buzz:dictation-key-down", handleKeyDown);
|
||||
window.removeEventListener("buzz:dictation-key-up", handleKeyUp);
|
||||
};
|
||||
}, [dictation.toggleRecording]);
|
||||
}, [
|
||||
dictation.isRecording,
|
||||
dictation.isStarting,
|
||||
dictation.startRecording,
|
||||
dictation.stopRecording,
|
||||
]);
|
||||
|
||||
return dictation;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Mic } from "lucide-react";
|
||||
import { Mic, Square } from "lucide-react";
|
||||
import { Button } from "@/shared/ui/button";
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "@/shared/ui/tooltip";
|
||||
import { cn } from "@/shared/lib/cn";
|
||||
@@ -51,7 +51,11 @@ export function DictationButton({
|
||||
type="button"
|
||||
variant={dictation.isRecording ? "default" : "ghost"}
|
||||
>
|
||||
<Mic />
|
||||
{dictation.isRecording ? (
|
||||
<Square className="h-3.5 w-3.5 fill-current" />
|
||||
) : (
|
||||
<Mic />
|
||||
)}
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
|
||||
@@ -184,7 +184,7 @@ export const KEYBOARD_SHORTCUTS: KeyboardShortcut[] = [
|
||||
{
|
||||
id: "voice-dictation",
|
||||
label: "Voice Dictation",
|
||||
description: "Start or stop voice dictation in the composer",
|
||||
description: "Hold to dictate, release to stop (push-to-talk)",
|
||||
keys: "⌘D",
|
||||
keysWindows: "Ctrl+D",
|
||||
category: "Messages",
|
||||
|
||||
Reference in New Issue
Block a user