editing once works, editing twice does not
This commit is contained in:
@@ -97,6 +97,8 @@ export const MESSAGE_PREVIEW_LENGTH = 80;
|
||||
export const QUOTED_REPLY_LENGTH = 30;
|
||||
// Length of a preview of a forwarded message.
|
||||
export const FORWARDED_PREVIEW_LENGTH = 84;
|
||||
// Length of preview for a message being edited.
|
||||
export const EDIT_PREVIEW_LENGTH = 60;
|
||||
|
||||
// Minimum duration of an audio recording in milliseconds (2 sec).
|
||||
export const MIN_DURATION = 2_000;
|
||||
|
||||
@@ -1451,5 +1451,26 @@
|
||||
"description": "Message explaining that the credential was successfully validated.",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"menu_item_edit": {
|
||||
"translation": "Bearbeiten",
|
||||
"defaultMessage": "Edit",
|
||||
"description": "Edit message",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"editing_message": {
|
||||
"translation": "Bearbeitung",
|
||||
"defaultMessage": "Editing",
|
||||
"description": "Title over message editing preview",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"message_edited_marker": {
|
||||
"translation": ", bearbeitet",
|
||||
"defaultMessage": ", edited",
|
||||
"description": "Marker indicating that the message was edited",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1451,5 +1451,26 @@
|
||||
"description": "Message explaining that the credential was successfully validated.",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"menu_item_edit": {
|
||||
"translation": "Edit",
|
||||
"defaultMessage": "Edit",
|
||||
"description": "Edit message",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"editing_message": {
|
||||
"translation": "Editing",
|
||||
"defaultMessage": "Editing",
|
||||
"description": "Title over message editing preview",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"message_edited_marker": {
|
||||
"translation": ", edited",
|
||||
"defaultMessage": ", edited",
|
||||
"description": "Marker indicating that the message was edited",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1451,5 +1451,26 @@
|
||||
"description": "Message explaining that the credential was successfully validated.",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"menu_item_edit": {
|
||||
"translation": "Editar",
|
||||
"defaultMessage": "Edit",
|
||||
"description": "Edit message",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"editing_message": {
|
||||
"translation": "Edición",
|
||||
"defaultMessage": "Editing",
|
||||
"description": "Title over message editing preview",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"message_edited_marker": {
|
||||
"translation": ", editado",
|
||||
"defaultMessage": ", edited",
|
||||
"description": "Marker indicating that the message was edited",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,6 +243,10 @@
|
||||
"defaultMessage": "Unsupported",
|
||||
"description": "Unsupported entity in drafty"
|
||||
},
|
||||
"editing_message": {
|
||||
"defaultMessage": "Editing",
|
||||
"description": "Title over message editing preview"
|
||||
},
|
||||
"email_dative": {
|
||||
"defaultMessage": "email",
|
||||
"description": "Dative case of 'email', i.e. 'email' in 'by email'"
|
||||
@@ -480,6 +484,10 @@
|
||||
"defaultMessage": "Delete",
|
||||
"description": "Delete entire topic"
|
||||
},
|
||||
"menu_item_edit": {
|
||||
"defaultMessage": "Edit",
|
||||
"description": "Edit message"
|
||||
},
|
||||
"menu_item_edit_permissions": {
|
||||
"defaultMessage": "Edit permissions",
|
||||
"description": "Menu item [Edit permissions]"
|
||||
@@ -524,6 +532,10 @@
|
||||
"defaultMessage": "Video call",
|
||||
"description": "Start video call"
|
||||
},
|
||||
"message_edited_marker": {
|
||||
"defaultMessage": ", edited",
|
||||
"description": "Marker indicating that the message was edited"
|
||||
},
|
||||
"message_sending": {
|
||||
"defaultMessage": "sending...",
|
||||
"description": "Message being sent, in place of time stamp"
|
||||
|
||||
@@ -1451,5 +1451,26 @@
|
||||
"description": "Message explaining that the credential was successfully validated.",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"menu_item_edit": {
|
||||
"translation": "Modifier",
|
||||
"defaultMessage": "Edit",
|
||||
"description": "Edit message",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"editing_message": {
|
||||
"translation": "Édition",
|
||||
"defaultMessage": "Editing",
|
||||
"description": "Title over message editing preview",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"message_edited_marker": {
|
||||
"translation": ", édité",
|
||||
"defaultMessage": ", edited",
|
||||
"description": "Marker indicating that the message was edited",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1451,5 +1451,26 @@
|
||||
"description": "Message explaining that the credential was successfully validated.",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"menu_item_edit": {
|
||||
"translation": "편집",
|
||||
"defaultMessage": "Edit",
|
||||
"description": "Edit message",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"editing_message": {
|
||||
"translation": "교정하다",
|
||||
"defaultMessage": "Editing",
|
||||
"description": "Title over message editing preview",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"message_edited_marker": {
|
||||
"translation": " 수정됨",
|
||||
"defaultMessage": ", edited",
|
||||
"description": "Marker indicating that the message was edited",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1451,5 +1451,26 @@
|
||||
"description": "Message explaining that the credential was successfully validated.",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"menu_item_edit": {
|
||||
"translation": "Editează",
|
||||
"defaultMessage": "Edit",
|
||||
"description": "Edit message",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"editing_message": {
|
||||
"translation": "Editare",
|
||||
"defaultMessage": "Editing",
|
||||
"description": "Title over message editing preview",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"message_edited_marker": {
|
||||
"translation": ", editat",
|
||||
"defaultMessage": ", edited",
|
||||
"description": "Marker indicating that the message was edited",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1451,5 +1451,26 @@
|
||||
"description": "Message explaining that the credential was successfully validated.",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"menu_item_edit": {
|
||||
"translation": "Изменить",
|
||||
"defaultMessage": "Edit",
|
||||
"description": "Edit message",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"editing_message": {
|
||||
"translation": "Редактирование",
|
||||
"defaultMessage": "Editing",
|
||||
"description": "Title over message editing preview",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"message_edited_marker": {
|
||||
"translation": ", изменено",
|
||||
"defaultMessage": ", edited",
|
||||
"description": "Marker indicating that the message was edited",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1451,5 +1451,26 @@
|
||||
"description": "Message explaining that the credential was successfully validated.",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"menu_item_edit": {
|
||||
"translation": "編輯",
|
||||
"defaultMessage": "Edit",
|
||||
"description": "Edit message",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"editing_message": {
|
||||
"translation": "編輯",
|
||||
"defaultMessage": "Editing",
|
||||
"description": "Title over message editing preview",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"message_edited_marker": {
|
||||
"translation": ",編輯",
|
||||
"defaultMessage": ", edited",
|
||||
"description": "Marker indicating that the message was edited",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1451,5 +1451,26 @@
|
||||
"description": "Message explaining that the credential was successfully validated.",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"menu_item_edit": {
|
||||
"translation": "编辑",
|
||||
"defaultMessage": "Edit",
|
||||
"description": "Edit message",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"editing_message": {
|
||||
"translation": "编辑",
|
||||
"defaultMessage": "Editing",
|
||||
"description": "Title over message editing preview",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"message_edited_marker": {
|
||||
"translation": ",编辑",
|
||||
"defaultMessage": ", edited",
|
||||
"description": "Marker indicating that the message was edited",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+61
-17
@@ -19,7 +19,7 @@ import LogoView from './logo-view.jsx';
|
||||
import MetaMessage from '../widgets/meta-message.jsx';
|
||||
import SendMessage from '../widgets/send-message.jsx';
|
||||
|
||||
import { DEFAULT_P2P_ACCESS_MODE, IMAGE_PREVIEW_DIM, KEYPRESS_DELAY,
|
||||
import { DEFAULT_P2P_ACCESS_MODE, EDIT_PREVIEW_LENGTH, IMAGE_PREVIEW_DIM, KEYPRESS_DELAY,
|
||||
MESSAGES_PAGE, MAX_EXTERN_ATTACHMENT_SIZE, MAX_IMAGE_DIM, MAX_INBAND_ATTACHMENT_SIZE,
|
||||
READ_DELAY, QUOTED_REPLY_LENGTH } from '../config.js';
|
||||
import { CALL_STATE_OUTGOING_INITATED, CALL_STATE_IN_PROGRESS } from '../constants.js';
|
||||
@@ -63,6 +63,11 @@ const messages = defineMessages({
|
||||
defaultMessage: 'invalid content',
|
||||
description: 'Shown when the message is unreadable'
|
||||
},
|
||||
editing_message: {
|
||||
id: 'editing_message',
|
||||
defaultMessage: 'Editing',
|
||||
description: 'Title over message editing preview'
|
||||
}
|
||||
});
|
||||
|
||||
// Checks if the access permissions are granted but not yet accepted.
|
||||
@@ -125,6 +130,7 @@ class MessagesView extends React.Component {
|
||||
this.goToLatestMessage = this.goToLatestMessage.bind(this);
|
||||
|
||||
this.handlePickReply = this.handlePickReply.bind(this);
|
||||
this.handleEditMessage = this.handleEditMessage.bind(this);
|
||||
this.handleCancelReply = this.handleCancelReply.bind(this);
|
||||
this.handleQuoteClick = this.handleQuoteClick.bind(this);
|
||||
this.handleCallHangup = this.handleCallHangup.bind(this);
|
||||
@@ -237,6 +243,7 @@ class MessagesView extends React.Component {
|
||||
peerMessagingDisabled: false,
|
||||
channel: false,
|
||||
reply: null,
|
||||
contentToEdit: null,
|
||||
showGoToLastButton: false
|
||||
};
|
||||
} else if (nextProps.topic != prevState.topic) {
|
||||
@@ -753,14 +760,19 @@ class MessagesView extends React.Component {
|
||||
msg = this.props.forwardMessage.msg;
|
||||
head = this.props.forwardMessage.head;
|
||||
this.handleCancelReply();
|
||||
} else if (this.state.reply && this.state.reply.content) {
|
||||
// We are replying to a message in this topic.
|
||||
head = {reply: '' + this.state.reply.seq};
|
||||
// Turn it into Drafty so we can make a quoted Drafty object later.
|
||||
if (typeof msg == 'string') {
|
||||
msg = Drafty.parse(msg);
|
||||
} else if (this.state.reply) {
|
||||
if (this.state.reply.editing) {
|
||||
// Editing an existing message.
|
||||
head = {replace: ':' + this.state.reply.seq};
|
||||
} else if (this.state.reply.content) {
|
||||
// Replying to a message in this topic.
|
||||
// Turn it into Drafty so we can make a quoted Drafty object later.
|
||||
head = {reply: '' + this.state.reply.seq};
|
||||
if (typeof msg == 'string') {
|
||||
msg = Drafty.parse(msg);
|
||||
}
|
||||
msg = Drafty.append(Drafty.sanitizeEntities(this.state.reply.content), msg);
|
||||
}
|
||||
msg = Drafty.append(Drafty.sanitizeEntities(this.state.reply.content), msg);
|
||||
this.handleCancelReply();
|
||||
}
|
||||
this.props.sendMessage(msg, uploadCompletionPromise, uploader, head);
|
||||
@@ -769,7 +781,7 @@ class MessagesView extends React.Component {
|
||||
// Retry sending a message.
|
||||
retrySend(pub) {
|
||||
this.props.sendMessage(pub.content, undefined, undefined, pub.head)
|
||||
.then(() => {
|
||||
.then(_ => {
|
||||
// All good. Remove the original message draft from the cache.
|
||||
const topic = this.props.tinode.getTopic(this.state.topic);
|
||||
topic.delMessagesList([pub.seq], true);
|
||||
@@ -977,9 +989,8 @@ class MessagesView extends React.Component {
|
||||
// senderId: UID of the sender of the source message.
|
||||
// senderName: full name of the sender of the original message.
|
||||
handlePickReply(seq, content, senderId, senderName) {
|
||||
this.setState({reply: null});
|
||||
|
||||
if (!seq || !content) {
|
||||
this.setState({reply: null});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1001,8 +1012,38 @@ class MessagesView extends React.Component {
|
||||
this.props.onCancelForwardMessage();
|
||||
}
|
||||
|
||||
// seq: seq ID of the message to edit.
|
||||
// context: message content.
|
||||
handleEditMessage(seq, content) {
|
||||
if (!seq || !content) {
|
||||
this.setState({reply: null});
|
||||
return;
|
||||
}
|
||||
|
||||
content = typeof content == 'string' ? Drafty.init(content) : content;
|
||||
const editable = Drafty.toMarkdown(content);
|
||||
if (Drafty.isValid(content)) {
|
||||
content = Drafty.replyContent(content, EDIT_PREVIEW_LENGTH);
|
||||
} else {
|
||||
// /!\ invalid content.
|
||||
content = Drafty.append(Drafty.init('\u26A0 '),
|
||||
Drafty.wrapInto(this.props.intl.formatMessage(messages.invalid_content), 'EM'));
|
||||
}
|
||||
|
||||
this.setState({
|
||||
reply: {
|
||||
content: Drafty.quote(this.props.intl.formatMessage(messages.message_editing), null, content),
|
||||
seq: seq,
|
||||
editing: true
|
||||
},
|
||||
contentToEdit: editable
|
||||
});
|
||||
this.props.onCancelForwardMessage();
|
||||
}
|
||||
|
||||
|
||||
handleCancelReply() {
|
||||
this.setState({reply: null});
|
||||
this.setState({reply: null, contentToEdit: null});
|
||||
this.props.onCancelForwardMessage();
|
||||
}
|
||||
|
||||
@@ -1011,7 +1052,7 @@ class MessagesView extends React.Component {
|
||||
if (ref && ref.current) {
|
||||
ref.current.scrollIntoView({block: "center", behavior: "smooth"});
|
||||
ref.current.classList.add('flash');
|
||||
setTimeout(() => { ref.current.classList.remove('flash') } , 1000);
|
||||
setTimeout(_ => {ref.current.classList.remove('flash')} , 1000);
|
||||
} else {
|
||||
console.error("Unresolved message ref", replyToSeq);
|
||||
}
|
||||
@@ -1157,6 +1198,8 @@ class MessagesView extends React.Component {
|
||||
tinode={this.props.tinode}
|
||||
content={msg.content}
|
||||
mimeType={msg.head && msg.head.mime}
|
||||
replyToSeq={replyToSeq}
|
||||
edited={msg.head && msg.head.replace && !msg.head.webrtc}
|
||||
timestamp={msg.ts}
|
||||
response={isReply}
|
||||
seq={msg.seq}
|
||||
@@ -1168,17 +1211,17 @@ class MessagesView extends React.Component {
|
||||
sequence={sequence}
|
||||
received={deliveryStatus}
|
||||
uploader={msg._uploader}
|
||||
userIsWriter={this.state.isWriter}
|
||||
viewportWidth={this.props.viewportWidth} // Used by `formatter`.
|
||||
showContextMenu={this.handleShowMessageContextMenu}
|
||||
onImagePreview={this.handleImagePostview}
|
||||
onFormResponse={this.handleFormResponse}
|
||||
onError={this.props.onError}
|
||||
onCancelUpload={this.handleCancelUpload}
|
||||
pickReply={this.handlePickReply}
|
||||
replyToSeq={replyToSeq}
|
||||
editMessage={this.handleEditMessage}
|
||||
onQuoteClick={this.handleQuoteClick}
|
||||
onError={this.props.onError}
|
||||
ref={ref}
|
||||
userIsWriter={this.state.isWriter}
|
||||
key={msg.seq} />
|
||||
);
|
||||
}
|
||||
@@ -1287,13 +1330,14 @@ class MessagesView extends React.Component {
|
||||
topicName={this.state.topic}
|
||||
noInput={!!this.props.forwardMessage}
|
||||
disabled={!this.state.isWriter || this.state.deleted}
|
||||
reply={this.state.reply}
|
||||
initMessage={this.state.contentToEdit}
|
||||
onKeyPress={this.sendKeyPress}
|
||||
onSendMessage={this.sendMessage}
|
||||
onAttachFile={this.props.forwardMessage ? null : this.handleAttachFile}
|
||||
onAttachImage={this.props.forwardMessage ? null : this.handleAttachImage}
|
||||
onAttachAudio={this.props.forwardMessage ? null : this.sendAudioAttachment}
|
||||
onError={this.props.onError}
|
||||
reply={this.state.reply}
|
||||
onQuoteClick={this.handleQuoteClick}
|
||||
onCancelReply={this.handleCancelReply} />}
|
||||
</>
|
||||
|
||||
@@ -80,6 +80,9 @@ class BaseChatMessage extends React.PureComponent {
|
||||
this.props.received > Tinode.MESSAGE_STATUS_FAILED &&
|
||||
this.props.received < Tinode.MESSAGE_STATUS_DEL_RANGE) {
|
||||
menuItems.push('menu_item_reply');
|
||||
if (!this.props.response) {
|
||||
menuItems.push('menu_item_edit');
|
||||
}
|
||||
}
|
||||
menuItems.push('menu_item_forward');
|
||||
|
||||
@@ -90,7 +93,8 @@ class BaseChatMessage extends React.PureComponent {
|
||||
userName: this.props.userName,
|
||||
y: e.pageY,
|
||||
x: e.pageX,
|
||||
pickReply: this.props.pickReply
|
||||
pickReply: this.props.pickReply,
|
||||
editMessage: this.props.editMessage,
|
||||
}, menuItems);
|
||||
}
|
||||
|
||||
@@ -175,6 +179,7 @@ class BaseChatMessage extends React.PureComponent {
|
||||
</div>
|
||||
{this.props.timestamp ?
|
||||
<ReceivedMarker
|
||||
edited={this.props.edited}
|
||||
timestamp={this.props.timestamp}
|
||||
received={this.props.received} />
|
||||
: null}
|
||||
|
||||
@@ -55,6 +55,11 @@ const messages = defineMessages({
|
||||
defaultMessage: 'Forward',
|
||||
description: 'Forward message'
|
||||
},
|
||||
edit: {
|
||||
id: 'menu_item_edit',
|
||||
defaultMessage: 'Edit',
|
||||
description: 'Edit message'
|
||||
},
|
||||
topic_delete: {
|
||||
id: 'menu_item_delete_topic',
|
||||
defaultMessage: 'Delete',
|
||||
@@ -193,6 +198,13 @@ class ContextMenu extends React.Component {
|
||||
title: formatMessage(messages.forward),
|
||||
handler: () => {} /* the action is taken directly in tinode-web */
|
||||
},
|
||||
'menu_item_edit': {
|
||||
id: 'menu_item_edit',
|
||||
title: formatMessage(messages.edit),
|
||||
handler: (params, errorHandler) => {
|
||||
return this.editMessage(params, errorHandler);
|
||||
}
|
||||
},
|
||||
'topic_unmute': {
|
||||
id: 'topic_unmute',
|
||||
title: formatMessage(messages.unmute),
|
||||
@@ -437,6 +449,10 @@ class ContextMenu extends React.Component {
|
||||
params.pickReply(params.seq, params.content, params.userFrom, params.userName, errorHandler);
|
||||
}
|
||||
|
||||
editMessage(params, errorHandler) {
|
||||
params.editMessage(params.seq, params.content, errorHandler);
|
||||
}
|
||||
|
||||
render() {
|
||||
const menu = [];
|
||||
let count = 0;
|
||||
|
||||
@@ -16,6 +16,11 @@ const messages = defineMessages({
|
||||
id: 'message_sending_failed',
|
||||
defaultMessage: 'failed',
|
||||
description: 'Failed to send message, in place of time stamp'
|
||||
},
|
||||
message_edited_marker: {
|
||||
id: 'message_edited_marker',
|
||||
defaultMessage: ', edited',
|
||||
description: 'Marker indicating that the message was edited'
|
||||
}
|
||||
});
|
||||
|
||||
@@ -33,10 +38,11 @@ class ReceivedMarker extends React.PureComponent {
|
||||
|
||||
const icon = deliveryMarker(this.props.received);
|
||||
const marker = icon ? <i className={'material-icons small ' + icon.color}>{icon.name}</i> : null;
|
||||
const edited = this.props.edited ? formatMessage(messages.message_edited_marker) : null;
|
||||
|
||||
return (
|
||||
<span className="timestamp">
|
||||
{timestamp}{'\u00a0'}{marker}
|
||||
{timestamp}{edited}{'\u00a0'}{marker}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -83,7 +83,14 @@ class SendMessage extends React.PureComponent {
|
||||
}
|
||||
|
||||
if (prevProps.topicName != this.props.topicName) {
|
||||
this.setState({message: '', audioRec: false, quote: null});
|
||||
this.setState({message: this.props.initMessage || '', audioRec: false, quote: null});
|
||||
} else if (prevProps.initMessage != this.props.initMessage) {
|
||||
const msg = this.props.initMessage || '';
|
||||
this.setState({message: msg}, _ => {
|
||||
// If there is text, scroll to bottom and set caret to the end.
|
||||
this.messageEditArea.scrollTop = this.messageEditArea.scrollHeight;
|
||||
this.messageEditArea.setSelectionRange(msg.length, msg.length);
|
||||
});
|
||||
}
|
||||
if (prevProps.reply != this.props.reply) {
|
||||
this.setState({quote: this.formatReply()});
|
||||
@@ -193,10 +200,13 @@ class SendMessage extends React.PureComponent {
|
||||
formatMessage(messages[this.props.messagePrompt]) :
|
||||
formatMessage(messages.type_new_message));
|
||||
|
||||
const sendIcon = (this.props.reply && this.props.reply.editing) ?
|
||||
'check_circle' : 'send';
|
||||
|
||||
const quote = this.state.quote ?
|
||||
(<div id="reply-quote-preview">
|
||||
<div className="cancel">
|
||||
<a href="#" onClick={(e) => {e.preventDefault(); this.props.onCancelReply();}}><i className="material-icons gray">close</i></a>
|
||||
<a href="#" onClick={e => {e.preventDefault(); this.props.onCancelReply();}}><i className="material-icons gray">close</i></a>
|
||||
</div>
|
||||
{this.state.quote}
|
||||
</div>) : null;
|
||||
@@ -209,10 +219,10 @@ class SendMessage extends React.PureComponent {
|
||||
<>
|
||||
{this.props.onAttachFile && !this.state.audioRec ?
|
||||
<>
|
||||
<a href="#" onClick={(e) => {e.preventDefault(); this.attachImage.click();}} title="Add image">
|
||||
<a href="#" onClick={e => {e.preventDefault(); this.attachImage.click();}} title="Add image">
|
||||
<i className="material-icons secondary">photo</i>
|
||||
</a>
|
||||
<a href="#" onClick={(e) => {e.preventDefault(); this.attachFile.click();}} title="Attach file">
|
||||
<a href="#" onClick={e => {e.preventDefault(); this.attachFile.click();}} title="Attach file">
|
||||
<i className="material-icons secondary">attach_file</i>
|
||||
</a>
|
||||
</>
|
||||
@@ -225,13 +235,14 @@ class SendMessage extends React.PureComponent {
|
||||
onDeleted={_ => this.setState({audioRec: false})}
|
||||
onFinished={this.handleAttachAudio}/> :
|
||||
<textarea id="sendMessage" placeholder={prompt}
|
||||
value={this.state.message} onChange={this.handleMessageTyping}
|
||||
value={this.state.message}
|
||||
onChange={this.handleMessageTyping}
|
||||
onKeyPress={this.handleKeyPress}
|
||||
ref={(ref) => {this.messageEditArea = ref;}}
|
||||
autoFocus />)}
|
||||
{this.state.message || !audioEnabled ?
|
||||
<a href="#" onClick={this.handleSend} title="Send">
|
||||
<i className="material-icons">send</i>
|
||||
<i className="material-icons">{sendIcon}</i>
|
||||
</a> :
|
||||
!this.state.audioRec ?
|
||||
<a href="#" onClick={e => {e.preventDefault(); this.setState({audioRec: true})}} title="Voice">
|
||||
@@ -239,9 +250,9 @@ class SendMessage extends React.PureComponent {
|
||||
</a> :
|
||||
null
|
||||
}
|
||||
<input type="file" ref={(ref) => {this.attachFile = ref;}}
|
||||
<input type="file" ref={ref => {this.attachFile = ref}}
|
||||
onChange={this.handleAttachFile} style={{display: 'none'}} />
|
||||
<input type="file" ref={(ref) => {this.attachImage = ref;}} accept="image/*"
|
||||
<input type="file" ref={ref => {this.attachImage = ref}} accept="image/*"
|
||||
onChange={this.handleAttachImage} style={{display: 'none'}} />
|
||||
</>
|
||||
:
|
||||
|
||||
Reference in New Issue
Block a user