204 lines
6.9 KiB
JavaScript
Executable File
204 lines
6.9 KiB
JavaScript
Executable File
/* @flow */
|
|
|
|
import React from 'react';
|
|
import Flux from '../../lib/flux';
|
|
import lodash from 'lodash';
|
|
import i18n from '../../i18n';
|
|
import TTS from '../../lib/TTS';
|
|
import * as SoundUtils from '../../utils/SoundUtils';
|
|
import type {Sound} from '../../utils/SoundUtils';
|
|
import {FormSection, FormTitle, FormTitleTags, FormItem, FormDivider, FormText, FormTextTypes} from '../../uikit/form';
|
|
import Flex from '../../uikit/Flex';
|
|
import Switch from '../../uikit/Switch';
|
|
import Select from '../../uikit/Select';
|
|
import SwitchItem from '../../uikit/SwitchItem';
|
|
import RadioGroup from '../../uikit/RadioGroup';
|
|
import NotificationActionCreators from '../../actions/NotificationActionCreators';
|
|
import UserSettingsActionCreators from '../../actions/UserSettingsActionCreators';
|
|
import NotificationStore from '../../stores/NotificationStore';
|
|
import UserSettingsStore from '../../stores/UserSettingsStore';
|
|
import {DesktopNotificationTypes, TTSNotificationTypes} from '../../Constants';
|
|
import '../../styles/user_settings_notifications.styl';
|
|
|
|
class UserSettingsNotifications extends React.PureComponent {
|
|
props: {
|
|
disabledSounds: Array<string>,
|
|
desktopType: string,
|
|
ttsType: string,
|
|
afkTimeout: number,
|
|
};
|
|
|
|
constructor(props) {
|
|
super(props);
|
|
|
|
lodash.bindAll(this, [
|
|
'handlePreviewSound',
|
|
'handleSoundChange',
|
|
'renderSounds',
|
|
'renderTTS',
|
|
'handleAFKTimeoutChange',
|
|
]);
|
|
}
|
|
|
|
_currentPlayingSound: ?Sound;
|
|
|
|
handlePreviewSound(sound: string, e: Event) {
|
|
e.stopPropagation();
|
|
|
|
if (this._currentPlayingSound != null) {
|
|
this._currentPlayingSound.stop();
|
|
}
|
|
if (e.target.type == null) {
|
|
this._currentPlayingSound = SoundUtils.playSound(sound);
|
|
}
|
|
}
|
|
|
|
handleSoundChange(sound: string, e: Event) {
|
|
const disabledSounds = this.props.disabledSounds.filter(s => s !== sound);
|
|
if (!e.currentTarget.checked) {
|
|
disabledSounds.push(sound);
|
|
}
|
|
NotificationActionCreators.setDisabledSounds(disabledSounds);
|
|
}
|
|
|
|
handleDesktopChange(e: Event) {
|
|
const desktopType = e.currentTarget.checked ? DesktopNotificationTypes.ALL : DesktopNotificationTypes.NEVER;
|
|
if (desktopType !== DesktopNotificationTypes.NEVER) {
|
|
NotificationActionCreators.requestPermission('UserSettingsModal');
|
|
} else {
|
|
NotificationActionCreators.setDesktopType(desktopType);
|
|
}
|
|
}
|
|
|
|
handleTTSChange(option: {value: string}) {
|
|
const ttsType = option.value;
|
|
NotificationActionCreators.setTTSType(ttsType);
|
|
}
|
|
|
|
handleAFKTimeoutChange(option: {value: number}) {
|
|
const afkTimeout = option.value;
|
|
UserSettingsActionCreators.updateRemoteSettings({afkTimeout});
|
|
}
|
|
|
|
renderSounds() {
|
|
const {disabledSounds} = this.props;
|
|
|
|
return [
|
|
{label: i18n.Messages.SOUND_MESSAGE, sound: 'message1'},
|
|
{label: i18n.Messages.SOUND_DEAFEN, sound: 'deafen'},
|
|
{label: i18n.Messages.SOUND_UNDEAFEN, sound: 'undeafen'},
|
|
{label: i18n.Messages.MUTE, sound: 'mute'},
|
|
{label: i18n.Messages.UNMUTE, sound: 'unmute'},
|
|
{label: i18n.Messages.SOUND_VOICE_DISCONNECTED, sound: 'disconnect'},
|
|
{label: i18n.Messages.SOUND_PTT_ACTIVATE, sound: 'ptt_start'},
|
|
{label: i18n.Messages.SOUND_PTT_DEACTIVATE, sound: 'ptt_stop'},
|
|
{label: i18n.Messages.SOUND_USER_JOIN, sound: 'user_join'},
|
|
{label: i18n.Messages.SOUND_USER_LEAVE, sound: 'user_leave'},
|
|
{label: i18n.Messages.SOUND_OUTGOING_RING, sound: 'call_calling'},
|
|
{label: i18n.Messages.SOUND_INCOMING_RING, sound: 'call_ringing'},
|
|
].map(({label, sound}) =>
|
|
<Flex
|
|
key={sound}
|
|
className="notifications-sound"
|
|
justify={Flex.Justify.BETWEEN}
|
|
align={Flex.Align.CENTER}
|
|
onClick={this.handlePreviewSound.bind(this, sound)}>
|
|
<Flex className="notifications-sound-label" grow={0}>
|
|
<Flex.Child className="notifications-sound-icon">
|
|
<i />
|
|
</Flex.Child>
|
|
<Flex.Child>
|
|
<FormTitle className="notifications-sound-text" tag={FormTitleTags.H3}>
|
|
{label}
|
|
</FormTitle>
|
|
</Flex.Child>
|
|
</Flex>
|
|
<Flex.Child wrap grow={0}>
|
|
<Switch value={disabledSounds.indexOf(sound) === -1} onChange={this.handleSoundChange.bind(this, sound)} />
|
|
</Flex.Child>
|
|
</Flex>
|
|
);
|
|
}
|
|
|
|
renderTTS() {
|
|
if (!TTS.supported) {
|
|
return null;
|
|
}
|
|
const TTSOptions = [
|
|
{
|
|
name: i18n.Messages.TTS_ALLS,
|
|
value: TTSNotificationTypes.ALL_CHANNELS,
|
|
},
|
|
{
|
|
name: i18n.Messages.TTS_CURRENT,
|
|
value: TTSNotificationTypes.SELECTED_CHANNEL,
|
|
},
|
|
{
|
|
name: i18n.Messages.TTS_NEVER,
|
|
value: TTSNotificationTypes.NEVER,
|
|
},
|
|
];
|
|
|
|
return (
|
|
<FormItem title={i18n.Messages.FORM_LABEL_TTS_NOTIFICATIONS}>
|
|
<FormText type={FormTextTypes.DESCRIPTION} className="margin-bottom-8">
|
|
{i18n.Messages.FORM_DESCRIPTION_TTS}
|
|
</FormText>
|
|
<RadioGroup options={TTSOptions} onChange={this.handleTTSChange} value={this.props.ttsType} />
|
|
<FormDivider key="tts-divider" className="margin-top-40 margin-bottom-40" />
|
|
</FormItem>
|
|
);
|
|
}
|
|
|
|
render() {
|
|
const {desktopType, afkTimeout} = this.props;
|
|
const afkTimeoutOptions = lodash
|
|
.range(1, 11)
|
|
.map(minutes => ({value: 60 * minutes, label: i18n.Messages.DURATION_MINUTES.format({minutes})}));
|
|
return (
|
|
<FormSection tag={FormTitleTags.H2} title={i18n.Messages.NOTIFICATIONS} className="user-settings-notifications">
|
|
<SwitchItem
|
|
className="margin-bottom-40"
|
|
value={desktopType !== DesktopNotificationTypes.NEVER}
|
|
onChange={this.handleDesktopChange}
|
|
note={i18n.Messages.DESKTOP_NOTIFICATIONS_ENABLE_BODY}>
|
|
{i18n.Messages.DESKTOP_NOTIFICATIONS_ENABLE}
|
|
</SwitchItem>
|
|
<FormItem title={i18n.Messages.FORM_LABEL_PUSH_AFK_TIMEOUT}>
|
|
<Select
|
|
value={afkTimeout}
|
|
clearable={false}
|
|
searchable={false}
|
|
onChange={this.handleAFKTimeoutChange}
|
|
options={afkTimeoutOptions}
|
|
/>
|
|
<FormText type={FormTextTypes.DESCRIPTION} className="margin-top-8">
|
|
{i18n.Messages.FORM_DESCRIPTION_PUSH_AFK_TIMEOUT}
|
|
</FormText>
|
|
<FormDivider className="margin-top-40 margin-bottom-40" />
|
|
</FormItem>
|
|
{this.renderTTS()}
|
|
<FormItem className="sound-list">
|
|
<FormTitle className="margin-reset">
|
|
{i18n.Messages.SOUNDS}
|
|
</FormTitle>
|
|
{this.renderSounds()}
|
|
</FormItem>
|
|
</FormSection>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default Flux.connectStores([NotificationStore, UserSettingsStore], () => {
|
|
return {
|
|
disabledSounds: NotificationStore.getDisabledSounds(),
|
|
desktopType: NotificationStore.getDesktopType(),
|
|
ttsType: NotificationStore.getTTSType(),
|
|
afkTimeout: UserSettingsStore.afkTimeout,
|
|
};
|
|
})(UserSettingsNotifications);
|
|
|
|
|
|
|
|
// WEBPACK FOOTER //
|
|
// ./discord_app/components/user_settings/UserSettingsNotifications.js
|