Files
mattermost/webapp/stores/post_store.jsx
2017-06-30 14:01:42 -07:00

243 lines
6.9 KiB
JavaScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import AppDispatcher from '../dispatcher/app_dispatcher.jsx';
import EventEmitter from 'events';
import ChannelStore from 'stores/channel_store.jsx';
import BrowserStore from 'stores/browser_store.jsx';
import UserStore from 'stores/user_store.jsx';
import * as PostUtils from 'utils/post_utils.jsx';
import {Constants} from 'utils/constants.jsx';
const ActionTypes = Constants.ActionTypes;
const FOCUSED_POST_CHANGE = 'focused_post_change';
const EDIT_POST_EVENT = 'edit_post';
const POST_PINNED_CHANGE_EVENT = 'post_pinned_change';
import store from 'stores/redux_store.jsx';
const dispatch = store.dispatch;
const getState = store.getState;
import * as Selectors from 'mattermost-redux/selectors/entities/posts';
class PostStoreClass extends EventEmitter {
constructor() {
super();
this.selectedPostId = null;
this.currentFocusedPostId = null;
}
emitPostFocused() {
this.emit(FOCUSED_POST_CHANGE);
}
addPostFocusedListener(callback) {
this.on(FOCUSED_POST_CHANGE, callback);
}
removePostFocusedListener(callback) {
this.removeListener(FOCUSED_POST_CHANGE, callback);
}
emitEditPost(post) {
this.emit(EDIT_POST_EVENT, post);
}
addEditPostListener(callback) {
this.on(EDIT_POST_EVENT, callback);
}
removeEditPostListner(callback) {
this.removeListener(EDIT_POST_EVENT, callback);
}
emitPostPinnedChange() {
this.emit(POST_PINNED_CHANGE_EVENT);
}
addPostPinnedChangeListener(callback) {
this.on(POST_PINNED_CHANGE_EVENT, callback);
}
removePostPinnedChangeListener(callback) {
this.removeListener(POST_PINNED_CHANGE_EVENT, callback);
}
getLatestPostId(channelId) {
const postsInChannel = getState().entities.posts.postsInChannel[channelId] || [];
return postsInChannel[0];
}
getLatestReplyablePost(channelId) {
const postIds = getState().entities.posts.postsInChannel[channelId] || [];
const posts = getState().entities.posts.posts;
for (const postId of postIds) {
const post = posts[postId] || {};
if (post.state !== Constants.POST_DELETED && !PostUtils.isSystemMessage(post)) {
return post;
}
}
return null;
}
getVisiblePosts() {
const posts = Selectors.getPostsInCurrentChannel(getState());
const currentChannelId = getState().entities.channels.currentChannelId;
return posts.slice(0, getState().views.channel.postVisibility[currentChannelId]);
}
getFocusedPostId() {
return this.currentFocusedPostId;
}
storeFocusedPostId(postId) {
this.currentFocusedPostId = postId;
}
clearFocusedPost() {
this.currentFocusedPostId = null;
}
getCurrentUsersLatestPost(channelId, rootId) {
const userId = UserStore.getCurrentId();
const postIds = getState().entities.posts.postsInChannel[channelId] || [];
let lastPost = null;
for (const id of postIds) {
const post = Selectors.getPost(getState(), id) || {};
// don't edit webhook posts, deleted posts, or system messages
if (post.user_id !== userId ||
(post.props && post.props.from_webhook) ||
post.state === Constants.POST_DELETED ||
(post.type && post.type.startsWith(Constants.SYSTEM_MESSAGE_PREFIX))) {
continue;
}
if (rootId) {
if (post.root_id === rootId || post.id === rootId) {
lastPost = post;
break;
}
} else {
lastPost = post;
break;
}
}
return lastPost;
}
normalizeDraft(originalDraft) {
let draft = {
message: '',
uploadsInProgress: [],
fileInfos: []
};
// Make sure that the post draft is non-null and has all the required fields
if (originalDraft) {
draft = {
message: originalDraft.message || draft.message,
uploadsInProgress: originalDraft.uploadsInProgress || draft.uploadsInProgress,
fileInfos: originalDraft.fileInfos || draft.fileInfos
};
}
return draft;
}
storeCurrentDraft(draft) {
var channelId = ChannelStore.getCurrentId();
BrowserStore.setGlobalItem('draft_' + channelId, draft);
}
getCurrentDraft() {
var channelId = ChannelStore.getCurrentId();
return this.getDraft(channelId);
}
storeDraft(channelId, draft) {
BrowserStore.setGlobalItem('draft_' + channelId, draft);
}
getDraft(channelId) {
return this.normalizeDraft(BrowserStore.getGlobalItem('draft_' + channelId));
}
storeCommentDraft(parentPostId, draft) {
BrowserStore.setGlobalItem('comment_draft_' + parentPostId, draft);
}
getCommentDraft(parentPostId) {
return this.normalizeDraft(BrowserStore.getGlobalItem('comment_draft_' + parentPostId));
}
clearDraftUploads() {
BrowserStore.actionOnGlobalItemsWithPrefix('draft_', (key, value) => {
if (value) {
value.uploadsInProgress = [];
BrowserStore.setGlobalItem(key, value);
}
});
}
clearCommentDraftUploads() {
BrowserStore.actionOnGlobalItemsWithPrefix('comment_draft_', (key, value) => {
if (value) {
value.uploadsInProgress = [];
BrowserStore.setGlobalItem(key, value);
}
});
}
getCommentCount(rootPost) {
const postIds = getState().entities.posts.postsInChannel[rootPost.channel_id] || [];
let commentCount = 0;
for (const postId of postIds) {
const post = Selectors.getPost(getState(), postId) || {};
if (post.root_id === rootPost.id) {
commentCount += 1;
}
}
return commentCount;
}
}
var PostStore = new PostStoreClass();
PostStore.dispatchToken = AppDispatcher.register((payload) => {
var action = payload.action;
switch (action.type) {
case ActionTypes.RECEIVED_FOCUSED_POST:
PostStore.storeFocusedPostId(action.postId);
PostStore.emitPostFocused();
break;
case ActionTypes.CLICK_CHANNEL:
PostStore.clearFocusedPost();
break;
case ActionTypes.RECEIVED_EDIT_POST:
PostStore.emitEditPost(action);
break;
case ActionTypes.RECEIVED_POST_SELECTED:
dispatch({...action, type: ActionTypes.SELECT_POST});
break;
case ActionTypes.RECEIVED_POST_PINNED:
case ActionTypes.RECEIVED_POST_UNPINNED:
PostStore.emitPostPinnedChange();
break;
default:
}
});
export default PostStore;