diff --git a/actions/views/channel_sidebar.ts b/actions/views/channel_sidebar.ts index b46014e8377d..4bbc184bcec9 100644 --- a/actions/views/channel_sidebar.ts +++ b/actions/views/channel_sidebar.ts @@ -142,7 +142,14 @@ export function adjustTargetIndexForMove(state: GlobalState, categoryId: string, } export function clearChannelSelection() { - return (dispatch: DispatchFunc) => { + return (dispatch: DispatchFunc, getState: () => GlobalState) => { + const state = getState(); + + if (state.views.channelSidebar.multiSelectedChannelIds.length === 0) { + // No selection to clear + return Promise.resolve({data: true}); + } + return dispatch({ type: ActionTypes.MULTISELECT_CHANNEL_CLEAR, }); diff --git a/components/legacy_sidebar/sidebar.jsx b/components/legacy_sidebar/sidebar.jsx index 12a8995ff842..73d9a7f66c88 100644 --- a/components/legacy_sidebar/sidebar.jsx +++ b/components/legacy_sidebar/sidebar.jsx @@ -8,6 +8,7 @@ import ReactDOM from 'react-dom'; import {FormattedMessage, injectIntl} from 'react-intl'; import {PropTypes} from 'prop-types'; import classNames from 'classnames'; +import throttle from 'lodash/throttle'; import Scrollbars from 'react-custom-scrollbars'; import {SpringSystem, MathUtil} from 'rebound'; @@ -270,9 +271,9 @@ class LegacySidebar extends React.PureComponent { } } - onScroll = () => { + onScroll = throttle(() => { this.updateUnreadIndicators(); - } + }, 100); handleScrollAnimationUpdate = (spring) => { const {scrollbar} = this.refs; diff --git a/components/sidebar/index.ts b/components/sidebar/index.ts index 756c4b2cfc2d..3c24523be546 100644 --- a/components/sidebar/index.ts +++ b/components/sidebar/index.ts @@ -13,7 +13,7 @@ import {getLicense} from 'mattermost-redux/selectors/entities/general'; import {getBool} from 'mattermost-redux/selectors/entities/preferences'; import {haveIChannelPermission} from 'mattermost-redux/selectors/entities/roles'; import {getCurrentTeam} from 'mattermost-redux/selectors/entities/teams'; -import {GenericAction, ActionFunc} from 'mattermost-redux/types/actions'; +import {GenericAction} from 'mattermost-redux/types/actions'; import {createCategory, clearChannelSelection} from 'actions/views/channel_sidebar'; import {isUnreadFilterEnabled} from 'selectors/views/channel_sidebar'; @@ -66,7 +66,7 @@ type Actions = { function mapDispatchToProps(dispatch: Dispatch) { return { - actions: bindActionCreators, Actions>({ + actions: bindActionCreators({ clearChannelSelection, createCategory, fetchMyCategories, diff --git a/components/sidebar/sidebar_channel_list/sidebar_channel_list.tsx b/components/sidebar/sidebar_channel_list/sidebar_channel_list.tsx index 20cd55645f79..b44d3496ccd8 100644 --- a/components/sidebar/sidebar_channel_list/sidebar_channel_list.tsx +++ b/components/sidebar/sidebar_channel_list/sidebar_channel_list.tsx @@ -7,7 +7,7 @@ import Scrollbars from 'react-custom-scrollbars'; import {DragDropContext, Droppable, DropResult, DragStart, BeforeCapture} from 'react-beautiful-dnd'; import {Spring, SpringSystem} from 'rebound'; import classNames from 'classnames'; -import debounce from 'lodash/debounce'; +import throttle from 'lodash/throttle'; import {General} from 'mattermost-redux/constants'; import {Channel} from 'mattermost-redux/types/channels'; @@ -357,11 +357,11 @@ export default class SidebarChannelList extends React.PureComponent { + onScroll = throttle(() => { this.updateUnreadIndicators(); - } + }, 100); - onTransitionEnd = debounce(() => { + onTransitionEnd = throttle(() => { this.updateUnreadIndicators(); }, 100); diff --git a/components/sidebar/sidebar_menu/sidebar_menu.tsx b/components/sidebar/sidebar_menu/sidebar_menu.tsx index dcf0dc79ce59..b7ac97ab552c 100644 --- a/components/sidebar/sidebar_menu/sidebar_menu.tsx +++ b/components/sidebar/sidebar_menu/sidebar_menu.tsx @@ -59,22 +59,6 @@ export default class SidebarMenu extends React.PureComponent { } } - // TODO: Temporary code to keep the menu in place while scrolling - // This shouldn't be necessary once the menus are fixed up - componentDidMount() { - const scrollbars = document.querySelectorAll('#SidebarContainer .SidebarNavContainer .scrollbar--view'); - if (scrollbars && scrollbars[0]) { - scrollbars[0].addEventListener('scroll', this.closeMenu); - } - } - - componentWillUnmount() { - const scrollbars = document.querySelectorAll('#SidebarContainer .SidebarNavContainer .scrollbar--view'); - if (scrollbars && scrollbars[0]) { - scrollbars[0].removeEventListener('scroll', this.closeMenu); - } - } - closeMenu = () => { if (this.menuWrapperRef.current) { this.menuWrapperRef.current.close(); diff --git a/reducers/views/channel_sidebar.test.ts b/reducers/views/channel_sidebar.test.ts index 71051635f4d5..c987ad2d71e6 100644 --- a/reducers/views/channel_sidebar.test.ts +++ b/reducers/views/channel_sidebar.test.ts @@ -99,4 +99,17 @@ describe('multiSelectedChannelIds', () => { 'channel-2', ]); }); + + test('should not update state when clearing without a selection', () => { + const initialState: string[] = []; + + const state = Reducers.multiSelectedChannelIds( + initialState, + { + type: ActionTypes.MULTISELECT_CHANNEL_CLEAR, + }, + ); + + expect(state).toBe(initialState); + }); }); diff --git a/reducers/views/channel_sidebar.ts b/reducers/views/channel_sidebar.ts index da551c094e35..f6faeacab20f 100644 --- a/reducers/views/channel_sidebar.ts +++ b/reducers/views/channel_sidebar.ts @@ -106,7 +106,10 @@ export function multiSelectedChannelIds(state: string[] = [], action: GenericAct return removeItem(state, action.data); case ActionTypes.MULTISELECT_CHANNEL_TO: return action.data; + case ActionTypes.MULTISELECT_CHANNEL_CLEAR: + return state.length > 0 ? [] : state; + case UserTypes.LOGOUT_SUCCESS: return []; default: