mattermost-redux
Version:
Common code (API client, Redux stores, logic, utility functions) for building a Mattermost client
147 lines (146 loc) • 6.36 kB
JavaScript
;
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.byId = byId;
exports.orderByTeam = orderByTeam;
const redux_1 = require("redux");
const action_types_1 = require("mattermost-redux/action_types");
const array_utils_1 = require("mattermost-redux/utils/array_utils");
function byId(state = {}, action) {
switch (action.type) {
case action_types_1.ChannelCategoryTypes.RECEIVED_CATEGORIES: {
const categories = action.data;
return categories.reduce((nextState, category) => {
return {
...nextState,
[category.id]: {
...nextState[category.id],
...category,
collapsed: action.isWebSocket ? state[category.id].collapsed : category.collapsed,
},
};
}, state);
}
case action_types_1.ChannelCategoryTypes.RECEIVED_CATEGORY: {
const category = action.data;
return {
...state,
[category.id]: {
...state[category.id],
...category,
},
};
}
case action_types_1.ChannelCategoryTypes.CATEGORY_DELETED: {
const categoryId = action.data;
const nextState = { ...state };
Reflect.deleteProperty(nextState, categoryId);
return nextState;
}
case action_types_1.ChannelTypes.LEAVE_CHANNEL: {
const channelId = action.data.id;
const nextState = { ...state };
let changed = false;
for (const category of Object.values(state)) {
const index = category.channel_ids.indexOf(channelId);
if (index === -1) {
continue;
}
const nextChannelIds = [...category.channel_ids];
nextChannelIds.splice(index, 1);
nextState[category.id] = {
...category,
channel_ids: nextChannelIds,
};
changed = true;
}
return changed ? nextState : state;
}
case action_types_1.TeamTypes.LEAVE_TEAM: {
const team = action.data;
const nextState = { ...state };
let changed = false;
for (const category of Object.values(state)) {
if (category.team_id !== team.id) {
continue;
}
Reflect.deleteProperty(nextState, category.id);
changed = true;
}
return changed ? nextState : state;
}
case action_types_1.ChannelTypes.GM_CONVERTED_TO_CHANNEL: {
// For GM to Private channel conversion feature
// In the case when someone converts your GM to a private channel and moves it to a team
// you're not currently on, we need to remove the channel from "direct messages" category
// and add it to "channels" category of target team. Even though the server sends a websocket event about updated category data,
// it does so only for the team the channel got moved into, and not every team a user is part of, for performance reasons.
// For every other team, we update the state here. Everything is correct on server side, but we update state here
// to avoid re-fetching all categories again for all teams.
const receivedChannel = action.data;
const newState = {};
const categoryIDs = Object.keys(state);
categoryIDs.forEach((categoryID) => {
if (categoryID.startsWith('channels_') && state[categoryID].team_id === receivedChannel.team_id && state[categoryID].channel_ids.indexOf(receivedChannel.id) < 0) {
// We don't need to worry about adding the channel in the right order as this is only
// an intermediate step, meant to handle the edge case of missing the upcoming "update category"
// websocket message, triggered on conversion of GM to private channel.
newState[categoryID] = {
...state[categoryID],
channel_ids: [...state[categoryID].channel_ids, receivedChannel.id],
};
}
else {
newState[categoryID] = {
...state[categoryID],
channel_ids: state[categoryID].channel_ids.filter((channelID) => channelID !== receivedChannel.id),
};
}
});
return newState;
}
case action_types_1.UserTypes.LOGOUT_SUCCESS:
return {};
default:
return state;
}
}
function orderByTeam(state = {}, action) {
switch (action.type) {
case action_types_1.ChannelCategoryTypes.RECEIVED_CATEGORY_ORDER: {
const teamId = action.data.teamId;
const order = action.data.order;
return {
...state,
[teamId]: order,
};
}
case action_types_1.ChannelCategoryTypes.CATEGORY_DELETED: {
const categoryId = action.data;
const nextState = { ...state };
for (const teamId of Object.keys(nextState)) {
// removeItem only modifies the array if it contains the category ID, so other teams' state won't be modified
nextState[teamId] = (0, array_utils_1.removeItem)(state[teamId], categoryId);
}
return nextState;
}
case action_types_1.TeamTypes.LEAVE_TEAM: {
const team = action.data;
if (!state[team.id]) {
return state;
}
const nextState = { ...state };
Reflect.deleteProperty(nextState, team.id);
return nextState;
}
case action_types_1.UserTypes.LOGOUT_SUCCESS:
return {};
default:
return state;
}
}
exports.default = (0, redux_1.combineReducers)({
byId,
orderByTeam,
});