[MM-59299] Investigate further breaking down chunks of components/node_modules for initial load (#27845)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
e104575505
Коммит
7232feecf7
@@ -13,6 +13,7 @@ exports[`components/FileUploadOverlay should match snapshot when file upload is
|
||||
<img
|
||||
alt="Files"
|
||||
className="overlay__files"
|
||||
loading="lazy"
|
||||
src=""
|
||||
/>
|
||||
<span>
|
||||
@@ -28,6 +29,7 @@ exports[`components/FileUploadOverlay should match snapshot when file upload is
|
||||
<img
|
||||
alt="Logo"
|
||||
className="overlay__logo"
|
||||
loading="lazy"
|
||||
src=""
|
||||
/>
|
||||
</div>
|
||||
@@ -48,6 +50,7 @@ exports[`components/FileUploadOverlay should match snapshot when file upload is
|
||||
<img
|
||||
alt="Files"
|
||||
className="overlay__files"
|
||||
loading="lazy"
|
||||
src=""
|
||||
/>
|
||||
<span>
|
||||
@@ -63,6 +66,7 @@ exports[`components/FileUploadOverlay should match snapshot when file upload is
|
||||
<img
|
||||
alt="Logo"
|
||||
className="overlay__logo"
|
||||
loading="lazy"
|
||||
src=""
|
||||
/>
|
||||
</div>
|
||||
@@ -83,6 +87,7 @@ exports[`components/FileUploadOverlay should match snapshot when file upload is
|
||||
<img
|
||||
alt="Files"
|
||||
className="overlay__files"
|
||||
loading="lazy"
|
||||
src=""
|
||||
/>
|
||||
<span>
|
||||
@@ -98,6 +103,7 @@ exports[`components/FileUploadOverlay should match snapshot when file upload is
|
||||
<img
|
||||
alt="Logo"
|
||||
className="overlay__logo"
|
||||
loading="lazy"
|
||||
src=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import classNames from 'classnames';
|
||||
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
|
||||
import React, {lazy, useCallback, useEffect, useMemo, useRef, useState} from 'react';
|
||||
import {FormattedMessage, useIntl} from 'react-intl';
|
||||
import {useDispatch, useSelector} from 'react-redux';
|
||||
|
||||
@@ -24,9 +24,9 @@ import {makeGetDraft} from 'selectors/rhs';
|
||||
import {connectionErrorCount} from 'selectors/views/system';
|
||||
import LocalStorageStore from 'stores/local_storage_store';
|
||||
|
||||
import {makeAsyncComponent} from 'components/async_load';
|
||||
import AutoHeightSwitcher from 'components/common/auto_height_switcher';
|
||||
import useDidUpdate from 'components/common/hooks/useDidUpdate';
|
||||
import FileLimitStickyBanner from 'components/file_limit_sticky_banner';
|
||||
import MessageSubmitError from 'components/message_submit_error';
|
||||
import MsgTyping from 'components/msg_typing';
|
||||
import RhsSuggestionList from 'components/suggestion/rhs_suggestion_list';
|
||||
@@ -66,6 +66,8 @@ import useUploadFiles from './use_upload_files';
|
||||
|
||||
import './advanced_text_editor.scss';
|
||||
|
||||
const FileLimitStickyBanner = makeAsyncComponent('FileLimitStickyBanner', lazy(() => import('components/file_limit_sticky_banner')));
|
||||
|
||||
function isDraftEmpty(draft: PostDraft) {
|
||||
return draft.message === '' && draft.fileInfos.length === 0 && draft.uploadsInProgress.length === 0;
|
||||
}
|
||||
|
||||
@@ -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, {lazy} from 'react';
|
||||
import {hot} from 'react-hot-loader/root';
|
||||
import {Provider} from 'react-redux';
|
||||
import {Router} from 'react-router-dom';
|
||||
@@ -11,7 +11,7 @@ import store from 'stores/redux_store';
|
||||
import {makeAsyncComponent} from 'components/async_load';
|
||||
|
||||
import {getHistory} from 'utils/browser_history';
|
||||
const LazyRoot = React.lazy(() => import('components/root'));
|
||||
const LazyRoot = lazy(() => import('components/root'));
|
||||
|
||||
const Root = makeAsyncComponent('Root', LazyRoot);
|
||||
|
||||
|
||||
@@ -2,43 +2,34 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
import React, {lazy} from 'react';
|
||||
import {Route, Switch, Redirect} from 'react-router-dom';
|
||||
|
||||
import {makeAsyncComponent} from 'components/async_load';
|
||||
import ChannelIdentifierRouter from 'components/channel_layout/channel_identifier_router';
|
||||
import PlaybookRunner from 'components/channel_layout/playbook_runner';
|
||||
import LoadingScreen from 'components/loading_screen';
|
||||
import PermalinkView from 'components/permalink_view';
|
||||
|
||||
import {IDENTIFIER_PATH_PATTERN, ID_PATH_PATTERN, TEAM_NAME_PATH_PATTERN} from 'utils/path';
|
||||
|
||||
import type {OwnProps, PropsFromRedux} from './index';
|
||||
|
||||
const LazyChannelHeaderMobile = makeAsyncComponent(
|
||||
'LazyChannelHeaderMobile',
|
||||
React.lazy(() => import('components/channel_header_mobile')),
|
||||
);
|
||||
|
||||
const LazyGlobalThreads = makeAsyncComponent(
|
||||
'LazyGlobalThreads',
|
||||
React.lazy(() => import('components/threading/global_threads')),
|
||||
const ChannelHeaderMobile = makeAsyncComponent('ChannelHeaderMobile', lazy(() => import('components/channel_header_mobile')));
|
||||
const GlobalThreads = makeAsyncComponent('GlobalThreads', lazy(() => import('components/threading/global_threads')),
|
||||
(
|
||||
<div className='app__content'>
|
||||
<LoadingScreen/>
|
||||
</div>
|
||||
),
|
||||
);
|
||||
|
||||
const LazyDrafts = makeAsyncComponent(
|
||||
'LazyDrafts',
|
||||
React.lazy(() => import('components/drafts')),
|
||||
const Drafts = makeAsyncComponent('Drafts', lazy(() => import('components/drafts')),
|
||||
(
|
||||
<div className='app__content'>
|
||||
<LoadingScreen/>
|
||||
</div>
|
||||
),
|
||||
);
|
||||
const PermalinkView = makeAsyncComponent('PermalinkView', lazy(() => import('components/permalink_view')));
|
||||
const PlaybookRunner = makeAsyncComponent('PlaybookRunner', lazy(() => import('components/channel_layout/playbook_runner')));
|
||||
|
||||
type Props = PropsFromRedux & OwnProps;
|
||||
|
||||
@@ -85,11 +76,13 @@ export default class CenterChannel extends React.PureComponent<Props, State> {
|
||||
})}
|
||||
>
|
||||
{isMobileView && (
|
||||
<div className='row header'>
|
||||
<div id='navbar_wrapper'>
|
||||
<LazyChannelHeaderMobile/>
|
||||
<>
|
||||
<div className='row header'>
|
||||
<div id='navbar_wrapper'>
|
||||
<ChannelHeaderMobile/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className='row main'>
|
||||
<Switch>
|
||||
@@ -114,12 +107,12 @@ export default class CenterChannel extends React.PureComponent<Props, State> {
|
||||
{isCollapsedThreadsEnabled ? (
|
||||
<Route
|
||||
path={`/:team(${TEAM_NAME_PATH_PATTERN})/threads/:threadIdentifier(${ID_PATH_PATTERN})?`}
|
||||
component={LazyGlobalThreads}
|
||||
component={GlobalThreads}
|
||||
/>
|
||||
) : null}
|
||||
<Route
|
||||
path={`/:team(${TEAM_NAME_PATH_PATTERN})/drafts`}
|
||||
component={LazyDrafts}
|
||||
component={Drafts}
|
||||
/>
|
||||
|
||||
<Redirect to={lastChannelPath}/>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import classNames from 'classnames';
|
||||
import React, {useEffect} from 'react';
|
||||
import React, {lazy, useEffect} from 'react';
|
||||
import {useDispatch, useSelector} from 'react-redux';
|
||||
|
||||
import {cleanUpStatusAndProfileFetchingPoll} from 'mattermost-redux/actions/status_profile_polling';
|
||||
@@ -10,10 +10,9 @@ import {getIsUserStatusesConfigEnabled} from 'mattermost-redux/selectors/entitie
|
||||
|
||||
import {addVisibleUsersInCurrentChannelToStatusPoll} from 'actions/status_actions';
|
||||
|
||||
import {makeAsyncComponent} from 'components/async_load';
|
||||
import CenterChannel from 'components/channel_layout/center_channel';
|
||||
import LoadingScreen from 'components/loading_screen';
|
||||
import ProductNoticesModal from 'components/product_notices_modal';
|
||||
import ResetStatusModal from 'components/reset_status_modal';
|
||||
import Sidebar from 'components/sidebar';
|
||||
import CRTPostsChannelResetWatcher from 'components/threading/channel_threads/posts_channel_reset_watcher';
|
||||
import UnreadsStatusHandler from 'components/unreads_status_handler';
|
||||
@@ -22,6 +21,9 @@ import Pluggable from 'plugins/pluggable';
|
||||
import {Constants} from 'utils/constants';
|
||||
import {isInternetExplorer, isEdge} from 'utils/user_agent';
|
||||
|
||||
const ProductNoticesModal = makeAsyncComponent('ProductNoticesModal', lazy(() => import('components/product_notices_modal')));
|
||||
const ResetStatusModal = makeAsyncComponent('ResetStatusModal', lazy(() => import('components/reset_status_modal')));
|
||||
|
||||
const BODY_CLASS_FOR_CHANNEL = ['app__body', 'channel-view'];
|
||||
|
||||
type Props = {
|
||||
|
||||
@@ -8,7 +8,7 @@ exports[`components/channel_view Should match snapshot if channel is archived 1`
|
||||
<FileUploadOverlay
|
||||
overlayType="center"
|
||||
/>
|
||||
<withRouter(Connect(injectIntl(ChannelHeader)))
|
||||
<ChannelHeader
|
||||
channelId="channelId"
|
||||
channelIsArchived={true}
|
||||
deactivatedChannel={false}
|
||||
@@ -66,7 +66,7 @@ exports[`components/channel_view Should match snapshot if channel is deactivated
|
||||
<FileUploadOverlay
|
||||
overlayType="center"
|
||||
/>
|
||||
<withRouter(Connect(injectIntl(ChannelHeader)))
|
||||
<ChannelHeader
|
||||
channelId="channelId"
|
||||
channelIsArchived={false}
|
||||
deactivatedChannel={true}
|
||||
@@ -123,7 +123,7 @@ exports[`components/channel_view Should match snapshot with base props 1`] = `
|
||||
<FileUploadOverlay
|
||||
overlayType="center"
|
||||
/>
|
||||
<withRouter(Connect(injectIntl(ChannelHeader)))
|
||||
<ChannelHeader
|
||||
channelId="channelId"
|
||||
channelIsArchived={false}
|
||||
deactivatedChannel={false}
|
||||
@@ -152,7 +152,7 @@ exports[`components/channel_view Should match snapshot with base props 1`] = `
|
||||
data-testid="post-create"
|
||||
id="post-create"
|
||||
>
|
||||
<Memo(AdvancedCreatePost) />
|
||||
<AdvancedCreatePost />
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import React, {lazy} from 'react';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
import type {RouteComponentProps} from 'react-router-dom';
|
||||
|
||||
import AdvancedCreatePost from 'components/advanced_create_post';
|
||||
import ChannelBookmarks from 'components/channel_bookmarks';
|
||||
import ChannelHeader from 'components/channel_header';
|
||||
import {makeAsyncComponent} from 'components/async_load';
|
||||
import deferComponentRender from 'components/deferComponentRender';
|
||||
import FileUploadOverlay from 'components/file_upload_overlay';
|
||||
import FormattedMarkdownMessage from 'components/formatted_markdown_message';
|
||||
import PostView from 'components/post_view';
|
||||
|
||||
@@ -17,6 +14,11 @@ import WebSocketClient from 'client/web_websocket_client';
|
||||
|
||||
import type {PropsFromRedux} from './index';
|
||||
|
||||
const ChannelHeader = makeAsyncComponent('ChannelHeader', lazy(() => import('components/channel_header')));
|
||||
const FileUploadOverlay = makeAsyncComponent('FileUploadOverlay', lazy(() => import('components/file_upload_overlay')));
|
||||
const ChannelBookmarks = makeAsyncComponent('ChannelBookmarks', lazy(() => import('components/channel_bookmarks')));
|
||||
const AdvancedCreatePost = makeAsyncComponent('AdvancedCreatePost', lazy(() => import('components/advanced_create_post')));
|
||||
|
||||
export type Props = PropsFromRedux & RouteComponentProps<{
|
||||
postid?: string;
|
||||
}>;
|
||||
|
||||
@@ -29,6 +29,7 @@ const FileUploadOverlay = (props: Props) => {
|
||||
className='overlay__files'
|
||||
src={fileOverlayImage}
|
||||
alt='Files'
|
||||
loading='lazy'
|
||||
/>
|
||||
<span>
|
||||
<i
|
||||
@@ -44,6 +45,7 @@ const FileUploadOverlay = (props: Props) => {
|
||||
className='overlay__logo'
|
||||
src={overlayLogoImage}
|
||||
alt='Logo'
|
||||
loading='lazy'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
40
webapp/channels/src/components/logged_in_route/index.tsx
Обычный файл
40
webapp/channels/src/components/logged_in_route/index.tsx
Обычный файл
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {lazy} from 'react';
|
||||
import type {RouteComponentProps} from 'react-router-dom';
|
||||
import {Route} from 'react-router-dom';
|
||||
|
||||
import type {Theme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
import {makeAsyncComponent} from 'components/async_load';
|
||||
import CompassThemeProvider from 'components/compass_theme_provider/compass_theme_provider';
|
||||
import LoggedIn from 'components/logged_in';
|
||||
|
||||
const OnBoardingTaskList = makeAsyncComponent('OnboardingTaskList', lazy(() => import('components/onboarding_tasklist')));
|
||||
|
||||
type Props = {
|
||||
component: React.ComponentType<RouteComponentProps<any>>;
|
||||
path: string | string[];
|
||||
theme?: Theme; // the routes that send the theme are the ones that will actually need to show the onboarding tasklist
|
||||
};
|
||||
|
||||
export default function LoggedInRoute(props: Props) {
|
||||
const {component: Component, theme, ...rest} = props;
|
||||
|
||||
return (
|
||||
<Route
|
||||
{...rest}
|
||||
render={(routeProps) => (
|
||||
<LoggedIn {...routeProps}>
|
||||
{theme && (
|
||||
<CompassThemeProvider theme={theme}>
|
||||
<OnBoardingTaskList/>
|
||||
</CompassThemeProvider>
|
||||
)}
|
||||
<Component {...(routeProps)}/>
|
||||
</LoggedIn>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import classNames from 'classnames';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
import React from 'react';
|
||||
import React, {lazy} from 'react';
|
||||
import {Route, Switch, Redirect} from 'react-router-dom';
|
||||
import type {RouteComponentProps} from 'react-router-dom';
|
||||
|
||||
@@ -13,42 +13,31 @@ import {setSystemEmojis} from 'mattermost-redux/actions/emojis';
|
||||
import {setUrl} from 'mattermost-redux/actions/general';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import {rudderAnalytics, RudderTelemetryHandler} from 'mattermost-redux/client/rudder';
|
||||
import type {Theme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
import {measurePageLoadTelemetry, temporarilySetPageLoadContext, trackEvent, trackSelectorMetrics} from 'actions/telemetry_actions.jsx';
|
||||
import BrowserStore from 'stores/browser_store';
|
||||
|
||||
import AccessProblem from 'components/access_problem';
|
||||
import AnnouncementBarController from 'components/announcement_bar';
|
||||
import AppBar from 'components/app_bar/app_bar';
|
||||
import {makeAsyncComponent} from 'components/async_load';
|
||||
import CloudEffects from 'components/cloud_effects';
|
||||
import CompassThemeProvider from 'components/compass_theme_provider/compass_theme_provider';
|
||||
import OpenPluginInstallPost from 'components/custom_open_plugin_install_post_renderer';
|
||||
import GlobalHeader from 'components/global_header/global_header';
|
||||
import {HFRoute} from 'components/header_footer_route/header_footer_route';
|
||||
import {HFTRoute, LoggedInHFTRoute} from 'components/header_footer_template_route';
|
||||
import InitialLoadingScreen from 'components/initial_loading_screen';
|
||||
import MobileViewWatcher from 'components/mobile_view_watcher';
|
||||
import ModalController from 'components/modal_controller';
|
||||
import LaunchingWorkspace, {LAUNCHING_WORKSPACE_FULLSCREEN_Z_INDEX} from 'components/preparing_workspace/launching_workspace';
|
||||
import LoggedIn from 'components/logged_in';
|
||||
import LoggedInRoute from 'components/logged_in_route';
|
||||
import {LAUNCHING_WORKSPACE_FULLSCREEN_Z_INDEX} from 'components/preparing_workspace/launching_workspace';
|
||||
import {Animations} from 'components/preparing_workspace/steps';
|
||||
import SidebarRight from 'components/sidebar_right';
|
||||
import SidebarRightMenu from 'components/sidebar_right_menu';
|
||||
import SystemNotice from 'components/system_notice';
|
||||
import TeamSidebar from 'components/team_sidebar';
|
||||
import WindowSizeObserver from 'components/window_size_observer/WindowSizeObserver';
|
||||
import SidebarMobileRightMenu from 'components/sidebar_mobile_right_menu';
|
||||
|
||||
import webSocketClient from 'client/web_websocket_client';
|
||||
import {initializePlugins} from 'plugins';
|
||||
import Pluggable from 'plugins/pluggable';
|
||||
import A11yController from 'utils/a11y_controller';
|
||||
import {PageLoadContext} from 'utils/constants';
|
||||
import {EmojiIndicesByAlias} from 'utils/emoji';
|
||||
import {TEAM_NAME_PATH_PATTERN} from 'utils/path';
|
||||
import {getSiteURL} from 'utils/url';
|
||||
import * as UserAgent from 'utils/user_agent';
|
||||
import * as Utils from 'utils/utils';
|
||||
import {isAndroidWeb, isChromebook, isDesktopApp, isIosWeb} from 'utils/user_agent';
|
||||
import {applyTheme, isTextDroppableEvent} from 'utils/utils';
|
||||
|
||||
import LuxonController from './luxon_controller';
|
||||
import PerformanceReporterController from './performance_reporter_controller';
|
||||
@@ -59,68 +48,36 @@ import type {PropsFromRedux} from './index';
|
||||
|
||||
import 'plugins/export.js';
|
||||
|
||||
const LazyErrorPage = React.lazy(() => import('components/error_page'));
|
||||
const LazyLogin = React.lazy(() => import('components/login/login'));
|
||||
const LazyAdminConsole = React.lazy(() => import('components/admin_console'));
|
||||
const LazyLoggedIn = React.lazy(() => import('components/logged_in'));
|
||||
const LazyPasswordResetSendLink = React.lazy(() => import('components/password_reset_send_link'));
|
||||
const LazyPasswordResetForm = React.lazy(() => import('components/password_reset_form'));
|
||||
const LazySignup = React.lazy(() => import('components/signup/signup'));
|
||||
const LazyTermsOfService = React.lazy(() => import('components/terms_of_service'));
|
||||
const LazyShouldVerifyEmail = React.lazy(() => import('components/should_verify_email/should_verify_email'));
|
||||
const LazyDoVerifyEmail = React.lazy(() => import('components/do_verify_email/do_verify_email'));
|
||||
const LazyClaimController = React.lazy(() => import('components/claim'));
|
||||
const LazyLinkingLandingPage = React.lazy(() => import('components/linking_landing_page'));
|
||||
const LazySelectTeam = React.lazy(() => import('components/select_team'));
|
||||
const LazyAuthorize = React.lazy(() => import('components/authorize'));
|
||||
const LazyCreateTeam = React.lazy(() => import('components/create_team'));
|
||||
const LazyMfa = React.lazy(() => import('components/mfa/mfa_controller'));
|
||||
const LazyPreparingWorkspace = React.lazy(() => import('components/preparing_workspace'));
|
||||
const LazyTeamController = React.lazy(() => import('components/team_controller'));
|
||||
const LazyOnBoardingTaskList = React.lazy(() => import('components/onboarding_tasklist'));
|
||||
|
||||
const CreateTeam = makeAsyncComponent('CreateTeam', LazyCreateTeam);
|
||||
const ErrorPage = makeAsyncComponent('ErrorPage', LazyErrorPage);
|
||||
const TermsOfService = makeAsyncComponent('TermsOfService', LazyTermsOfService);
|
||||
const Login = makeAsyncComponent('LoginController', LazyLogin);
|
||||
const AdminConsole = makeAsyncComponent('AdminConsole', LazyAdminConsole);
|
||||
const LoggedIn = makeAsyncComponent('LoggedIn', LazyLoggedIn);
|
||||
const PasswordResetSendLink = makeAsyncComponent('PasswordResedSendLink', LazyPasswordResetSendLink);
|
||||
const PasswordResetForm = makeAsyncComponent('PasswordResetForm', LazyPasswordResetForm);
|
||||
const Signup = makeAsyncComponent('SignupController', LazySignup);
|
||||
const ShouldVerifyEmail = makeAsyncComponent('ShouldVerifyEmail', LazyShouldVerifyEmail);
|
||||
const DoVerifyEmail = makeAsyncComponent('DoVerifyEmail', LazyDoVerifyEmail);
|
||||
const ClaimController = makeAsyncComponent('ClaimController', LazyClaimController);
|
||||
const LinkingLandingPage = makeAsyncComponent('LinkingLandingPage', LazyLinkingLandingPage);
|
||||
const SelectTeam = makeAsyncComponent('SelectTeam', LazySelectTeam);
|
||||
const Authorize = makeAsyncComponent('Authorize', LazyAuthorize);
|
||||
const Mfa = makeAsyncComponent('Mfa', LazyMfa);
|
||||
const PreparingWorkspace = makeAsyncComponent('PreparingWorkspace', LazyPreparingWorkspace);
|
||||
const TeamController = makeAsyncComponent('TeamController', LazyTeamController);
|
||||
const OnBoardingTaskList = makeAsyncComponent('OnboardingTaskList', LazyOnBoardingTaskList);
|
||||
|
||||
type LoggedInRouteProps = {
|
||||
component: React.ComponentType<RouteComponentProps<any>>;
|
||||
path: string | string[];
|
||||
theme?: Theme; // the routes that send the theme are the ones that will actually need to show the onboarding tasklist
|
||||
};
|
||||
|
||||
function LoggedInRoute(props: LoggedInRouteProps) {
|
||||
const {component: Component, theme, ...rest} = props;
|
||||
return (
|
||||
<Route
|
||||
{...rest}
|
||||
render={(routeProps) => (
|
||||
<LoggedIn {...routeProps}>
|
||||
{theme && <CompassThemeProvider theme={theme}>
|
||||
<OnBoardingTaskList/>
|
||||
</CompassThemeProvider>}
|
||||
<Component {...(routeProps)}/>
|
||||
</LoggedIn>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
const MobileViewWatcher = makeAsyncComponent('MobileViewWatcher', lazy(() => import('components/mobile_view_watcher')));
|
||||
const WindowSizeObserver = makeAsyncComponent('WindowSizeObserver', lazy(() => import('components/window_size_observer/WindowSizeObserver')));
|
||||
const ErrorPage = makeAsyncComponent('ErrorPage', lazy(() => import('components/error_page')));
|
||||
const Login = makeAsyncComponent('LoginController', lazy(() => import('components/login/login')));
|
||||
const AccessProblem = makeAsyncComponent('AccessProblem', lazy(() => import('components/access_problem')));
|
||||
const PasswordResetSendLink = makeAsyncComponent('PasswordResedSendLink', lazy(() => import('components/password_reset_send_link')));
|
||||
const PasswordResetForm = makeAsyncComponent('PasswordResetForm', lazy(() => import('components/password_reset_form')));
|
||||
const Signup = makeAsyncComponent('SignupController', lazy(() => import('components/signup/signup')));
|
||||
const ShouldVerifyEmail = makeAsyncComponent('ShouldVerifyEmail', lazy(() => import('components/should_verify_email/should_verify_email')));
|
||||
const DoVerifyEmail = makeAsyncComponent('DoVerifyEmail', lazy(() => import('components/do_verify_email/do_verify_email')));
|
||||
const ClaimController = makeAsyncComponent('ClaimController', lazy(() => import('components/claim')));
|
||||
const TermsOfService = makeAsyncComponent('TermsOfService', lazy(() => import('components/terms_of_service')));
|
||||
const LinkingLandingPage = makeAsyncComponent('LinkingLandingPage', lazy(() => import('components/linking_landing_page')));
|
||||
const AdminConsole = makeAsyncComponent('AdminConsole', lazy(() => import('components/admin_console')));
|
||||
const SelectTeam = makeAsyncComponent('SelectTeam', lazy(() => import('components/select_team')));
|
||||
const Authorize = makeAsyncComponent('Authorize', lazy(() => import('components/authorize')));
|
||||
const CreateTeam = makeAsyncComponent('CreateTeam', lazy(() => import('components/create_team')));
|
||||
const Mfa = makeAsyncComponent('Mfa', lazy(() => import('components/mfa/mfa_controller')));
|
||||
const PreparingWorkspace = makeAsyncComponent('PreparingWorkspace', lazy(() => import('components/preparing_workspace')));
|
||||
const Pluggable = makeAsyncComponent('Pluggable', lazy(() => import('plugins/pluggable')));
|
||||
const LaunchingWorkspace = makeAsyncComponent('LaunchingWorkspace', lazy(() => import('components/preparing_workspace/launching_workspace')));
|
||||
const CompassThemeProvider = makeAsyncComponent('CompassThemeProvider', lazy(() => import('components/compass_theme_provider/compass_theme_provider')));
|
||||
const TeamController = makeAsyncComponent('TeamController', lazy(() => import('components/team_controller')));
|
||||
const AnnouncementBarController = makeAsyncComponent('AnnouncementBarController', lazy(() => import('components/announcement_bar')));
|
||||
const SystemNotice = makeAsyncComponent('SystemNotice', lazy(() => import('components/system_notice')));
|
||||
const CloudEffects = makeAsyncComponent('CloudEffects', lazy(() => import('components/cloud_effects')));
|
||||
const TeamSidebar = makeAsyncComponent('TeamSidebar', lazy(() => import('components/team_sidebar')));
|
||||
const SidebarRight = makeAsyncComponent('SidebarRight', lazy(() => import('components/sidebar_right')));
|
||||
const ModalController = makeAsyncComponent('ModalController', lazy(() => import('components/modal_controller')));
|
||||
const AppBar = makeAsyncComponent('AppBar', lazy(() => import('components/app_bar/app_bar')));
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
@@ -138,7 +95,6 @@ export default class Root extends React.PureComponent<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
// Redux
|
||||
setUrl(getSiteURL());
|
||||
|
||||
// Disable auth header to enable CSRF check
|
||||
@@ -146,24 +102,6 @@ export default class Root extends React.PureComponent<Props, State> {
|
||||
|
||||
setSystemEmojis(new Set(EmojiIndicesByAlias.keys()));
|
||||
|
||||
// Force logout of all tabs if one tab is logged out
|
||||
window.addEventListener('storage', this.handleLogoutLoginSignal);
|
||||
|
||||
// Prevent drag and drop files from navigating away from the app
|
||||
document.addEventListener('drop', (e) => {
|
||||
if (e.dataTransfer && e.dataTransfer.items.length > 0 && e.dataTransfer.items[0].kind === 'file') {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('dragover', (e) => {
|
||||
if (!Utils.isTextDroppableEvent(e) && !document.body.classList.contains('focalboard-body')) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
this.state = {
|
||||
shouldMountAppRoutes: false,
|
||||
};
|
||||
@@ -251,23 +189,23 @@ export default class Root extends React.PureComponent<Props, State> {
|
||||
|
||||
this.showLandingPageIfNecessary();
|
||||
|
||||
Utils.applyTheme(this.props.theme);
|
||||
applyTheme(this.props.theme);
|
||||
};
|
||||
|
||||
private showLandingPageIfNecessary = () => {
|
||||
// We have nothing to redirect to if we're already on Desktop App
|
||||
// Chromebook has no Desktop App to switch to
|
||||
if (UserAgent.isDesktopApp() || UserAgent.isChromebook()) {
|
||||
if (isDesktopApp() || isChromebook()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Nothing to link to if we've removed the Android App download link
|
||||
if (UserAgent.isAndroidWeb() && !this.props.androidDownloadLink) {
|
||||
if (isAndroidWeb() && !this.props.androidDownloadLink) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Nothing to link to if we've removed the iOS App download link
|
||||
if (UserAgent.isIosWeb() && !this.props.iosDownloadLink) {
|
||||
if (isIosWeb() && !this.props.iosDownloadLink) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -312,7 +250,7 @@ export default class Root extends React.PureComponent<Props, State> {
|
||||
|
||||
componentDidUpdate(prevProps: Props, prevState: State) {
|
||||
if (!deepEqual(prevProps.theme, this.props.theme)) {
|
||||
Utils.applyTheme(this.props.theme);
|
||||
applyTheme(this.props.theme);
|
||||
}
|
||||
|
||||
if (this.props.location.pathname === '/') {
|
||||
@@ -384,6 +322,20 @@ export default class Root extends React.PureComponent<Props, State> {
|
||||
}
|
||||
};
|
||||
|
||||
handleDropEvent = (e: DragEvent) => {
|
||||
if (e.dataTransfer && e.dataTransfer.items.length > 0 && e.dataTransfer.items[0].kind === 'file') {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
};
|
||||
|
||||
handleDragOverEvent = (e: DragEvent) => {
|
||||
if (!isTextDroppableEvent(e) && !document.body.classList.contains('focalboard-body')) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
temporarilySetPageLoadContext(PageLoadContext.PAGE_LOAD);
|
||||
|
||||
@@ -394,10 +346,20 @@ export default class Root extends React.PureComponent<Props, State> {
|
||||
|
||||
measurePageLoadTelemetry();
|
||||
trackSelectorMetrics();
|
||||
|
||||
// Force logout of all tabs if one tab is logged out
|
||||
window.addEventListener('storage', this.handleLogoutLoginSignal);
|
||||
|
||||
// Prevent drag and drop files from navigating away from the app
|
||||
document.addEventListener('drop', this.handleDropEvent);
|
||||
|
||||
document.addEventListener('dragover', this.handleDragOverEvent);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('storage', this.handleLogoutLoginSignal);
|
||||
document.removeEventListener('drop', this.handleDropEvent);
|
||||
document.removeEventListener('dragover', this.handleDragOverEvent);
|
||||
}
|
||||
|
||||
handleLogoutLoginSignal = (e: StorageEvent) => {
|
||||
@@ -600,7 +562,7 @@ export default class Root extends React.PureComponent<Props, State> {
|
||||
</div>
|
||||
<Pluggable pluggableName='Global'/>
|
||||
<AppBar/>
|
||||
<SidebarRightMenu/>
|
||||
<SidebarMobileRightMenu/>
|
||||
</CompassThemeProvider>
|
||||
</Switch>
|
||||
</RootProvider>
|
||||
|
||||
@@ -85,7 +85,7 @@ exports[`components/sidebar should match snapshot when direct channels modal is
|
||||
onDragStart={[Function]}
|
||||
/>
|
||||
<Connect(DataPrefetch) />
|
||||
<Connect(MoreDirectChannels)
|
||||
<MoreDirectChannels
|
||||
isExistingChannel={false}
|
||||
onModalDismissed={[Function]}
|
||||
/>
|
||||
|
||||
@@ -9,7 +9,7 @@ import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
import {Preferences} from 'mattermost-redux/constants';
|
||||
|
||||
import mergeObjects from 'packages/mattermost-redux/test/merge_objects';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen, waitFor} from 'tests/react_testing_utils';
|
||||
import Constants, {ModalIdentifiers} from 'utils/constants';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
@@ -164,7 +164,7 @@ describe('components/sidebar', () => {
|
||||
},
|
||||
};
|
||||
|
||||
test('should not render unreads category when disabled by user preference', () => {
|
||||
test('should not render unreads category when disabled by user preference', async () => {
|
||||
const testState = {
|
||||
entities: {
|
||||
channels: {
|
||||
@@ -185,10 +185,12 @@ describe('components/sidebar', () => {
|
||||
mergeObjects(baseState, testState),
|
||||
);
|
||||
|
||||
expect(screen.queryByText('UNREADS')).not.toBeInTheDocument();
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('UNREADS')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
test('should render unreads category when there are unread channels', () => {
|
||||
test('should render unreads category when there are unread channels', async () => {
|
||||
const testState: DeepPartial<GlobalState> = {
|
||||
entities: {
|
||||
channels: {
|
||||
@@ -209,10 +211,12 @@ describe('components/sidebar', () => {
|
||||
mergeObjects(baseState, testState),
|
||||
);
|
||||
|
||||
expect(screen.queryByText('UNREADS')).toBeInTheDocument();
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('UNREADS')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
test('should not render unreads category when there are no unread channels', () => {
|
||||
test('should not render unreads category when there are no unread channels', async () => {
|
||||
const testState: DeepPartial<GlobalState> = {
|
||||
entities: {
|
||||
preferences: {
|
||||
@@ -228,10 +232,12 @@ describe('components/sidebar', () => {
|
||||
mergeObjects(baseState, testState),
|
||||
);
|
||||
|
||||
expect(screen.queryByText('UNREADS')).not.toBeInTheDocument();
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('UNREADS')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
test('should render unreads category when there are no unread channels but the current channel was previously unread', () => {
|
||||
test('should render unreads category when there are no unread channels but the current channel was previously unread', async () => {
|
||||
const testState: DeepPartial<GlobalState> = {
|
||||
entities: {
|
||||
preferences: {
|
||||
@@ -252,7 +258,9 @@ describe('components/sidebar', () => {
|
||||
mergeObjects(baseState, testState),
|
||||
);
|
||||
|
||||
expect(screen.queryByText('UNREADS')).toBeInTheDocument();
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('UNREADS')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,34 +2,36 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
import React, {lazy} from 'react';
|
||||
|
||||
import {trackEvent} from 'actions/telemetry_actions';
|
||||
|
||||
import BrowseChannels from 'components/browse_channels';
|
||||
import CreateUserGroupsModal from 'components/create_user_groups_modal';
|
||||
import {makeAsyncComponent} from 'components/async_load';
|
||||
import DataPrefetch from 'components/data_prefetch';
|
||||
import EditCategoryModal from 'components/edit_category_modal';
|
||||
import InvitationModal from 'components/invitation_modal';
|
||||
import KeyboardShortcutsModal from 'components/keyboard_shortcuts/keyboard_shortcuts_modal/keyboard_shortcuts_modal';
|
||||
import MoreDirectChannels from 'components/more_direct_channels';
|
||||
import NewChannelModal from 'components/new_channel_modal/new_channel_modal';
|
||||
import ResizableLhs from 'components/resizable_sidebar/resizable_lhs';
|
||||
import UserSettingsModal from 'components/user_settings/modal';
|
||||
import SidebarHeader from 'components/sidebar/sidebar_header';
|
||||
|
||||
import Pluggable from 'plugins/pluggable';
|
||||
import Constants, {ModalIdentifiers, RHSStates} from 'utils/constants';
|
||||
import * as Keyboard from 'utils/keyboard';
|
||||
import * as Utils from 'utils/utils';
|
||||
import {isKeyPressed, cmdOrCtrlPressed} from 'utils/keyboard';
|
||||
import {localizeMessage} from 'utils/utils';
|
||||
|
||||
import type {ModalData} from 'types/actions';
|
||||
import type {RhsState} from 'types/store/rhs';
|
||||
|
||||
import ChannelNavigator from './channel_navigator';
|
||||
import MobileSidebarHeader from './mobile_sidebar_header';
|
||||
import SidebarHeader from './sidebar_header';
|
||||
import SidebarList from './sidebar_list';
|
||||
|
||||
const MobileSidebarHeader = makeAsyncComponent('MobileSidebarHeader', lazy(() => import('./mobile_sidebar_header')));
|
||||
const MoreDirectChannels = makeAsyncComponent('MoreDirectChannels', lazy(() => import('components/more_direct_channels')));
|
||||
const BrowseChannels = makeAsyncComponent('BrowseChannels', lazy(() => import('components/browse_channels')));
|
||||
const EditCategoryModal = makeAsyncComponent('EditCategoryModal', lazy(() => import('components/edit_category_modal')));
|
||||
const CreateUserGroupsModal = makeAsyncComponent('CreateUserGroupsModal', lazy(() => import('components/create_user_groups_modal')));
|
||||
const InvitationModal = makeAsyncComponent('InvitationModal', lazy(() => import('components/invitation_modal')));
|
||||
const KeyboardShortcutsModal = makeAsyncComponent('KeyboardShortcutsModal', lazy(() => import('components/keyboard_shortcuts/keyboard_shortcuts_modal/keyboard_shortcuts_modal')));
|
||||
const NewChannelModal = makeAsyncComponent('NewChannelModal', lazy(() => import('components/new_channel_modal/new_channel_modal')));
|
||||
const UserSettingsModal = makeAsyncComponent('UserSettingsModal', lazy(() => import('components/user_settings/modal')));
|
||||
|
||||
type Props = {
|
||||
teamId: string;
|
||||
canCreatePublicChannel: boolean;
|
||||
@@ -95,15 +97,15 @@ export default class Sidebar extends React.PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
handleKeyDownEvent = (event: KeyboardEvent) => {
|
||||
if (Keyboard.isKeyPressed(event, Constants.KeyCodes.ESCAPE)) {
|
||||
if (isKeyPressed(event, Constants.KeyCodes.ESCAPE)) {
|
||||
this.props.actions.clearChannelSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
const ctrlOrMetaKeyPressed = Keyboard.cmdOrCtrlPressed(event, true);
|
||||
const ctrlOrMetaKeyPressed = cmdOrCtrlPressed(event, true);
|
||||
|
||||
if (ctrlOrMetaKeyPressed) {
|
||||
if (Keyboard.isKeyPressed(event, Constants.KeyCodes.FORWARD_SLASH)) {
|
||||
if (isKeyPressed(event, Constants.KeyCodes.FORWARD_SLASH)) {
|
||||
event.preventDefault();
|
||||
if (this.props.isKeyBoardShortcutModalOpen) {
|
||||
this.props.actions.closeModal(ModalIdentifiers.KEYBOARD_SHORTCUTS_MODAL);
|
||||
@@ -113,7 +115,7 @@ export default class Sidebar extends React.PureComponent<Props, State> {
|
||||
dialogType: KeyboardShortcutsModal,
|
||||
});
|
||||
}
|
||||
} else if (Keyboard.isKeyPressed(event, Constants.KeyCodes.A) && event.shiftKey) {
|
||||
} else if (isKeyPressed(event, Constants.KeyCodes.A) && event.shiftKey) {
|
||||
event.preventDefault();
|
||||
|
||||
this.props.actions.openModal({
|
||||
@@ -225,7 +227,7 @@ export default class Sidebar extends React.PureComponent<Props, State> {
|
||||
return (<div/>);
|
||||
}
|
||||
|
||||
const ariaLabel = Utils.localizeMessage('accessibility.sections.lhsNavigator', 'channel navigator region');
|
||||
const ariaLabel = localizeMessage('accessibility.sections.lhsNavigator', 'channel navigator region');
|
||||
|
||||
return (
|
||||
<ResizableLhs
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
exports[`SidebarList should match snapshot 1`] = `
|
||||
<Fragment>
|
||||
<GlobalThreadsLink />
|
||||
<Memo(DraftsLink) />
|
||||
<DraftsLink />
|
||||
<div
|
||||
aria-label="channel sidebar region"
|
||||
className="SidebarNavContainer a11y__region"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import classNames from 'classnames';
|
||||
import debounce from 'lodash/debounce';
|
||||
import React from 'react';
|
||||
import React, {lazy} from 'react';
|
||||
import type {CSSProperties} from 'react';
|
||||
import {DragDropContext, Droppable} from 'react-beautiful-dnd';
|
||||
import type {DropResult, DragStart, BeforeCapture} from 'react-beautiful-dnd';
|
||||
@@ -20,20 +20,21 @@ import {General} from 'mattermost-redux/constants';
|
||||
|
||||
import {trackEvent} from 'actions/telemetry_actions';
|
||||
|
||||
import DraftsLink from 'components/drafts/drafts_link/drafts_link';
|
||||
import GlobalThreadsLink from 'components/threading/global_threads_link';
|
||||
import {makeAsyncComponent} from 'components/async_load';
|
||||
import SidebarCategory from 'components/sidebar/sidebar_category';
|
||||
|
||||
import * as ChannelUtils from 'utils/channel_utils';
|
||||
import {findNextUnreadChannelId} from 'utils/channel_utils';
|
||||
import {Constants, DraggingStates, DraggingStateTypes} from 'utils/constants';
|
||||
import * as Keyboard from 'utils/keyboard';
|
||||
import * as Utils from 'utils/utils';
|
||||
import {isKeyPressed, cmdOrCtrlPressed} from 'utils/keyboard';
|
||||
import {localizeMessage, mod} from 'utils/utils';
|
||||
|
||||
import type {DraggingState} from 'types/store';
|
||||
import type {StaticPage} from 'types/store/lhs';
|
||||
|
||||
import SidebarCategory from '../sidebar_category';
|
||||
import UnreadChannelIndicator from '../unread_channel_indicator';
|
||||
import UnreadChannels from '../unread_channels';
|
||||
const DraftsLink = makeAsyncComponent('DraftsLink', lazy(() => import('components/drafts/drafts_link/drafts_link')));
|
||||
const GlobalThreadsLink = makeAsyncComponent('GlobalThreadsLink', lazy(() => import('components/threading/global_threads_link')));
|
||||
const UnreadChannelIndicator = makeAsyncComponent('UnreadChannelIndicator', lazy(() => import('../unread_channel_indicator')));
|
||||
const UnreadChannels = makeAsyncComponent('UnreadChannels', lazy(() => import('../unread_channels')));
|
||||
|
||||
export function renderView(props: React.HTMLProps<HTMLDivElement>) {
|
||||
return (
|
||||
@@ -318,7 +319,7 @@ export default class SidebarList extends React.PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
navigateChannelShortcut = (e: KeyboardEvent) => {
|
||||
if (e.altKey && !e.shiftKey && !e.ctrlKey && !e.metaKey && (Keyboard.isKeyPressed(e, Constants.KeyCodes.UP) || Keyboard.isKeyPressed(e, Constants.KeyCodes.DOWN))) {
|
||||
if (e.altKey && !e.shiftKey && !e.ctrlKey && !e.metaKey && (isKeyPressed(e, Constants.KeyCodes.UP) || isKeyPressed(e, Constants.KeyCodes.DOWN))) {
|
||||
e.preventDefault();
|
||||
|
||||
const staticPageIds = this.getDisplayedStaticPageIds();
|
||||
@@ -328,24 +329,24 @@ export default class SidebarList extends React.PureComponent<Props, State> {
|
||||
const curIndex = allIds.indexOf(curSelectedId);
|
||||
|
||||
let nextIndex;
|
||||
if (Keyboard.isKeyPressed(e, Constants.KeyCodes.DOWN)) {
|
||||
if (isKeyPressed(e, Constants.KeyCodes.DOWN)) {
|
||||
nextIndex = curIndex + 1;
|
||||
} else {
|
||||
nextIndex = curIndex - 1;
|
||||
}
|
||||
|
||||
const nextId = allIds[Utils.mod(nextIndex, allIds.length)];
|
||||
const nextId = allIds[mod(nextIndex, allIds.length)];
|
||||
this.navigateById(nextId);
|
||||
if (nextIndex >= staticPageIds.length) {
|
||||
this.scrollToChannel(nextId);
|
||||
}
|
||||
} else if (Keyboard.cmdOrCtrlPressed(e) && e.shiftKey && Keyboard.isKeyPressed(e, Constants.KeyCodes.K)) {
|
||||
} else if (cmdOrCtrlPressed(e) && e.shiftKey && isKeyPressed(e, Constants.KeyCodes.K)) {
|
||||
this.props.handleOpenMoreDirectChannelsModal(e);
|
||||
}
|
||||
};
|
||||
|
||||
navigateUnreadChannelShortcut = (e: KeyboardEvent) => {
|
||||
if (e.altKey && e.shiftKey && !e.ctrlKey && !e.metaKey && (Keyboard.isKeyPressed(e, Constants.KeyCodes.UP) || Keyboard.isKeyPressed(e, Constants.KeyCodes.DOWN))) {
|
||||
if (e.altKey && e.shiftKey && !e.ctrlKey && !e.metaKey && (isKeyPressed(e, Constants.KeyCodes.UP) || isKeyPressed(e, Constants.KeyCodes.DOWN))) {
|
||||
e.preventDefault();
|
||||
|
||||
const allChannelIds = this.getDisplayedChannelIds();
|
||||
@@ -360,13 +361,13 @@ export default class SidebarList extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
let direction = 0;
|
||||
if (Keyboard.isKeyPressed(e, Constants.KeyCodes.UP)) {
|
||||
if (isKeyPressed(e, Constants.KeyCodes.UP)) {
|
||||
direction = -1;
|
||||
} else {
|
||||
direction = 1;
|
||||
}
|
||||
|
||||
const nextIndex = ChannelUtils.findNextUnreadChannelId(
|
||||
const nextIndex = findNextUnreadChannelId(
|
||||
this.props.currentChannelId,
|
||||
allChannelIds,
|
||||
unreadChannelIds,
|
||||
@@ -546,7 +547,7 @@ export default class SidebarList extends React.PureComponent<Props, State> {
|
||||
/>
|
||||
);
|
||||
|
||||
const ariaLabel = Utils.localizeMessage('accessibility.sections.lhsList', 'channel sidebar region');
|
||||
const ariaLabel = localizeMessage('accessibility.sections.lhsList', 'channel sidebar region');
|
||||
|
||||
return (
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import {getIsMobileView} from 'selectors/views/browser';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
import SidebarRightMenu from './sidebar_right_menu';
|
||||
import SidebarMobileRightMenu from './sidebar_mobile_right_menu';
|
||||
|
||||
function mapStateToProps(state: GlobalState) {
|
||||
const config = getConfig(state);
|
||||
@@ -27,4 +27,4 @@ function mapStateToProps(state: GlobalState) {
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(SidebarRightMenu);
|
||||
export default connect(mapStateToProps)(SidebarMobileRightMenu);
|
||||
@@ -131,7 +131,9 @@ describe('identifyElementRegion', () => {
|
||||
},
|
||||
);
|
||||
|
||||
expect(identifyElementRegion(screen.getAllByText(channel.display_name)[0])).toEqual('channel_sidebar');
|
||||
await waitFor(() => {
|
||||
expect(identifyElementRegion(screen.getAllByText(channel.display_name)[0])).toEqual('channel_sidebar');
|
||||
});
|
||||
|
||||
expect(identifyElementRegion(screen.getAllByText(channel.display_name)[1])).toEqual('channel_header');
|
||||
expect(identifyElementRegion(screen.getAllByText(channel.header)[0])).toEqual('channel_header');
|
||||
|
||||
Ссылка в новой задаче
Block a user