UNPKG

mattermost-redux

Version:

Common code (API client, Redux stores, logic, utility functions) for building a Mattermost client

169 lines (168 loc) 6.54 kB
"use strict"; // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. Object.defineProperty(exports, "__esModule", { value: true }); exports.threadsReducer = void 0; const action_types_1 = require("mattermost-redux/action_types"); const counts_1 = require("./counts"); const threadsInTeam_1 = require("./threadsInTeam"); const threadsReducer = (state = {}, action, extra) => { switch (action.type) { case action_types_1.ThreadTypes.RECEIVED_UNREAD_THREADS: case action_types_1.ThreadTypes.RECEIVED_THREADS: { const { threads } = action.data; return { ...state, ...threads.reduce((results, thread) => { results[thread.id] = thread; return results; }, {}), }; } case action_types_1.PostTypes.POST_DELETED: case action_types_1.PostTypes.POST_REMOVED: { const post = action.data; if (post.root_id || !state[post.id]) { return state; } const nextState = { ...state }; Reflect.deleteProperty(nextState, post.id); return nextState; } case action_types_1.ThreadTypes.RECEIVED_THREAD: { const { thread } = action.data; return { ...state, [thread.id]: thread, }; } case action_types_1.ThreadTypes.READ_CHANGED_THREAD: { const { id, newUnreadMentions, newUnreadReplies, lastViewedAt, } = action.data; return { ...state, [id]: { ...(state[id] || {}), last_viewed_at: lastViewedAt, unread_mentions: newUnreadMentions, unread_replies: newUnreadReplies, is_following: true, }, }; } case action_types_1.ThreadTypes.FOLLOW_CHANGED_THREAD: { const { id, following } = action.data; if (!state[id]) { return state; } return { ...state, [id]: { ...state[id], is_following: following, }, }; } case action_types_1.PostTypes.RECEIVED_NEW_POST: { const post = action.data; const thread = state[post.root_id]; if (post.root_id && thread) { const participants = thread.participants || []; const nextThread = { ...thread }; if (!participants.find((user) => user.id === post.user_id)) { nextThread.participants = [...participants, { id: post.user_id }]; } if (post.reply_count) { nextThread.reply_count = post.reply_count; } return { ...state, [post.root_id]: nextThread, }; } return state; } case action_types_1.ThreadTypes.ALL_TEAM_THREADS_READ: { return Object.entries(state).reduce((newState, [id, thread]) => { newState[id] = { ...thread, unread_mentions: 0, unread_replies: 0, }; return newState; }, {}); } case action_types_1.UserTypes.LOGOUT_SUCCESS: return {}; case action_types_1.ChannelTypes.RECEIVED_CHANNEL_DELETED: case action_types_1.ChannelTypes.LEAVE_CHANNEL: { if (!extra.threadsToDelete || extra.threadsToDelete.length === 0) { return state; } let threadDeleted = false; // Remove entries for any thread in the channel const nextState = { ...state }; for (const thread of extra.threadsToDelete) { Reflect.deleteProperty(nextState, thread.id); threadDeleted = true; } if (!threadDeleted) { // Nothing was actually removed return state; } return nextState; } } return state; }; exports.threadsReducer = threadsReducer; function getThreadsOfChannel(threads, channelId) { const channelThreads = []; for (const rootId of Object.keys(threads)) { if (threads[rootId] && threads[rootId].post && threads[rootId].post.channel_id === channelId) { channelThreads.push(threads[rootId]); } } return channelThreads; } const initialState = { threads: {}, threadsInTeam: {}, unreadThreadsInTeam: {}, counts: {}, countsIncludingDirect: {}, }; // custom combineReducers function // enables passing data between reducers function reducer(state = initialState, action) { const extra = { threads: state.threads, }; // acting as a 'middleware' if (action.type === action_types_1.ChannelTypes.LEAVE_CHANNEL) { extra.threadsToDelete = getThreadsOfChannel(state.threads, action.data.id); } const nextState = { // Object mapping thread ids to thread objects threads: (0, exports.threadsReducer)(state.threads, action, extra), // Object mapping teams ids to thread ids threadsInTeam: (0, threadsInTeam_1.threadsInTeamReducer)(state.threadsInTeam, action, extra), // Object mapping teams ids to unread thread ids unreadThreadsInTeam: (0, threadsInTeam_1.unreadThreadsInTeamReducer)(state.unreadThreadsInTeam, action, extra), // Object mapping teams ids to unread counts without DM/GM counts: (0, counts_1.countsReducer)(state.counts, action, extra), // Object mapping teams ids to unread counts including direct channels countsIncludingDirect: (0, counts_1.countsIncludingDirectReducer)(state.countsIncludingDirect, action, extra), }; if (state.threads === nextState.threads && state.threadsInTeam === nextState.threadsInTeam && state.unreadThreadsInTeam === nextState.unreadThreadsInTeam && state.counts === nextState.counts && state.countsIncludingDirect === nextState.countsIncludingDirect) { // None of the children have changed so don't even let the parent object change return state; } return nextState; } exports.default = reducer;