mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
MM-49393 Remove Utils.isMobile (#24271)
* Switch Utils.isMobile to getIsMobileView in most places * Copy Utils.isMobile into menu widgets * Actually remove Utils.isMobile * Remove pointless checkAndSetMobileView action * Fix incorrect import of UserProfile * Fix unit test
This commit is contained in:
parent
47e18ea829
commit
b17daf79b1
@ -273,8 +273,6 @@ export class ActionMenuClass extends React.PureComponent<Props, State> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// const isMobile = this.props.isMobileView TODO;
|
|
||||||
|
|
||||||
const pluginItems = this.props.pluginMenuItems?.
|
const pluginItems = this.props.pluginMenuItems?.
|
||||||
filter((item) => {
|
filter((item) => {
|
||||||
return item.filter ? item.filter(this.props.post.id) : item;
|
return item.filter ? item.filter(this.props.post.id) : item;
|
||||||
|
@ -15,10 +15,9 @@ import {ActionFunc} from 'mattermost-redux/types/actions';
|
|||||||
|
|
||||||
import {GlobalState} from 'types/store';
|
import {GlobalState} from 'types/store';
|
||||||
|
|
||||||
import {isMobile} from 'utils/utils';
|
|
||||||
|
|
||||||
import {getNavigationBlocked} from 'selectors/views/admin';
|
|
||||||
import {getAdminDefinition, getConsoleAccess} from 'selectors/admin_console';
|
import {getAdminDefinition, getConsoleAccess} from 'selectors/admin_console';
|
||||||
|
import {getNavigationBlocked} from 'selectors/views/admin';
|
||||||
|
import {getIsMobileView} from 'selectors/views/browser';
|
||||||
|
|
||||||
import {OnboardingTaskCategory, OnboardingTaskList} from 'components/onboarding_tasks';
|
import {OnboardingTaskCategory, OnboardingTaskList} from 'components/onboarding_tasks';
|
||||||
|
|
||||||
@ -33,7 +32,7 @@ function mapStateToProps(state: GlobalState) {
|
|||||||
const consoleAccess = getConsoleAccess(state);
|
const consoleAccess = getConsoleAccess(state);
|
||||||
const taskListStatus = getBool(state, OnboardingTaskCategory, OnboardingTaskList.ONBOARDING_TASK_LIST_SHOW);
|
const taskListStatus = getBool(state, OnboardingTaskCategory, OnboardingTaskList.ONBOARDING_TASK_LIST_SHOW);
|
||||||
const isUserFirstAdmin = isFirstAdmin(state);
|
const isUserFirstAdmin = isFirstAdmin(state);
|
||||||
const isMobileView = isMobile();
|
const isMobileView = getIsMobileView(state);
|
||||||
const showTaskList = isUserFirstAdmin && taskListStatus && !isMobileView;
|
const showTaskList = isUserFirstAdmin && taskListStatus && !isMobileView;
|
||||||
const subscriptionProduct = getSubscriptionProduct(state);
|
const subscriptionProduct = getSubscriptionProduct(state);
|
||||||
|
|
||||||
|
@ -107,6 +107,11 @@ const initialState = {
|
|||||||
config: {PostEditTimeLimit: -1},
|
config: {PostEditTimeLimit: -1},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
views: {
|
||||||
|
browser: {
|
||||||
|
windowSize: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('channel_info_rhs/about_area_gm', () => {
|
describe('channel_info_rhs/about_area_gm', () => {
|
||||||
|
@ -160,14 +160,14 @@ export default class LinkingLandingPage extends PureComponent<Props, State> {
|
|||||||
renderGoNativeAppMessage = () => {
|
renderGoNativeAppMessage = () => {
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
href={Utils.isMobile() ? '#' : this.state.nativeLocation}
|
href={UserAgent.isMobile() ? '#' : this.state.nativeLocation}
|
||||||
onMouseDown={() => {
|
onMouseDown={() => {
|
||||||
this.setPreference(LandingPreferenceTypes.MATTERMOSTAPP, true);
|
this.setPreference(LandingPreferenceTypes.MATTERMOSTAPP, true);
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
this.setPreference(LandingPreferenceTypes.MATTERMOSTAPP, true);
|
this.setPreference(LandingPreferenceTypes.MATTERMOSTAPP, true);
|
||||||
this.setState({redirectPage: true, navigating: true});
|
this.setState({redirectPage: true, navigating: true});
|
||||||
if (Utils.isMobile()) {
|
if (UserAgent.isMobile()) {
|
||||||
if (UserAgent.isAndroidWeb()) {
|
if (UserAgent.isAndroidWeb()) {
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
window.location.replace(this.getDownloadLink()!);
|
window.location.replace(this.getDownloadLink()!);
|
||||||
|
@ -22,14 +22,6 @@ const suggestionProviders = [
|
|||||||
new SearchUserProvider(jest.fn()),
|
new SearchUserProvider(jest.fn()),
|
||||||
];
|
];
|
||||||
|
|
||||||
jest.mock('utils/utils', () => {
|
|
||||||
const original = jest.requireActual('utils/utils');
|
|
||||||
return {
|
|
||||||
...original,
|
|
||||||
isMobile: jest.fn(() => false),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const wrapIntl = (component: JSX.Element) => (
|
const wrapIntl = (component: JSX.Element) => (
|
||||||
<IntlProvider
|
<IntlProvider
|
||||||
locale={'en'}
|
locale={'en'}
|
||||||
|
@ -8,6 +8,7 @@ import {getConfig} from 'mattermost-redux/selectors/entities/general';
|
|||||||
import {getCurrentTeam} from 'mattermost-redux/selectors/entities/teams';
|
import {getCurrentTeam} from 'mattermost-redux/selectors/entities/teams';
|
||||||
import {openMenu as openRhsMenu} from 'actions/views/rhs';
|
import {openMenu as openRhsMenu} from 'actions/views/rhs';
|
||||||
import {getIsRhsMenuOpen} from 'selectors/rhs';
|
import {getIsRhsMenuOpen} from 'selectors/rhs';
|
||||||
|
import {getIsMobileView} from 'selectors/views/browser';
|
||||||
|
|
||||||
import {GlobalState} from 'types/store';
|
import {GlobalState} from 'types/store';
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ function mapStateToProps(state: GlobalState) {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
teamDisplayName: currentTeam && currentTeam.display_name,
|
teamDisplayName: currentTeam && currentTeam.display_name,
|
||||||
|
isMobileView: getIsMobileView(state),
|
||||||
isOpen: getIsRhsMenuOpen(state),
|
isOpen: getIsRhsMenuOpen(state),
|
||||||
siteName,
|
siteName,
|
||||||
};
|
};
|
||||||
|
@ -8,7 +8,6 @@ import {CSSTransition} from 'react-transition-group';
|
|||||||
|
|
||||||
import * as GlobalActions from 'actions/global_actions';
|
import * as GlobalActions from 'actions/global_actions';
|
||||||
import {Constants} from 'utils/constants';
|
import {Constants} from 'utils/constants';
|
||||||
import * as Utils from 'utils/utils';
|
|
||||||
|
|
||||||
import MainMenu from 'components/main_menu';
|
import MainMenu from 'components/main_menu';
|
||||||
|
|
||||||
@ -17,6 +16,7 @@ type Action = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
isMobileView: boolean;
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
teamDisplayName?: string;
|
teamDisplayName?: string;
|
||||||
siteName?: string;
|
siteName?: string;
|
||||||
@ -42,7 +42,7 @@ export default class SidebarRightMenu extends React.PureComponent<Props> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames('sidebar--menu', {'move--left': this.props.isOpen && Utils.isMobile()})}
|
className={classNames('sidebar--menu', {'move--left': this.props.isOpen && this.props.isMobileView})}
|
||||||
id='sidebar-menu'
|
id='sidebar-menu'
|
||||||
>
|
>
|
||||||
<div className='team__header theme'>
|
<div className='team__header theme'>
|
||||||
@ -56,7 +56,7 @@ export default class SidebarRightMenu extends React.PureComponent<Props> {
|
|||||||
|
|
||||||
<div className='nav-pills__container mobile-main-menu'>
|
<div className='nav-pills__container mobile-main-menu'>
|
||||||
<CSSTransition
|
<CSSTransition
|
||||||
in={this.props.isOpen && Utils.isMobile()}
|
in={this.props.isOpen && this.props.isMobileView}
|
||||||
classNames='MobileRightSidebarMenu'
|
classNames='MobileRightSidebarMenu'
|
||||||
enter={true}
|
enter={true}
|
||||||
exit={true}
|
exit={true}
|
||||||
|
@ -10,6 +10,8 @@ import {Permissions} from 'mattermost-redux/constants';
|
|||||||
import {haveITeamPermission} from 'mattermost-redux/selectors/entities/roles';
|
import {haveITeamPermission} from 'mattermost-redux/selectors/entities/roles';
|
||||||
import {ActionResult, GenericAction} from 'mattermost-redux/types/actions';
|
import {ActionResult, GenericAction} from 'mattermost-redux/types/actions';
|
||||||
|
|
||||||
|
import {getIsMobileView} from 'selectors/views/browser';
|
||||||
|
|
||||||
import {GlobalState} from 'types/store/index';
|
import {GlobalState} from 'types/store/index';
|
||||||
|
|
||||||
import {Team} from '@mattermost/types/teams';
|
import {Team} from '@mattermost/types/teams';
|
||||||
@ -33,6 +35,7 @@ function mapStateToProps(state: GlobalState, ownProps: OwnProps) {
|
|||||||
return {
|
return {
|
||||||
maxFileSize,
|
maxFileSize,
|
||||||
canInviteTeamMembers,
|
canInviteTeamMembers,
|
||||||
|
isMobileView: getIsMobileView(state),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ describe('components/TeamSettings', () => {
|
|||||||
collapseModal: jest.fn(),
|
collapseModal: jest.fn(),
|
||||||
actions: baseActions,
|
actions: baseActions,
|
||||||
canInviteTeamMembers: true,
|
canInviteTeamMembers: true,
|
||||||
|
isMobileView: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
test('should handle bad updateTeamIcon function call', () => {
|
test('should handle bad updateTeamIcon function call', () => {
|
||||||
|
@ -5,7 +5,7 @@ import React, {ChangeEvent, MouseEvent, ReactNode} from 'react';
|
|||||||
import {FormattedMessage, FormattedDate} from 'react-intl';
|
import {FormattedMessage, FormattedDate} from 'react-intl';
|
||||||
|
|
||||||
import Constants from 'utils/constants';
|
import Constants from 'utils/constants';
|
||||||
import {imageURLForTeam, isMobile, localizeMessage, moveCursorToEnd} from 'utils/utils';
|
import {imageURLForTeam, localizeMessage, moveCursorToEnd} from 'utils/utils';
|
||||||
import {t} from 'utils/i18n';
|
import {t} from 'utils/i18n';
|
||||||
|
|
||||||
import SettingItemMax from 'components/setting_item_max';
|
import SettingItemMax from 'components/setting_item_max';
|
||||||
@ -390,7 +390,7 @@ export default class GeneralTab extends React.PureComponent<Props, State> {
|
|||||||
if (this.props.activeSection === 'name') {
|
if (this.props.activeSection === 'name') {
|
||||||
const inputs = [];
|
const inputs = [];
|
||||||
|
|
||||||
const teamNameLabel = isMobile() ? '' : (
|
const teamNameLabel = this.props.isMobileView ? '' : (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='general_tab.teamName'
|
id='general_tab.teamName'
|
||||||
defaultMessage='Team Name'
|
defaultMessage='Team Name'
|
||||||
@ -449,7 +449,7 @@ export default class GeneralTab extends React.PureComponent<Props, State> {
|
|||||||
if (this.props.activeSection === 'description') {
|
if (this.props.activeSection === 'description') {
|
||||||
const inputs = [];
|
const inputs = [];
|
||||||
|
|
||||||
const teamDescriptionLabel = isMobile() ? '' : (
|
const teamDescriptionLabel = this.props.isMobileView ? '' : (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='general_tab.teamDescription'
|
id='general_tab.teamDescription'
|
||||||
defaultMessage='Team Description'
|
defaultMessage='Team Description'
|
||||||
@ -557,7 +557,7 @@ export default class GeneralTab extends React.PureComponent<Props, State> {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
minMessage = isMobile() ? localizeMessage('general_tab.teamIconEditHintMobile', 'Click to upload an image') : localizeMessage('general_tab.teamIconEditHint', 'Click \'Edit\' to upload an image.');
|
minMessage = this.props.isMobileView ? localizeMessage('general_tab.teamIconEditHintMobile', 'Click to upload an image') : localizeMessage('general_tab.teamIconEditHint', 'Click \'Edit\' to upload an image.');
|
||||||
}
|
}
|
||||||
|
|
||||||
teamIconSection = (
|
teamIconSection = (
|
||||||
|
@ -13,9 +13,10 @@ import {Post} from '@mattermost/types/posts';
|
|||||||
|
|
||||||
import {FakePost} from 'types/store/rhs';
|
import {FakePost} from 'types/store/rhs';
|
||||||
|
|
||||||
|
import {getIsMobileView} from 'selectors/views/browser';
|
||||||
import {makePrepareReplyIdsForThreadViewer, makeGetThreadLastViewedAt} from 'selectors/views/threads';
|
import {makePrepareReplyIdsForThreadViewer, makeGetThreadLastViewedAt} from 'selectors/views/threads';
|
||||||
|
|
||||||
import {GlobalState} from 'types/store';
|
import type {GlobalState} from 'types/store';
|
||||||
|
|
||||||
import ThreadViewerVirtualized from './virtualized_thread_viewer';
|
import ThreadViewerVirtualized from './virtualized_thread_viewer';
|
||||||
|
|
||||||
@ -51,6 +52,7 @@ function makeMapStateToProps() {
|
|||||||
return {
|
return {
|
||||||
currentUserId,
|
currentUserId,
|
||||||
directTeammate,
|
directTeammate,
|
||||||
|
isMobileView: getIsMobileView(state),
|
||||||
lastPost,
|
lastPost,
|
||||||
replyListIds,
|
replyListIds,
|
||||||
lastViewedAt,
|
lastViewedAt,
|
||||||
|
@ -54,7 +54,6 @@ describe('components/threading/VirtualizedThreadViewer', () => {
|
|||||||
socketConnectionStatus: true,
|
socketConnectionStatus: true,
|
||||||
actions,
|
actions,
|
||||||
directTeammate,
|
directTeammate,
|
||||||
isCollapsedThreadsEnabled: false,
|
|
||||||
posts: [post],
|
posts: [post],
|
||||||
lastPost: post,
|
lastPost: post,
|
||||||
onCardClick: () => {},
|
onCardClick: () => {},
|
||||||
@ -62,6 +61,7 @@ describe('components/threading/VirtualizedThreadViewer', () => {
|
|||||||
replyListIds: [],
|
replyListIds: [],
|
||||||
teamId: '',
|
teamId: '',
|
||||||
useRelativeTimestamp: true,
|
useRelativeTimestamp: true,
|
||||||
|
isMobileView: false,
|
||||||
isThreadView: true,
|
isThreadView: true,
|
||||||
lastViewedAt: 0,
|
lastViewedAt: 0,
|
||||||
newMessagesSeparatorActions: [],
|
newMessagesSeparatorActions: [],
|
||||||
|
@ -36,6 +36,7 @@ type Props = {
|
|||||||
replyListIds: string[];
|
replyListIds: string[];
|
||||||
selected: Post | FakePost;
|
selected: Post | FakePost;
|
||||||
useRelativeTimestamp: boolean;
|
useRelativeTimestamp: boolean;
|
||||||
|
isMobileView: boolean;
|
||||||
isThreadView: boolean;
|
isThreadView: boolean;
|
||||||
lastViewedAt: number;
|
lastViewedAt: number;
|
||||||
newMessagesSeparatorActions: PluginComponent[];
|
newMessagesSeparatorActions: PluginComponent[];
|
||||||
@ -43,7 +44,6 @@ type Props = {
|
|||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
createCommentHeight: number;
|
createCommentHeight: number;
|
||||||
isMobile: boolean;
|
|
||||||
isScrolling: boolean;
|
isScrolling: boolean;
|
||||||
topRhsPostId?: string;
|
topRhsPostId?: string;
|
||||||
userScrolled: boolean;
|
userScrolled: boolean;
|
||||||
@ -96,7 +96,6 @@ class ThreadViewerVirtualized extends PureComponent<Props, State> {
|
|||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
const postIndex = this.getInitialPostIndex();
|
const postIndex = this.getInitialPostIndex();
|
||||||
const isMobile = Utils.isMobile();
|
|
||||||
|
|
||||||
this.initRangeToRender = [
|
this.initRangeToRender = [
|
||||||
Math.max(postIndex - 30, 0),
|
Math.max(postIndex - 30, 0),
|
||||||
@ -110,7 +109,6 @@ class ThreadViewerVirtualized extends PureComponent<Props, State> {
|
|||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
createCommentHeight: 0,
|
createCommentHeight: 0,
|
||||||
isMobile,
|
|
||||||
isScrolling: false,
|
isScrolling: false,
|
||||||
userScrolled: false,
|
userScrolled: false,
|
||||||
userScrolledToBottom: false,
|
userScrolledToBottom: false,
|
||||||
@ -125,12 +123,10 @@ class ThreadViewerVirtualized extends PureComponent<Props, State> {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.mounted = true;
|
this.mounted = true;
|
||||||
window.addEventListener('resize', this.handleWindowResize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.mounted = false;
|
this.mounted = false;
|
||||||
window.removeEventListener('resize', this.handleWindowResize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps: Props) {
|
componentDidUpdate(prevProps: Props) {
|
||||||
@ -156,15 +152,6 @@ class ThreadViewerVirtualized extends PureComponent<Props, State> {
|
|||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleWindowResize = () => {
|
|
||||||
const isMobile = Utils.isMobile();
|
|
||||||
if (isMobile !== this.state.isMobile) {
|
|
||||||
this.setState({
|
|
||||||
isMobile,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
initScrollToIndex = (): {index: number; position: string; offset?: number} => {
|
initScrollToIndex = (): {index: number; position: string; offset?: number} => {
|
||||||
const {highlightedPostId, replyListIds} = this.props;
|
const {highlightedPostId, replyListIds} = this.props;
|
||||||
|
|
||||||
@ -207,7 +194,7 @@ class ThreadViewerVirtualized extends PureComponent<Props, State> {
|
|||||||
updatedState.userScrolled = true;
|
updatedState.userScrolled = true;
|
||||||
updatedState.userScrolledToBottom = userScrolledToBottom;
|
updatedState.userScrolledToBottom = userScrolledToBottom;
|
||||||
|
|
||||||
if (this.state.isMobile) {
|
if (this.props.isMobileView) {
|
||||||
if (!this.state.isScrolling) {
|
if (!this.state.isScrolling) {
|
||||||
updatedState.isScrolling = true;
|
updatedState.isScrolling = true;
|
||||||
}
|
}
|
||||||
@ -241,7 +228,7 @@ class ThreadViewerVirtualized extends PureComponent<Props, State> {
|
|||||||
overscanStartIndex,
|
overscanStartIndex,
|
||||||
overscanStopIndex,
|
overscanStopIndex,
|
||||||
}: OnItemsRenderedArgs) => {
|
}: OnItemsRenderedArgs) => {
|
||||||
if (this.state.isMobile) {
|
if (this.props.isMobileView) {
|
||||||
this.updateFloatingTimestamp(visibleStartIndex);
|
this.updateFloatingTimestamp(visibleStartIndex);
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -434,11 +421,11 @@ class ThreadViewerVirtualized extends PureComponent<Props, State> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {isMobile, topRhsPostId} = this.state;
|
const {topRhsPostId} = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isMobile && topRhsPostId && !this.props.useRelativeTimestamp && (
|
{this.props.isMobileView && topRhsPostId && !this.props.useRelativeTimestamp && (
|
||||||
<FloatingTimestamp
|
<FloatingTimestamp
|
||||||
isRhsPost={true}
|
isRhsPost={true}
|
||||||
isScrolling={this.state.isScrolling}
|
isScrolling={this.state.isScrolling}
|
||||||
|
@ -6,7 +6,8 @@ import {connect} from 'react-redux';
|
|||||||
import {getUser, makeGetDisplayName} from 'mattermost-redux/selectors/entities/users';
|
import {getUser, makeGetDisplayName} from 'mattermost-redux/selectors/entities/users';
|
||||||
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
|
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
|
||||||
|
|
||||||
import {GlobalState} from '@mattermost/types/store';
|
import {getIsMobileView} from 'selectors/views/browser';
|
||||||
|
import {GlobalState} from 'types/store';
|
||||||
|
|
||||||
import UserProfile from './user_profile';
|
import UserProfile from './user_profile';
|
||||||
|
|
||||||
@ -25,6 +26,7 @@ function makeMapStateToProps() {
|
|||||||
displayName: getDisplayName(state, ownProps.userId, true),
|
displayName: getDisplayName(state, ownProps.userId, true),
|
||||||
user,
|
user,
|
||||||
theme,
|
theme,
|
||||||
|
isMobileView: getIsMobileView(state),
|
||||||
isShared: Boolean(user && user.remote_id),
|
isShared: Boolean(user && user.remote_id),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -13,6 +13,7 @@ describe('components/UserProfile', () => {
|
|||||||
const baseProps = {
|
const baseProps = {
|
||||||
displayName: 'nickname',
|
displayName: 'nickname',
|
||||||
isBusy: false,
|
isBusy: false,
|
||||||
|
isMobileView: false,
|
||||||
user: {username: 'username'} as UserProfileType,
|
user: {username: 'username'} as UserProfileType,
|
||||||
userId: 'user_id',
|
userId: 'user_id',
|
||||||
theme: Preferences.THEMES.onyx,
|
theme: Preferences.THEMES.onyx,
|
||||||
|
@ -12,7 +12,7 @@ import {UserProfile as UserProfileType} from '@mattermost/types/users';
|
|||||||
import {Theme} from 'mattermost-redux/selectors/entities/preferences';
|
import {Theme} from 'mattermost-redux/selectors/entities/preferences';
|
||||||
import {isGuest} from 'mattermost-redux/utils/user_utils';
|
import {isGuest} from 'mattermost-redux/utils/user_utils';
|
||||||
|
|
||||||
import {imageURLForUser, isMobile} from 'utils/utils';
|
import {imageURLForUser} from 'utils/utils';
|
||||||
|
|
||||||
import OverlayTrigger, {BaseOverlayTrigger} from 'components/overlay_trigger';
|
import OverlayTrigger, {BaseOverlayTrigger} from 'components/overlay_trigger';
|
||||||
import ProfilePopover from 'components/profile_popover';
|
import ProfilePopover from 'components/profile_popover';
|
||||||
@ -34,6 +34,7 @@ export type UserProfileProps = {
|
|||||||
colorize?: boolean;
|
colorize?: boolean;
|
||||||
hasMention?: boolean;
|
hasMention?: boolean;
|
||||||
hideStatus?: boolean;
|
hideStatus?: boolean;
|
||||||
|
isMobileView: boolean;
|
||||||
isRHS?: boolean;
|
isRHS?: boolean;
|
||||||
channelId?: string;
|
channelId?: string;
|
||||||
theme?: Theme;
|
theme?: Theme;
|
||||||
@ -68,6 +69,7 @@ export default class UserProfile extends PureComponent<UserProfileProps> {
|
|||||||
displayName,
|
displayName,
|
||||||
displayUsername,
|
displayUsername,
|
||||||
isBusy,
|
isBusy,
|
||||||
|
isMobileView,
|
||||||
isRHS,
|
isRHS,
|
||||||
isShared,
|
isShared,
|
||||||
hasMention,
|
hasMention,
|
||||||
@ -110,7 +112,7 @@ export default class UserProfile extends PureComponent<UserProfileProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let placement = 'right';
|
let placement = 'right';
|
||||||
if (isRHS && !isMobile()) {
|
if (isRHS && !isMobileView) {
|
||||||
placement = 'left';
|
placement = 'left';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,9 +13,12 @@ import {
|
|||||||
import {clearErrors, logError} from 'mattermost-redux/actions/errors';
|
import {clearErrors, logError} from 'mattermost-redux/actions/errors';
|
||||||
import {getConfig} from 'mattermost-redux/selectors/entities/general';
|
import {getConfig} from 'mattermost-redux/selectors/entities/general';
|
||||||
|
|
||||||
import {GlobalState} from '@mattermost/types/store';
|
|
||||||
import {ActionFunc} from 'mattermost-redux/types/actions';
|
import {ActionFunc} from 'mattermost-redux/types/actions';
|
||||||
|
|
||||||
|
import {getIsMobileView} from 'selectors/views/browser';
|
||||||
|
|
||||||
|
import type {GlobalState} from 'types/store';
|
||||||
|
|
||||||
import UserSettingsGeneralTab, {Props} from './user_settings_general';
|
import UserSettingsGeneralTab, {Props} from './user_settings_general';
|
||||||
|
|
||||||
function mapStateToProps(state: GlobalState) {
|
function mapStateToProps(state: GlobalState) {
|
||||||
@ -34,6 +37,7 @@ function mapStateToProps(state: GlobalState) {
|
|||||||
const ldapPictureAttributeSet = config.LdapPictureAttributeSet === 'true';
|
const ldapPictureAttributeSet = config.LdapPictureAttributeSet === 'true';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
isMobileView: getIsMobileView(state),
|
||||||
requireEmailVerification,
|
requireEmailVerification,
|
||||||
maxFileSize,
|
maxFileSize,
|
||||||
ldapFirstNameAttributeSet,
|
ldapFirstNameAttributeSet,
|
||||||
|
@ -34,6 +34,7 @@ describe('components/user_settings/general/UserSettingsGeneral', () => {
|
|||||||
activeSection: '',
|
activeSection: '',
|
||||||
closeModal: jest.fn(),
|
closeModal: jest.fn(),
|
||||||
collapseModal: jest.fn(),
|
collapseModal: jest.fn(),
|
||||||
|
isMobileView: false,
|
||||||
actions: {
|
actions: {
|
||||||
logError: jest.fn(),
|
logError: jest.fn(),
|
||||||
clearErrors: jest.fn(),
|
clearErrors: jest.fn(),
|
||||||
|
@ -101,6 +101,7 @@ export type Props = {
|
|||||||
activeSection?: string;
|
activeSection?: string;
|
||||||
closeModal: () => void;
|
closeModal: () => void;
|
||||||
collapseModal: () => void;
|
collapseModal: () => void;
|
||||||
|
isMobileView: boolean;
|
||||||
maxFileSize: number;
|
maxFileSize: number;
|
||||||
actions: {
|
actions: {
|
||||||
logError: ({message, type}: {message: any; type: string}, status: boolean) => void;
|
logError: ({message, type}: {message: any; type: string}, status: boolean) => void;
|
||||||
@ -934,7 +935,7 @@ export class UserSettingsGeneralTab extends React.Component<Props, State> {
|
|||||||
defaultMessage="Click 'Edit' to add your full name"
|
defaultMessage="Click 'Edit' to add your full name"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
if (Utils.isMobile()) {
|
if (this.props.isMobileView) {
|
||||||
describe = (
|
describe = (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='user.settings.general.mobile.emptyName'
|
id='user.settings.general.mobile.emptyName'
|
||||||
@ -984,7 +985,7 @@ export class UserSettingsGeneralTab extends React.Component<Props, State> {
|
|||||||
defaultMessage='Nickname'
|
defaultMessage='Nickname'
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
if (Utils.isMobile()) {
|
if (this.props.isMobileView) {
|
||||||
nicknameLabel = '';
|
nicknameLabel = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1046,7 +1047,7 @@ export class UserSettingsGeneralTab extends React.Component<Props, State> {
|
|||||||
defaultMessage="Click 'Edit' to add a nickname"
|
defaultMessage="Click 'Edit' to add a nickname"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
if (Utils.isMobile()) {
|
if (this.props.isMobileView) {
|
||||||
describe = (
|
describe = (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='user.settings.general.mobile.emptyNickname'
|
id='user.settings.general.mobile.emptyNickname'
|
||||||
@ -1086,7 +1087,7 @@ export class UserSettingsGeneralTab extends React.Component<Props, State> {
|
|||||||
defaultMessage='Username'
|
defaultMessage='Username'
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
if (Utils.isMobile()) {
|
if (this.props.isMobileView) {
|
||||||
usernameLabel = '';
|
usernameLabel = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1187,7 +1188,7 @@ export class UserSettingsGeneralTab extends React.Component<Props, State> {
|
|||||||
defaultMessage='Position'
|
defaultMessage='Position'
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
if (Utils.isMobile()) {
|
if (this.props.isMobileView) {
|
||||||
positionLabel = '';
|
positionLabel = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1250,7 +1251,7 @@ export class UserSettingsGeneralTab extends React.Component<Props, State> {
|
|||||||
defaultMessage="Click 'Edit' to add your job title / position"
|
defaultMessage="Click 'Edit' to add your job title / position"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
if (Utils.isMobile()) {
|
if (this.props.isMobileView) {
|
||||||
describe = (
|
describe = (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='user.settings.general.mobile.emptyPosition'
|
id='user.settings.general.mobile.emptyPosition'
|
||||||
@ -1332,7 +1333,7 @@ export class UserSettingsGeneralTab extends React.Component<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let minMessage: JSX.Element|string = formatMessage(holders.uploadImage);
|
let minMessage: JSX.Element|string = formatMessage(holders.uploadImage);
|
||||||
if (Utils.isMobile()) {
|
if (this.props.isMobileView) {
|
||||||
minMessage = formatMessage(holders.uploadImageMobile);
|
minMessage = formatMessage(holders.uploadImageMobile);
|
||||||
}
|
}
|
||||||
if (user.last_picture_update > 0) {
|
if (user.last_picture_update > 0) {
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
import {getIsMobileView} from 'selectors/views/browser';
|
||||||
|
|
||||||
|
import store from 'stores/redux_store';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated This is a horrible hack that shouldn't used done elsewhere because we shouldn't be accessing the global
|
||||||
|
* store directly, but it's too hard to get this value into these component properly without rewriting everything.
|
||||||
|
* These components will eventually be replaced by the newer components in `components/menu` anyway.
|
||||||
|
*/
|
||||||
|
export function isMobile() {
|
||||||
|
return getIsMobileView(store.getState());
|
||||||
|
}
|
@ -171,3 +171,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.Menu__content {
|
||||||
|
&.openLeft {
|
||||||
|
right: 0;
|
||||||
|
left: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.openUp {
|
||||||
|
@media screen and (min-width: 768px) {
|
||||||
|
top: auto;
|
||||||
|
bottom: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,19 +6,15 @@ import {shallow} from 'enzyme';
|
|||||||
|
|
||||||
import Menu from './menu';
|
import Menu from './menu';
|
||||||
|
|
||||||
|
jest.mock('./is_mobile_view_hack', () => ({
|
||||||
|
isMobile: jest.fn(() => false),
|
||||||
|
}));
|
||||||
|
|
||||||
(global as any).MutationObserver = class {
|
(global as any).MutationObserver = class {
|
||||||
public disconnect() {}
|
public disconnect() {}
|
||||||
public observe() {}
|
public observe() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
jest.mock('utils/utils', () => {
|
|
||||||
const original = jest.requireActual('utils/utils');
|
|
||||||
return {
|
|
||||||
...original,
|
|
||||||
isMobile: jest.fn(() => false),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('components/Menu', () => {
|
describe('components/Menu', () => {
|
||||||
test('should match snapshot', () => {
|
test('should match snapshot', () => {
|
||||||
const wrapper = shallow(<Menu ariaLabel='test-label'>{'text'}</Menu>);
|
const wrapper = shallow(<Menu ariaLabel='test-label'>{'text'}</Menu>);
|
||||||
@ -68,46 +64,7 @@ describe('components/Menu', () => {
|
|||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should match snapshot with openLeft and openUp when is mobile', () => {
|
|
||||||
const utils = require('utils/utils'); //eslint-disable-line global-require
|
|
||||||
utils.isMobile.mockReturnValue(true);
|
|
||||||
|
|
||||||
const wrapper = shallow(
|
|
||||||
<Menu
|
|
||||||
openLeft={true}
|
|
||||||
openUp={true}
|
|
||||||
ariaLabel='test-label'
|
|
||||||
>
|
|
||||||
{'text'}
|
|
||||||
</Menu>,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(wrapper).toMatchInlineSnapshot(`
|
|
||||||
<div
|
|
||||||
aria-label="test-label"
|
|
||||||
className="a11y__popup Menu"
|
|
||||||
role="menu"
|
|
||||||
>
|
|
||||||
<ul
|
|
||||||
className="Menu__content dropdown-menu"
|
|
||||||
onClick={[Function]}
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"left": "inherit",
|
|
||||||
"right": 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
text
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should match snapshot with openLeft and openUp', () => {
|
test('should match snapshot with openLeft and openUp', () => {
|
||||||
const utils = require('utils/utils'); //eslint-disable-line global-require
|
|
||||||
utils.isMobile.mockReturnValue(false);
|
|
||||||
|
|
||||||
const wrapper = shallow(
|
const wrapper = shallow(
|
||||||
<Menu
|
<Menu
|
||||||
openLeft={true}
|
openLeft={true}
|
||||||
@ -125,16 +82,9 @@ describe('components/Menu', () => {
|
|||||||
role="menu"
|
role="menu"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
className="Menu__content dropdown-menu"
|
className="Menu__content dropdown-menu openLeft openUp"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
style={
|
style={Object {}}
|
||||||
Object {
|
|
||||||
"bottom": "100%",
|
|
||||||
"left": "inherit",
|
|
||||||
"right": 0,
|
|
||||||
"top": "auto",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
text
|
text
|
||||||
</ul>
|
</ul>
|
||||||
@ -143,8 +93,6 @@ describe('components/Menu', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should hide the correct dividers', () => {
|
test('should hide the correct dividers', () => {
|
||||||
const utils = require('utils/utils'); //eslint-disable-line global-require
|
|
||||||
utils.isMobile.mockReturnValue(false);
|
|
||||||
const pseudoMenu = document.createElement('div');
|
const pseudoMenu = document.createElement('div');
|
||||||
const listOfItems = [
|
const listOfItems = [
|
||||||
'menu-divider',
|
'menu-divider',
|
||||||
@ -255,8 +203,6 @@ describe('components/Menu', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should hide the correct dividers on mobile', () => {
|
test('should hide the correct dividers on mobile', () => {
|
||||||
const utils = require('utils/utils'); //eslint-disable-line global-require
|
|
||||||
utils.isMobile.mockReturnValue(false);
|
|
||||||
const pseudoMenu = document.createElement('div');
|
const pseudoMenu = document.createElement('div');
|
||||||
const listOfItems = [
|
const listOfItems = [
|
||||||
'mobile-menu-divider',
|
'mobile-menu-divider',
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
import React, {CSSProperties} from 'react';
|
import React, {CSSProperties} from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import {isMobile} from 'utils/utils';
|
|
||||||
|
|
||||||
import SubMenuItem from './menu_items/submenu_item';
|
import SubMenuItem from './menu_items/submenu_item';
|
||||||
|
|
||||||
import MenuHeader from './menu_header';
|
import MenuHeader from './menu_header';
|
||||||
@ -123,15 +121,6 @@ export default class Menu extends React.PureComponent<Props> {
|
|||||||
let styles: CSSProperties = {};
|
let styles: CSSProperties = {};
|
||||||
if (customStyles) {
|
if (customStyles) {
|
||||||
styles = customStyles;
|
styles = customStyles;
|
||||||
} else {
|
|
||||||
if (openLeft) {
|
|
||||||
styles.left = 'inherit';
|
|
||||||
styles.right = 0;
|
|
||||||
}
|
|
||||||
if (openUp && !isMobile()) {
|
|
||||||
styles.bottom = '100%';
|
|
||||||
styles.top = 'auto';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -145,7 +134,14 @@ export default class Menu extends React.PureComponent<Props> {
|
|||||||
id={listId}
|
id={listId}
|
||||||
ref={this.node}
|
ref={this.node}
|
||||||
style={styles}
|
style={styles}
|
||||||
className={classNames('Menu__content dropdown-menu', this.props.className)}
|
className={classNames(
|
||||||
|
'Menu__content dropdown-menu',
|
||||||
|
{
|
||||||
|
openLeft,
|
||||||
|
openUp,
|
||||||
|
},
|
||||||
|
this.props.className,
|
||||||
|
)}
|
||||||
onClick={this.handleMenuClick}
|
onClick={this.handleMenuClick}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
@ -8,6 +8,10 @@ import Constants from 'utils/constants';
|
|||||||
|
|
||||||
import SubMenuItem from './submenu_item';
|
import SubMenuItem from './submenu_item';
|
||||||
|
|
||||||
|
jest.mock('../is_mobile_view_hack', () => ({
|
||||||
|
isMobile: jest.fn(() => false),
|
||||||
|
}));
|
||||||
|
|
||||||
describe('components/widgets/menu/menu_items/submenu_item', () => {
|
describe('components/widgets/menu/menu_items/submenu_item', () => {
|
||||||
test('empty subMenu should match snapshot', () => {
|
test('empty subMenu should match snapshot', () => {
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
|
@ -6,10 +6,13 @@ import classNames from 'classnames';
|
|||||||
|
|
||||||
import * as Keyboard from 'utils/keyboard';
|
import * as Keyboard from 'utils/keyboard';
|
||||||
import * as Utils from 'utils/utils';
|
import * as Utils from 'utils/utils';
|
||||||
|
|
||||||
import {showMobileSubMenuModal} from 'actions/global_actions';
|
import {showMobileSubMenuModal} from 'actions/global_actions';
|
||||||
|
|
||||||
import type {Menu} from 'types/store/plugins';
|
import type {Menu} from 'types/store/plugins';
|
||||||
|
|
||||||
|
import {isMobile as isMobileViewHack} from '../is_mobile_view_hack';
|
||||||
|
|
||||||
import './menu_item.scss';
|
import './menu_item.scss';
|
||||||
import Constants from 'utils/constants';
|
import Constants from 'utils/constants';
|
||||||
|
|
||||||
@ -94,7 +97,7 @@ export default class SubMenuItem extends React.PureComponent<Props, State> {
|
|||||||
private onClick = (event: React.SyntheticEvent<HTMLElement>) => {
|
private onClick = (event: React.SyntheticEvent<HTMLElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const {id, postId, subMenu, action, root, isHeader} = this.props;
|
const {id, postId, subMenu, action, root, isHeader} = this.props;
|
||||||
const isMobile = Utils.isMobile();
|
const isMobile = isMobileViewHack();
|
||||||
if (isHeader) {
|
if (isHeader) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
return;
|
return;
|
||||||
@ -141,7 +144,7 @@ export default class SubMenuItem extends React.PureComponent<Props, State> {
|
|||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const {id, postId, text, selectedValueText, subMenu, icon, filter, ariaLabel, direction, styleSelectableItem, extraText, renderSelected, rightDecorator, tabIndex} = this.props;
|
const {id, postId, text, selectedValueText, subMenu, icon, filter, ariaLabel, direction, styleSelectableItem, extraText, renderSelected, rightDecorator, tabIndex} = this.props;
|
||||||
const isMobile = Utils.isMobile();
|
const isMobile = isMobileViewHack();
|
||||||
|
|
||||||
if (filter && !filter(id)) {
|
if (filter && !filter(id)) {
|
||||||
return ('');
|
return ('');
|
||||||
|
@ -5,7 +5,11 @@ import React from 'react';
|
|||||||
import {shallow, mount} from 'enzyme';
|
import {shallow, mount} from 'enzyme';
|
||||||
import {Modal} from 'react-bootstrap';
|
import {Modal} from 'react-bootstrap';
|
||||||
|
|
||||||
import SubMenuModal from 'components/widgets/menu/menu_modals/submenu_modal/submenu_modal';
|
import SubMenuModal from './submenu_modal';
|
||||||
|
|
||||||
|
jest.mock('../../is_mobile_view_hack', () => ({
|
||||||
|
isMobile: jest.fn(() => false),
|
||||||
|
}));
|
||||||
|
|
||||||
(global as any).MutationObserver = class {
|
(global as any).MutationObserver = class {
|
||||||
public disconnect() {}
|
public disconnect() {}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {CSSTransition} from 'react-transition-group';
|
import {CSSTransition} from 'react-transition-group';
|
||||||
|
|
||||||
import {isMobile} from 'utils/utils';
|
import {isMobile} from './is_mobile_view_hack';
|
||||||
|
|
||||||
const ANIMATION_DURATION = 80;
|
const ANIMATION_DURATION = 80;
|
||||||
|
|
||||||
|
@ -35,6 +35,11 @@ describe('selectors/onboarding', () => {
|
|||||||
profiles,
|
profiles,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
views: {
|
||||||
|
browser: {
|
||||||
|
windowSize: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
} as unknown as GlobalState;
|
} as unknown as GlobalState;
|
||||||
|
|
||||||
const [showTaskList, firstTimeOnboarding] = getShowTaskListBool(state);
|
const [showTaskList, firstTimeOnboarding] = getShowTaskListBool(state);
|
||||||
@ -65,6 +70,11 @@ describe('selectors/onboarding', () => {
|
|||||||
profiles,
|
profiles,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
views: {
|
||||||
|
browser: {
|
||||||
|
windowSize: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
} as unknown as GlobalState;
|
} as unknown as GlobalState;
|
||||||
|
|
||||||
const [showTaskList, firstTimeOnboarding] = getShowTaskListBool(state);
|
const [showTaskList, firstTimeOnboarding] = getShowTaskListBool(state);
|
||||||
@ -95,6 +105,11 @@ describe('selectors/onboarding', () => {
|
|||||||
profiles,
|
profiles,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
views: {
|
||||||
|
browser: {
|
||||||
|
windowSize: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
} as unknown as GlobalState;
|
} as unknown as GlobalState;
|
||||||
|
|
||||||
const [showTaskList, firstTimeOnboarding] = getShowTaskListBool(state);
|
const [showTaskList, firstTimeOnboarding] = getShowTaskListBool(state);
|
||||||
@ -128,6 +143,11 @@ describe('selectors/onboarding', () => {
|
|||||||
profiles,
|
profiles,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
views: {
|
||||||
|
browser: {
|
||||||
|
windowSize: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
} as unknown as GlobalState;
|
} as unknown as GlobalState;
|
||||||
|
|
||||||
const [showTaskList, firstTimeOnboarding] = getShowTaskListBool(state);
|
const [showTaskList, firstTimeOnboarding] = getShowTaskListBool(state);
|
||||||
@ -165,6 +185,11 @@ describe('selectors/onboarding', () => {
|
|||||||
profiles,
|
profiles,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
views: {
|
||||||
|
browser: {
|
||||||
|
windowSize: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
} as unknown as GlobalState;
|
} as unknown as GlobalState;
|
||||||
|
|
||||||
const [showTaskList, firstTimeOnboarding] = getShowTaskListBool(state);
|
const [showTaskList, firstTimeOnboarding] = getShowTaskListBool(state);
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import {isMobile} from 'utils/utils';
|
|
||||||
|
|
||||||
import {createSelector} from 'mattermost-redux/selectors/create_selector';
|
import {createSelector} from 'mattermost-redux/selectors/create_selector';
|
||||||
import {makeGetCategory, getBool} from 'mattermost-redux/selectors/entities/preferences';
|
import {makeGetCategory, getBool} from 'mattermost-redux/selectors/entities/preferences';
|
||||||
import {getCurrentUser, isFirstAdmin} from 'mattermost-redux/selectors/entities/users';
|
import {getCurrentUser, isFirstAdmin} from 'mattermost-redux/selectors/entities/users';
|
||||||
|
|
||||||
import {OnboardingTaskCategory, OnboardingTaskList} from 'components/onboarding_tasks';
|
import {OnboardingTaskCategory, OnboardingTaskList} from 'components/onboarding_tasks';
|
||||||
|
|
||||||
|
import {getIsMobileView} from 'selectors/views/browser';
|
||||||
|
|
||||||
import {GlobalState} from 'types/store';
|
import {GlobalState} from 'types/store';
|
||||||
|
|
||||||
import {RecommendedNextStepsLegacy, Preferences} from 'utils/constants';
|
import {RecommendedNextStepsLegacy, Preferences} from 'utils/constants';
|
||||||
@ -125,9 +125,8 @@ export const getShowTaskListBool = createSelector(
|
|||||||
(state: GlobalState) => state,
|
(state: GlobalState) => state,
|
||||||
(state: GlobalState) => getCategory(state, OnboardingTaskCategory),
|
(state: GlobalState) => getCategory(state, OnboardingTaskCategory),
|
||||||
(state: GlobalState) => getCategory(state, Preferences.RECOMMENDED_NEXT_STEPS),
|
(state: GlobalState) => getCategory(state, Preferences.RECOMMENDED_NEXT_STEPS),
|
||||||
(state, onboardingPreferences, legacyStepsPreferences) => {
|
getIsMobileView,
|
||||||
const isMobileView = isMobile();
|
(state, onboardingPreferences, legacyStepsPreferences, isMobileView) => {
|
||||||
|
|
||||||
// conditions to validate scenario where users (initially first_admins) had already set any of the onboarding task list preferences values.
|
// conditions to validate scenario where users (initially first_admins) had already set any of the onboarding task list preferences values.
|
||||||
// We check wether the preference value exists meaning the onboarding tasks list already started no matter what the state of the process is
|
// We check wether the preference value exists meaning the onboarding tasks list already started no matter what the state of the process is
|
||||||
const hasUserStartedOnboardingTaskListProcess = onboardingPreferences?.some((pref) =>
|
const hasUserStartedOnboardingTaskListProcess = onboardingPreferences?.some((pref) =>
|
||||||
|
@ -47,12 +47,10 @@ import {searchForTerm} from 'actions/post_actions';
|
|||||||
import {getHistory} from 'utils/browser_history';
|
import {getHistory} from 'utils/browser_history';
|
||||||
import * as Keyboard from 'utils/keyboard';
|
import * as Keyboard from 'utils/keyboard';
|
||||||
import * as UserAgent from 'utils/user_agent';
|
import * as UserAgent from 'utils/user_agent';
|
||||||
import {isDesktopApp} from 'utils/user_agent';
|
|
||||||
import {t} from 'utils/i18n';
|
import {t} from 'utils/i18n';
|
||||||
import store from 'stores/redux_store.jsx';
|
import store from 'stores/redux_store.jsx';
|
||||||
|
|
||||||
import {getCurrentLocale, getTranslations} from 'selectors/i18n';
|
import {getCurrentLocale, getTranslations} from 'selectors/i18n';
|
||||||
import {getIsMobileView} from 'selectors/views/browser';
|
|
||||||
|
|
||||||
import {FileInfo} from '@mattermost/types/files';
|
import {FileInfo} from '@mattermost/types/files';
|
||||||
import {Team} from '@mattermost/types/teams';
|
import {Team} from '@mattermost/types/teams';
|
||||||
@ -890,10 +888,6 @@ export function isValidBotUsername(name: string) {
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isMobile() {
|
|
||||||
return getIsMobileView(store.getState());
|
|
||||||
}
|
|
||||||
|
|
||||||
export function loadImage(
|
export function loadImage(
|
||||||
url: string,
|
url: string,
|
||||||
onLoad: ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null,
|
onLoad: ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null,
|
||||||
@ -1720,9 +1714,9 @@ const TrackFlowSources: Record<string, string> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function getTrackFlowSource() {
|
function getTrackFlowSource() {
|
||||||
if (isMobile()) {
|
if (UserAgent.isMobile()) {
|
||||||
return TrackFlowSources.wm;
|
return TrackFlowSources.wm;
|
||||||
} else if (isDesktopApp()) {
|
} else if (UserAgent.isDesktopApp()) {
|
||||||
return TrackFlowSources.d;
|
return TrackFlowSources.d;
|
||||||
}
|
}
|
||||||
return TrackFlowSources.wd;
|
return TrackFlowSources.wd;
|
||||||
|
Loading…
Reference in New Issue
Block a user