mattermost-redux
Version:
Common code (API client, Redux stores, logic, utility functions) for building a Mattermost client
191 lines (190 loc) • 6.67 kB
JavaScript
"use strict";
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.files = files;
exports.filesFromSearch = filesFromSearch;
exports.fileIdsByPostId = fileIdsByPostId;
const redux_1 = require("redux");
const action_types_1 = require("mattermost-redux/action_types");
function files(state = {}, action) {
switch (action.type) {
case action_types_1.FileTypes.RECEIVED_UPLOAD_FILES:
case action_types_1.FileTypes.RECEIVED_FILES_FOR_POST: {
const filesById = action.data.reduce((filesMap, file) => {
return { ...filesMap,
[file.id]: file,
};
}, {});
return { ...state,
...filesById,
};
}
case action_types_1.PostTypes.RECEIVED_NEW_POST:
case action_types_1.PostTypes.RECEIVED_POST: {
const post = action.data;
return storeAllFilesForPost(storeFilesForPost, state, post);
}
case action_types_1.PostTypes.RECEIVED_POSTS: {
const posts = Object.values(action.data.posts);
return posts.reduce((nextState, post) => {
return storeAllFilesForPost(storeFilesForPost, nextState, post);
}, state);
}
case action_types_1.PostTypes.POST_DELETED:
case action_types_1.PostTypes.POST_REMOVED: {
if (action.data && action.data.file_ids && action.data.file_ids.length) {
const nextState = { ...state };
const fileIds = action.data.file_ids;
fileIds.forEach((id) => {
Reflect.deleteProperty(nextState, id);
});
return nextState;
}
return state;
}
case action_types_1.FileTypes.REMOVED_FILE: {
const nextState = { ...state };
const { fileIds } = action.data;
if (fileIds) {
fileIds.forEach((id) => {
Reflect.deleteProperty(nextState, id);
});
}
return nextState;
}
case action_types_1.ChannelBookmarkTypes.RECEIVED_BOOKMARKS: {
const bookmarks = action.data.bookmarks;
const nextState = { ...state };
bookmarks.forEach(({ file }) => {
if (file) {
nextState[file.id] = file;
}
});
return nextState;
}
case action_types_1.ChannelBookmarkTypes.RECEIVED_BOOKMARK: {
const { file } = action.data;
if (file) {
return { ...state, [file.id]: file };
}
return state;
}
case action_types_1.ChannelBookmarkTypes.BOOKMARK_DELETED: {
const { file } = action.data;
if (!file) {
return state;
}
const nextState = { ...state };
Reflect.deleteProperty(nextState, file.id);
return nextState;
}
case action_types_1.UserTypes.LOGOUT_SUCCESS:
return {};
default:
return state;
}
}
function filesFromSearch(state = {}, action) {
switch (action.type) {
case action_types_1.FileTypes.RECEIVED_FILES_FOR_SEARCH: {
return { ...state,
...action.data,
};
}
case action_types_1.UserTypes.LOGOUT_SUCCESS:
return {};
default:
return state;
}
}
function storeAllFilesForPost(storeFilesCallback, state, post) {
let currentState = state;
// Handle permalink embedded files
if (post.metadata && post.metadata.embeds) {
const embeds = post.metadata.embeds;
currentState = embeds.reduce((nextState, embed) => {
if (embed && embed.type === 'permalink' && embed.data && 'post' in embed.data && embed.data.post) {
return storeFilesCallback(nextState, embed.data.post);
}
return nextState;
}, currentState);
}
return storeFilesCallback(currentState, post);
}
function storeFilesForPost(state, post) {
if (!post.metadata || !post.metadata.files) {
return state;
}
return post.metadata.files.reduce((nextState, file) => {
if (nextState[file.id]) {
// File is already in the store
return nextState;
}
return {
...nextState,
[file.id]: file,
};
}, state);
}
function fileIdsByPostId(state = {}, action) {
switch (action.type) {
case action_types_1.FileTypes.RECEIVED_FILES_FOR_POST: {
const { data, postId } = action;
const filesIdsForPost = data.map((file) => file.id);
return { ...state,
[postId]: filesIdsForPost,
};
}
case action_types_1.PostTypes.RECEIVED_NEW_POST:
case action_types_1.PostTypes.RECEIVED_POST: {
const post = action.data;
return storeAllFilesForPost(storeFilesIdsForPost, state, post);
}
case action_types_1.PostTypes.RECEIVED_POSTS: {
const posts = Object.values(action.data.posts);
return posts.reduce((nextState, post) => {
return storeAllFilesForPost(storeFilesIdsForPost, nextState, post);
}, state);
}
case action_types_1.PostTypes.POST_DELETED:
case action_types_1.PostTypes.POST_REMOVED: {
if (action.data) {
const nextState = { ...state };
Reflect.deleteProperty(nextState, action.data.id);
return nextState;
}
return state;
}
case action_types_1.UserTypes.LOGOUT_SUCCESS:
return {};
default:
return state;
}
}
function storeFilesIdsForPost(state, post) {
if (!post.metadata || !post.metadata.files) {
return state;
}
return {
...state,
[post.id]: post.metadata.files ? post.metadata.files.map((file) => file.id) : [],
};
}
function filePublicLink(state = { link: '' }, action) {
switch (action.type) {
case action_types_1.FileTypes.RECEIVED_FILE_PUBLIC_LINK: {
return action.data;
}
case action_types_1.UserTypes.LOGOUT_SUCCESS:
return { link: '' };
default:
return state;
}
}
exports.default = (0, redux_1.combineReducers)({
files,
filesFromSearch,
fileIdsByPostId,
filePublicLink,
});