2019-08-06 15:03:44 +00:00
|
|
|
/*
|
|
|
|
Copyright 2019 New Vector Ltd
|
|
|
|
Copyright 2019 The Matrix.org Foundation C.I.C.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
import React from 'react';
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import dis from '../../../dispatcher';
|
|
|
|
import EditorModel from '../../../editor/model';
|
|
|
|
import {getCaretOffsetAndText} from '../../../editor/dom';
|
|
|
|
import {htmlSerializeIfNeeded, textSerialize} from '../../../editor/serialize';
|
|
|
|
import {PartCreator} from '../../../editor/parts';
|
|
|
|
import EditorStateTransfer from '../../../utils/EditorStateTransfer';
|
|
|
|
import {MatrixClient} from 'matrix-js-sdk';
|
|
|
|
import BasicMessageComposer from "./BasicMessageComposer";
|
2019-08-07 13:14:50 +00:00
|
|
|
import ReplyPreview from "./ReplyPreview";
|
2019-08-06 15:03:44 +00:00
|
|
|
|
|
|
|
function createMessageContent(model, editedEvent) {
|
|
|
|
const body = textSerialize(model);
|
|
|
|
const content = {
|
|
|
|
msgtype: "m.text",
|
|
|
|
body,
|
|
|
|
};
|
|
|
|
const formattedBody = htmlSerializeIfNeeded(model, {forceHTML: false});
|
|
|
|
if (formattedBody) {
|
|
|
|
content.format = "org.matrix.custom.html";
|
|
|
|
content.formatted_body = formattedBody;
|
|
|
|
}
|
|
|
|
return content;
|
|
|
|
}
|
|
|
|
|
|
|
|
export default class SendMessageComposer extends React.Component {
|
|
|
|
static propTypes = {
|
|
|
|
// the message event being edited
|
|
|
|
editState: PropTypes.instanceOf(EditorStateTransfer).isRequired,
|
|
|
|
};
|
|
|
|
|
|
|
|
static contextTypes = {
|
|
|
|
matrixClient: PropTypes.instanceOf(MatrixClient).isRequired,
|
|
|
|
};
|
|
|
|
|
|
|
|
constructor(props, context) {
|
|
|
|
super(props, context);
|
|
|
|
this.model = null;
|
|
|
|
this._editorRef = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
_setEditorRef = ref => {
|
|
|
|
this._editorRef = ref;
|
|
|
|
};
|
|
|
|
|
|
|
|
_onKeyDown = (event) => {
|
|
|
|
if (event.metaKey || event.altKey || event.shiftKey) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (event.key === "Enter") {
|
|
|
|
this._sendMessage();
|
|
|
|
event.preventDefault();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-06 15:22:26 +00:00
|
|
|
_sendMessage() {
|
2019-08-06 15:03:44 +00:00
|
|
|
const {roomId} = this.props.room;
|
|
|
|
this.context.matrixClient.sendMessage(roomId, createMessageContent(this.model));
|
|
|
|
this.model.reset([]);
|
|
|
|
dis.dispatch({action: 'focus_composer'});
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillUnmount() {
|
|
|
|
const sel = document.getSelection();
|
|
|
|
const {caret} = getCaretOffsetAndText(this._editorRef, sel);
|
|
|
|
const parts = this.model.serializeParts();
|
|
|
|
this.props.editState.setEditorState(caret, parts);
|
2019-08-07 13:14:16 +00:00
|
|
|
dis.unregister(this.dispatcherRef);
|
2019-08-06 15:03:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
componentWillMount() {
|
|
|
|
const partCreator = new PartCreator(this.props.room, this.context.matrixClient);
|
|
|
|
this.model = new EditorModel([], partCreator);
|
2019-08-07 13:14:16 +00:00
|
|
|
this.dispatcherRef = dis.register(this.onAction);
|
2019-08-06 15:03:44 +00:00
|
|
|
}
|
|
|
|
|
2019-08-07 13:14:16 +00:00
|
|
|
onAction = (payload) => {
|
|
|
|
switch (payload.action) {
|
2019-08-07 13:14:50 +00:00
|
|
|
case 'reply_to_event':
|
2019-08-07 13:14:16 +00:00
|
|
|
case 'focus_composer':
|
|
|
|
this._editorRef.focus();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-08-06 15:03:44 +00:00
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<div className="mx_SendMessageComposer" onClick={this.focusComposer} onKeyDown={this._onKeyDown}>
|
2019-08-07 13:14:50 +00:00
|
|
|
<div className="mx_SendMessageComposer_overlayWrapper">
|
|
|
|
<ReplyPreview permalinkCreator={this.props.permalinkCreator} />
|
|
|
|
</div>
|
2019-08-06 15:03:44 +00:00
|
|
|
<BasicMessageComposer
|
|
|
|
ref={this._setEditorRef}
|
|
|
|
model={this.model}
|
|
|
|
room={this.props.room}
|
2019-08-06 15:53:23 +00:00
|
|
|
label={this.props.placeholder}
|
2019-08-06 15:52:47 +00:00
|
|
|
placeholder={this.props.placeholder}
|
2019-08-06 15:03:44 +00:00
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|