diff --git a/public/locales/en-GB/app.json b/public/locales/en-GB/app.json index 7a390c2f..a34ab87c 100644 --- a/public/locales/en-GB/app.json +++ b/public/locales/en-GB/app.json @@ -144,6 +144,10 @@ "room_auth_view_eula_caption": "By clicking \"Continue\", you agree to our <2>End User Licensing Agreement (EULA)", "screenshare_button_label": "Share screen", "settings": { + "audio_tab": { + "effect_volume_label": "Sound effect volume", + "effect_volume_description": "Adjust the volume at which reactions and hand raised effects play" + }, "developer_settings_label": "Developer Settings", "developer_settings_label_description": "Expose developer settings in the settings window.", "developer_tab_title": "Developer", diff --git a/src/room/ReactionAudioRenderer.tsx b/src/room/ReactionAudioRenderer.tsx index 12977629..a672e633 100644 --- a/src/room/ReactionAudioRenderer.tsx +++ b/src/room/ReactionAudioRenderer.tsx @@ -8,12 +8,17 @@ Please see LICENSE in the repository root for full details. import { ReactNode, useEffect, useRef } from "react"; import { useReactions } from "../useReactions"; -import { playReactionsSound, useSetting } from "../settings/settings"; +import { + playReactionsSound, + effectSoundVolume as effectSoundVolumeSetting, + useSetting, +} from "../settings/settings"; import { GenericReaction, ReactionSet } from "../reactions"; export function ReactionsAudioRenderer(): ReactNode { const { reactions } = useReactions(); const [shouldPlay] = useSetting(playReactionsSound); + const [effectSoundVolume] = useSetting(effectSoundVolumeSetting); const audioElements = useRef>({}); useEffect(() => { @@ -30,6 +35,7 @@ export function ReactionsAudioRenderer(): ReactNode { const audioElement = audioElements.current[reactionName] ?? audioElements.current.generic; if (audioElement?.paused) { + audioElement.volume = effectSoundVolume; void audioElement.play(); } } diff --git a/src/settings/SettingsModal.module.css b/src/settings/SettingsModal.module.css index b8c2857e..3d8f0cbf 100644 --- a/src/settings/SettingsModal.module.css +++ b/src/settings/SettingsModal.module.css @@ -16,3 +16,20 @@ Please see LICENSE in the repository root for full details. .fieldRowText { margin-bottom: 0; } + +.volumeSlider { + margin-top: var(--cpd-space-2x); +} + +.volumeSlider > label { + margin-bottom: var(--cpd-space-1x); + display: block; +} + +.volumeSlider > span { + max-width: 20em; +} + +.volumeSlider > p { + color: var(--cpd-color-text-secondary); +} diff --git a/src/settings/SettingsModal.tsx b/src/settings/SettingsModal.tsx index db702ef8..8679d739 100644 --- a/src/settings/SettingsModal.tsx +++ b/src/settings/SettingsModal.tsx @@ -8,7 +8,7 @@ Please see LICENSE in the repository root for full details. import { ChangeEvent, FC, ReactNode, useCallback } from "react"; import { Trans, useTranslation } from "react-i18next"; import { MatrixClient } from "matrix-js-sdk/src/matrix"; -import { Dropdown, Text } from "@vector-im/compound-web"; +import { Dropdown, Separator, Text } from "@vector-im/compound-web"; import { Modal } from "../Modal"; import styles from "./SettingsModal.module.css"; @@ -28,9 +28,11 @@ import { developerSettingsTab as developerSettingsTabSetting, duplicateTiles as duplicateTilesSetting, useOptInAnalytics, + effectSoundVolume, } from "./settings"; import { isFirefox } from "../Platform"; import { PreferencesSettingsTab } from "./PreferencesSettingsTab"; +import { Slider } from "../Slider"; type SettingsTab = | "audio" @@ -116,6 +118,8 @@ export const SettingsModal: FC = ({ const devices = useMediaDevices(); useMediaDeviceNames(devices, open); + const [soundVolume, setSoundVolume] = useSetting(effectSoundVolume); + const audioTab: Tab = { key: "audio", name: t("common.audio"), @@ -127,6 +131,19 @@ export const SettingsModal: FC = ({ devices.audioOutput, t("settings.speaker_device_selection_label"), )} + +
+ +

{t("settings.audio_tab.effect_volume_description")}

+ +
), }; diff --git a/src/settings/settings.ts b/src/settings/settings.ts index 09b4dbdc..5f23beb8 100644 --- a/src/settings/settings.ts +++ b/src/settings/settings.ts @@ -100,4 +100,6 @@ export const playReactionsSound = new Setting( true, ); +export const effectSoundVolume = new Setting("effects-sound-volume", 1); + export const alwaysShowSelf = new Setting("always-show-self", true);