diff options
-rw-r--r-- | modern/public/alarm.mp3 | bin | 92368 -> 4642 bytes | |||
-rw-r--r-- | modern/src/SocketController.js | 14 | ||||
-rw-r--r-- | modern/src/settings/PreferencesPage.js | 38 |
3 files changed, 51 insertions, 1 deletions
diff --git a/modern/public/alarm.mp3 b/modern/public/alarm.mp3 Binary files differindex ed3e3083..43d3687e 100644 --- a/modern/public/alarm.mp3 +++ b/modern/public/alarm.mp3 diff --git a/modern/src/SocketController.js b/modern/src/SocketController.js index 57ffa0d5..05236971 100644 --- a/modern/src/SocketController.js +++ b/modern/src/SocketController.js @@ -8,6 +8,9 @@ import { useEffectAsync } from './reactHelper'; import { useTranslation } from './common/components/LocalizationProvider'; import { prefixString } from './common/util/stringUtils'; import { snackBarDurationLongMs } from './common/util/duration'; +import usePersistedState from './common/util/usePersistedState'; + +import alarm from '../public/alarm.mp3'; const SocketController = () => { const dispatch = useDispatch(); @@ -22,6 +25,9 @@ const SocketController = () => { const [events, setEvents] = useState([]); const [notifications, setNotifications] = useState([]); + const [soundEvents] = usePersistedState('soundEvents', []); + const [soundAlarms] = usePersistedState('soundAlarms', ['sos']); + const connectSocket = () => { const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; const socket = new WebSocket(`${protocol}//${window.location.host}/api/socket`); @@ -87,6 +93,14 @@ const SocketController = () => { }))); }, [events, devices, t]); + useEffect(() => { + events.forEach((event) => { + if (soundEvents.includes(event.type) || (event.type === 'alarm' && soundAlarms.includes(event.attributes.alarm))) { + new Audio(alarm).play(); + } + }); + }, [events, soundEvents, soundAlarms]); + return ( <> {notifications.map((notification) => ( diff --git a/modern/src/settings/PreferencesPage.js b/modern/src/settings/PreferencesPage.js index 344beed8..64268e63 100644 --- a/modern/src/settings/PreferencesPage.js +++ b/modern/src/settings/PreferencesPage.js @@ -15,11 +15,13 @@ import { } from '@mui/material'; import makeStyles from '@mui/styles/makeStyles'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; -import { useLocalization, useTranslation } from '../common/components/LocalizationProvider'; +import { useLocalization, useTranslation, useTranslationKeys } from '../common/components/LocalizationProvider'; import usePersistedState from '../common/util/usePersistedState'; import PageLayout from '../common/components/PageLayout'; import SettingsMenu from './components/SettingsMenu'; import usePositionAttributes from '../common/attributes/usePositionAttributes'; +import { prefixString, unprefixString } from '../common/util/stringUtils'; +import SelectField from '../common/components/SelectField'; const useStyles = makeStyles((theme) => ({ container: { @@ -47,6 +49,14 @@ const PreferencesPage = () => { const [mapFollow, setMapFollow] = usePersistedState('mapFollow', false); const [mapCluster, setMapCluster] = usePersistedState('mapCluster', true); + const alarms = useTranslationKeys((it) => it.startsWith('alarm')).map((it) => ({ + key: unprefixString('alarm', it), + name: t(it), + })); + + const [soundEvents, setSoundEvents] = usePersistedState('soundEvents', []); + const [soundAlarms, setSoundAlarms] = usePersistedState('soundAlarms', ['sos']); + return ( <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'sharedPreferences']}> <Container maxWidth="xs" className={classes.container}> @@ -105,6 +115,32 @@ const PreferencesPage = () => { </FormGroup> </AccordionDetails> </Accordion> + <Accordion> + <AccordionSummary expandIcon={<ExpandMoreIcon />}> + <Typography variant="subtitle1"> + {t('sharedSound')} + </Typography> + </AccordionSummary> + <AccordionDetails className={classes.details}> + <SelectField + multiple + value={soundEvents} + onChange={(e) => setSoundEvents(e.target.value)} + endpoint="/api/notifications/types" + keyGetter={(it) => it.type} + titleGetter={(it) => t(prefixString('event', it.type))} + label={t('reportEventTypes')} + /> + <SelectField + multiple + value={soundAlarms} + onChange={(e) => setSoundAlarms(e.target.value)} + data={alarms} + keyGetter={(it) => it.key} + label={t('sharedAlarms')} + /> + </AccordionDetails> + </Accordion> </Container> </PageLayout> ); |