PLT-3101 Added message history (#3205)
* Added message history * Minor logical changes * Fixed indexes resetting * Fixed double messages * Fixed resetting main history when RHS opened
Этот коммит содержится в:
коммит произвёл
Harrison Healey
родитель
96e8fc165f
Коммит
2c42294bbc
@@ -11,6 +11,7 @@ import UserStore from 'stores/user_store.jsx';
|
|||||||
import PostDeletedModal from './post_deleted_modal.jsx';
|
import PostDeletedModal from './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 MessageHistoryStore from 'stores/message_history_store.jsx';
|
||||||
import Textbox from './textbox.jsx';
|
import Textbox from './textbox.jsx';
|
||||||
import MsgTyping from './msg_typing.jsx';
|
import MsgTyping from './msg_typing.jsx';
|
||||||
import FileUpload from './file_upload.jsx';
|
import FileUpload from './file_upload.jsx';
|
||||||
@@ -68,11 +69,11 @@ class CreateComment extends React.Component {
|
|||||||
this.hidePostDeletedModal = this.hidePostDeletedModal.bind(this);
|
this.hidePostDeletedModal = this.hidePostDeletedModal.bind(this);
|
||||||
|
|
||||||
PostStore.clearCommentDraftUploads();
|
PostStore.clearCommentDraftUploads();
|
||||||
|
MessageHistoryStore.resetHistoryIndex('comment');
|
||||||
|
|
||||||
const draft = PostStore.getCommentDraft(this.props.rootId);
|
const draft = PostStore.getCommentDraft(this.props.rootId);
|
||||||
this.state = {
|
this.state = {
|
||||||
messageText: draft.message,
|
messageText: draft.message,
|
||||||
lastMessage: '',
|
|
||||||
uploadsInProgress: draft.uploadsInProgress,
|
uploadsInProgress: draft.uploadsInProgress,
|
||||||
previews: draft.previews,
|
previews: draft.previews,
|
||||||
submitting: false,
|
submitting: false,
|
||||||
@@ -80,18 +81,22 @@ class CreateComment extends React.Component {
|
|||||||
showPostDeletedModal: false
|
showPostDeletedModal: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
PreferenceStore.addChangeListener(this.onPreferenceChange);
|
PreferenceStore.addChangeListener(this.onPreferenceChange);
|
||||||
this.focusTextbox();
|
this.focusTextbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
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')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps, prevState) {
|
componentDidUpdate(prevProps, prevState) {
|
||||||
if (prevState.uploadsInProgress < this.state.uploadsInProgress) {
|
if (prevState.uploadsInProgress < this.state.uploadsInProgress) {
|
||||||
$('.post-right__scroll').scrollTop($('.post-right__scroll')[0].scrollHeight);
|
$('.post-right__scroll').scrollTop($('.post-right__scroll')[0].scrollHeight);
|
||||||
@@ -101,6 +106,7 @@ class CreateComment extends React.Component {
|
|||||||
this.focusTextbox();
|
this.focusTextbox();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubmit(e) {
|
handleSubmit(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
@@ -125,6 +131,8 @@ class CreateComment extends React.Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageHistoryStore.storeMessageInHistory(this.state.messageText);
|
||||||
|
|
||||||
const userId = UserStore.getCurrentId();
|
const userId = UserStore.getCurrentId();
|
||||||
|
|
||||||
post.channel_id = this.props.channelId;
|
post.channel_id = this.props.channelId;
|
||||||
@@ -173,13 +181,13 @@ class CreateComment extends React.Component {
|
|||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
messageText: '',
|
messageText: '',
|
||||||
lastMessage: this.state.messageText,
|
|
||||||
submitting: false,
|
submitting: false,
|
||||||
postError: null,
|
postError: null,
|
||||||
previews: [],
|
previews: [],
|
||||||
serverError: null
|
serverError: null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
commentMsgKeyPress(e) {
|
commentMsgKeyPress(e) {
|
||||||
if (this.state.ctrlSend && e.ctrlKey || !this.state.ctrlSend) {
|
if (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) {
|
||||||
@@ -191,6 +199,7 @@ class CreateComment extends React.Component {
|
|||||||
|
|
||||||
GlobalActions.emitLocalUserTypingEvent(this.props.channelId, this.props.rootId);
|
GlobalActions.emitLocalUserTypingEvent(this.props.channelId, this.props.rootId);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUserInput(messageText) {
|
handleUserInput(messageText) {
|
||||||
const draft = PostStore.getCommentDraft(this.props.rootId);
|
const draft = PostStore.getCommentDraft(this.props.rootId);
|
||||||
draft.message = messageText;
|
draft.message = messageText;
|
||||||
@@ -199,6 +208,7 @@ class CreateComment extends React.Component {
|
|||||||
$('.post-right__scroll').parent().scrollTop($('.post-right__scroll')[0].scrollHeight);
|
$('.post-right__scroll').parent().scrollTop($('.post-right__scroll')[0].scrollHeight);
|
||||||
this.setState({messageText: messageText});
|
this.setState({messageText: messageText});
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
@@ -224,22 +234,21 @@ class CreateComment extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((e.ctrlKey || e.metaKey) && !e.altKey && !e.shiftKey && e.keyCode === KeyCodes.UP) {
|
if ((e.ctrlKey || e.metaKey) && !e.altKey && !e.shiftKey && (e.keyCode === Constants.KeyCodes.UP || e.keyCode === Constants.KeyCodes.DOWN)) {
|
||||||
const lastPost = PostStore.getCurrentUsersLatestPost(this.props.channelId, this.props.rootId);
|
const lastMessage = MessageHistoryStore.nextMessageInHistory(e.keyCode, this.state.messageText, 'comment');
|
||||||
if (!lastPost || this.state.messageText !== '') {
|
if (lastMessage !== null) {
|
||||||
return;
|
e.preventDefault();
|
||||||
|
this.setState({
|
||||||
|
messageText: lastMessage
|
||||||
|
});
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
|
||||||
let message = lastPost.message;
|
|
||||||
if (this.state.lastMessage !== '') {
|
|
||||||
message = this.state.lastMessage;
|
|
||||||
}
|
|
||||||
this.setState({messageText: message});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUploadClick() {
|
handleUploadClick() {
|
||||||
this.focusTextbox();
|
this.focusTextbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUploadStart(clientIds) {
|
handleUploadStart(clientIds) {
|
||||||
const draft = PostStore.getCommentDraft(this.props.rootId);
|
const draft = PostStore.getCommentDraft(this.props.rootId);
|
||||||
|
|
||||||
@@ -252,6 +261,7 @@ class CreateComment extends React.Component {
|
|||||||
// but this also resets the focus after a drag and drop
|
// but this also resets the focus after a drag and drop
|
||||||
this.focusTextbox();
|
this.focusTextbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleFileUploadComplete(filenames, clientIds) {
|
handleFileUploadComplete(filenames, clientIds) {
|
||||||
const draft = PostStore.getCommentDraft(this.props.rootId);
|
const draft = PostStore.getCommentDraft(this.props.rootId);
|
||||||
|
|
||||||
@@ -269,6 +279,7 @@ class CreateComment extends React.Component {
|
|||||||
|
|
||||||
this.setState({uploadsInProgress: draft.uploadsInProgress, previews: draft.previews});
|
this.setState({uploadsInProgress: draft.uploadsInProgress, previews: draft.previews});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUploadError(err, clientId) {
|
handleUploadError(err, clientId) {
|
||||||
if (clientId === -1) {
|
if (clientId === -1) {
|
||||||
this.setState({serverError: err});
|
this.setState({serverError: err});
|
||||||
@@ -285,6 +296,7 @@ class CreateComment extends React.Component {
|
|||||||
this.setState({uploadsInProgress: draft.uploadsInProgress, serverError: err});
|
this.setState({uploadsInProgress: draft.uploadsInProgress, serverError: err});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removePreview(id) {
|
removePreview(id) {
|
||||||
const previews = this.state.previews;
|
const previews = this.state.previews;
|
||||||
const uploadsInProgress = this.state.uploadsInProgress;
|
const uploadsInProgress = this.state.uploadsInProgress;
|
||||||
@@ -309,30 +321,36 @@ class CreateComment extends React.Component {
|
|||||||
|
|
||||||
this.setState({previews: previews, uploadsInProgress: uploadsInProgress});
|
this.setState({previews: previews, uploadsInProgress: uploadsInProgress});
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(newProps) {
|
componentWillReceiveProps(newProps) {
|
||||||
if (newProps.rootId !== this.props.rootId) {
|
if (newProps.rootId !== this.props.rootId) {
|
||||||
const draft = PostStore.getCommentDraft(newProps.rootId);
|
const draft = PostStore.getCommentDraft(newProps.rootId);
|
||||||
this.setState({messageText: draft.message, uploadsInProgress: draft.uploadsInProgress, previews: draft.previews});
|
this.setState({messageText: draft.message, uploadsInProgress: draft.uploadsInProgress, previews: draft.previews});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getFileCount() {
|
getFileCount() {
|
||||||
return this.state.previews.length + this.state.uploadsInProgress.length;
|
return this.state.previews.length + this.state.uploadsInProgress.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
focusTextbox() {
|
focusTextbox() {
|
||||||
if (!Utils.isMobile()) {
|
if (!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
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let serverError = null;
|
let serverError = null;
|
||||||
if (this.state.serverError) {
|
if (this.state.serverError) {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import * as ChannelActions from 'actions/channel_actions.jsx';
|
|||||||
|
|
||||||
import ChannelStore from 'stores/channel_store.jsx';
|
import ChannelStore from 'stores/channel_store.jsx';
|
||||||
import PostStore from 'stores/post_store.jsx';
|
import PostStore from 'stores/post_store.jsx';
|
||||||
|
import MessageHistoryStore from 'stores/message_history_store.jsx';
|
||||||
import UserStore from 'stores/user_store.jsx';
|
import UserStore from 'stores/user_store.jsx';
|
||||||
import PreferenceStore from 'stores/preference_store.jsx';
|
import PreferenceStore from 'stores/preference_store.jsx';
|
||||||
|
|
||||||
@@ -79,7 +80,6 @@ class CreatePost extends React.Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
channelId: ChannelStore.getCurrentId(),
|
channelId: ChannelStore.getCurrentId(),
|
||||||
messageText: draft.messageText,
|
messageText: draft.messageText,
|
||||||
lastMessage: '',
|
|
||||||
uploadsInProgress: draft.uploadsInProgress,
|
uploadsInProgress: draft.uploadsInProgress,
|
||||||
previews: draft.previews,
|
previews: draft.previews,
|
||||||
submitting: false,
|
submitting: false,
|
||||||
@@ -90,6 +90,7 @@ class CreatePost extends React.Component {
|
|||||||
showPostDeletedModal: false
|
showPostDeletedModal: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentDraft() {
|
getCurrentDraft() {
|
||||||
const draft = PostStore.getCurrentDraft();
|
const draft = PostStore.getCurrentDraft();
|
||||||
const safeDraft = {previews: [], messageText: '', uploadsInProgress: []};
|
const safeDraft = {previews: [], messageText: '', uploadsInProgress: []};
|
||||||
@@ -108,6 +109,7 @@ class CreatePost extends React.Component {
|
|||||||
|
|
||||||
return safeDraft;
|
return safeDraft;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubmit(e) {
|
handleSubmit(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
@@ -128,8 +130,10 @@ class CreatePost extends React.Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageHistoryStore.storeMessageInHistory(this.state.messageText);
|
||||||
|
|
||||||
this.setState({submitting: true, serverError: null});
|
this.setState({submitting: true, serverError: null});
|
||||||
this.setState({lastMessage: this.state.messageText});
|
|
||||||
if (post.message.indexOf('/') === 0) {
|
if (post.message.indexOf('/') === 0) {
|
||||||
ChannelActions.executeCommand(
|
ChannelActions.executeCommand(
|
||||||
this.state.channelId,
|
this.state.channelId,
|
||||||
@@ -158,6 +162,7 @@ class CreatePost extends React.Component {
|
|||||||
this.sendMessage(post);
|
this.sendMessage(post);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessage(post) {
|
sendMessage(post) {
|
||||||
post.channel_id = this.state.channelId;
|
post.channel_id = this.state.channelId;
|
||||||
post.filenames = this.state.previews;
|
post.filenames = this.state.previews;
|
||||||
@@ -193,11 +198,13 @@ class CreatePost extends React.Component {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
focusTextbox() {
|
focusTextbox() {
|
||||||
if (!Utils.isMobile()) {
|
if (!Utils.isMobile()) {
|
||||||
this.refs.textbox.focus();
|
this.refs.textbox.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
postMsgKeyPress(e) {
|
postMsgKeyPress(e) {
|
||||||
if (this.state.ctrlSend && e.ctrlKey || !this.state.ctrlSend) {
|
if (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) {
|
||||||
@@ -209,6 +216,7 @@ class CreatePost extends React.Component {
|
|||||||
|
|
||||||
GlobalActions.emitLocalUserTypingEvent(this.state.channelId, '');
|
GlobalActions.emitLocalUserTypingEvent(this.state.channelId, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUserInput(messageText) {
|
handleUserInput(messageText) {
|
||||||
this.setState({messageText});
|
this.setState({messageText});
|
||||||
|
|
||||||
@@ -216,9 +224,11 @@ class CreatePost extends React.Component {
|
|||||||
draft.message = messageText;
|
draft.message = messageText;
|
||||||
PostStore.storeCurrentDraft(draft);
|
PostStore.storeCurrentDraft(draft);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUploadClick() {
|
handleUploadClick() {
|
||||||
this.focusTextbox();
|
this.focusTextbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUploadStart(clientIds, channelId) {
|
handleUploadStart(clientIds, channelId) {
|
||||||
const draft = PostStore.getDraft(channelId);
|
const draft = PostStore.getDraft(channelId);
|
||||||
|
|
||||||
@@ -231,6 +241,7 @@ class CreatePost extends React.Component {
|
|||||||
// but this also resets the focus after a drag and drop
|
// but this also resets the focus after a drag and drop
|
||||||
this.focusTextbox();
|
this.focusTextbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleFileUploadComplete(filenames, clientIds, channelId) {
|
handleFileUploadComplete(filenames, clientIds, channelId) {
|
||||||
const draft = PostStore.getDraft(channelId);
|
const draft = PostStore.getDraft(channelId);
|
||||||
|
|
||||||
@@ -250,6 +261,7 @@ class CreatePost extends React.Component {
|
|||||||
this.setState({uploadsInProgress: draft.uploadsInProgress, previews: draft.previews});
|
this.setState({uploadsInProgress: draft.uploadsInProgress, previews: draft.previews});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUploadError(err, clientId, channelId) {
|
handleUploadError(err, clientId, channelId) {
|
||||||
let message = err;
|
let message = err;
|
||||||
if (message && typeof message !== 'string') {
|
if (message && typeof message !== 'string') {
|
||||||
@@ -274,6 +286,7 @@ class CreatePost extends React.Component {
|
|||||||
|
|
||||||
this.setState({serverError: message});
|
this.setState({serverError: message});
|
||||||
}
|
}
|
||||||
|
|
||||||
removePreview(id) {
|
removePreview(id) {
|
||||||
const previews = Object.assign([], this.state.previews);
|
const previews = Object.assign([], this.state.previews);
|
||||||
const uploadsInProgress = this.state.uploadsInProgress;
|
const uploadsInProgress = this.state.uploadsInProgress;
|
||||||
@@ -298,6 +311,7 @@ class CreatePost extends React.Component {
|
|||||||
|
|
||||||
this.setState({previews, uploadsInProgress});
|
this.setState({previews, uploadsInProgress});
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
const tutorialStep = PreferenceStore.getInt(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), 999);
|
const tutorialStep = PreferenceStore.getInt(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), 999);
|
||||||
|
|
||||||
@@ -308,6 +322,7 @@ class CreatePost extends React.Component {
|
|||||||
showTutorialTip: tutorialStep === TutorialSteps.POST_POPOVER
|
showTutorialTip: tutorialStep === TutorialSteps.POST_POPOVER
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
ChannelStore.addChangeListener(this.onChange);
|
ChannelStore.addChangeListener(this.onChange);
|
||||||
PreferenceStore.addChangeListener(this.onPreferenceChange);
|
PreferenceStore.addChangeListener(this.onPreferenceChange);
|
||||||
@@ -315,11 +330,13 @@ class CreatePost extends React.Component {
|
|||||||
this.focusTextbox();
|
this.focusTextbox();
|
||||||
document.addEventListener('keydown', this.showShortcuts);
|
document.addEventListener('keydown', this.showShortcuts);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps, prevState) {
|
componentDidUpdate(prevProps, prevState) {
|
||||||
if (prevState.channelId !== this.state.channelId) {
|
if (prevState.channelId !== this.state.channelId) {
|
||||||
this.focusTextbox();
|
this.focusTextbox();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
ChannelStore.removeChangeListener(this.onChange);
|
ChannelStore.removeChangeListener(this.onChange);
|
||||||
PreferenceStore.removeChangeListener(this.onPreferenceChange);
|
PreferenceStore.removeChangeListener(this.onPreferenceChange);
|
||||||
@@ -342,6 +359,7 @@ class CreatePost extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange() {
|
onChange() {
|
||||||
const channelId = ChannelStore.getCurrentId();
|
const channelId = ChannelStore.getCurrentId();
|
||||||
if (this.state.channelId !== channelId) {
|
if (this.state.channelId !== channelId) {
|
||||||
@@ -350,6 +368,7 @@ class CreatePost extends React.Component {
|
|||||||
this.setState({channelId, messageText: draft.messageText, initialText: draft.messageText, submitting: false, serverError: null, postError: null, previews: draft.previews, uploadsInProgress: draft.uploadsInProgress});
|
this.setState({channelId, messageText: draft.messageText, initialText: draft.messageText, submitting: false, serverError: null, postError: null, previews: draft.previews, uploadsInProgress: draft.uploadsInProgress});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onPreferenceChange() {
|
onPreferenceChange() {
|
||||||
const tutorialStep = PreferenceStore.getInt(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), 999);
|
const tutorialStep = PreferenceStore.getInt(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), 999);
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -358,6 +377,7 @@ class CreatePost extends React.Component {
|
|||||||
centerTextbox: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT) === Preferences.CHANNEL_DISPLAY_MODE_CENTERED
|
centerTextbox: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT) === Preferences.CHANNEL_DISPLAY_MODE_CENTERED
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getFileCount(channelId) {
|
getFileCount(channelId) {
|
||||||
if (channelId === this.state.channelId) {
|
if (channelId === this.state.channelId) {
|
||||||
return this.state.previews.length + this.state.uploadsInProgress.length;
|
return this.state.previews.length + this.state.uploadsInProgress.length;
|
||||||
@@ -366,6 +386,7 @@ class CreatePost extends React.Component {
|
|||||||
const draft = PostStore.getDraft(channelId);
|
const draft = PostStore.getDraft(channelId);
|
||||||
return draft.previews.length + draft.uploadsInProgress.length;
|
return draft.previews.length + draft.uploadsInProgress.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
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.postMsgKeyPress(e);
|
this.postMsgKeyPress(e);
|
||||||
@@ -394,30 +415,29 @@ class CreatePost extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((e.ctrlKey || e.metaKey) && !e.altKey && !e.shiftKey && e.keyCode === KeyCodes.UP) {
|
if ((e.ctrlKey || e.metaKey) && !e.altKey && !e.shiftKey && (e.keyCode === Constants.KeyCodes.UP || e.keyCode === Constants.KeyCodes.DOWN)) {
|
||||||
const channelId = ChannelStore.getCurrentId();
|
const lastMessage = MessageHistoryStore.nextMessageInHistory(e.keyCode, this.state.messageText, 'post');
|
||||||
const lastPost = PostStore.getCurrentUsersLatestPost(channelId);
|
if (lastMessage !== null) {
|
||||||
if (!lastPost || this.state.messageText !== '') {
|
e.preventDefault();
|
||||||
return;
|
this.setState({
|
||||||
|
messageText: lastMessage
|
||||||
|
});
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
|
||||||
let message = lastPost.message;
|
|
||||||
if (this.state.lastMessage !== '') {
|
|
||||||
message = this.state.lastMessage;
|
|
||||||
}
|
|
||||||
this.setState({messageText: message});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showPostDeletedModal() {
|
showPostDeletedModal() {
|
||||||
this.setState({
|
this.setState({
|
||||||
showPostDeletedModal: true
|
showPostDeletedModal: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
hidePostDeletedModal() {
|
hidePostDeletedModal() {
|
||||||
this.setState({
|
this.setState({
|
||||||
showPostDeletedModal: false
|
showPostDeletedModal: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
createTutorialTip() {
|
createTutorialTip() {
|
||||||
const screens = [];
|
const screens = [];
|
||||||
|
|
||||||
@@ -438,6 +458,7 @@ class CreatePost extends React.Component {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let serverError = null;
|
let serverError = null;
|
||||||
if (this.state.serverError) {
|
if (this.state.serverError) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import * as GlobalActions from 'actions/global_actions.jsx';
|
|||||||
import Textbox from './textbox.jsx';
|
import Textbox from './textbox.jsx';
|
||||||
import BrowserStore from 'stores/browser_store.jsx';
|
import BrowserStore from 'stores/browser_store.jsx';
|
||||||
import PostStore from 'stores/post_store.jsx';
|
import PostStore from 'stores/post_store.jsx';
|
||||||
|
import MessageHistoryStore from 'stores/message_history_store.jsx';
|
||||||
import PreferenceStore from 'stores/preference_store.jsx';
|
import PreferenceStore from 'stores/preference_store.jsx';
|
||||||
|
|
||||||
import Constants from 'utils/constants.jsx';
|
import Constants from 'utils/constants.jsx';
|
||||||
@@ -49,6 +50,8 @@ class EditPostModal extends React.Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageHistoryStore.storeMessageInHistory(updatedPost.message);
|
||||||
|
|
||||||
if (updatedPost.message.length === 0) {
|
if (updatedPost.message.length === 0) {
|
||||||
var tempState = this.state;
|
var tempState = this.state;
|
||||||
Reflect.deleteProperty(tempState, 'editText');
|
Reflect.deleteProperty(tempState, 'editText');
|
||||||
|
|||||||
79
webapp/stores/message_history_store.jsx
Обычный файл
79
webapp/stores/message_history_store.jsx
Обычный файл
@@ -0,0 +1,79 @@
|
|||||||
|
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
import Constants from 'utils/constants.jsx';
|
||||||
|
|
||||||
|
const TYPE_POST = 'post';
|
||||||
|
const TYPE_COMMENT = 'comment';
|
||||||
|
|
||||||
|
class MessageHistoryStoreClass {
|
||||||
|
constructor() {
|
||||||
|
this.messageHistory = [];
|
||||||
|
this.index = [];
|
||||||
|
this.index[TYPE_POST] = 0;
|
||||||
|
this.index[TYPE_COMMENT] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
getMessageInHistory(type) {
|
||||||
|
if (this.index[type] >= this.messageHistory.length) {
|
||||||
|
return '';
|
||||||
|
} else if (this.index[type] < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.messageHistory[this.index[type]];
|
||||||
|
}
|
||||||
|
|
||||||
|
getHistoryLength() {
|
||||||
|
if (this.messageHistory === null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return this.messageHistory.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
storeMessageInHistory(message) {
|
||||||
|
this.messageHistory.push(message);
|
||||||
|
this.resetAllHistoryIndex();
|
||||||
|
if (this.messageHistory.length > Constants.MAX_PREV_MSGS) {
|
||||||
|
this.messageHistory = this.messageHistory.slice(1, Constants.MAX_PREV_MSGS + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
storeMessageInHistoryByIndex(index, message) {
|
||||||
|
this.messageHistory[index] = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
resetAllHistoryIndex() {
|
||||||
|
this.index[TYPE_POST] = this.messageHistory.length;
|
||||||
|
this.index[TYPE_COMMENT] = this.messageHistory.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
resetHistoryIndex(type) {
|
||||||
|
this.index[type] = this.messageHistory.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextMessageInHistory(keyCode, messageText, type) {
|
||||||
|
if (messageText !== '' && messageText !== this.getMessageInHistory(type)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyCode === Constants.KeyCodes.UP) {
|
||||||
|
this.index[type]--;
|
||||||
|
} else if (keyCode === Constants.KeyCodes.DOWN) {
|
||||||
|
this.index[type]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.index[type] < 0) {
|
||||||
|
this.index[type] = 0;
|
||||||
|
return null;
|
||||||
|
} else if (this.index[type] >= this.getHistoryLength()) {
|
||||||
|
this.index[type] = this.getHistoryLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.getMessageInHistory(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var MessageHistoryStore = new MessageHistoryStoreClass();
|
||||||
|
|
||||||
|
export default MessageHistoryStore;
|
||||||
@@ -752,6 +752,7 @@ export default {
|
|||||||
MHPNS: 'https://push.mattermost.com',
|
MHPNS: 'https://push.mattermost.com',
|
||||||
MTPNS: 'http://push-test.mattermost.com',
|
MTPNS: 'http://push-test.mattermost.com',
|
||||||
BOT_NAME: 'BOT',
|
BOT_NAME: 'BOT',
|
||||||
|
MAX_PREV_MSGS: 100,
|
||||||
POST_COLLAPSE_TIMEOUT: 1000 * 60 * 5, // five minutes
|
POST_COLLAPSE_TIMEOUT: 1000 * 60 * 5, // five minutes
|
||||||
LICENSE_EXPIRY_NOTIFICATION: 1000 * 60 * 60 * 24 * 15, // 15 days
|
LICENSE_EXPIRY_NOTIFICATION: 1000 * 60 * 60 * 24 * 15, // 15 days
|
||||||
LICENSE_GRACE_PERIOD: 1000 * 60 * 60 * 24 * 15 // 15 days
|
LICENSE_GRACE_PERIOD: 1000 * 60 * 60 * 24 * 15 // 15 days
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
// See License.txt for license information.
|
// See License.txt for license information.
|
||||||
|
|
||||||
import Client from 'utils/web_client.jsx';
|
import Client from 'utils/web_client.jsx';
|
||||||
|
|
||||||
import Constants from 'utils/constants.jsx';
|
import Constants from 'utils/constants.jsx';
|
||||||
|
|
||||||
export function isSystemMessage(post) {
|
export function isSystemMessage(post) {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user