get /commands working again

pull/21833/head
Aviral Dasgupta 2016-06-12 00:11:27 +05:30
parent b960d220d2
commit c0d7629980
1 changed files with 53 additions and 89 deletions

View File

@ -46,6 +46,7 @@ import * as RichText from '../../../RichText';
const TYPING_USER_TIMEOUT = 10000, TYPING_SERVER_TIMEOUT = 30000; const TYPING_USER_TIMEOUT = 10000, TYPING_SERVER_TIMEOUT = 30000;
// FIXME Breaks markdown with multiple paragraphs, since it only strips first and last <p>
function mdownToHtml(mdown) { function mdownToHtml(mdown) {
var html = marked(mdown) || ""; var html = marked(mdown) || "";
html = html.trim(); html = html.trim();
@ -67,14 +68,19 @@ export default class MessageComposerInput extends React.Component {
super(props, context); super(props, context);
this.onAction = this.onAction.bind(this); this.onAction = this.onAction.bind(this);
this.onInputClick = this.onInputClick.bind(this); this.onInputClick = this.onInputClick.bind(this);
this.handleReturn = this.handleReturn.bind(this);
this.handleKeyCommand = this.handleKeyCommand.bind(this);
this.onChange = this.onChange.bind(this);
this.state = { this.state = {
isRichtextEnabled: false, isRichtextEnabled: false, // TODO enable by default when RTE is mature enough
editorState: null editorState: null
}; };
// bit of a hack, but we need to do this here since createEditorState needs isRichtextEnabled // bit of a hack, but we need to do this here since createEditorState needs isRichtextEnabled
this.state.editorState = this.createEditorState(); this.state.editorState = this.createEditorState();
this.client = MatrixClientPeg.get();
} }
static getKeyBinding(e: SyntheticKeyboardEvent): string { static getKeyBinding(e: SyntheticKeyboardEvent): string {
@ -97,7 +103,7 @@ export default class MessageComposerInput extends React.Component {
if(this.state.isRichtextEnabled) { if(this.state.isRichtextEnabled) {
args.push(RichText.getScopedDecorator(this.props)); args.push(RichText.getScopedDecorator(this.props));
} }
return func.apply(null, args); return func(...args);
} }
componentWillMount() { componentWillMount() {
@ -254,86 +260,6 @@ export default class MessageComposerInput extends React.Component {
} }
} }
onEnter(ev) {
var contentText = this.refs.textarea.value;
// bodge for now to set markdown state on/off. We probably want a separate
// area for "local" commands which don't hit out to the server.
// if (contentText.indexOf("/markdown") === 0) {
// ev.preventDefault();
// this.refs.textarea.value = '';
// if (contentText.indexOf("/markdown on") === 0) {
// this.markdownEnabled = true;
// }
// else if (contentText.indexOf("/markdown off") === 0) {
// this.markdownEnabled = false;
// }
// else {
// const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
// Modal.createDialog(ErrorDialog, {
// title: "Unknown command",
// description: "Usage: /markdown on|off"
// });
// }
// return;
// }
var cmd = SlashCommands.processInput(this.props.room.roomId, contentText);
if (cmd) {
ev.preventDefault();
if (!cmd.error) {
this.refs.textarea.value = '';
}
if (cmd.promise) {
cmd.promise.done(function() {
console.log("Command success.");
}, function(err) {
console.error("Command failure: %s", err);
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Server error",
description: err.message
});
});
}
else if (cmd.error) {
console.error(cmd.error);
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Command error",
description: cmd.error
});
}
return;
}
var isEmote = /^\/me( |$)/i.test(contentText);
var sendMessagePromise;
if (isEmote) {
contentText = contentText.substring(4);
}
else if (contentText[0] === '/') {
contentText = contentText.substring(1);
}
var htmlText;
if (this.markdownEnabled && (htmlText = mdownToHtml(contentText)) !== contentText) {
sendMessagePromise = isEmote ?
MatrixClientPeg.get().sendHtmlEmote(this.props.room.roomId, contentText, htmlText) :
MatrixClientPeg.get().sendHtmlMessage(this.props.room.roomId, contentText, htmlText);
}
else {
sendMessagePromise = isEmote ?
MatrixClientPeg.get().sendEmoteMessage(this.props.room.roomId, contentText) :
MatrixClientPeg.get().sendTextMessage(this.props.room.roomId, contentText);
}
this.refs.textarea.value = '';
ev.preventDefault();
}
onTypingActivity() { onTypingActivity() {
this.isTyping = true; this.isTyping = true;
if (!this.userTypingTimer) { if (!this.userTypingTimer) {
@ -460,8 +386,6 @@ export default class MessageComposerInput extends React.Component {
'insert-characters' 'insert-characters'
); );
} }
console.log(modifyFn);
console.log(newState);
} }
if(newState == null) if(newState == null)
@ -484,14 +408,53 @@ export default class MessageComposerInput extends React.Component {
let contentText = contentState.getPlainText(), contentHTML; let contentText = contentState.getPlainText(), contentHTML;
var cmd = SlashCommands.processInput(this.props.room.roomId, contentText);
if (cmd) {
if (!cmd.error) {
this.setState({
editorState: this.createEditorState()
});
}
if (cmd.promise) {
cmd.promise.done(function() {
console.log("Command success.");
}, function(err) {
console.error("Command failure: %s", err);
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Server error",
description: err.message
});
});
}
else if (cmd.error) {
console.error(cmd.error);
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Command error",
description: cmd.error
});
}
return true;
}
if(this.state.isRichtextEnabled) { if(this.state.isRichtextEnabled) {
contentHTML = RichText.contentStateToHTML(contentState); contentHTML = RichText.contentStateToHTML(contentState);
} else { } else {
contentHTML = mdownToHtml(contentText); contentHTML = mdownToHtml(contentText);
} }
let sendFn = this.client.sendHtmlMessage;
if (contentText.startsWith('/me')) {
contentText = contentText.replace('/me', '');
// bit of a hack, but the alternative would be quite complicated
contentHTML = contentHTML.replace('/me', '');
sendFn = this.client.sendHtmlEmote;
}
this.sentHistory.push(contentHTML); this.sentHistory.push(contentHTML);
let sendMessagePromise = MatrixClientPeg.get().sendHtmlMessage(this.props.room.roomId, contentText, contentHTML); let sendMessagePromise = sendFn.call(this.client, this.props.room.roomId, contentText, contentHTML);
sendMessagePromise.done(() => { sendMessagePromise.done(() => {
dis.dispatch({ dis.dispatch({
@ -517,17 +480,18 @@ export default class MessageComposerInput extends React.Component {
className += " mx_MessageComposer_input_rte"; // placeholder indicator for RTE mode className += " mx_MessageComposer_input_rte"; // placeholder indicator for RTE mode
} }
return ( return (
<div className={className} <div className={className}
onClick={ this.onInputClick }> onClick={ this.onInputClick }>
<Editor ref="editor" <Editor ref="editor"
placeholder="Type a message…" placeholder="Type a message…"
editorState={this.state.editorState} editorState={this.state.editorState}
onChange={(state) => this.onChange(state)} onChange={this.onChange}
keyBindingFn={MessageComposerInput.getKeyBinding} keyBindingFn={MessageComposerInput.getKeyBinding}
handleKeyCommand={(command) => this.handleKeyCommand(command)} handleKeyCommand={this.handleKeyCommand}
handleReturn={ev => this.handleReturn(ev)} /> handleReturn={this.handleReturn}
stripPastedStyles={!this.state.isRichtextEnabled}
spellCheck={true} />
</div> </div>
); );
} }