mirror of https://github.com/buster-so/buster.git
add dictation
This commit is contained in:
parent
8e1b106d9c
commit
d5db629b22
|
@ -172,6 +172,7 @@
|
|||
"react-markdown": "^10.1.0",
|
||||
"react-mentions": "^4.4.10",
|
||||
"react-player": "^3.3.3",
|
||||
"react-speech-recognition": "^4.0.1",
|
||||
"react-textarea-autosize": "^8.5.9",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"scheduler": "^0.26.0",
|
||||
|
@ -210,6 +211,7 @@
|
|||
"@types/react": "catalog:",
|
||||
"@types/react-dom": "catalog:",
|
||||
"@types/react-mentions": "^4.4.1",
|
||||
"@types/react-speech-recognition": "^3.9.6",
|
||||
"@vitejs/plugin-react": "^5.0.3",
|
||||
"@vitest/browser": "3.2.4",
|
||||
"@vitest/coverage-v8": "3.2.4",
|
||||
|
|
|
@ -80,6 +80,7 @@ export const BusterChatInputBase: React.FC<BusterChatInput> = React.memo(
|
|||
disabled={disabled}
|
||||
mode="auto"
|
||||
onModeChange={() => {}}
|
||||
onDictate={() => {}}
|
||||
/>
|
||||
</MentionInputSuggestions>
|
||||
);
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import React from 'react';
|
||||
import type React from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition';
|
||||
import { Button } from '@/components/ui/buttons';
|
||||
import { ArrowUp, Magnifier, Sparkle2 } from '@/components/ui/icons';
|
||||
import Atom from '@/components/ui/icons/NucleoIconOutlined/atom';
|
||||
import Microphone from '@/components/ui/icons/NucleoIconOutlined/microphone';
|
||||
import { Popover } from '@/components/ui/popover';
|
||||
import { AppSegmented, type AppSegmentedProps } from '@/components/ui/segmented';
|
||||
import { Text } from '@/components/ui/typography';
|
||||
|
@ -16,6 +19,7 @@ type BusterChatInputButtons = {
|
|||
disabled: boolean;
|
||||
mode: BusterChatInputMode;
|
||||
onModeChange: (mode: BusterChatInputMode) => void;
|
||||
onDictate: (transcript: string) => void;
|
||||
};
|
||||
|
||||
export const BusterChatInputButtons = ({
|
||||
|
@ -25,15 +29,48 @@ export const BusterChatInputButtons = ({
|
|||
disabled,
|
||||
mode,
|
||||
onModeChange,
|
||||
onDictate,
|
||||
}: BusterChatInputButtons) => {
|
||||
const { transcript, listening, resetTranscript, browserSupportsSpeechRecognition } =
|
||||
useSpeechRecognition();
|
||||
|
||||
const startListening = () => {
|
||||
SpeechRecognition.startListening({ continuous: true });
|
||||
};
|
||||
|
||||
const stopListening = () => {
|
||||
SpeechRecognition.stopListening();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (listening && transcript) {
|
||||
onDictate(transcript);
|
||||
}
|
||||
}, [listening, transcript, onDictate]);
|
||||
|
||||
return (
|
||||
<div className="flex justify-between items-center gap-2">
|
||||
<AppSegmented value={mode} options={modesOptions} onChange={(v) => onModeChange(v.value)} />
|
||||
|
||||
<div>
|
||||
<div className="flex items-center gap-2">
|
||||
{browserSupportsSpeechRecognition && (
|
||||
<Button
|
||||
rounding={'large'}
|
||||
variant={'ghost'}
|
||||
prefix={<Microphone />}
|
||||
onClick={listening ? stopListening : startListening}
|
||||
loading={submitting}
|
||||
disabled={disabled}
|
||||
className={cn(
|
||||
'origin-center transform-gpu transition-all duration-300 ease-out will-change-transform text-text-secondary',
|
||||
!disabled && 'hover:scale-110 active:scale-95',
|
||||
listening && 'bg-item-select text-foreground'
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
<Button
|
||||
rounding={'large'}
|
||||
variant="black"
|
||||
variant={'default'}
|
||||
prefix={<ArrowUp />}
|
||||
onClick={submitting ? onStop : onSubmit}
|
||||
loading={submitting}
|
||||
|
|
|
@ -48,7 +48,6 @@ export const MentionInputSuggestions = ({
|
|||
const commandListNavigatedRef = useRef(false);
|
||||
const commandRef = useRef<HTMLDivElement>(null);
|
||||
const mentionsInputRef = useRef<MentionInputRef>(null);
|
||||
console.log(hasResults);
|
||||
|
||||
const showSuggestionList = !hasClickedSelect && suggestionItems.length > 0;
|
||||
|
||||
|
@ -117,6 +116,8 @@ export const MentionInputSuggestions = ({
|
|||
}
|
||||
}, [showSuggestionList]);
|
||||
|
||||
useImperativeHandle(ref, () => ({}), []);
|
||||
|
||||
return (
|
||||
<Command
|
||||
ref={commandRef}
|
||||
|
|
|
@ -838,6 +838,9 @@ importers:
|
|||
react-player:
|
||||
specifier: ^3.3.3
|
||||
version: 3.3.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
react-speech-recognition:
|
||||
specifier: ^4.0.1
|
||||
version: 4.0.1(react@19.1.1)
|
||||
react-textarea-autosize:
|
||||
specifier: ^8.5.9
|
||||
version: 8.5.9(@types/react@19.1.13)(react@19.1.1)
|
||||
|
@ -947,6 +950,9 @@ importers:
|
|||
'@types/react-mentions':
|
||||
specifier: ^4.4.1
|
||||
version: 4.4.1
|
||||
'@types/react-speech-recognition':
|
||||
specifier: ^3.9.6
|
||||
version: 3.9.6
|
||||
'@vitejs/plugin-react':
|
||||
specifier: ^5.0.3
|
||||
version: 5.0.3(vite@7.1.4(@types/node@24.3.1)(jiti@2.5.1)(lightningcss@1.30.1)(sass@1.93.1)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1))
|
||||
|
@ -6268,6 +6274,9 @@ packages:
|
|||
'@types/doctrine@0.0.9':
|
||||
resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==}
|
||||
|
||||
'@types/dom-speech-recognition@0.0.6':
|
||||
resolution: {integrity: sha512-o7pAVq9UQPJL5RDjO1f/fcpfFHdgiMnR4PoIU2N/ZQrYOS3C5rzdOJMsrpqeBCbii2EE9mERXgqspQqPDdPahw==}
|
||||
|
||||
'@types/eslint-scope@3.7.7':
|
||||
resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==}
|
||||
|
||||
|
@ -6381,6 +6390,9 @@ packages:
|
|||
'@types/react-mentions@4.4.1':
|
||||
resolution: {integrity: sha512-65QdcZYkGe2I4GnOLY2OhlXCGz/Csd8NhytwE5r59CoFeYafMltAE/WqFB/Y6SoPU8LvF7EyUrq6Rxrf0Kzxkg==}
|
||||
|
||||
'@types/react-speech-recognition@3.9.6':
|
||||
resolution: {integrity: sha512-cdzwXIZXWyp8zfM2XI7APDW1rZf4Nz73T4SIS2y+cC7zHnZluCdumYKH6HacxgxJH+zemAq2oXbHWXcyW0eT3A==}
|
||||
|
||||
'@types/react@19.1.13':
|
||||
resolution: {integrity: sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ==}
|
||||
|
||||
|
@ -9513,6 +9525,9 @@ packages:
|
|||
lodash-es@4.17.21:
|
||||
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
|
||||
|
||||
lodash.debounce@4.0.8:
|
||||
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
|
||||
|
||||
lodash.defaults@4.2.0:
|
||||
resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==}
|
||||
|
||||
|
@ -11090,6 +11105,11 @@ packages:
|
|||
'@types/react':
|
||||
optional: true
|
||||
|
||||
react-speech-recognition@4.0.1:
|
||||
resolution: {integrity: sha512-0fIqzLtfY8vuYA6AmJVK7qiabZx0oFKOO+rbiBgFI3COWVGREy0A+gdU16hWXmFebeyrI8JsOLYsWk6WaHUXRw==}
|
||||
peerDependencies:
|
||||
react: '>=16.8.0'
|
||||
|
||||
react-style-singleton@2.2.3:
|
||||
resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
@ -19220,6 +19240,8 @@ snapshots:
|
|||
|
||||
'@types/doctrine@0.0.9': {}
|
||||
|
||||
'@types/dom-speech-recognition@0.0.6': {}
|
||||
|
||||
'@types/eslint-scope@3.7.7':
|
||||
dependencies:
|
||||
'@types/eslint': 9.6.1
|
||||
|
@ -19354,6 +19376,10 @@ snapshots:
|
|||
dependencies:
|
||||
'@types/react': 19.1.13
|
||||
|
||||
'@types/react-speech-recognition@3.9.6':
|
||||
dependencies:
|
||||
'@types/dom-speech-recognition': 0.0.6
|
||||
|
||||
'@types/react@19.1.13':
|
||||
dependencies:
|
||||
csstype: 3.1.3
|
||||
|
@ -22862,6 +22888,8 @@ snapshots:
|
|||
|
||||
lodash-es@4.17.21: {}
|
||||
|
||||
lodash.debounce@4.0.8: {}
|
||||
|
||||
lodash.defaults@4.2.0: {}
|
||||
|
||||
lodash.flattendeep@4.4.0: {}
|
||||
|
@ -25044,6 +25072,11 @@ snapshots:
|
|||
optionalDependencies:
|
||||
'@types/react': 19.1.13
|
||||
|
||||
react-speech-recognition@4.0.1(react@19.1.1):
|
||||
dependencies:
|
||||
lodash.debounce: 4.0.8
|
||||
react: 19.1.1
|
||||
|
||||
react-style-singleton@2.2.3(@types/react@19.1.13)(react@19.1.1):
|
||||
dependencies:
|
||||
get-nonce: 1.0.1
|
||||
|
|
Loading…
Reference in New Issue