PLT-74: Enable Up Arrow keyboard shortcut to edit your last message
Этот коммит содержится в:
@@ -16,6 +16,7 @@ const Utils = require('../utils/utils.jsx');
|
|||||||
|
|
||||||
const Constants = require('../utils/constants.jsx');
|
const Constants = require('../utils/constants.jsx');
|
||||||
const ActionTypes = Constants.ActionTypes;
|
const ActionTypes = Constants.ActionTypes;
|
||||||
|
const KeyCodes = Constants.KeyCodes;
|
||||||
|
|
||||||
export default class CreatePost extends React.Component {
|
export default class CreatePost extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -35,6 +36,7 @@ export default class CreatePost extends React.Component {
|
|||||||
this.removePreview = this.removePreview.bind(this);
|
this.removePreview = this.removePreview.bind(this);
|
||||||
this.onChange = this.onChange.bind(this);
|
this.onChange = this.onChange.bind(this);
|
||||||
this.getFileCount = this.getFileCount.bind(this);
|
this.getFileCount = this.getFileCount.bind(this);
|
||||||
|
this.handleArrowUp = this.handleArrowUp.bind(this);
|
||||||
|
|
||||||
PostStore.clearDraftUploads();
|
PostStore.clearDraftUploads();
|
||||||
|
|
||||||
@@ -172,7 +174,7 @@ export default class CreatePost extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
postMsgKeyPress(e) {
|
postMsgKeyPress(e) {
|
||||||
if (e.which === 13 && !e.shiftKey && !e.altKey) {
|
if (e.which === KeyCodes.ENTER && !e.shiftKey && !e.altKey) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
ReactDOM.findDOMNode(this.refs.textbox).blur();
|
ReactDOM.findDOMNode(this.refs.textbox).blur();
|
||||||
this.handleSubmit(e);
|
this.handleSubmit(e);
|
||||||
@@ -292,6 +294,24 @@ export default 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;
|
||||||
}
|
}
|
||||||
|
handleArrowUp(e) {
|
||||||
|
if (e.keyCode === KeyCodes.UP && this.state.messageText === '') {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const channelId = ChannelStore.getCurrentId();
|
||||||
|
const lastPost = PostStore.getCurrentUsersLatestPost(channelId);
|
||||||
|
var type = (lastPost.root_id && lastPost.root_id.length > 0) ? 'Comment' : 'Post';
|
||||||
|
|
||||||
|
AppDispatcher.handleViewAction({
|
||||||
|
type: ActionTypes.RECIEVED_EDIT_POST,
|
||||||
|
refoucsId: '#post_textbox',
|
||||||
|
title: type,
|
||||||
|
message: lastPost.message,
|
||||||
|
lastPostId: lastPost.id,
|
||||||
|
channelId: lastPost.channel_id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
render() {
|
render() {
|
||||||
let serverError = null;
|
let serverError = null;
|
||||||
if (this.state.serverError) {
|
if (this.state.serverError) {
|
||||||
@@ -336,6 +356,7 @@ export default class CreatePost extends React.Component {
|
|||||||
<Textbox
|
<Textbox
|
||||||
onUserInput={this.handleUserInput}
|
onUserInput={this.handleUserInput}
|
||||||
onKeyPress={this.postMsgKeyPress}
|
onKeyPress={this.postMsgKeyPress}
|
||||||
|
onKeyDown={this.handleArrowUp}
|
||||||
onHeightChange={this.resizePostHolder}
|
onHeightChange={this.resizePostHolder}
|
||||||
messageText={this.state.messageText}
|
messageText={this.state.messageText}
|
||||||
createMessage='Write a message...'
|
createMessage='Write a message...'
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ var Client = require('../utils/client.jsx');
|
|||||||
var AsyncClient = require('../utils/async_client.jsx');
|
var AsyncClient = require('../utils/async_client.jsx');
|
||||||
var Textbox = require('./textbox.jsx');
|
var Textbox = require('./textbox.jsx');
|
||||||
var BrowserStore = require('../stores/browser_store.jsx');
|
var BrowserStore = require('../stores/browser_store.jsx');
|
||||||
|
var PostStore = require('../stores/post_store.jsx');
|
||||||
|
|
||||||
export default class EditPostModal extends React.Component {
|
export default class EditPostModal extends React.Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -14,6 +15,7 @@ export default class EditPostModal extends React.Component {
|
|||||||
this.handleEditInput = this.handleEditInput.bind(this);
|
this.handleEditInput = this.handleEditInput.bind(this);
|
||||||
this.handleEditKeyPress = this.handleEditKeyPress.bind(this);
|
this.handleEditKeyPress = this.handleEditKeyPress.bind(this);
|
||||||
this.handleUserInput = this.handleUserInput.bind(this);
|
this.handleUserInput = this.handleUserInput.bind(this);
|
||||||
|
this.handleEditPostEvent = this.handleEditPostEvent.bind(this);
|
||||||
|
|
||||||
this.state = {editText: '', title: '', post_id: '', channel_id: '', comments: 0, refocusId: ''};
|
this.state = {editText: '', title: '', post_id: '', channel_id: '', comments: 0, refocusId: ''};
|
||||||
}
|
}
|
||||||
@@ -59,6 +61,18 @@ export default class EditPostModal extends React.Component {
|
|||||||
handleUserInput(e) {
|
handleUserInput(e) {
|
||||||
this.setState({editText: e.target.value});
|
this.setState({editText: e.target.value});
|
||||||
}
|
}
|
||||||
|
handleEditPostEvent(options) {
|
||||||
|
this.setState({
|
||||||
|
editText: options.message || '',
|
||||||
|
title: options.title || '',
|
||||||
|
post_id: options.postId || '',
|
||||||
|
channel_id: options.channelId || '',
|
||||||
|
comments: options.comments || 0,
|
||||||
|
refocusId: options.refocusId || ''
|
||||||
|
});
|
||||||
|
|
||||||
|
$(React.findDOMNode(this.refs.modal)).modal('show');
|
||||||
|
}
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
@@ -68,12 +82,20 @@ export default class EditPostModal extends React.Component {
|
|||||||
|
|
||||||
$(ReactDOM.findDOMNode(this.refs.modal)).on('show.bs.modal', function onShow(e) {
|
$(ReactDOM.findDOMNode(this.refs.modal)).on('show.bs.modal', function onShow(e) {
|
||||||
var button = e.relatedTarget;
|
var button = e.relatedTarget;
|
||||||
|
if (!button) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
self.setState({editText: $(button).attr('data-message'), title: $(button).attr('data-title'), channel_id: $(button).attr('data-channelid'), post_id: $(button).attr('data-postid'), comments: $(button).attr('data-comments'), refocusId: $(button).attr('data-refoucsid')});
|
self.setState({editText: $(button).attr('data-message'), title: $(button).attr('data-title'), channel_id: $(button).attr('data-channelid'), post_id: $(button).attr('data-postid'), comments: $(button).attr('data-comments'), refocusId: $(button).attr('data-refoucsid')});
|
||||||
});
|
});
|
||||||
|
|
||||||
$(ReactDOM.findDOMNode(this.refs.modal)).on('shown.bs.modal', function onShown() {
|
$(ReactDOM.findDOMNode(this.refs.modal)).on('shown.bs.modal', function onShown() {
|
||||||
self.refs.editbox.resize();
|
self.refs.editbox.resize();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
PostStore.addEditPostListener(this.handleEditPostEvent);
|
||||||
|
}
|
||||||
|
componentWillUnmount() {
|
||||||
|
PostStore.removeEditPostListener(this.handleEditPostEvent);
|
||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
var error = (<div className='form-group'><br /></div>);
|
var error = (<div className='form-group'><br /></div>);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ const ErrorStore = require('../stores/error_store.jsx');
|
|||||||
const Utils = require('../utils/utils.jsx');
|
const Utils = require('../utils/utils.jsx');
|
||||||
const Constants = require('../utils/constants.jsx');
|
const Constants = require('../utils/constants.jsx');
|
||||||
const ActionTypes = Constants.ActionTypes;
|
const ActionTypes = Constants.ActionTypes;
|
||||||
|
const KeyCodes = Constants.KeyCodes;
|
||||||
|
|
||||||
export default class Textbox extends React.Component {
|
export default class Textbox extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -148,8 +149,10 @@ export default class Textbox extends React.Component {
|
|||||||
this.doProcessMentions = true;
|
this.doProcessMentions = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.keyCode === 8) {
|
if (e.keyCode === KeyCodes.BACKSPACE) {
|
||||||
this.handleBackspace(e);
|
this.handleBackspace(e);
|
||||||
|
} else if (this.props.onKeyDown) {
|
||||||
|
this.props.onKeyDown(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,5 +321,6 @@ Textbox.propTypes = {
|
|||||||
onUserInput: React.PropTypes.func.isRequired,
|
onUserInput: React.PropTypes.func.isRequired,
|
||||||
onKeyPress: React.PropTypes.func.isRequired,
|
onKeyPress: React.PropTypes.func.isRequired,
|
||||||
onHeightChange: React.PropTypes.func,
|
onHeightChange: React.PropTypes.func,
|
||||||
createMessage: React.PropTypes.string.isRequired
|
createMessage: React.PropTypes.string.isRequired,
|
||||||
|
onKeyDown: React.PropTypes.func
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ var EventEmitter = require('events').EventEmitter;
|
|||||||
|
|
||||||
var ChannelStore = require('../stores/channel_store.jsx');
|
var ChannelStore = require('../stores/channel_store.jsx');
|
||||||
var BrowserStore = require('../stores/browser_store.jsx');
|
var BrowserStore = require('../stores/browser_store.jsx');
|
||||||
|
var UserStore = require('../stores/user_store.jsx');
|
||||||
|
|
||||||
var Constants = require('../utils/constants.jsx');
|
var Constants = require('../utils/constants.jsx');
|
||||||
var ActionTypes = Constants.ActionTypes;
|
var ActionTypes = Constants.ActionTypes;
|
||||||
@@ -16,6 +17,7 @@ var SEARCH_TERM_CHANGE_EVENT = 'search_term_change';
|
|||||||
var SELECTED_POST_CHANGE_EVENT = 'selected_post_change';
|
var SELECTED_POST_CHANGE_EVENT = 'selected_post_change';
|
||||||
var MENTION_DATA_CHANGE_EVENT = 'mention_data_change';
|
var MENTION_DATA_CHANGE_EVENT = 'mention_data_change';
|
||||||
var ADD_MENTION_EVENT = 'add_mention';
|
var ADD_MENTION_EVENT = 'add_mention';
|
||||||
|
var EDIT_POST_EVENT = 'edit_post';
|
||||||
|
|
||||||
class PostStoreClass extends EventEmitter {
|
class PostStoreClass extends EventEmitter {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -75,6 +77,10 @@ class PostStoreClass extends EventEmitter {
|
|||||||
this.clearCommentDraftUploads = this.clearCommentDraftUploads.bind(this);
|
this.clearCommentDraftUploads = this.clearCommentDraftUploads.bind(this);
|
||||||
this.storeLatestUpdate = this.storeLatestUpdate.bind(this);
|
this.storeLatestUpdate = this.storeLatestUpdate.bind(this);
|
||||||
this.getLatestUpdate = this.getLatestUpdate.bind(this);
|
this.getLatestUpdate = this.getLatestUpdate.bind(this);
|
||||||
|
this.emitEditPost = this.emitEditPost.bind(this);
|
||||||
|
this.addEditPostListener = this.addEditPostListener.bind(this);
|
||||||
|
this.removeEditPostListener = this.removeEditPostListener.bind(this);
|
||||||
|
this.getCurrentUsersLatestPost = this.getCurrentUsersLatestPost.bind(this);
|
||||||
}
|
}
|
||||||
emitChange() {
|
emitChange() {
|
||||||
this.emit(CHANGE_EVENT);
|
this.emit(CHANGE_EVENT);
|
||||||
@@ -148,6 +154,18 @@ class PostStoreClass extends EventEmitter {
|
|||||||
this.removeListener(ADD_MENTION_EVENT, callback);
|
this.removeListener(ADD_MENTION_EVENT, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emitEditPost(post) {
|
||||||
|
this.emit(EDIT_POST_EVENT, post);
|
||||||
|
}
|
||||||
|
|
||||||
|
addEditPostListener(callback) {
|
||||||
|
this.on(EDIT_POST_EVENT, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeEditPostListener(callback) {
|
||||||
|
this.removeListener(EDIT_POST_EVENT, callback);
|
||||||
|
}
|
||||||
|
|
||||||
getCurrentPosts() {
|
getCurrentPosts() {
|
||||||
var currentId = ChannelStore.getCurrentId();
|
var currentId = ChannelStore.getCurrentId();
|
||||||
|
|
||||||
@@ -212,6 +230,22 @@ class PostStoreClass extends EventEmitter {
|
|||||||
getPosts(channelId) {
|
getPosts(channelId) {
|
||||||
return BrowserStore.getItem('posts_' + channelId);
|
return BrowserStore.getItem('posts_' + channelId);
|
||||||
}
|
}
|
||||||
|
getCurrentUsersLatestPost(channelId) {
|
||||||
|
const userId = UserStore.getCurrentId();
|
||||||
|
var postList = makePostListNonNull(this.getPosts(channelId));
|
||||||
|
var i = 0;
|
||||||
|
var len = postList.order.length;
|
||||||
|
var lastPost = null;
|
||||||
|
|
||||||
|
for (i; i < len; i++) {
|
||||||
|
if (postList.posts[postList.order[i]].user_id === userId) {
|
||||||
|
lastPost = postList.posts[postList.order[i]];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastPost;
|
||||||
|
}
|
||||||
storePost(post) {
|
storePost(post) {
|
||||||
this.pStorePost(post);
|
this.pStorePost(post);
|
||||||
this.emitChange();
|
this.emitChange();
|
||||||
@@ -446,6 +480,9 @@ PostStore.dispatchToken = AppDispatcher.register(function registry(payload) {
|
|||||||
case ActionTypes.RECIEVED_ADD_MENTION:
|
case ActionTypes.RECIEVED_ADD_MENTION:
|
||||||
PostStore.emitAddMention(action.id, action.username);
|
PostStore.emitAddMention(action.id, action.username);
|
||||||
break;
|
break;
|
||||||
|
case ActionTypes.RECIEVED_EDIT_POST:
|
||||||
|
PostStore.emitEditPost(action);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ module.exports = {
|
|||||||
|
|
||||||
RECIEVED_POSTS: null,
|
RECIEVED_POSTS: null,
|
||||||
RECIEVED_POST: null,
|
RECIEVED_POST: null,
|
||||||
|
RECIEVED_EDIT_POST: null,
|
||||||
RECIEVED_SEARCH: null,
|
RECIEVED_SEARCH: null,
|
||||||
RECIEVED_POST_SELECTED: null,
|
RECIEVED_POST_SELECTED: null,
|
||||||
RECIEVED_MENTION_DATA: null,
|
RECIEVED_MENTION_DATA: null,
|
||||||
@@ -289,5 +290,14 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
Preferences: {
|
Preferences: {
|
||||||
CATEGORY_DIRECT_CHANNEL_SHOW: 'direct_channel_show'
|
CATEGORY_DIRECT_CHANNEL_SHOW: 'direct_channel_show'
|
||||||
|
},
|
||||||
|
KeyCodes: {
|
||||||
|
UP: 38,
|
||||||
|
DOWN: 40,
|
||||||
|
LEFT: 37,
|
||||||
|
RIGHT: 39,
|
||||||
|
BACKSPACE: 8,
|
||||||
|
ENTER: 13,
|
||||||
|
ESCAPE: 27
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user