mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
243 lines
6.9 KiB
JavaScript
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;
|