From 0cd123aecc17e909641f3f9df9f8580ca0b37409 Mon Sep 17 00:00:00 2001 From: Mattermost Build Date: Thu, 18 Jun 2020 03:25:59 +0200 Subject: [PATCH] MM-25695 Select channel when switching teams if available (#4443) Co-authored-by: Elias Nahum --- app/actions/helpers/channels.ts | 41 ++++++++++++++++++++++++++++++-- app/actions/views/channel.js | 26 +++----------------- app/actions/views/select_team.js | 32 +++++++++++++++++++------ app/mm-redux/types/store.ts | 1 + 4 files changed, 68 insertions(+), 32 deletions(-) diff --git a/app/actions/helpers/channels.ts b/app/actions/helpers/channels.ts index 9c67bf8f6..02366edef 100644 --- a/app/actions/helpers/channels.ts +++ b/app/actions/helpers/channels.ts @@ -4,11 +4,11 @@ import {ChannelTypes, PreferenceTypes, RoleTypes, UserTypes} from '@mm-redux/action_types'; import {Client4} from '@mm-redux/client'; import {General, Preferences} from '@mm-redux/constants'; -import {getCurrentChannelId} from '@mm-redux/selectors/entities/channels'; +import {getCurrentChannelId, getRedirectChannelNameForTeam, getChannelsNameMapInTeam} from '@mm-redux/selectors/entities/channels'; import {getConfig} from '@mm-redux/selectors/entities/general'; import {getMyPreferences} from '@mm-redux/selectors/entities/preferences'; import {getCurrentUserId, getUsers, getUserIdsInChannels} from '@mm-redux/selectors/entities/users'; -import {getUserIdFromChannelName, isAutoClosed} from '@mm-redux/utils/channel_utils'; +import {getChannelByName as selectChannelByName, getUserIdFromChannelName, isAutoClosed} from '@mm-redux/utils/channel_utils'; import {getPreferenceKey} from '@mm-redux/utils/preference_utils'; import {ActionResult, GenericAction} from '@mm-redux/types/actions'; @@ -281,6 +281,43 @@ export async function getAddedDmUsersIfNecessary(state: GlobalState, preferences return actions; } +export function lastChannelIdForTeam(state: GlobalState, teamId: string): string { + const {channels, myMembers} = state.entities.channels; + const {currentUserId} = state.entities.users; + const {myPreferences} = state.entities.preferences; + const lastChannelForTeam = state.views.team.lastChannelForTeam[teamId]; + const lastChannelId = lastChannelForTeam && lastChannelForTeam.length ? lastChannelForTeam[0] : ''; + const lastChannel = channels[lastChannelId]; + + const isDMVisible = lastChannel && lastChannel.type === General.DM_CHANNEL && + isDirectChannelVisible(currentUserId, myPreferences, lastChannel); + + const isGMVisible = lastChannel && lastChannel.type === General.GM_CHANNEL && + isGroupChannelVisible(myPreferences, lastChannel); + + if ( + myMembers[lastChannelId] && + lastChannel && + (lastChannel.team_id === teamId || isDMVisible || isGMVisible) + ) { + return lastChannelId; + } + + // Fallback to default channel + const channelsInTeam = getChannelsNameMapInTeam(state, teamId); + const channel = selectChannelByName(channelsInTeam, getRedirectChannelNameForTeam(state, teamId)); + + if (channel) { + return channel.id; + } + + // Handle case when the default channel cannot be found + // so we need to get the first available channel of the team + const teamChannels = Object.values(channelsInTeam); + const firstChannel = teamChannels.length ? teamChannels[0].id : ''; + return firstChannel; +} + function fetchDirectMessageProfileIfNeeded(state: GlobalState, channel: Channel, channelMembers: Array, profilesInChannel: Array) { const currentUserId = getCurrentUserId(state); const myPreferences = getMyPreferences(state); diff --git a/app/actions/views/channel.js b/app/actions/views/channel.js index e34929147..cdf613bd1 100644 --- a/app/actions/views/channel.js +++ b/app/actions/views/channel.js @@ -29,7 +29,7 @@ import {getTeamByName} from '@mm-redux/selectors/entities/teams'; import {getChannelByName as selectChannelByName, getChannelsIdForTeam} from '@mm-redux/utils/channel_utils'; import EventEmitter from '@mm-redux/utils/event_emitter'; -import {loadSidebarDirectMessagesProfiles} from '@actions/helpers/channels'; +import {lastChannelIdForTeam, loadSidebarDirectMessagesProfiles} from '@actions/helpers/channels'; import {getPosts, getPostsBefore, getPostsSince, getPostThread, loadUnreadChannelPosts} from '@actions/views/post'; import {INSERT_TO_COMMENT, INSERT_TO_DRAFT} from '@constants/post_draft'; import {getChannelReachable} from '@selectors/channel'; @@ -136,29 +136,9 @@ export function loadThreadIfNecessary(rootId) { export function selectInitialChannel(teamId) { return (dispatch, getState) => { const state = getState(); - const {channels, myMembers} = state.entities.channels; - const {currentUserId} = state.entities.users; - const {myPreferences} = state.entities.preferences; - const lastChannelForTeam = state.views.team.lastChannelForTeam[teamId]; - const lastChannelId = lastChannelForTeam && lastChannelForTeam.length ? lastChannelForTeam[0] : ''; - const lastChannel = channels[lastChannelId]; + const channelId = lastChannelIdForTeam(state, teamId); - const isDMVisible = lastChannel && lastChannel.type === General.DM_CHANNEL && - isDirectChannelVisible(currentUserId, myPreferences, lastChannel); - - const isGMVisible = lastChannel && lastChannel.type === General.GM_CHANNEL && - isGroupChannelVisible(myPreferences, lastChannel); - - if ( - myMembers[lastChannelId] && - lastChannel && - (lastChannel.team_id === teamId || isDMVisible || isGMVisible) - ) { - dispatch(handleSelectChannel(lastChannelId)); - return; - } - - dispatch(selectDefaultChannel(teamId)); + dispatch(handleSelectChannel(channelId)); }; } diff --git a/app/actions/views/select_team.js b/app/actions/views/select_team.js index fc4019cb6..5d80d7ea2 100644 --- a/app/actions/views/select_team.js +++ b/app/actions/views/select_team.js @@ -3,14 +3,14 @@ import {batchActions} from 'redux-batched-actions'; +import {lastChannelIdForTeam} from '@actions/helpers/channels'; +import {NavigationTypes} from '@constants'; import {ChannelTypes, TeamTypes} from '@mm-redux/action_types'; import {getMyTeams} from '@mm-redux/actions/teams'; import {RequestStatus} from '@mm-redux/constants'; import {getConfig} from '@mm-redux/selectors/entities/general'; import EventEmitter from '@mm-redux/utils/event_emitter'; - -import {NavigationTypes} from 'app/constants'; -import {selectFirstAvailableTeam} from 'app/utils/teams'; +import {selectFirstAvailableTeam} from '@utils/teams'; export function handleTeamChange(teamId) { return async (dispatch, getState) => { @@ -20,10 +20,28 @@ export function handleTeamChange(teamId) { return; } - dispatch(batchActions([ - {type: TeamTypes.SELECT_TEAM, data: teamId}, - {type: ChannelTypes.SELECT_CHANNEL, data: '', extra: {}}, - ], 'BATCH_SWITCH_TEAM')); + const actions = [{type: TeamTypes.SELECT_TEAM, data: teamId}]; + const {channels, myMembers} = state.entities.channels; + const channelId = lastChannelIdForTeam(state, teamId); + + if (channelId) { + const channel = channels[channelId]; + const member = myMembers[channelId]; + + actions.push({ + type: ChannelTypes.SELECT_CHANNEL, + data: channelId, + extra: { + channel, + member, + teamId, + }, + }); + } else { + actions.push({type: ChannelTypes.SELECT_CHANNEL, data: '', extra: {}}); + } + + dispatch(batchActions(actions, 'BATCH_SWITCH_TEAM')); }; } diff --git a/app/mm-redux/types/store.ts b/app/mm-redux/types/store.ts index 542970cb4..e0822111f 100644 --- a/app/mm-redux/types/store.ts +++ b/app/mm-redux/types/store.ts @@ -64,6 +64,7 @@ export type GlobalState = { roles: RolesRequestsStatuses; jobs: JobsRequestsStatuses; }; + views: any; websocket: { connected: boolean; lastConnectAt: number;