diff --git a/src/apps/chat/components/composer/Composer.tsx b/src/apps/chat/components/composer/Composer.tsx index df5ffa9f5..7b51702b8 100644 --- a/src/apps/chat/components/composer/Composer.tsx +++ b/src/apps/chat/components/composer/Composer.tsx @@ -658,6 +658,7 @@ export function Composer(props: { const showChatInReferenceTo = !!inReferenceTo?.length; const showChatExtras = isText && !showChatInReferenceTo && !assistantAbortible && composerQuickButton !== 'off'; + const speechMayWork = browserSpeechRecognitionCapability().mayWork; const sendButtonVariant: VariantProp = (isAppend || (isMobile && isTextBeam)) ? 'outlined' : 'solid'; @@ -964,7 +965,7 @@ export function Composer(props: { {/* [mobile] bottom-corner secondary button */} {isMobile && (showChatExtras - ? (composerQuickButton === 'call' + ? (composerQuickButton === 'call' && speechMayWork ? : ) : isDraw @@ -1055,8 +1056,8 @@ export function Composer(props: { {/* [desktop] secondary bottom-buttons (aligned to bottom for now, and mutually exclusive) */} {isDesktop && - {/* [desktop] Call secondary button */} - {showChatExtras && } + {/* [desktop] Call secondary button - hidden when speech recognition is not available */} + {showChatExtras && speechMayWork && } {/* [desktop] Draw Options secondary button */} {isDraw && } diff --git a/src/common/components/speechrecognition/useSpeechRecognition.ts b/src/common/components/speechrecognition/useSpeechRecognition.ts index ca556fa19..54a0336a4 100644 --- a/src/common/components/speechrecognition/useSpeechRecognition.ts +++ b/src/common/components/speechrecognition/useSpeechRecognition.ts @@ -18,13 +18,17 @@ let cachedCapability: CapabilityBrowserSpeechRecognition | null = null; export const browserSpeechRecognitionCapability = (): CapabilityBrowserSpeechRecognition => { if (!cachedCapability) { - const isApiAvailable = !!getSpeechRecognitionClass(); + const isBraveBlocked = Is.Browser.Brave; // Brave exposes the API but silently blocks results + const isApiAvailable = !!getSpeechRecognitionClass() && !isBraveBlocked; const isDeviceNotSupported = false; cachedCapability = { mayWork: isApiAvailable && !isDeviceNotSupported, isApiAvailable, isDeviceNotSupported, - warnings: Is.OS.iOS ? ['Not tested on this browser/device.'] : [], + warnings: [ + ...Is.OS.iOS ? ['Not tested on this browser/device.'] : [], + ...isBraveBlocked ? ['Speech recognition is not supported in Brave. Please use Chrome, Edge, or Safari.'] : [], + ], }; } return cachedCapability; diff --git a/src/common/util/pwaUtils.ts b/src/common/util/pwaUtils.ts index c5af2f490..176ede929 100644 --- a/src/common/util/pwaUtils.ts +++ b/src/common/util/pwaUtils.ts @@ -11,6 +11,7 @@ const _safeUA = isBrowser ? window.navigator?.userAgent.toLowerCase() || '' : '' export const Is = { Desktop: !/mobile|android|iphone|ipad|ipod/.test(_safeUA), Browser: { + Brave: isBrowser && !!(navigator as any).brave, Chrome: _safeUA.includes('chrome') || _safeUA.includes('crios'), get Safari() { return _safeUA.includes('safari') && !this.Chrome && !_safeUA.includes('chromium');