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');