From e89966435a6eba789df44ce3fd8d64d8dae8c4c1 Mon Sep 17 00:00:00 2001 From: devsyncwrld Date: Mon, 31 Aug 2026 13:54:00 -0300 Subject: [PATCH] fix(soundboard): read MANAGE_SPACE from the space bitfield MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The add-sound control was gated on channelPermissions, which carries the per-channel bitfield; MANAGE_SPACE lives in the space-level one. The check silently evaluated false for everybody, including owners, so the button never rendered and there was no way to add a sound at all. Also raise the clip cap to 2 MB — a 30-second clip at a high bitrate cleared 1 MB — and stop reporting every upload failure as 'too large', which sent people to shrink a file that was not the problem. --- packages/web/src/components/voice/SoundboardPopover.tsx | 6 ++++-- packages/web/src/components/voice/VoiceControls.tsx | 6 +++++- packages/web/src/i18n/locales/en.ts | 3 ++- packages/web/src/i18n/locales/pt-BR.ts | 3 ++- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/web/src/components/voice/SoundboardPopover.tsx b/packages/web/src/components/voice/SoundboardPopover.tsx index 24e24054..8aed4846 100644 --- a/packages/web/src/components/voice/SoundboardPopover.tsx +++ b/packages/web/src/components/voice/SoundboardPopover.tsx @@ -12,7 +12,7 @@ interface SoundboardPopoverProps { } /** Clips are short gags; anything larger is a music file in disguise. */ -const MAX_SOUND_BYTES = 1024 * 1024; +const MAX_SOUND_BYTES = 2 * 1024 * 1024; export function SoundboardPopover({ spaceId, canManage, onClose }: SoundboardPopoverProps) { const t = useT(); @@ -66,7 +66,9 @@ export function SoundboardPopover({ spaceId, canManage, onClose }: SoundboardPop const created = await api.soundboard.add(spaceId, name, filename); setSounds((prev) => [...prev, created]); } catch { - setError(t('soundboard.tooLarge')); + // Distinct from the size check above: reporting every failure as "too + // large" sends people to shrink a file that was never the problem. + setError(t('soundboard.uploadFailed')); } finally { setUploading(false); if (fileRef.current) fileRef.current.value = ''; diff --git a/packages/web/src/components/voice/VoiceControls.tsx b/packages/web/src/components/voice/VoiceControls.tsx index 1a6d2cf7..198d20e9 100644 --- a/packages/web/src/components/voice/VoiceControls.tsx +++ b/packages/web/src/components/voice/VoiceControls.tsx @@ -39,6 +39,10 @@ export function VoiceControls() { const activeDmCall = useVoiceStore((s) => s.activeDmCall); const channelPerms = useSpaceStore((s) => currentVoiceChannelId ? s.channelPermissions.get(currentVoiceChannelId) : undefined); + // MANAGE_SPACE lives in the space-level bitfield, not the per-channel one — + // reading it from channelPermissions silently yielded false for everyone. + const spacePerms = useSpaceStore((s) => currentVoiceSpaceId ? s.spacePermissions.get(currentVoiceSpaceId) : undefined); + const canManageSpace = hasPermissionBit(spacePerms, PermissionBits.MANAGE_SPACE); // In DM calls, all permissions are granted; in space channels, check SPEAK and STREAM const isDmCall = !!activeDmCall; @@ -128,7 +132,7 @@ export function VoiceControls() { {showSoundboard && currentVoiceSpaceId && ( setShowSoundboard(false)} /> )} diff --git a/packages/web/src/i18n/locales/en.ts b/packages/web/src/i18n/locales/en.ts index f5bc413d..14461441 100644 --- a/packages/web/src/i18n/locales/en.ts +++ b/packages/web/src/i18n/locales/en.ts @@ -41,7 +41,8 @@ export const en = { 'soundboard.remove': 'Remove', 'soundboard.namePrompt': 'Name for this sound', 'soundboard.joinFirst': 'Join a voice channel to use the soundboard.', - 'soundboard.tooLarge': 'Sound must be under 1 MB and a few seconds long.', + 'soundboard.tooLarge': 'Sound must be under 2 MB and a few seconds long.', + 'soundboard.uploadFailed': 'Could not upload that file. Try a different one.', // Account menu (own name in the user bar) 'accountMenu.editProfile': 'Edit Profile', diff --git a/packages/web/src/i18n/locales/pt-BR.ts b/packages/web/src/i18n/locales/pt-BR.ts index 3a4ae689..8e0b2f5b 100644 --- a/packages/web/src/i18n/locales/pt-BR.ts +++ b/packages/web/src/i18n/locales/pt-BR.ts @@ -40,7 +40,8 @@ export const ptBR: Partial = { 'soundboard.remove': 'Remover', 'soundboard.namePrompt': 'Nome deste som', 'soundboard.joinFirst': 'Entre num canal de voz para usar o soundboard.', - 'soundboard.tooLarge': 'O som precisa ter menos de 1 MB e poucos segundos.', + 'soundboard.tooLarge': 'O som precisa ter menos de 2 MB e poucos segundos.', + 'soundboard.uploadFailed': 'Não foi possível enviar esse arquivo. Tente outro.', // Menu da conta (próprio nome na barra de usuário) 'accountMenu.editProfile': 'Editar perfil',