Fix commenting on deleted post (#7095)
Этот коммит содержится в:
коммит произвёл
Christopher Speller
родитель
4d45214394
Коммит
dab299c9af
@@ -3,19 +3,19 @@
|
|||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import AppDispatcher from '../dispatcher/app_dispatcher.jsx';
|
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
|
||||||
import * as ChannelActions from 'actions/channel_actions.jsx';
|
import * as ChannelActions from 'actions/channel_actions.jsx';
|
||||||
import EmojiStore from 'stores/emoji_store.jsx';
|
import EmojiStore from 'stores/emoji_store.jsx';
|
||||||
import UserStore from 'stores/user_store.jsx';
|
import UserStore from 'stores/user_store.jsx';
|
||||||
import PostDeletedModal from './post_deleted_modal.jsx';
|
import PostDeletedModal from 'components/post_deleted_modal.jsx';
|
||||||
import PostStore from 'stores/post_store.jsx';
|
import PostStore from 'stores/post_store.jsx';
|
||||||
import PreferenceStore from 'stores/preference_store.jsx';
|
import PreferenceStore from 'stores/preference_store.jsx';
|
||||||
import TeamStore from 'stores/team_store.jsx';
|
import TeamStore from 'stores/team_store.jsx';
|
||||||
import MessageHistoryStore from 'stores/message_history_store.jsx';
|
import MessageHistoryStore from 'stores/message_history_store.jsx';
|
||||||
import Textbox from './textbox.jsx';
|
import Textbox from 'components/textbox.jsx';
|
||||||
import MsgTyping from './msg_typing.jsx';
|
import MsgTyping from 'components/msg_typing.jsx';
|
||||||
import FileUpload from './file_upload.jsx';
|
import FileUpload from 'components/file_upload.jsx';
|
||||||
import FilePreview from './file_preview.jsx';
|
import FilePreview from 'components/file_preview.jsx';
|
||||||
import EmojiPickerOverlay from 'components/emoji_picker/emoji_picker_overlay.jsx';
|
import EmojiPickerOverlay from 'components/emoji_picker/emoji_picker_overlay.jsx';
|
||||||
import * as EmojiPicker from 'components/emoji_picker/emoji_picker.jsx';
|
import * as EmojiPicker from 'components/emoji_picker/emoji_picker.jsx';
|
||||||
import * as Utils from 'utils/utils.jsx';
|
import * as Utils from 'utils/utils.jsx';
|
||||||
@@ -31,40 +31,24 @@ import {browserHistory} from 'react-router/es6';
|
|||||||
const ActionTypes = Constants.ActionTypes;
|
const ActionTypes = Constants.ActionTypes;
|
||||||
const KeyCodes = Constants.KeyCodes;
|
const KeyCodes = Constants.KeyCodes;
|
||||||
|
|
||||||
import {REACTION_PATTERN, EMOJI_PATTERN} from './create_post.jsx';
|
import {REACTION_PATTERN, EMOJI_PATTERN} from 'components/create_post.jsx';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
export default class CreateComment extends React.Component {
|
export default class CreateComment extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
channelId: PropTypes.string.isRequired,
|
||||||
|
rootId: PropTypes.string.isRequired,
|
||||||
|
latestPostId: PropTypes.string,
|
||||||
|
getSidebarBody: PropTypes.func,
|
||||||
|
createPostErrorId: PropTypes.string
|
||||||
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.lastTime = 0;
|
this.lastTime = 0;
|
||||||
|
|
||||||
this.handleSubmit = this.handleSubmit.bind(this);
|
|
||||||
this.handleSubmitPost = this.handleSubmitPost.bind(this);
|
|
||||||
this.handleSubmitReaction = this.handleSubmitReaction.bind(this);
|
|
||||||
this.commentMsgKeyPress = this.commentMsgKeyPress.bind(this);
|
|
||||||
this.handleChange = this.handleChange.bind(this);
|
|
||||||
this.handleKeyDown = this.handleKeyDown.bind(this);
|
|
||||||
this.handleBlur = this.handleBlur.bind(this);
|
|
||||||
this.handleFileUploadChange = this.handleFileUploadChange.bind(this);
|
|
||||||
this.handleUploadStart = this.handleUploadStart.bind(this);
|
|
||||||
this.handleFileUploadComplete = this.handleFileUploadComplete.bind(this);
|
|
||||||
this.handleUploadError = this.handleUploadError.bind(this);
|
|
||||||
this.removePreview = this.removePreview.bind(this);
|
|
||||||
this.getFileCount = this.getFileCount.bind(this);
|
|
||||||
this.getFileUploadTarget = this.getFileUploadTarget.bind(this);
|
|
||||||
this.getCreateCommentControls = this.getCreateCommentControls.bind(this);
|
|
||||||
this.onPreferenceChange = this.onPreferenceChange.bind(this);
|
|
||||||
this.focusTextbox = this.focusTextbox.bind(this);
|
|
||||||
this.showPostDeletedModal = this.showPostDeletedModal.bind(this);
|
|
||||||
this.hidePostDeletedModal = this.hidePostDeletedModal.bind(this);
|
|
||||||
this.handlePostError = this.handlePostError.bind(this);
|
|
||||||
this.handleEmojiClick = this.handleEmojiClick.bind(this);
|
|
||||||
this.toggleEmojiPicker = this.toggleEmojiPicker.bind(this);
|
|
||||||
this.hideEmojiPicker = this.hideEmojiPicker.bind(this);
|
|
||||||
|
|
||||||
PostStore.clearCommentDraftUploads();
|
PostStore.clearCommentDraftUploads();
|
||||||
MessageHistoryStore.resetHistoryIndex('comment');
|
MessageHistoryStore.resetHistoryIndex('comment');
|
||||||
|
|
||||||
@@ -84,15 +68,15 @@ export default class CreateComment extends React.Component {
|
|||||||
this.lastBlurAt = 0;
|
this.lastBlurAt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleEmojiPicker() {
|
toggleEmojiPicker = () => {
|
||||||
this.setState({showEmojiPicker: !this.state.showEmojiPicker});
|
this.setState({showEmojiPicker: !this.state.showEmojiPicker});
|
||||||
}
|
}
|
||||||
|
|
||||||
hideEmojiPicker() {
|
hideEmojiPicker = () => {
|
||||||
this.setState({showEmojiPicker: false});
|
this.setState({showEmojiPicker: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleEmojiClick(emoji) {
|
handleEmojiClick = (emoji) => {
|
||||||
const emojiAlias = emoji.name || emoji.aliases[0];
|
const emojiAlias = emoji.name || emoji.aliases[0];
|
||||||
|
|
||||||
if (!emojiAlias) {
|
if (!emojiAlias) {
|
||||||
@@ -125,7 +109,7 @@ export default class CreateComment extends React.Component {
|
|||||||
PreferenceStore.removeChangeListener(this.onPreferenceChange);
|
PreferenceStore.removeChangeListener(this.onPreferenceChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
onPreferenceChange() {
|
onPreferenceChange = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
ctrlSend: PreferenceStore.getBool(Constants.Preferences.CATEGORY_ADVANCED_SETTINGS, 'send_on_ctrl_enter')
|
ctrlSend: PreferenceStore.getBool(Constants.Preferences.CATEGORY_ADVANCED_SETTINGS, 'send_on_ctrl_enter')
|
||||||
});
|
});
|
||||||
@@ -141,11 +125,11 @@ export default class CreateComment extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePostError(postError) {
|
handlePostError = (postError) => {
|
||||||
this.setState({postError});
|
this.setState({postError});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubmit(e) {
|
handleSubmit = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (this.state.uploadsInProgress.length > 0 || this.state.submitting) {
|
if (this.state.uploadsInProgress.length > 0 || this.state.submitting) {
|
||||||
@@ -190,7 +174,7 @@ export default class CreateComment extends React.Component {
|
|||||||
this.focusTextbox(forceFocus);
|
this.focusTextbox(forceFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubmitCommand(message) {
|
handleSubmitCommand = (message) => {
|
||||||
PostStore.storeCommentDraft(this.props.rootId, null);
|
PostStore.storeCommentDraft(this.props.rootId, null);
|
||||||
this.setState({
|
this.setState({
|
||||||
message: '',
|
message: '',
|
||||||
@@ -230,7 +214,7 @@ export default class CreateComment extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubmitPost(message) {
|
handleSubmitPost = (message) => {
|
||||||
const userId = UserStore.getCurrentId();
|
const userId = UserStore.getCurrentId();
|
||||||
const time = Utils.getTimestamp();
|
const time = Utils.getTimestamp();
|
||||||
|
|
||||||
@@ -254,21 +238,7 @@ export default class CreateComment extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
PostActions.createPost(post, this.state.fileInfos, null,
|
PostActions.createPost(post, this.state.fileInfos);
|
||||||
(err) => {
|
|
||||||
if (err.id === 'api.post.create_post.root_id.app_error') {
|
|
||||||
this.showPostDeletedModal();
|
|
||||||
PostStore.removePendingPost(post.channel_id, post.pending_post_id);
|
|
||||||
this.setState({message: post.message});
|
|
||||||
} else {
|
|
||||||
this.forceUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
submitting: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
message: '',
|
message: '',
|
||||||
@@ -284,7 +254,7 @@ export default class CreateComment extends React.Component {
|
|||||||
this.focusTextbox(forceFocus);
|
this.focusTextbox(forceFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubmitReaction(isReaction) {
|
handleSubmitReaction = (isReaction) => {
|
||||||
const action = isReaction[1];
|
const action = isReaction[1];
|
||||||
|
|
||||||
const emojiName = isReaction[2];
|
const emojiName = isReaction[2];
|
||||||
@@ -299,7 +269,7 @@ export default class CreateComment extends React.Component {
|
|||||||
PostStore.storeCommentDraft(this.props.rootId, null);
|
PostStore.storeCommentDraft(this.props.rootId, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
commentMsgKeyPress(e) {
|
commentMsgKeyPress = (e) => {
|
||||||
if (!UserAgent.isMobile() && ((this.state.ctrlSend && e.ctrlKey) || !this.state.ctrlSend)) {
|
if (!UserAgent.isMobile() && ((this.state.ctrlSend && e.ctrlKey) || !this.state.ctrlSend)) {
|
||||||
if (e.which === KeyCodes.ENTER && !e.shiftKey && !e.altKey) {
|
if (e.which === KeyCodes.ENTER && !e.shiftKey && !e.altKey) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -311,7 +281,7 @@ export default class CreateComment extends React.Component {
|
|||||||
GlobalActions.emitLocalUserTypingEvent(this.props.channelId, this.props.rootId);
|
GlobalActions.emitLocalUserTypingEvent(this.props.channelId, this.props.rootId);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChange(e) {
|
handleChange = (e) => {
|
||||||
const message = e.target.value;
|
const message = e.target.value;
|
||||||
|
|
||||||
const draft = PostStore.getCommentDraft(this.props.rootId);
|
const draft = PostStore.getCommentDraft(this.props.rootId);
|
||||||
@@ -328,7 +298,7 @@ export default class CreateComment extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleKeyDown(e) {
|
handleKeyDown = (e) => {
|
||||||
if (this.state.ctrlSend && e.keyCode === KeyCodes.ENTER && e.ctrlKey === true) {
|
if (this.state.ctrlSend && e.keyCode === KeyCodes.ENTER && e.ctrlKey === true) {
|
||||||
this.commentMsgKeyPress(e);
|
this.commentMsgKeyPress(e);
|
||||||
return;
|
return;
|
||||||
@@ -365,11 +335,11 @@ export default class CreateComment extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleFileUploadChange() {
|
handleFileUploadChange = () => {
|
||||||
this.focusTextbox();
|
this.focusTextbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUploadStart(clientIds) {
|
handleUploadStart = (clientIds) => {
|
||||||
const draft = PostStore.getCommentDraft(this.props.rootId);
|
const draft = PostStore.getCommentDraft(this.props.rootId);
|
||||||
|
|
||||||
draft.uploadsInProgress = draft.uploadsInProgress.concat(clientIds);
|
draft.uploadsInProgress = draft.uploadsInProgress.concat(clientIds);
|
||||||
@@ -382,7 +352,7 @@ export default class CreateComment extends React.Component {
|
|||||||
this.focusTextbox();
|
this.focusTextbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleFileUploadComplete(fileInfos, clientIds) {
|
handleFileUploadComplete = (fileInfos, clientIds) => {
|
||||||
const draft = PostStore.getCommentDraft(this.props.rootId);
|
const draft = PostStore.getCommentDraft(this.props.rootId);
|
||||||
|
|
||||||
// remove each finished file from uploads
|
// remove each finished file from uploads
|
||||||
@@ -412,7 +382,7 @@ export default class CreateComment extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUploadError(err, clientId) {
|
handleUploadError = (err, clientId) => {
|
||||||
if (clientId === -1) {
|
if (clientId === -1) {
|
||||||
this.setState({serverError: err});
|
this.setState({serverError: err});
|
||||||
} else {
|
} else {
|
||||||
@@ -429,7 +399,7 @@ export default class CreateComment extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removePreview(id) {
|
removePreview = (id) => {
|
||||||
const fileInfos = this.state.fileInfos;
|
const fileInfos = this.state.fileInfos;
|
||||||
const uploadsInProgress = this.state.uploadsInProgress;
|
const uploadsInProgress = this.state.uploadsInProgress;
|
||||||
|
|
||||||
@@ -470,43 +440,47 @@ export default class CreateComment extends React.Component {
|
|||||||
enableAddButton
|
enableAddButton
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (newProps.createPostErrorId === 'api.post.create_post.root_id.app_error' && newProps.createPostErrorId !== this.props.createPostErrorId) {
|
||||||
|
this.showPostDeletedModal();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getFileCount() {
|
getFileCount = () => {
|
||||||
return this.state.fileInfos.length + this.state.uploadsInProgress.length;
|
return this.state.fileInfos.length + this.state.uploadsInProgress.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
getFileUploadTarget() {
|
getFileUploadTarget = () => {
|
||||||
return this.refs.textbox;
|
return this.refs.textbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCreateCommentControls() {
|
getCreateCommentControls = () => {
|
||||||
return this.refs.createCommentControls;
|
return this.refs.createCommentControls;
|
||||||
}
|
}
|
||||||
|
|
||||||
focusTextbox(keepFocus = false) {
|
focusTextbox = (keepFocus = false) => {
|
||||||
if (keepFocus || !Utils.isMobile()) {
|
if (keepFocus || !Utils.isMobile()) {
|
||||||
this.refs.textbox.focus();
|
this.refs.textbox.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showPostDeletedModal() {
|
showPostDeletedModal = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
showPostDeletedModal: true
|
showPostDeletedModal: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
hidePostDeletedModal() {
|
hidePostDeletedModal = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
showPostDeletedModal: false
|
showPostDeletedModal: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleBlur() {
|
handleBlur = () => {
|
||||||
this.lastBlurAt = Date.now();
|
this.lastBlurAt = Date.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleEnableAddButton(message, fileInfos) {
|
handleEnableAddButton = (message, fileInfos) => {
|
||||||
return message.trim().length !== 0 || fileInfos.length !== 0;
|
return message.trim().length !== 0 || fileInfos.length !== 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -656,10 +630,3 @@ export default class CreateComment extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateComment.propTypes = {
|
|
||||||
channelId: PropTypes.string.isRequired,
|
|
||||||
rootId: PropTypes.string.isRequired,
|
|
||||||
latestPostId: PropTypes.string,
|
|
||||||
getSidebarBody: PropTypes.func
|
|
||||||
};
|
|
||||||
16
webapp/components/create_comment/index.js
Обычный файл
16
webapp/components/create_comment/index.js
Обычный файл
@@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
|
||||||
|
import CreateComment from './create_comment.jsx';
|
||||||
|
|
||||||
|
function mapStateToProps(state, ownProps) {
|
||||||
|
const err = state.requests.posts.createPost.error || {};
|
||||||
|
return {
|
||||||
|
...ownProps,
|
||||||
|
createPostErrorId: err.server_error_id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps)(CreateComment);
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See License.txt for license information.
|
// See License.txt for license information.
|
||||||
|
|
||||||
import CreateComment from 'components/create_comment.jsx';
|
import CreateComment from 'components/create_comment';
|
||||||
import RhsHeaderPost from 'components/rhs_header_post.jsx';
|
import RhsHeaderPost from 'components/rhs_header_post.jsx';
|
||||||
import RootPost from 'components/rhs_root_post.jsx';
|
import RootPost from 'components/rhs_root_post.jsx';
|
||||||
import Comment from 'components/rhs_comment.jsx';
|
import Comment from 'components/rhs_comment.jsx';
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user