({
id: 'globalThreads.threadPane.unreadMessageLink',
defaultMessage: 'You have {numUnread, plural, =0 {no unread threads} =1 {{numUnread} thread} other {{numUnread} threads}} {numUnread, plural, =0 {} other {with unread messages}}',
}, {
diff --git a/webapp/channels/src/components/threading/global_threads/thread_list/thread_list.tsx b/webapp/channels/src/components/threading/global_threads/thread_list/thread_list.tsx
index 06a3d7dd7b..c49571f1c9 100644
--- a/webapp/channels/src/components/threading/global_threads/thread_list/thread_list.tsx
+++ b/webapp/channels/src/components/threading/global_threads/thread_list/thread_list.tsx
@@ -8,7 +8,7 @@ import {isEmpty} from 'lodash';
import {PlaylistCheckIcon} from '@mattermost/compass-icons/components';
-import * as Utils from 'utils/utils';
+import * as Keyboard from 'utils/keyboard';
import {getThreadCountsInCurrentTeam} from 'mattermost-redux/selectors/entities/threads';
import {getThreads, markAllThreadsInTeamRead} from 'mattermost-redux/actions/threads';
import {trackEvent} from 'actions/telemetry_actions';
@@ -80,7 +80,7 @@ const ThreadList = ({
return;
}
const comboKeyPressed = e.altKey || e.metaKey || e.shiftKey || e.ctrlKey;
- if (comboKeyPressed || (!Utils.isKeyPressed(e, Constants.KeyCodes.DOWN) && !Utils.isKeyPressed(e, Constants.KeyCodes.UP))) {
+ if (comboKeyPressed || (!Keyboard.isKeyPressed(e, Constants.KeyCodes.DOWN) && !Keyboard.isKeyPressed(e, Constants.KeyCodes.UP))) {
return;
}
@@ -94,7 +94,7 @@ const ThreadList = ({
let threadIdToSelect = 0;
if (selectedThreadId) {
const selectedThreadIndex = data.indexOf(selectedThreadId);
- if (Utils.isKeyPressed(e, Constants.KeyCodes.DOWN)) {
+ if (Keyboard.isKeyPressed(e, Constants.KeyCodes.DOWN)) {
if (selectedThreadIndex < data.length - 1) {
threadIdToSelect = selectedThreadIndex + 1;
}
@@ -104,7 +104,7 @@ const ThreadList = ({
}
}
- if (Utils.isKeyPressed(e, Constants.KeyCodes.UP)) {
+ if (Keyboard.isKeyPressed(e, Constants.KeyCodes.UP)) {
if (selectedThreadIndex > 0) {
threadIdToSelect = selectedThreadIndex - 1;
} else {
diff --git a/webapp/channels/src/components/toast_wrapper/toast_wrapper.tsx b/webapp/channels/src/components/toast_wrapper/toast_wrapper.tsx
index 45f0033ffa..11b37d203d 100644
--- a/webapp/channels/src/components/toast_wrapper/toast_wrapper.tsx
+++ b/webapp/channels/src/components/toast_wrapper/toast_wrapper.tsx
@@ -7,8 +7,9 @@ import {RouteComponentProps} from 'react-router-dom';
import {Preferences} from 'mattermost-redux/constants';
+import {isKeyPressed} from 'utils/keyboard';
import {isIdNotPost, getNewMessageIndex} from 'utils/post_utils';
-import {isKeyPressed, localizeMessage} from 'utils/utils';
+import {localizeMessage} from 'utils/utils';
import {isToday} from 'utils/datetime';
import Constants from 'utils/constants';
import {getHistory} from 'utils/browser_history';
diff --git a/webapp/channels/src/components/tours/crt_tour/collapsed_reply_threads_modal/collapsed_reply_threads_modal.tsx b/webapp/channels/src/components/tours/crt_tour/collapsed_reply_threads_modal/collapsed_reply_threads_modal.tsx
index 8f529e9df0..106cccae55 100644
--- a/webapp/channels/src/components/tours/crt_tour/collapsed_reply_threads_modal/collapsed_reply_threads_modal.tsx
+++ b/webapp/channels/src/components/tours/crt_tour/collapsed_reply_threads_modal/collapsed_reply_threads_modal.tsx
@@ -13,7 +13,7 @@ import GenericModal from 'components/generic_modal';
import NextIcon from 'components/widgets/icons/fa_next_icon';
import FormattedMarkdownMessage from 'components/formatted_markdown_message';
import {Constants, ModalIdentifiers, Preferences} from 'utils/constants';
-import * as Utils from 'utils/utils';
+import * as Keyboard from 'utils/keyboard';
import './collapsed_reply_threads_modal.scss';
import {AutoTourStatus, TTNameMapToATStatusKey, TutorialTourName} from '../../constant';
@@ -26,7 +26,7 @@ function CollapsedReplyThreadsModal(props: Props) {
const dispatch = useDispatch();
const currentUserId = useSelector(getCurrentUserId);
const handleKeyDown = useCallback((e: KeyboardEvent) => {
- if (Utils.isKeyPressed(e, Constants.KeyCodes.ENTER)) {
+ if (Keyboard.isKeyPressed(e, Constants.KeyCodes.ENTER)) {
onNext();
}
}, []);
diff --git a/webapp/channels/src/components/tours/crt_tour/crt_threads_pane_tutorial_tip.tsx b/webapp/channels/src/components/tours/crt_tour/crt_threads_pane_tutorial_tip.tsx
index 907966e23f..549bdd2521 100644
--- a/webapp/channels/src/components/tours/crt_tour/crt_threads_pane_tutorial_tip.tsx
+++ b/webapp/channels/src/components/tours/crt_tour/crt_threads_pane_tutorial_tip.tsx
@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import React from 'react';
+import React, {ReactNode} from 'react';
import {FormattedMessage, useIntl} from 'react-intl';
import {useDispatch, useSelector} from 'react-redux';
@@ -29,7 +29,7 @@ const CRTThreadsPaneTutorialTip = () => {
const screen = (
- {formatMessage(
+ {formatMessage(
{
id: 'tutorial_threads.threads_pane.description',
defaultMessage: 'Click the Follow button to be notified about replies and see it in your Threads view. Within a thread, the New Messages line shows you where you left off.',
diff --git a/webapp/channels/src/components/tours/crt_tour/crt_unread_tutorial_tip.tsx b/webapp/channels/src/components/tours/crt_tour/crt_unread_tutorial_tip.tsx
index 37b3d2e8c7..f86d207528 100644
--- a/webapp/channels/src/components/tours/crt_tour/crt_unread_tutorial_tip.tsx
+++ b/webapp/channels/src/components/tours/crt_tour/crt_unread_tutorial_tip.tsx
@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import React from 'react';
+import React, {ReactNode} from 'react';
import {FormattedMessage, useIntl} from 'react-intl';
import {useMeasurePunchouts} from '@mattermost/components';
@@ -19,7 +19,7 @@ const CRTUnreadTutorialTip = () => {
const screen = (
- {formatMessage(
+ {formatMessage(
{
id: 'tutorial_threads.unread.description',
defaultMessage: 'You can switch to Unreads to show only threads that are unread.',
diff --git a/webapp/channels/src/components/update_user_group_modal/update_user_group_modal.tsx b/webapp/channels/src/components/update_user_group_modal/update_user_group_modal.tsx
index aeae2f4969..e82b9c802f 100644
--- a/webapp/channels/src/components/update_user_group_modal/update_user_group_modal.tsx
+++ b/webapp/channels/src/components/update_user_group_modal/update_user_group_modal.tsx
@@ -7,6 +7,7 @@ import {Modal} from 'react-bootstrap';
import {FormattedMessage} from 'react-intl';
+import * as Keyboard from 'utils/keyboard';
import * as Utils from 'utils/utils';
import {CustomGroupPatch, Group} from '@mattermost/types/groups';
@@ -52,7 +53,7 @@ const UpdateUserGroupModal = (props: Props) => {
}, [name, mention, hasUpdated, saving]);
const handleKeyDown = useCallback((e: KeyboardEvent) => {
- if (Utils.isKeyPressed(e, Constants.KeyCodes.ENTER) && isSaveEnabled()) {
+ if (Keyboard.isKeyPressed(e, Constants.KeyCodes.ENTER) && isSaveEnabled()) {
patchGroup();
}
}, [name, mention, hasUpdated, saving]);
diff --git a/webapp/channels/src/components/user_group_popover/__snapshots__/user_group_popover.test.tsx.snap b/webapp/channels/src/components/user_group_popover/__snapshots__/user_group_popover.test.tsx.snap
index bada1bc768..bb7813eb26 100644
--- a/webapp/channels/src/components/user_group_popover/__snapshots__/user_group_popover.test.tsx.snap
+++ b/webapp/channels/src/components/user_group_popover/__snapshots__/user_group_popover.test.tsx.snap
@@ -1177,9 +1177,11 @@ exports[`component/user_group_popover should match snapshot 1`] = `
id="name-id0"
intl={
Object {
+ "$t": [Function],
"defaultFormats": Object {},
"defaultLocale": "en",
"defaultRichTextElements": undefined,
+ "fallbackOnEmptyString": true,
"formatDate": [Function],
"formatDateTimeRange": [Function],
"formatDateToParts": [Function],
@@ -1206,6 +1208,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"locale": "en",
"messages": Object {},
"onError": [Function],
+ "onWarn": [Function],
"textComponent": "span",
"timeZone": "Etc/UTC",
"wrapRichTextChunksInFragment": undefined,
@@ -1393,9 +1396,11 @@ exports[`component/user_group_popover should match snapshot 1`] = `
id="name-id1"
intl={
Object {
+ "$t": [Function],
"defaultFormats": Object {},
"defaultLocale": "en",
"defaultRichTextElements": undefined,
+ "fallbackOnEmptyString": true,
"formatDate": [Function],
"formatDateTimeRange": [Function],
"formatDateToParts": [Function],
@@ -1422,6 +1427,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"locale": "en",
"messages": Object {},
"onError": [Function],
+ "onWarn": [Function],
"textComponent": "span",
"timeZone": "Etc/UTC",
"wrapRichTextChunksInFragment": undefined,
@@ -1609,9 +1615,11 @@ exports[`component/user_group_popover should match snapshot 1`] = `
id="name-id10"
intl={
Object {
+ "$t": [Function],
"defaultFormats": Object {},
"defaultLocale": "en",
"defaultRichTextElements": undefined,
+ "fallbackOnEmptyString": true,
"formatDate": [Function],
"formatDateTimeRange": [Function],
"formatDateToParts": [Function],
@@ -1638,6 +1646,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"locale": "en",
"messages": Object {},
"onError": [Function],
+ "onWarn": [Function],
"textComponent": "span",
"timeZone": "Etc/UTC",
"wrapRichTextChunksInFragment": undefined,
@@ -1825,9 +1834,11 @@ exports[`component/user_group_popover should match snapshot 1`] = `
id="name-id11"
intl={
Object {
+ "$t": [Function],
"defaultFormats": Object {},
"defaultLocale": "en",
"defaultRichTextElements": undefined,
+ "fallbackOnEmptyString": true,
"formatDate": [Function],
"formatDateTimeRange": [Function],
"formatDateToParts": [Function],
@@ -1854,6 +1865,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"locale": "en",
"messages": Object {},
"onError": [Function],
+ "onWarn": [Function],
"textComponent": "span",
"timeZone": "Etc/UTC",
"wrapRichTextChunksInFragment": undefined,
@@ -2041,9 +2053,11 @@ exports[`component/user_group_popover should match snapshot 1`] = `
id="name-id12"
intl={
Object {
+ "$t": [Function],
"defaultFormats": Object {},
"defaultLocale": "en",
"defaultRichTextElements": undefined,
+ "fallbackOnEmptyString": true,
"formatDate": [Function],
"formatDateTimeRange": [Function],
"formatDateToParts": [Function],
@@ -2070,6 +2084,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
"locale": "en",
"messages": Object {},
"onError": [Function],
+ "onWarn": [Function],
"textComponent": "span",
"timeZone": "Etc/UTC",
"wrapRichTextChunksInFragment": undefined,
diff --git a/webapp/channels/src/components/user_group_popover/group_member_list/__snapshots__/group_member_list.test.tsx.snap b/webapp/channels/src/components/user_group_popover/group_member_list/__snapshots__/group_member_list.test.tsx.snap
index 2af3bd35f5..5b176b147b 100644
--- a/webapp/channels/src/components/user_group_popover/group_member_list/__snapshots__/group_member_list.test.tsx.snap
+++ b/webapp/channels/src/components/user_group_popover/group_member_list/__snapshots__/group_member_list.test.tsx.snap
@@ -457,9 +457,11 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
id="name-id0"
intl={
Object {
+ "$t": [Function],
"defaultFormats": Object {},
"defaultLocale": "en",
"defaultRichTextElements": undefined,
+ "fallbackOnEmptyString": true,
"formatDate": [Function],
"formatDateTimeRange": [Function],
"formatDateToParts": [Function],
@@ -486,6 +488,7 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
"locale": "en",
"messages": Object {},
"onError": [Function],
+ "onWarn": [Function],
"textComponent": "span",
"timeZone": "Etc/UTC",
"wrapRichTextChunksInFragment": undefined,
@@ -673,9 +676,11 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
id="name-id1"
intl={
Object {
+ "$t": [Function],
"defaultFormats": Object {},
"defaultLocale": "en",
"defaultRichTextElements": undefined,
+ "fallbackOnEmptyString": true,
"formatDate": [Function],
"formatDateTimeRange": [Function],
"formatDateToParts": [Function],
@@ -702,6 +707,7 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
"locale": "en",
"messages": Object {},
"onError": [Function],
+ "onWarn": [Function],
"textComponent": "span",
"timeZone": "Etc/UTC",
"wrapRichTextChunksInFragment": undefined,
@@ -889,9 +895,11 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
id="name-id2"
intl={
Object {
+ "$t": [Function],
"defaultFormats": Object {},
"defaultLocale": "en",
"defaultRichTextElements": undefined,
+ "fallbackOnEmptyString": true,
"formatDate": [Function],
"formatDateTimeRange": [Function],
"formatDateToParts": [Function],
@@ -918,6 +926,7 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
"locale": "en",
"messages": Object {},
"onError": [Function],
+ "onWarn": [Function],
"textComponent": "span",
"timeZone": "Etc/UTC",
"wrapRichTextChunksInFragment": undefined,
@@ -1105,9 +1114,11 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
id="name-id3"
intl={
Object {
+ "$t": [Function],
"defaultFormats": Object {},
"defaultLocale": "en",
"defaultRichTextElements": undefined,
+ "fallbackOnEmptyString": true,
"formatDate": [Function],
"formatDateTimeRange": [Function],
"formatDateToParts": [Function],
@@ -1134,6 +1145,7 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
"locale": "en",
"messages": Object {},
"onError": [Function],
+ "onWarn": [Function],
"textComponent": "span",
"timeZone": "Etc/UTC",
"wrapRichTextChunksInFragment": undefined,
@@ -1321,9 +1333,11 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
id="name-id4"
intl={
Object {
+ "$t": [Function],
"defaultFormats": Object {},
"defaultLocale": "en",
"defaultRichTextElements": undefined,
+ "fallbackOnEmptyString": true,
"formatDate": [Function],
"formatDateTimeRange": [Function],
"formatDateToParts": [Function],
@@ -1350,6 +1364,7 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
"locale": "en",
"messages": Object {},
"onError": [Function],
+ "onWarn": [Function],
"textComponent": "span",
"timeZone": "Etc/UTC",
"wrapRichTextChunksInFragment": undefined,
diff --git a/webapp/channels/src/components/user_group_popover/user_group_popover.tsx b/webapp/channels/src/components/user_group_popover/user_group_popover.tsx
index e543e9ff86..523df8f013 100644
--- a/webapp/channels/src/components/user_group_popover/user_group_popover.tsx
+++ b/webapp/channels/src/components/user_group_popover/user_group_popover.tsx
@@ -14,7 +14,7 @@ import {Group} from '@mattermost/types/groups';
import {ActionResult} from 'mattermost-redux/types/actions';
import {shouldFocusMainTextbox} from 'utils/post_utils';
-import * as Utils from 'utils/utils';
+import * as Keyboard from 'utils/keyboard';
import Constants, {A11yClassNames, A11yCustomEventTypes, A11yFocusEventDetail, ModalIdentifiers} from 'utils/constants';
import {QuickInput} from 'components/quick_input/quick_input';
@@ -169,7 +169,7 @@ const UserGroupPopover = (props: Props) => {
const handleKeyDown = (e: React.KeyboardEvent) => {
if (shouldFocusMainTextbox(e, document.activeElement)) {
hide();
- } else if (Utils.isKeyPressed(e, Constants.KeyCodes.ESCAPE)) {
+ } else if (Keyboard.isKeyPressed(e, Constants.KeyCodes.ESCAPE)) {
returnFocus();
}
};
diff --git a/webapp/channels/src/components/user_settings/advanced/user_settings_advanced.test.tsx b/webapp/channels/src/components/user_settings/advanced/user_settings_advanced.test.tsx
index 03854f35ef..9ef4be1ef2 100644
--- a/webapp/channels/src/components/user_settings/advanced/user_settings_advanced.test.tsx
+++ b/webapp/channels/src/components/user_settings/advanced/user_settings_advanced.test.tsx
@@ -8,10 +8,10 @@ import AdvancedSettingsDisplay from 'components/user_settings/advanced/user_sett
import {Preferences} from 'utils/constants';
import {TestHelper} from 'utils/test_helper';
-import {isMac} from 'utils/utils';
+import {isMac} from 'utils/user_agent';
jest.mock('actions/global_actions');
-jest.mock('utils/utils');
+jest.mock('utils/user_agent');
describe('components/user_settings/display/UserSettingsDisplay', () => {
const user = TestHelper.getUserMock({
diff --git a/webapp/channels/src/components/user_settings/advanced/user_settings_advanced.tsx b/webapp/channels/src/components/user_settings/advanced/user_settings_advanced.tsx
index 660ca1e8ae..c4dc2b556e 100644
--- a/webapp/channels/src/components/user_settings/advanced/user_settings_advanced.tsx
+++ b/webapp/channels/src/components/user_settings/advanced/user_settings_advanced.tsx
@@ -10,7 +10,8 @@ import {emitUserLoggedOutEvent} from 'actions/global_actions';
import Constants, {AdvancedSections, Preferences} from 'utils/constants';
import {t} from 'utils/i18n';
-import {a11yFocus, isMac, localizeMessage} from 'utils/utils';
+import {isMac} from 'utils/user_agent';
+import {a11yFocus, localizeMessage} from 'utils/utils';
import SettingItemMax from 'components/setting_item_max';
import ConfirmModal from 'components/confirm_modal';
diff --git a/webapp/channels/src/components/user_settings/display/manage_languages/manage_languages.tsx b/webapp/channels/src/components/user_settings/display/manage_languages/manage_languages.tsx
index 98c30d1668..1ed2d04de9 100644
--- a/webapp/channels/src/components/user_settings/display/manage_languages/manage_languages.tsx
+++ b/webapp/channels/src/components/user_settings/display/manage_languages/manage_languages.tsx
@@ -10,7 +10,7 @@ import SettingItemMax from 'components/setting_item_max';
import {ActionResult} from 'mattermost-redux/types/actions';
import * as I18n from 'i18n/i18n.jsx';
-import {isKeyPressed} from 'utils/utils';
+import {isKeyPressed} from 'utils/keyboard';
import Constants from 'utils/constants';
import {UserProfile} from '@mattermost/types/users';
diff --git a/webapp/channels/src/components/user_settings/modal/user_settings_modal.tsx b/webapp/channels/src/components/user_settings/modal/user_settings_modal.tsx
index 1c0fc6f932..bdba21b1e6 100644
--- a/webapp/channels/src/components/user_settings/modal/user_settings_modal.tsx
+++ b/webapp/channels/src/components/user_settings/modal/user_settings_modal.tsx
@@ -15,6 +15,7 @@ import {UserProfile} from '@mattermost/types/users';
import {StatusOK} from '@mattermost/types/client4';
import store from 'stores/redux_store.jsx';
import Constants from 'utils/constants';
+import * as Keyboard from 'utils/keyboard';
import * as Utils from 'utils/utils';
import {t} from 'utils/i18n';
import ConfirmModal from 'components/confirm_modal';
@@ -146,7 +147,7 @@ class UserSettingsModal extends React.PureComponent {
}
handleKeyDown = (e: KeyboardEvent) => {
- if (Utils.cmdOrCtrlPressed(e) && e.shiftKey && Utils.isKeyPressed(e, Constants.KeyCodes.A)) {
+ if (Keyboard.cmdOrCtrlPressed(e) && e.shiftKey && Keyboard.isKeyPressed(e, Constants.KeyCodes.A)) {
e.preventDefault();
this.handleHide();
}
diff --git a/webapp/channels/src/components/user_settings/notifications/desktop_notification_setting/desktop_notification_settings.test.tsx b/webapp/channels/src/components/user_settings/notifications/desktop_notification_setting/desktop_notification_settings.test.tsx
index d703d781ed..722e917ac2 100644
--- a/webapp/channels/src/components/user_settings/notifications/desktop_notification_setting/desktop_notification_settings.test.tsx
+++ b/webapp/channels/src/components/user_settings/notifications/desktop_notification_setting/desktop_notification_settings.test.tsx
@@ -8,8 +8,8 @@ import {NotificationLevels} from 'utils/constants';
import DesktopNotificationSettings from './desktop_notification_settings';
-jest.mock('utils/utils', () => {
- const original = jest.requireActual('utils/utils');
+jest.mock('utils/notification_sounds', () => {
+ const original = jest.requireActual('utils/notification_sounds');
return {
...original,
hasSoundOptions: jest.fn(() => true),
diff --git a/webapp/channels/src/components/user_settings/notifications/desktop_notification_setting/desktop_notification_settings.tsx b/webapp/channels/src/components/user_settings/notifications/desktop_notification_setting/desktop_notification_settings.tsx
index 9c0d3eefa2..56a7e711ba 100644
--- a/webapp/channels/src/components/user_settings/notifications/desktop_notification_setting/desktop_notification_settings.tsx
+++ b/webapp/channels/src/components/user_settings/notifications/desktop_notification_setting/desktop_notification_settings.tsx
@@ -8,6 +8,7 @@ import {FormattedMessage} from 'react-intl';
import semver from 'semver';
import {NotificationLevels} from 'utils/constants';
+import * as NotificationSounds from 'utils/notification_sounds';
import * as Utils from 'utils/utils';
import {t} from 'utils/i18n';
import {isDesktopApp} from 'utils/user_agent';
@@ -86,7 +87,7 @@ export default class DesktopNotificationSettings extends React.PureComponent {
return {value: sound, label: sound};
});
@@ -144,7 +145,7 @@ export default class DesktopNotificationSettings extends React.PureComponent