MM-52805 - Calls: Add calls ringing & settings panel option (#23444)

* add calls sounds; add calls options to settings panel

* i18n

* fix types; tests

* tests

* expose notificationSounds to plugins

* fix bad version reference

* the real fix

* turn off any currentRing if new ring is requested

* refactor isCallsEnabled into a selector

* fix version fallback

* remove unused vars

* merge conflicts

* stop notification rings on exits

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
Christopher Poile
2023-06-14 10:57:37 -04:00
коммит произвёл GitHub
родитель 79abeb6382
Коммит c06c47f22e
39 изменённых файлов: 838 добавлений и 14 удалений

Просмотреть файл

@@ -55,6 +55,7 @@ exports[`components/UserList should match default snapshot when there are users
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -114,6 +115,7 @@ exports[`components/UserList should match default snapshot when there are users
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",

Просмотреть файл

@@ -104,6 +104,7 @@ exports[`components/admin_console/add_users_to_team_modal/AddUsersToTeamModal sh
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -143,6 +144,7 @@ exports[`components/admin_console/add_users_to_team_modal/AddUsersToTeamModal sh
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -288,6 +290,7 @@ exports[`components/admin_console/add_users_to_team_modal/AddUsersToTeamModal sh
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -327,6 +330,7 @@ exports[`components/admin_console/add_users_to_team_modal/AddUsersToTeamModal sh
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",

Просмотреть файл

@@ -52,6 +52,7 @@ exports[`admin_console/team_channel_settings/group/GroupList should match snapsh
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -98,6 +99,7 @@ exports[`admin_console/team_channel_settings/group/GroupList should match snapsh
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -144,6 +146,7 @@ exports[`admin_console/team_channel_settings/group/GroupList should match snapsh
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -190,6 +193,7 @@ exports[`admin_console/team_channel_settings/group/GroupList should match snapsh
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -236,6 +240,7 @@ exports[`admin_console/team_channel_settings/group/GroupList should match snapsh
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -282,6 +287,7 @@ exports[`admin_console/team_channel_settings/group/GroupList should match snapsh
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -328,6 +334,7 @@ exports[`admin_console/team_channel_settings/group/GroupList should match snapsh
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -374,6 +381,7 @@ exports[`admin_console/team_channel_settings/group/GroupList should match snapsh
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -420,6 +428,7 @@ exports[`admin_console/team_channel_settings/group/GroupList should match snapsh
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -466,6 +475,7 @@ exports[`admin_console/team_channel_settings/group/GroupList should match snapsh
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",

Просмотреть файл

@@ -20,6 +20,7 @@ describe('components/admin_console/reset_password_modal/reset_password_modal.tsx
comments: 'never',
desktop: 'default',
desktop_sound: 'true',
calls_desktop_sound: 'true',
email: 'true',
first_name: 'true',
mark_unread: 'all',

Просмотреть файл

@@ -107,6 +107,7 @@ exports[`admin_console/add_users_to_role_modal should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -146,6 +147,7 @@ exports[`admin_console/add_users_to_role_modal should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",

Просмотреть файл

@@ -25,6 +25,7 @@ exports[`admin_console/system_role_users should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -64,6 +65,7 @@ exports[`admin_console/system_role_users should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -182,6 +184,7 @@ exports[`admin_console/system_role_users should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -226,6 +229,7 @@ exports[`admin_console/system_role_users should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -272,6 +276,7 @@ exports[`admin_console/system_role_users should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -316,6 +321,7 @@ exports[`admin_console/system_role_users should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -375,6 +381,7 @@ exports[`admin_console/system_role_users should match snapshot with readOnly tru
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -414,6 +421,7 @@ exports[`admin_console/system_role_users should match snapshot with readOnly tru
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -532,6 +540,7 @@ exports[`admin_console/system_role_users should match snapshot with readOnly tru
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -576,6 +585,7 @@ exports[`admin_console/system_role_users should match snapshot with readOnly tru
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -622,6 +632,7 @@ exports[`admin_console/system_role_users should match snapshot with readOnly tru
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -666,6 +677,7 @@ exports[`admin_console/system_role_users should match snapshot with readOnly tru
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",

Просмотреть файл

@@ -208,6 +208,7 @@ exports[`admin_console/team_channel_settings/channel/ChannelMembers should match
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -245,6 +246,7 @@ exports[`admin_console/team_channel_settings/channel/ChannelMembers should match
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -282,6 +284,7 @@ exports[`admin_console/team_channel_settings/channel/ChannelMembers should match
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",

Просмотреть файл

@@ -53,6 +53,7 @@ exports[`components/admin_console/team_channel_settings/group/UsersToRemoveRole
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -145,6 +146,7 @@ exports[`components/admin_console/team_channel_settings/group/UsersToRemoveRole
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -237,6 +239,7 @@ exports[`components/admin_console/team_channel_settings/group/UsersToRemoveRole
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -329,6 +332,7 @@ exports[`components/admin_console/team_channel_settings/group/UsersToRemoveRole
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -412,6 +416,7 @@ exports[`components/admin_console/team_channel_settings/group/UsersToRemoveRole
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -495,6 +500,7 @@ exports[`components/admin_console/team_channel_settings/group/UsersToRemoveRole
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",

Просмотреть файл

@@ -180,6 +180,7 @@ exports[`admin_console/team_channel_settings/team/TeamMembers should match snaps
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -217,6 +218,7 @@ exports[`admin_console/team_channel_settings/team/TeamMembers should match snaps
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -254,6 +256,7 @@ exports[`admin_console/team_channel_settings/team/TeamMembers should match snaps
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",

Просмотреть файл

@@ -77,6 +77,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -120,6 +121,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -178,6 +180,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -224,6 +227,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -267,6 +271,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -325,6 +330,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -440,6 +446,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -491,6 +498,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -541,6 +549,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -587,6 +596,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -630,6 +640,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -688,6 +699,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -734,6 +746,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -777,6 +790,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -835,6 +849,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -950,6 +965,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -993,6 +1009,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -1051,6 +1068,7 @@ exports[`components/admin_console/user_grid/UserGrid should match snapshot with
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",

Просмотреть файл

@@ -130,6 +130,7 @@ exports[`components/ChannelHeaderDropdown should match snapshot with no plugin i
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -205,6 +206,7 @@ exports[`components/ChannelHeaderDropdown should match snapshot with no plugin i
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -711,6 +713,7 @@ exports[`components/ChannelHeaderDropdown should match snapshot with no plugin i
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -919,6 +922,7 @@ exports[`components/ChannelHeaderDropdown should match snapshot with plugins 1`]
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -994,6 +998,7 @@ exports[`components/ChannelHeaderDropdown should match snapshot with plugins 1`]
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -1500,6 +1505,7 @@ exports[`components/ChannelHeaderDropdown should match snapshot with plugins 1`]
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",

Просмотреть файл

@@ -41,6 +41,7 @@ exports[`components/integrations/InstalledOutgoingWebhooks should match snapshot
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -147,6 +148,7 @@ exports[`components/integrations/InstalledOutgoingWebhooks should match snapshot
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",

Просмотреть файл

@@ -37,6 +37,7 @@ describe('components/KeyboardShortcutsModal', () => {
...initialState.plugins.plugins,
[suitePluginIds.calls]: {
id: suitePluginIds.calls,
version: '0.15.0',
},
},
},

Просмотреть файл

@@ -6,9 +6,6 @@ import {Modal} from 'react-bootstrap';
import {defineMessages, useIntl} from 'react-intl';
import {useSelector} from 'react-redux';
import {GlobalState} from 'types/store';
import {suitePluginIds} from 'utils/constants';
import * as UserAgent from 'utils/user_agent';
import KeyboardShortcutSequence, {
@@ -17,6 +14,7 @@ import KeyboardShortcutSequence, {
} from 'components/keyboard_shortcuts/keyboard_shortcuts_sequence';
import './keyboard_shortcuts_modal.scss';
import {isCallsEnabled} from 'selectors/calls';
const modalMessages = defineMessages({
msgHeader: {
@@ -91,9 +89,7 @@ const KeyboardShortcutsModal = ({onExited}: Props): JSX.Element => {
const isLinux = UserAgent.isLinux();
const isCallsEnabled = useSelector((state: GlobalState) => {
return Boolean(state.plugins.plugins[suitePluginIds.calls]);
});
const callsEnabled = useSelector(isCallsEnabled);
const renderShortcutSequences = (shortcuts: {[key: string]: KeyboardShortcutDescriptor}) => {
return Object.entries(shortcuts).map(([key, shortcut]) => {
@@ -203,7 +199,7 @@ const KeyboardShortcutsModal = ({onExited}: Props): JSX.Element => {
</div>
</div>
{ isCallsEnabled &&
{ callsEnabled &&
<div className='row'>
<div className='col-sm-4'>
<div className='section'>

Просмотреть файл

@@ -88,6 +88,7 @@ exports[`components/MoreDirectChannels should exclude deleted users if there is
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -125,6 +126,7 @@ exports[`components/MoreDirectChannels should exclude deleted users if there is
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -162,6 +164,7 @@ exports[`components/MoreDirectChannels should exclude deleted users if there is
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -199,6 +202,7 @@ exports[`components/MoreDirectChannels should exclude deleted users if there is
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -236,6 +240,7 @@ exports[`components/MoreDirectChannels should exclude deleted users if there is
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -368,6 +373,7 @@ exports[`components/MoreDirectChannels should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -405,6 +411,7 @@ exports[`components/MoreDirectChannels should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -442,6 +449,7 @@ exports[`components/MoreDirectChannels should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -484,6 +492,7 @@ exports[`components/MoreDirectChannels should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -523,6 +532,7 @@ exports[`components/MoreDirectChannels should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",

Просмотреть файл

@@ -132,6 +132,7 @@ exports[`components/ProfilePopover should disable start call button when user is
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -219,6 +220,7 @@ exports[`components/ProfilePopover should disable start call button when user is
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -315,6 +317,7 @@ exports[`components/ProfilePopover should disable start call button when user is
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -477,6 +480,7 @@ exports[`components/ProfilePopover should hide add-to-channel option if not on t
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -581,6 +585,7 @@ exports[`components/ProfilePopover should hide add-to-channel option if not on t
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -743,6 +748,7 @@ exports[`components/ProfilePopover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -830,6 +836,7 @@ exports[`components/ProfilePopover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -930,6 +937,7 @@ exports[`components/ProfilePopover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -1107,6 +1115,7 @@ exports[`components/ProfilePopover should match snapshot for shared user 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -1195,6 +1204,7 @@ exports[`components/ProfilePopover should match snapshot for shared user 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -1296,6 +1306,7 @@ exports[`components/ProfilePopover should match snapshot for shared user 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -1459,6 +1470,7 @@ exports[`components/ProfilePopover should match snapshot when calls are disabled
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -1546,6 +1558,7 @@ exports[`components/ProfilePopover should match snapshot when calls are disabled
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -1612,6 +1625,7 @@ exports[`components/ProfilePopover should match snapshot when calls are disabled
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -1781,6 +1795,7 @@ exports[`components/ProfilePopover should match snapshot with custom status 1`]
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -1906,6 +1921,7 @@ exports[`components/ProfilePopover should match snapshot with custom status 1`]
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -2006,6 +2022,7 @@ exports[`components/ProfilePopover should match snapshot with custom status 1`]
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -2175,6 +2192,7 @@ exports[`components/ProfilePopover should match snapshot with custom status expi
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -2262,6 +2280,7 @@ exports[`components/ProfilePopover should match snapshot with custom status expi
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -2362,6 +2381,7 @@ exports[`components/ProfilePopover should match snapshot with custom status expi
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -2524,6 +2544,7 @@ exports[`components/ProfilePopover should match snapshot with custom status not
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -2648,6 +2669,7 @@ exports[`components/ProfilePopover should match snapshot with custom status not
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -2810,6 +2832,7 @@ exports[`components/ProfilePopover should match snapshot with last active displa
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -2897,6 +2920,7 @@ exports[`components/ProfilePopover should match snapshot with last active displa
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -2997,6 +3021,7 @@ exports[`components/ProfilePopover should match snapshot with last active displa
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -3134,6 +3159,7 @@ exports[`components/ProfilePopover should match snapshot with no last active dis
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -3221,6 +3247,7 @@ exports[`components/ProfilePopover should match snapshot with no last active dis
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -3321,6 +3348,7 @@ exports[`components/ProfilePopover should match snapshot with no last active dis
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -3434,6 +3462,7 @@ exports[`components/ProfilePopover should show the start call button when isCall
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -3569,6 +3598,7 @@ exports[`components/ProfilePopover should show the start call button when isCall
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -3912,6 +3942,7 @@ exports[`components/ProfilePopover should show the start call button when isCall
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -3992,6 +4023,7 @@ exports[`components/ProfilePopover should show the start call button when isCall
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -4161,6 +4193,7 @@ exports[`components/ProfilePopover should show the start call button when isCall
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -4223,6 +4256,7 @@ exports[`components/ProfilePopover should show the start call button when isCall
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -4392,6 +4426,7 @@ exports[`components/ProfilePopover should show the start call button when isCall
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -4472,6 +4507,7 @@ exports[`components/ProfilePopover should show the start call button when isCall
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",

Просмотреть файл

@@ -35,10 +35,10 @@ import {GlobalState} from 'types/store';
import {ServerError} from '@mattermost/types/errors';
import {suitePluginIds} from 'utils/constants';
import {getDirectChannelName} from 'utils/utils';
import ProfilePopover from './profile_popover';
import {isCallsEnabled} from 'selectors/calls';
type OwnProps = {
userId: string;
@@ -91,9 +91,9 @@ function makeMapStateToProps() {
const enableLastActiveTime = displayLastActiveLabel(state, userId);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const isCallsEnabled = Boolean(state.plugins.plugins[suitePluginIds.calls]) && Boolean(state['plugins-' + suitePluginIds.calls]);
const callsEnabled = isCallsEnabled(state);
const currentUserId = getCurrentUserId(state);
const callsConfig = isCallsEnabled ? getCallsConfig(state) : undefined;
const callsConfig = callsEnabled ? getCallsConfig(state) : undefined;
return {
currentTeamId: team.id,
@@ -116,9 +116,9 @@ function makeMapStateToProps() {
enableLastActiveTime,
timestampUnits,
isMobileView: getIsMobileView(state),
isCallsEnabled,
isUserInCall: isCallsEnabled ? checkUserInCall(state, userId) : undefined,
isCurrentUserInCall: isCallsEnabled ? checkUserInCall(state, currentUserId) : undefined,
isCallsEnabled: callsEnabled,
isUserInCall: callsEnabled ? checkUserInCall(state, userId) : undefined,
isCurrentUserInCall: callsEnabled ? checkUserInCall(state, currentUserId) : undefined,
isCallsDefaultEnabledOnAllChannels: callsConfig?.DefaultEnabled,
isCallsCanBeDisabledOnSpecificChannels: callsConfig?.AllowEnableCalls,
dMChannel: getChannelByName(state, getDirectChannelName(currentUserId, userId)),

Просмотреть файл

@@ -404,6 +404,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -444,6 +445,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -484,6 +486,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -524,6 +527,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -564,6 +568,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -604,6 +609,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -644,6 +650,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -684,6 +691,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -724,6 +732,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -764,6 +773,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -804,6 +814,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -844,6 +855,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -884,6 +896,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -924,6 +937,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -964,6 +978,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",

Просмотреть файл

@@ -84,6 +84,7 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -124,6 +125,7 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -164,6 +166,7 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -204,6 +207,7 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",
@@ -244,6 +248,7 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
"mfa_active": false,
"nickname": "",
"notify_props": Object {
"calls_desktop_sound": "true",
"channel": "false",
"comments": "never",
"desktop": "default",

Просмотреть файл

@@ -20,6 +20,7 @@ import * as Keyboard from 'utils/keyboard';
import * as Utils from 'utils/utils';
import ConfirmModal from 'components/confirm_modal';
import * as NotificationSounds from 'utils/notification_sounds';
const UserSettings = React.lazy(() => import(/* webpackPrefetch: true */ 'components/user_settings'));
const SettingsSidebar = React.lazy(() => import(/* webpackPrefetch: true */ '../../settings_sidebar'));
@@ -161,6 +162,9 @@ class UserSettingsModal extends React.PureComponent<Props, State> {
return;
}
// Cancel any ongoing notification sound, if any (from DesktopNotificationSettings)
NotificationSounds.stopTryNotificationRing();
this.setState({
show: false,
});

Просмотреть файл

@@ -435,6 +435,463 @@ exports[`components/user_settings/notifications/DesktopNotificationSettings shou
/>
`;
exports[`components/user_settings/notifications/DesktopNotificationSettings should match snapshot, on max setting with Calls enabled 1`] = `
<SettingItemMax
containerStyle=""
infoPosition="bottom"
inputs={
Array [
<div>
<fieldset>
<legend
className="form-legend"
>
<Memo(MemoizedFormattedMessage)
defaultMessage="Send desktop notifications"
id="user.settings.notifications.desktop"
/>
</legend>
<div
className="radio"
>
<label>
<input
checked={false}
data-key="desktopActivity"
data-value="all"
id="desktopNotificationAllActivity"
name="desktopNotificationLevel"
onChange={[Function]}
type="radio"
/>
<Memo(MemoizedFormattedMessage)
defaultMessage="For all activity"
id="user.settings.notifications.allActivity"
/>
</label>
<br />
</div>
<div
className="radio"
>
<label>
<input
checked={true}
data-key="desktopActivity"
data-value="mention"
id="desktopNotificationMentions"
name="desktopNotificationLevel"
onChange={[Function]}
type="radio"
/>
<Memo(MemoizedFormattedMessage)
defaultMessage="Only for mentions and direct messages"
id="user.settings.notifications.onlyMentions"
/>
</label>
<br />
</div>
<div
className="radio"
>
<label>
<input
checked={false}
data-key="desktopActivity"
data-value="none"
id="desktopNotificationNever"
name="desktopNotificationLevel"
onChange={[Function]}
type="radio"
/>
<Memo(MemoizedFormattedMessage)
defaultMessage="Never"
id="user.settings.notifications.never"
/>
</label>
</div>
<div
className="mt-5"
>
<Memo(MemoizedFormattedMessage)
defaultMessage="Desktop notifications are available on Edge, Firefox, Safari, Chrome and Mattermost Desktop Apps."
id="user.settings.notifications.info"
/>
</div>
</fieldset>
<hr />
<fieldset>
<legend
className="form-legend"
>
<Memo(MemoizedFormattedMessage)
defaultMessage="Notification sound"
id="user.settings.notifications.desktop.sound"
/>
</legend>
<div
className="radio"
>
<label>
<input
checked={false}
data-key="desktopSound"
data-value="true"
id="soundOn"
name="notificationSounds"
onChange={[Function]}
type="radio"
/>
<Memo(MemoizedFormattedMessage)
defaultMessage="On"
id="user.settings.notifications.on"
/>
</label>
<br />
</div>
<div
className="radio"
>
<label>
<input
checked={true}
data-key="desktopSound"
data-value="false"
id="soundOff"
name="notificationSounds"
onChange={[Function]}
type="radio"
/>
<Memo(MemoizedFormattedMessage)
defaultMessage="Off"
id="user.settings.notifications.off"
/>
</label>
<br />
</div>
<div
className="mt-5"
>
<Memo(MemoizedFormattedMessage)
defaultMessage="Notification sounds are available on Firefox, Edge, Safari, Chrome and Mattermost Desktop Apps."
id="user.settings.notifications.sounds_info"
/>
</div>
</fieldset>
<React.Fragment>
<hr />
<fieldset>
<legend
className="form-legend"
>
<Memo(MemoizedFormattedMessage)
defaultMessage="Notification sound for incoming calls"
id="user.settings.notifications.desktop.calls_sound"
/>
</legend>
<div
className="radio"
>
<label>
<input
checked={false}
data-key="callsDesktopSound"
data-value="true"
id="callsSoundOn"
name="callsNotificationSounds"
onChange={[Function]}
type="radio"
/>
<Memo(MemoizedFormattedMessage)
defaultMessage="On"
id="user.settings.notifications.on"
/>
</label>
<br />
</div>
<div
className="radio"
>
<label>
<input
checked={true}
data-key="callsDesktopSound"
data-value="false"
id="soundOff"
name="callsNotificationSounds"
onChange={[Function]}
type="radio"
/>
<Memo(MemoizedFormattedMessage)
defaultMessage="Off"
id="user.settings.notifications.off"
/>
</label>
<br />
</div>
</fieldset>
</React.Fragment>
</div>,
]
}
saving={false}
section=""
serverError=""
submit={[MockFunction]}
title="Desktop Notifications"
updateSection={[Function]}
/>
`;
exports[`components/user_settings/notifications/DesktopNotificationSettings should match snapshot, on max setting with Calls enabled, calls sound true 1`] = `
<SettingItemMax
containerStyle=""
infoPosition="bottom"
inputs={
Array [
<div>
<fieldset>
<legend
className="form-legend"
>
<Memo(MemoizedFormattedMessage)
defaultMessage="Send desktop notifications"
id="user.settings.notifications.desktop"
/>
</legend>
<div
className="radio"
>
<label>
<input
checked={false}
data-key="desktopActivity"
data-value="all"
id="desktopNotificationAllActivity"
name="desktopNotificationLevel"
onChange={[Function]}
type="radio"
/>
<Memo(MemoizedFormattedMessage)
defaultMessage="For all activity"
id="user.settings.notifications.allActivity"
/>
</label>
<br />
</div>
<div
className="radio"
>
<label>
<input
checked={true}
data-key="desktopActivity"
data-value="mention"
id="desktopNotificationMentions"
name="desktopNotificationLevel"
onChange={[Function]}
type="radio"
/>
<Memo(MemoizedFormattedMessage)
defaultMessage="Only for mentions and direct messages"
id="user.settings.notifications.onlyMentions"
/>
</label>
<br />
</div>
<div
className="radio"
>
<label>
<input
checked={false}
data-key="desktopActivity"
data-value="none"
id="desktopNotificationNever"
name="desktopNotificationLevel"
onChange={[Function]}
type="radio"
/>
<Memo(MemoizedFormattedMessage)
defaultMessage="Never"
id="user.settings.notifications.never"
/>
</label>
</div>
<div
className="mt-5"
>
<Memo(MemoizedFormattedMessage)
defaultMessage="Desktop notifications are available on Edge, Firefox, Safari, Chrome and Mattermost Desktop Apps."
id="user.settings.notifications.info"
/>
</div>
</fieldset>
<hr />
<fieldset>
<legend
className="form-legend"
>
<Memo(MemoizedFormattedMessage)
defaultMessage="Notification sound"
id="user.settings.notifications.desktop.sound"
/>
</legend>
<div
className="radio"
>
<label>
<input
checked={false}
data-key="desktopSound"
data-value="true"
id="soundOn"
name="notificationSounds"
onChange={[Function]}
type="radio"
/>
<Memo(MemoizedFormattedMessage)
defaultMessage="On"
id="user.settings.notifications.on"
/>
</label>
<br />
</div>
<div
className="radio"
>
<label>
<input
checked={true}
data-key="desktopSound"
data-value="false"
id="soundOff"
name="notificationSounds"
onChange={[Function]}
type="radio"
/>
<Memo(MemoizedFormattedMessage)
defaultMessage="Off"
id="user.settings.notifications.off"
/>
</label>
<br />
</div>
<div
className="mt-5"
>
<Memo(MemoizedFormattedMessage)
defaultMessage="Notification sounds are available on Firefox, Edge, Safari, Chrome and Mattermost Desktop Apps."
id="user.settings.notifications.sounds_info"
/>
</div>
</fieldset>
<React.Fragment>
<hr />
<fieldset>
<legend
className="form-legend"
>
<Memo(MemoizedFormattedMessage)
defaultMessage="Notification sound for incoming calls"
id="user.settings.notifications.desktop.calls_sound"
/>
</legend>
<div
className="radio"
>
<label>
<input
checked={true}
data-key="callsDesktopSound"
data-value="true"
id="callsSoundOn"
name="callsNotificationSounds"
onChange={[Function]}
type="radio"
/>
<Memo(MemoizedFormattedMessage)
defaultMessage="On"
id="user.settings.notifications.on"
/>
</label>
<br />
</div>
<div
className="radio"
>
<label>
<input
checked={false}
data-key="callsDesktopSound"
data-value="false"
id="soundOff"
name="callsNotificationSounds"
onChange={[Function]}
type="radio"
/>
<Memo(MemoizedFormattedMessage)
defaultMessage="Off"
id="user.settings.notifications.off"
/>
</label>
<br />
</div>
<div
className="pt-2"
>
<StateManager
className="react-select notification-sound-dropdown"
classNamePrefix="react-select"
clearable={false}
defaultInputValue=""
defaultMenuIsOpen={false}
defaultValue={null}
id="displayCallsSoundNotification"
isSearchable={false}
onChange={[Function]}
options={
Array [
Object {
"label": "Dynamic",
"value": "Dynamic",
},
Object {
"label": "Calm",
"value": "Calm",
},
Object {
"label": "Urgent",
"value": "Urgent",
},
Object {
"label": "Cheerful",
"value": "Cheerful",
},
]
}
value={
Object {
"label": "Dynamic",
"value": "Dynamic",
}
}
/>
</div>
</fieldset>
</React.Fragment>
</div>,
]
}
saving={false}
section=""
serverError=""
submit={[MockFunction]}
title="Desktop Notifications"
updateSection={[Function]}
/>
`;
exports[`components/user_settings/notifications/DesktopNotificationSettings should match snapshot, on max setting with sound enabled 1`] = `
<SettingItemMax
containerStyle=""

Просмотреть файл

@@ -31,6 +31,9 @@ describe('components/user_settings/notifications/DesktopNotificationSettings', (
selectedSound: 'Bing',
isCollapsedThreadsEnabled: false,
threads: NotificationLevels.ALL,
callsSelectedSound: 'Dynamic',
callsSound: 'false',
isCallsEnabled: false,
};
test('should match snapshot, on max setting', () => {
@@ -50,6 +53,24 @@ describe('components/user_settings/notifications/DesktopNotificationSettings', (
expect(wrapper).toMatchSnapshot();
});
test('should match snapshot, on max setting with Calls enabled', () => {
const props = {...baseProps, isCallsEnabled: true};
const wrapper = shallow(
<DesktopNotificationSettings {...props}/>,
);
expect(wrapper).toMatchSnapshot();
});
test('should match snapshot, on max setting with Calls enabled, calls sound true', () => {
const props = {...baseProps, isCallsEnabled: true, callsSound: 'true'};
const wrapper = shallow(
<DesktopNotificationSettings {...props}/>,
);
expect(wrapper).toMatchSnapshot();
});
test('should match snapshot, on min setting', () => {
const props = {...baseProps, active: false};
const wrapper = shallow(

Просмотреть файл

@@ -23,6 +23,7 @@ type Props = {
activity: string;
threads?: string;
sound: string;
callsSound: string;
updateSection: (section: string) => void;
setParentState: (key: string, value: string | boolean) => void;
submit: () => void;
@@ -32,26 +33,33 @@ type Props = {
areAllSectionsInactive: boolean;
saving: boolean;
selectedSound: string;
callsSelectedSound: string;
isCollapsedThreadsEnabled: boolean;
isCallsEnabled: boolean;
};
type State = {
selectedOption: SelectedOption;
callsSelectedOption: SelectedOption;
blurDropdown: boolean;
};
export default class DesktopNotificationSettings extends React.PureComponent<Props, State> {
dropdownSoundRef: RefObject<ReactSelect>;
callsDropdownRef: RefObject<ReactSelect>;
minRef: RefObject<SettingItemMinComponent>;
constructor(props: Props) {
super(props);
const selectedOption = {value: props.selectedSound, label: props.selectedSound};
const callsSelectedOption = {value: props.callsSelectedSound, label: props.callsSelectedSound};
this.state = {
selectedOption,
callsSelectedOption,
blurDropdown: false,
};
this.dropdownSoundRef = React.createRef();
this.callsDropdownRef = React.createRef();
this.minRef = React.createRef();
}
@@ -73,6 +81,9 @@ export default class DesktopNotificationSettings extends React.PureComponent<Pro
this.props.setParentState(key, value);
Utils.a11yFocus(e.currentTarget);
}
if (key === 'callsDesktopSound' && value === 'false') {
NotificationSounds.stopTryNotificationRing();
}
};
handleThreadsOnChange = (e: ChangeEvent<HTMLInputElement>): void => {
@@ -88,12 +99,23 @@ export default class DesktopNotificationSettings extends React.PureComponent<Pro
}
};
setCallsNotificationRing: ReactSelect['onChange'] = (selectedOption: ValueType<SelectedOption>): void => {
if (selectedOption && 'value' in selectedOption) {
this.props.setParentState('callsNotificationSound', selectedOption.value);
this.setState({callsSelectedOption: selectedOption});
NotificationSounds.tryNotificationRing(selectedOption.value);
}
};
blurDropdown(): void {
if (!this.state.blurDropdown) {
this.setState({blurDropdown: true});
if (this.dropdownSoundRef.current) {
this.dropdownSoundRef.current.blur();
}
if (this.callsDropdownRef.current) {
this.callsDropdownRef.current.blur();
}
}
}
@@ -112,6 +134,8 @@ export default class DesktopNotificationSettings extends React.PureComponent<Pro
let soundSection;
let notificationSelection;
let threadsNotificationSelection;
let callsSection;
let callsNotificationSelection;
if (this.props.activity !== NotificationLevels.NONE) {
const soundRadio = [false, false];
if (this.props.sound === 'false') {
@@ -140,6 +164,86 @@ export default class DesktopNotificationSettings extends React.PureComponent<Pro
/></div>);
}
if (this.props.isCallsEnabled) {
const callsSoundRadio = [false, false];
if (this.props.callsSound === 'false') {
callsSoundRadio[1] = true;
} else {
callsSoundRadio[0] = true;
}
if (this.props.callsSound === 'true') {
const callsSounds = Array.from(NotificationSounds.callsNotificationSounds.keys());
const callsOptions = callsSounds.map((sound) => {
return {value: sound, label: sound};
});
callsNotificationSelection = (<div className='pt-2'>
<ReactSelect
className='react-select notification-sound-dropdown'
classNamePrefix='react-select'
id='displayCallsSoundNotification'
options={callsOptions}
clearable={false}
onChange={this.setCallsNotificationRing}
value={this.state.callsSelectedOption}
isSearchable={false}
ref={this.callsDropdownRef}
/></div>);
}
callsSection = (
<>
<hr/>
<fieldset>
<legend className='form-legend'>
<FormattedMessage
id='user.settings.notifications.desktop.calls_sound'
defaultMessage='Notification sound for incoming calls'
/>
</legend>
<div className='radio'>
<label>
<input
id='callsSoundOn'
type='radio'
name='callsNotificationSounds'
checked={callsSoundRadio[0]}
data-key={'callsDesktopSound'}
data-value={'true'}
onChange={this.handleOnChange}
/>
<FormattedMessage
id='user.settings.notifications.on'
defaultMessage='On'
/>
</label>
<br/>
</div>
<div className='radio'>
<label>
<input
id='soundOff'
type='radio'
name='callsNotificationSounds'
checked={callsSoundRadio[1]}
data-key={'callsDesktopSound'}
data-value={'false'}
onChange={this.handleOnChange}
/>
<FormattedMessage
id='user.settings.notifications.off'
defaultMessage='Off'
/>
</label>
<br/>
</div>
{callsNotificationSelection}
</fieldset>
</>
);
}
if (NotificationSounds.hasSoundOptions()) {
soundSection = (
<fieldset>
@@ -323,6 +427,7 @@ export default class DesktopNotificationSettings extends React.PureComponent<Pro
<hr/>
{threadsNotificationSelection}
{soundSection}
{callsSection}
</div>,
);

Просмотреть файл

@@ -12,6 +12,7 @@ import {ActionFunc} from 'mattermost-redux/types/actions';
import {GlobalState} from 'types/store';
import UserSettingsNotifications, {Props} from './user_settings_notifications';
import {isCallsEnabled} from 'selectors/calls';
function mapStateToProps(state: GlobalState) {
const config = getConfig(state);
@@ -23,6 +24,7 @@ function mapStateToProps(state: GlobalState) {
sendPushNotifications,
enableAutoResponder,
isCollapsedThreadsEnabled: isCollapsedThreadsEnabled(state),
isCallsEnabled: isCallsEnabled(state, '0.17.0'),
};
}

Просмотреть файл

@@ -27,6 +27,7 @@ describe('components/user_settings/display/UserSettingsDisplay', () => {
isCollapsedThreadsEnabled: false,
sendPushNotifications: false,
enableAutoResponder: false,
isCallsEnabled: true,
};
test('should have called handleSubmit', async () => {

Просмотреть файл

@@ -9,6 +9,7 @@ import {FormattedMessage} from 'react-intl';
import {ActionResult} from 'mattermost-redux/types/actions';
import Constants, {NotificationLevels} from 'utils/constants';
import * as NotificationSounds from 'utils/notification_sounds';
import {a11yFocus, localizeMessage, moveCursorToEnd} from 'utils/utils';
import {t} from 'utils/i18n';
@@ -35,6 +36,7 @@ export type Props = {
updateMe: (user: UserProfile) => Promise<ActionResult>;
};
isCollapsedThreadsEnabled: boolean;
isCallsEnabled: boolean;
}
type State = {
@@ -46,7 +48,9 @@ type State = {
pushActivity: UserNotifyProps['push'];
pushStatus: UserNotifyProps['push_status'];
desktopSound: UserNotifyProps['desktop_sound'];
callsDesktopSound: UserNotifyProps['calls_desktop_sound'];
desktopNotificationSound: UserNotifyProps['desktop_notification_sound'];
callsNotificationSound: UserNotifyProps['calls_notification_sound'];
usernameKey: boolean;
customKeys: string;
customKeysChecked: boolean;
@@ -67,7 +71,9 @@ function getNotificationsStateFromProps(props: Props): State {
let pushThreads: UserNotifyProps['push_threads'] = NotificationLevels.ALL;
let emailThreads: UserNotifyProps['email_threads'] = NotificationLevels.ALL;
let sound: UserNotifyProps['desktop_sound'] = 'true';
let callsSound: UserNotifyProps['calls_desktop_sound'] = 'true';
let desktopNotificationSound: UserNotifyProps['desktop_notification_sound'] = 'Bing';
let callsNotificationSound: UserNotifyProps['calls_notification_sound'] = 'Dynamic';
let comments: UserNotifyProps['comments'] = 'never';
let enableEmail: UserNotifyProps['email'] = 'true';
let pushActivity: UserNotifyProps['push'] = NotificationLevels.MENTION;
@@ -94,9 +100,15 @@ function getNotificationsStateFromProps(props: Props): State {
if (user.notify_props.desktop_sound) {
sound = user.notify_props.desktop_sound;
}
if (user.notify_props.calls_desktop_sound) {
callsSound = user.notify_props.calls_desktop_sound;
}
if (user.notify_props.desktop_notification_sound) {
desktopNotificationSound = user.notify_props.desktop_notification_sound;
}
if (user.notify_props.calls_notification_sound) {
callsNotificationSound = user.notify_props.calls_notification_sound;
}
if (user.notify_props.comments) {
comments = user.notify_props.comments;
}
@@ -159,7 +171,9 @@ function getNotificationsStateFromProps(props: Props): State {
pushActivity,
pushStatus,
desktopSound: sound,
callsDesktopSound: callsSound,
desktopNotificationSound,
callsNotificationSound,
usernameKey,
customKeys,
customKeysChecked: customKeys.length > 0,
@@ -197,7 +211,9 @@ export default class NotificationsTab extends React.PureComponent<Props, State>
const data: UserNotifyProps = {} as UserNotifyProps;
data.email = this.state.enableEmail;
data.desktop_sound = this.state.desktopSound;
data.calls_desktop_sound = this.state.callsDesktopSound;
data.desktop_notification_sound = this.state.desktopNotificationSound;
data.calls_notification_sound = this.state.callsNotificationSound;
data.desktop = this.state.desktopActivity;
data.desktop_threads = this.state.desktopThreads;
data.email_threads = this.state.emailThreads;
@@ -230,6 +246,7 @@ export default class NotificationsTab extends React.PureComponent<Props, State>
data.channel = this.state.channelKey.toString() as UserNotifyProps['channel'];
this.setState({isSaving: true});
NotificationSounds.stopTryNotificationRing();
this.props.actions.updateMe({notify_props: data} as UserProfile).
then(({data: result, error: err}) => {
@@ -242,7 +259,10 @@ export default class NotificationsTab extends React.PureComponent<Props, State>
});
};
handleCancel = (): void => this.setState(getNotificationsStateFromProps(this.props));
handleCancel = (): void => {
this.setState(getNotificationsStateFromProps(this.props));
NotificationSounds.stopTryNotificationRing();
};
handleUpdateSection = (section: string): void => {
if (section) {
@@ -1026,6 +1046,7 @@ export default class NotificationsTab extends React.PureComponent<Props, State>
activity={this.state.desktopActivity}
threads={this.state.desktopThreads}
sound={this.state.desktopSound}
callsSound={this.state.callsDesktopSound}
updateSection={this.handleUpdateSection}
setParentState={this.setStateValue}
submit={this.handleSubmit}
@@ -1034,8 +1055,10 @@ export default class NotificationsTab extends React.PureComponent<Props, State>
error={this.state.serverError}
active={this.props.activeSection === 'desktop'}
selectedSound={this.state.desktopNotificationSound || 'default'}
callsSelectedSound={this.state.callsNotificationSound || 'default'}
isCollapsedThreadsEnabled={this.props.isCollapsedThreadsEnabled}
areAllSectionsInactive={this.props.activeSection === ''}
isCallsEnabled={this.props.isCallsEnabled}
/>
<div className='divider-light'/>
<EmailNotificationSetting

Просмотреть файл

@@ -5467,6 +5467,7 @@
"user.settings.notifications.desktop.allNoSound": "For all activity, without sound",
"user.settings.notifications.desktop.allSound": "For all activity, with sound",
"user.settings.notifications.desktop.allSoundHidden": "For all activity",
"user.settings.notifications.desktop.calls_sound": "Notification sound for incoming calls",
"user.settings.notifications.desktop.mentionsNoSound": "For mentions and direct messages, without sound",
"user.settings.notifications.desktop.mentionsSound": "For mentions and direct messages, with sound",
"user.settings.notifications.desktop.mentionsSoundHidden": "For mentions and direct messages",

Просмотреть файл

@@ -100,6 +100,7 @@ class TestHelper {
comments: 'never',
desktop: 'default',
desktop_sound: 'false',
calls_desktop_sound: 'true',
email: 'false',
first_name: 'false',
mark_unread: 'mention',
@@ -140,6 +141,7 @@ class TestHelper {
comments: 'never',
desktop: 'default',
desktop_sound: 'false',
calls_desktop_sound: 'true',
email: 'false',
first_name: 'false',
mark_unread: 'mention',
@@ -463,6 +465,7 @@ class TestHelper {
return {
desktop: 'default',
desktop_sound: 'true',
calls_desktop_sound: 'true',
email: 'true',
mark_unread: 'all',
push: 'default',

Просмотреть файл

@@ -7,6 +7,7 @@ import {getSelectedPostId, getIsRhsOpen} from 'selectors/rhs';
import BotTag from 'components/widgets/tag/bot_tag';
import messageHtmlToComponent from 'utils/message_html_to_component';
import * as NotificationSounds from 'utils/notification_sounds';
import {formatText} from 'utils/text_formatting';
import {getHistory} from 'utils/browser_history';
@@ -48,6 +49,7 @@ window.openInteractiveDialog = openInteractiveDialog;
window.useNotifyAdmin = useNotifyAdmin;
window.WebappUtils = {
modals: {openModal, ModalIdentifiers},
notificationSounds: {ring: NotificationSounds.ring, stopRing: NotificationSounds.stopRing},
};
Object.defineProperty(window.WebappUtils, 'browserHistory', {
get: () => getHistory(),

11
webapp/channels/src/selectors/calls.ts Обычный файл
Просмотреть файл

@@ -0,0 +1,11 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {GlobalState} from 'types/store';
import {suitePluginIds} from 'utils/constants';
import semver from 'semver';
export function isCallsEnabled(state: GlobalState, minVersion = '0.4.2') {
return state.plugins.plugins[suitePluginIds.calls] &&
semver.gte(state.plugins.plugins[suitePluginIds.calls].version || '0.0.0', minVersion);
}

Двоичные данные
webapp/channels/src/sounds/calls_calm.mp3 Обычный файл

Двоичный файл не отображается.

Двоичные данные
webapp/channels/src/sounds/calls_cheerful.mp3 Обычный файл

Двоичный файл не отображается.

Двоичные данные
webapp/channels/src/sounds/calls_dynamic.mp3 Обычный файл

Двоичный файл не отображается.

Двоичные данные
webapp/channels/src/sounds/calls_urgent.mp3 Обычный файл

Двоичный файл не отображается.

4
webapp/channels/src/types/sounds.d.ts поставляемый
Просмотреть файл

@@ -7,3 +7,7 @@ declare module 'sounds/down.mp3';
declare module 'sounds/hello.mp3';
declare module 'sounds/ripple.mp3';
declare module 'sounds/upstairs.mp3';
declare module 'sounds/calls_dynamic.mp3';
declare module 'sounds/calls_calm.mp3';
declare module 'sounds/calls_urgent.mp3';
declare module 'sounds/calls_cheerful.mp3';

Просмотреть файл

@@ -7,6 +7,10 @@ import down from 'sounds/down.mp3';
import hello from 'sounds/hello.mp3';
import ripple from 'sounds/ripple.mp3';
import upstairs from 'sounds/upstairs.mp3';
import calls_dynamic from 'sounds/calls_dynamic.mp3';
import calls_calm from 'sounds/calls_calm.mp3';
import calls_urgent from 'sounds/calls_urgent.mp3';
import calls_cheerful from 'sounds/calls_cheerful.mp3';
import * as UserAgent from 'utils/user_agent';
@@ -19,6 +23,13 @@ export const notificationSounds = new Map([
['Upstairs', upstairs],
]);
export const callsNotificationSounds = new Map([
['Dynamic', calls_dynamic],
['Calm', calls_calm],
['Urgent', calls_urgent],
['Cheerful', calls_cheerful],
]);
let canDing = true;
export function ding(name: string) {
if (hasSoundOptions() && canDing) {
@@ -35,6 +46,48 @@ export function tryNotificationSound(name: string) {
audio.play();
}
let currentRing: HTMLAudioElement | null = null;
export function ring(name: string) {
if (!hasSoundOptions()) {
return;
}
stopRing();
currentRing = loopNotificationRing(name);
}
export function stopRing() {
currentRing?.pause();
currentRing = null;
}
let currentTryRing: HTMLAudioElement | null = null;
let currentTimer: NodeJS.Timeout;
export function tryNotificationRing(name: string) {
if (!hasSoundOptions()) {
return;
}
stopTryNotificationRing();
clearTimeout(currentTimer);
currentTryRing = loopNotificationRing(name);
currentTimer = setTimeout(() => {
stopTryNotificationRing();
}, 5000);
}
export function stopTryNotificationRing() {
currentTryRing?.pause();
currentTryRing = null;
}
export function loopNotificationRing(name: string) {
const audio = new Audio(callsNotificationSounds.get(name) ?? callsNotificationSounds.get('Dynamic'));
audio.loop = true;
audio.play();
return audio;
}
export function hasSoundOptions() {
return (!UserAgent.isEdge());
}

Просмотреть файл

@@ -27,6 +27,7 @@ describe('Utils.Route', () => {
props: {userid: '121'},
notify_props: {desktop: 'default',
desktop_sound: 'false',
calls_desktop_sound: 'true',
email: 'true',
mark_unread: 'all',
push: 'default',
@@ -84,6 +85,7 @@ describe('Utils.Route', () => {
props: {userid: '121'},
notify_props: {desktop: 'default',
desktop_sound: 'false',
calls_desktop_sound: 'true',
email: 'true',
mark_unread: 'all',
push: 'default',

Просмотреть файл

@@ -47,6 +47,7 @@ export class TestHelper {
comments: 'never',
desktop: 'default',
desktop_sound: 'false',
calls_desktop_sound: 'true',
email: 'false',
first_name: 'false',
mark_unread: 'mention',

Просмотреть файл

@@ -11,6 +11,7 @@ import {IDMappedObjects, RelationOneToMany, RelationOneToManyUnique, RelationOne
export type UserNotifyProps = {
desktop: 'default' | 'all' | 'mention' | 'none';
desktop_sound: 'true' | 'false';
calls_desktop_sound: 'true' | 'false';
email: 'true' | 'false';
mark_unread: 'all' | 'mention';
push: 'default' | 'all' | 'mention' | 'none';
@@ -20,6 +21,7 @@ export type UserNotifyProps = {
channel: 'true' | 'false';
mention_keys: string;
desktop_notification_sound?: 'Bing' | 'Crackle' | 'Down' | 'Hello' | 'Ripple' | 'Upstairs';
calls_notification_sound?: 'Dynamic' | 'Calm' | 'Urgent' | 'Cheerful';
desktop_threads?: 'default' | 'all' | 'mention' | 'none';
email_threads?: 'default' | 'all' | 'mention' | 'none';
push_threads?: 'default' | 'all' | 'mention' | 'none';