From c3b1c2ff9bd5207a0bfeff7af69f34140db06ca7 Mon Sep 17 00:00:00 2001 From: Jesse Hallam Date: Tue, 27 Mar 2018 09:49:57 -0400 Subject: [PATCH] MM-9787: Transition [lr]hs open state to redux, fixing Safari race condition. (#991) * move the [lr]hs open state into redux This eliminates race conditions around toggling classes all over the code base in an attempt to slide the various components around. It also has the nice side effect of getting rid of doStrangeThings. WebRTC remains in beta, and remains functional with these changes, but the absolute minimum set of changes were made to integrate the old flux store with the new state. This remains intentionally hacky, as the medium-term vision is to rip this feature out and replace it as a plugin. * fix a rendering issue with PermalinkView Now that opening the sidebar triggers a re-render (vs. just toggling classes), the PermalinkView would incorrectly transition between valid and invalid internal states even if the target permalink hadn't changed. This resulted in a flashing when opening the sidebar, e.g. to view flagged messages. This restricts the handling of a permalink event to when the post id has actually changed. * remove unused initTeamChangeActions in lhs actions --- actions/global_actions.jsx | 9 +- actions/views/lhs.js | 23 +- actions/views/rhs.js | 12 + actions/views/webrtc.js | 14 + .../center_channel/center_channel.jsx | 13 +- .../channel_layout/center_channel/index.js | 7 + .../channel_layout/channel_controller.jsx | 4 +- components/create_post/create_post.jsx | 2 +- components/navbar/index.js | 15 +- components/navbar/navbar.jsx | 23 +- components/permalink_view/permalink_view.jsx | 4 +- components/search_bar/index.jsx | 2 + components/search_bar/search_bar.jsx | 11 +- components/sidebar/header/sidebar_header.jsx | 9 +- components/sidebar/index.js | 11 +- components/sidebar/sidebar.jsx | 10 +- components/sidebar/sidebar_channel/index.js | 2 + .../sidebar_channel/sidebar_channel.jsx | 13 +- components/sidebar/sidebar_tutorial_tip.jsx | 2 +- components/sidebar_right/index.js | 3 +- components/sidebar_right/sidebar_right.jsx | 28 +- components/sidebar_right_menu/index.js | 7 +- .../sidebar_right_menu/sidebar_right_menu.jsx | 46 +- components/team_sidebar/index.js | 3 + .../team_sidebar/team_sidebar_controller.jsx | 4 +- components/tutorial/menu_tutorial_tip.jsx | 50 ++ components/tutorial/tutorial_tip/index.js | 16 + .../{ => tutorial_tip}/tutorial_tip.jsx | 53 +- components/webrtc/controller/index.js | 13 +- .../webrtc/controller/webrtc_controller.jsx | 5 +- components/webrtc/notification/index.js | 26 + .../webrtc_notification.jsx | 26 +- components/webrtc/sidebar/index.js | 18 + components/webrtc/sidebar/webrtc_sidebar.jsx | 96 ++++ components/webrtc/webrtc_sidebar.jsx | 128 ----- reducers/views/index.js | 4 + reducers/views/lhs.js | 30 ++ reducers/views/rhs.js | 44 +- reducers/views/webrtc.js | 30 ++ selectors/lhs.jsx | 6 + selectors/rhs.jsx | 8 + selectors/webrtc.jsx | 6 + stores/webrtc_store.jsx | 17 +- .../__snapshots__/create_post.test.jsx.snap | 141 ++++++ .../create_post/create_post.test.jsx | 2 +- .../sidebar_tutorial_tip.test.jsx.snap | 8 +- .../sidebar/sidebar_channel.test.jsx | 479 ++++++++---------- tests/redux/actions/views/lhs.test.js | 71 ++- tests/redux/actions/views/rhs.test.js | 36 ++ tests/redux/reducers/views/lhs.test.js | 110 ++++ tests/redux/reducers/views/rhs.test.js | 108 +++- tests/redux/selectors/lhs.test.js | 26 + tests/redux/selectors/rhs.test.js | 24 + utils/constants.jsx | 12 +- 54 files changed, 1260 insertions(+), 610 deletions(-) create mode 100644 actions/views/webrtc.js create mode 100644 components/tutorial/menu_tutorial_tip.jsx create mode 100644 components/tutorial/tutorial_tip/index.js rename components/tutorial/{ => tutorial_tip}/tutorial_tip.jsx (80%) create mode 100644 components/webrtc/notification/index.js rename components/webrtc/{ => notification}/webrtc_notification.jsx (95%) create mode 100644 components/webrtc/sidebar/index.js create mode 100644 components/webrtc/sidebar/webrtc_sidebar.jsx delete mode 100644 components/webrtc/webrtc_sidebar.jsx create mode 100644 reducers/views/lhs.js create mode 100644 reducers/views/webrtc.js create mode 100644 selectors/lhs.jsx create mode 100644 selectors/webrtc.jsx create mode 100644 tests/redux/reducers/views/lhs.test.js create mode 100644 tests/redux/selectors/lhs.test.js diff --git a/actions/global_actions.jsx b/actions/global_actions.jsx index dda4af5726da..91ea2fc45c94 100644 --- a/actions/global_actions.jsx +++ b/actions/global_actions.jsx @@ -24,7 +24,8 @@ import {loadChannelsForCurrentUser} from 'actions/channel_actions.jsx'; import {handleNewPost} from 'actions/post_actions.jsx'; import {stopPeriodicStatusUpdates} from 'actions/status_actions.jsx'; import {loadNewDMIfNeeded, loadNewGMIfNeeded, loadProfilesForSidebar} from 'actions/user_actions.jsx'; -import {closeRightHandSide} from 'actions/views/rhs'; +import {closeRightHandSide, closeMenu as closeRhsMenu} from 'actions/views/rhs'; +import {close as closeLhs} from 'actions/views/lhs'; import * as WebsocketActions from 'actions/websocket_actions.jsx'; import AppDispatcher from 'dispatcher/app_dispatcher.jsx'; import BrowserStore from 'stores/browser_store.jsx'; @@ -472,10 +473,8 @@ export function clientLogout(redirectTo = '/') { export function toggleSideBarRightMenuAction() { dispatch(closeRightHandSide()); - - document.querySelector('.app__body .inner-wrap').classList.remove('move--right', 'move--left', 'move--left-small'); - document.querySelector('.app__body .sidebar--left').classList.remove('move--right'); - document.querySelector('.app__body .sidebar--right').classList.remove('move--left'); + dispatch(closeLhs()); + dispatch(closeRhsMenu()); document.querySelector('.app__body .sidebar--menu').classList.remove('move--left'); } diff --git a/actions/views/lhs.js b/actions/views/lhs.js index d07e5b174924..def81cd5cfe9 100644 --- a/actions/views/lhs.js +++ b/actions/views/lhs.js @@ -1,15 +1,16 @@ +// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. -import {fetchMyChannelsAndMembers} from 'mattermost-redux/actions/channels'; +import {ActionTypes} from 'utils/constants.jsx'; -import {loadProfilesForSidebar} from 'actions/user_actions.jsx'; -import {loadStatusesForChannelAndSidebar} from 'actions/status_actions.jsx'; -import store from 'stores/redux_store.jsx'; +export const toggle = () => (dispatch) => dispatch({ + type: ActionTypes.TOGGLE_LHS, +}); -const dispatch = store.dispatch; -const getState = store.getState; +export const open = () => (dispatch) => dispatch({ + type: ActionTypes.OPEN_LHS, +}); -export async function initTeamChangeActions(teamId) { - await fetchMyChannelsAndMembers(teamId)(dispatch, getState); - loadStatusesForChannelAndSidebar(); - loadProfilesForSidebar(); -} +export const close = () => (dispatch) => dispatch({ + type: ActionTypes.CLOSE_LHS, +}); diff --git a/actions/views/rhs.js b/actions/views/rhs.js index 34deb460fe5c..f10bc8b5f245 100644 --- a/actions/views/rhs.js +++ b/actions/views/rhs.js @@ -261,3 +261,15 @@ export function closeRightHandSide() { ])); }; } + +export const toggleMenu = () => (dispatch) => dispatch({ + type: ActionTypes.TOGGLE_RHS_MENU, +}); + +export const openMenu = () => (dispatch) => dispatch({ + type: ActionTypes.OPEN_RHS_MENU, +}); + +export const closeMenu = () => (dispatch) => dispatch({ + type: ActionTypes.CLOSE_RHS_MENU, +}); diff --git a/actions/views/webrtc.js b/actions/views/webrtc.js new file mode 100644 index 000000000000..231fb5fd73ed --- /dev/null +++ b/actions/views/webrtc.js @@ -0,0 +1,14 @@ +// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import {ActionTypes} from 'utils/constants.jsx'; + +export const initWebrtc = (userId, isCaller) => (dispatch) => dispatch({ + type: ActionTypes.INIT_WEBRTC, + userId, + isCaller, +}); + +export const closeWebrtc = () => (dispatch) => dispatch({ + type: ActionTypes.CLOSE_WEBRTC, +}); diff --git a/components/channel_layout/center_channel/center_channel.jsx b/components/channel_layout/center_channel/center_channel.jsx index ce1235ccd356..3cdde5a2e98e 100644 --- a/components/channel_layout/center_channel/center_channel.jsx +++ b/components/channel_layout/center_channel/center_channel.jsx @@ -4,6 +4,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import {Route, Switch, Redirect} from 'react-router-dom'; +import classNames from 'classnames'; import PermalinkView from 'components/permalink_view'; import Navbar from 'components/navbar'; @@ -14,6 +15,10 @@ export default class CenterChannel extends React.PureComponent { match: PropTypes.object.isRequired, location: PropTypes.object.isRequired, lastChannelPath: PropTypes.string.isRequired, + lhsOpen: PropTypes.bool.isRequired, + rhsOpen: PropTypes.bool.isRequired, + rhsMenuOpen: PropTypes.bool.isRequired, + webRtcOpen: PropTypes.bool.isRequired, }; constructor(props) { @@ -34,9 +39,13 @@ export default class CenterChannel extends React.PureComponent { const url = this.props.match.url; return (