fix: voice call settings show while calls are not allowed (#32975)

The Voice section in Settings > Interface, with voice interruption and emoji in call, showed to users without the call permission, who cannot start a call. The section now only shows to users who can make calls, and the settings search skips it for everyone else.

Refs #32830

Co-authored-by: Tim Baek <tim@openwebui.com>
This commit is contained in:
Classic298 2026-10-24 04:25:36 +02:00 • committed by GitHub
parent f31bdacae1
commit d48b5e1c87
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 58 additions and 48 deletions

View file

@ -1,5 +1,6 @@
<script lang="ts">
import {
canUseCalls,
canUseChannels,
canUseTemporaryChats,
canUseWebSearch,
@ -1975,59 +1976,61 @@
</p>
</div>
<div class={sectionHeadingClass}>
{$i18n.t('settings.personal.interface.sections.voice.title')}
</div>
<div>
<div class={settingRowClass}>
<label
class={settingLabelClass}
id="allow-voice-interruption-in-call-label"
for="allow-voice-interruption-in-call-label-control"
>
{$i18n.t('settings.personal.interface.allowVoiceInterruptionInCall.label')}
</label>
<div class={settingControlClass}>
<Switch
ariaLabelledbyId="allow-voice-interruption-in-call-label"
tooltip={true}
bind:state={voiceInterruption}
inherited={isDefaultSetting('voiceInterruption')}
on:change={() => {
saveSettings({ voiceInterruption });
}}
/>
</div>
{#if canUseCalls({ user: $user, config: $config })}
<div class={sectionHeadingClass}>
{$i18n.t('settings.personal.interface.sections.voice.title')}
</div>
<p class={settingDescriptionClass}>
{$i18n.t('settings.personal.interface.allowVoiceInterruptionInCall.description')}
</p>
</div>
<div>
<div class={settingRowClass}>
<label id="display-emoji-label" class={settingLabelClass} for="display-emoji-label-control">
{$i18n.t('settings.personal.interface.displayEmojiInCall.label')}
</label>
<div>
<div class={settingRowClass}>
<label
class={settingLabelClass}
id="allow-voice-interruption-in-call-label"
for="allow-voice-interruption-in-call-label-control"
>
{$i18n.t('settings.personal.interface.allowVoiceInterruptionInCall.label')}
</label>
<div class={settingControlClass}>
<Switch
ariaLabelledbyId="display-emoji-label"
tooltip={true}
bind:state={showEmojiInCall}
inherited={isDefaultSetting('showEmojiInCall')}
on:change={() => {
saveSettings({ showEmojiInCall });
}}
/>
<div class={settingControlClass}>
<Switch
ariaLabelledbyId="allow-voice-interruption-in-call-label"
tooltip={true}
bind:state={voiceInterruption}
inherited={isDefaultSetting('voiceInterruption')}
on:change={() => {
saveSettings({ voiceInterruption });
}}
/>
</div>
</div>
<p class={settingDescriptionClass}>
{$i18n.t('settings.personal.interface.allowVoiceInterruptionInCall.description')}
</p>
</div>
<p class={settingDescriptionClass}>
{$i18n.t('settings.personal.interface.displayEmojiInCall.description')}
</p>
</div>
<div>
<div class={settingRowClass}>
<label id="display-emoji-label" class={settingLabelClass} for="display-emoji-label-control">
{$i18n.t('settings.personal.interface.displayEmojiInCall.label')}
</label>
<div class={settingControlClass}>
<Switch
ariaLabelledbyId="display-emoji-label"
tooltip={true}
bind:state={showEmojiInCall}
inherited={isDefaultSetting('showEmojiInCall')}
on:change={() => {
saveSettings({ showEmojiInCall });
}}
/>
</div>
</div>
<p class={settingDescriptionClass}>
{$i18n.t('settings.personal.interface.displayEmojiInCall.description')}
</p>
</div>
{/if}
<div class={sectionHeadingClass}>
{$i18n.t('settings.personal.interface.sections.file.title')}

View file

@ -21,6 +21,8 @@ export const canUseTemporaryChats = ({ user }: SettingsAccessContext) =>
export const canUseChannels = ({ user, config }: SettingsAccessContext) =>
config?.features?.enable_channels &&
(user?.role === 'admin' || (user?.permissions?.features?.channels ?? true));
export const canUseCalls = ({ user }: SettingsAccessContext) =>
user?.role === 'admin' || (user?.permissions?.chat?.call ?? true);
export const canUseWebSearch = ({ user, config }: SettingsAccessContext) =>
config?.features?.enable_web_search &&
(user?.role === 'admin' || user?.permissions?.features?.web_search);
@ -73,6 +75,11 @@ export function canSearchSetting(
return !!canUseTemporaryChats(context);
if (stem === 'settings.personal.interface.compressImagesInChannels')
return !!canUseChannels(context);
if (
key.startsWith('settings.personal.interface.') &&
/\.(sections\.voice|allowVoiceInterruptionInCall|displayEmojiInCall)\./.test(key)
)
return canUseCalls(context);
if (stem === 'settings.personal.interface.webSearchInChat') return !!canUseWebSearch(context);
return true;
}