previewing image before sending works now
This commit is contained in:
@@ -146,6 +146,7 @@
|
|||||||
"search_placeholder": "List like email:alice@example.com, tel:17025550003...",
|
"search_placeholder": "List like email:alice@example.com, tel:17025550003...",
|
||||||
"messaging_disabled_prompt": "Messaging disabled",
|
"messaging_disabled_prompt": "Messaging disabled",
|
||||||
"new_message_prompt": "New message",
|
"new_message_prompt": "New message",
|
||||||
|
"image_caption_prompt": "Image caption",
|
||||||
"file_attachment_too_large": "The file size {size} exceeds the {limit} limit.",
|
"file_attachment_too_large": "The file size {size} exceeds the {limit} limit.",
|
||||||
"cannot_initiate_file_upload": "Cannot initiate file upload.",
|
"cannot_initiate_file_upload": "Cannot initiate file upload.",
|
||||||
"tags_not_found": "No tags defined. Add some.",
|
"tags_not_found": "No tags defined. Add some.",
|
||||||
|
|||||||
+2
-1
@@ -150,5 +150,6 @@
|
|||||||
"topic_delete_warning": "Вы действительно хотите удалить этот чат?",
|
"topic_delete_warning": "Вы действительно хотите удалить этот чат?",
|
||||||
"topic_block_warning": "Вы действительно хотите заблокировать этот чат?",
|
"topic_block_warning": "Вы действительно хотите заблокировать этот чат?",
|
||||||
"search_no_results": "Ничего не найдено",
|
"search_no_results": "Ничего не найдено",
|
||||||
"deleted_content": "удалено"
|
"deleted_content": "удалено",
|
||||||
|
"image_caption_prompt": "Подпись к фото"
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -150,5 +150,6 @@
|
|||||||
"topic_delete_warning": ":!![MISSING]!!:Are you sure you want to delete this conversation?",
|
"topic_delete_warning": ":!![MISSING]!!:Are you sure you want to delete this conversation?",
|
||||||
"topic_block_warning": ":!![MISSING]!!:Are you sure you want to block this conversation?",
|
"topic_block_warning": ":!![MISSING]!!:Are you sure you want to block this conversation?",
|
||||||
"search_no_results": ":!![MISSING]!!:Search returned no results",
|
"search_no_results": ":!![MISSING]!!:Search returned no results",
|
||||||
"deleted_content": "内容已删除"
|
"deleted_content": "内容已删除",
|
||||||
|
"image_caption_prompt": "图片标题"
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -147,6 +147,7 @@
|
|||||||
"search_placeholder": "List like email:alice@example.com, tel:17025550003...",
|
"search_placeholder": "List like email:alice@example.com, tel:17025550003...",
|
||||||
"messaging_disabled_prompt": "Messaging disabled",
|
"messaging_disabled_prompt": "Messaging disabled",
|
||||||
"new_message_prompt": "New message",
|
"new_message_prompt": "New message",
|
||||||
|
"image_caption_prompt": "Image caption",
|
||||||
"file_attachment_too_large": "The file size {size} exceeds the {limit} limit.",
|
"file_attachment_too_large": "The file size {size} exceeds the {limit} limit.",
|
||||||
"cannot_initiate_file_upload": "Cannot initiate file upload.",
|
"cannot_initiate_file_upload": "Cannot initiate file upload.",
|
||||||
"tags_not_found": "No tags defined. Add some.",
|
"tags_not_found": "No tags defined. Add some.",
|
||||||
@@ -305,7 +306,8 @@
|
|||||||
"topic_delete_warning": "Вы действительно хотите удалить этот чат?",
|
"topic_delete_warning": "Вы действительно хотите удалить этот чат?",
|
||||||
"topic_block_warning": "Вы действительно хотите заблокировать этот чат?",
|
"topic_block_warning": "Вы действительно хотите заблокировать этот чат?",
|
||||||
"search_no_results": "Ничего не найдено",
|
"search_no_results": "Ничего не найдено",
|
||||||
"deleted_content": "удалено"
|
"deleted_content": "удалено",
|
||||||
|
"image_caption_prompt": "Подпись к фото"
|
||||||
},
|
},
|
||||||
"zh": {
|
"zh": {
|
||||||
"archived_contacts": "已归档联系人 ({count})",
|
"archived_contacts": "已归档联系人 ({count})",
|
||||||
@@ -450,6 +452,7 @@
|
|||||||
"action_delete_messages": "删除所有帖子",
|
"action_delete_messages": "删除所有帖子",
|
||||||
"action_block_contact": "屏蔽联系人",
|
"action_block_contact": "屏蔽联系人",
|
||||||
"action_report_chat": "检举垃圾邮件",
|
"action_report_chat": "检举垃圾邮件",
|
||||||
"deleted_content": "内容已删除"
|
"deleted_content": "内容已删除",
|
||||||
|
"image_caption_prompt": "图片标题"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+78
-21
@@ -14,9 +14,11 @@ import LoadSpinner from '../widgets/load-spinner.jsx';
|
|||||||
import LogoView from './logo-view.jsx';
|
import LogoView from './logo-view.jsx';
|
||||||
import SendMessage from '../widgets/send-message.jsx';
|
import SendMessage from '../widgets/send-message.jsx';
|
||||||
|
|
||||||
import { DEFAULT_P2P_ACCESS_MODE, KEYPRESS_DELAY, MESSAGES_PAGE, MAX_IMAGE_DIM, MAX_INBAND_ATTACHMENT_SIZE } from '../config.js';
|
import { DEFAULT_P2P_ACCESS_MODE, KEYPRESS_DELAY, MESSAGES_PAGE, MAX_EXTERN_ATTACHMENT_SIZE,
|
||||||
import { SUPPORTED_IMAGE_FORMATS, filePasted, fileToBase64, imageFileToBase64, imageFileScaledToBase64, makeImageUrl } from '../lib/blob-helpers.js';
|
MAX_IMAGE_DIM, MAX_INBAND_ATTACHMENT_SIZE } from '../config.js';
|
||||||
import { shortDateFormat } from '../lib/strformat.js';
|
import { SUPPORTED_IMAGE_FORMATS, filePasted, fileToBase64, imageFileToBase64,
|
||||||
|
imageFileScaledToBase64, makeImageUrl } from '../lib/blob-helpers.js';
|
||||||
|
import { bytesToHumanSize, shortDateFormat } from '../lib/strformat.js';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
online_now: {
|
online_now: {
|
||||||
@@ -61,6 +63,9 @@ class MessagesView extends React.Component {
|
|||||||
|
|
||||||
// this.propsChange = this.propsChange.bind(this);
|
// this.propsChange = this.propsChange.bind(this);
|
||||||
this.leave = this.leave.bind(this);
|
this.leave = this.leave.bind(this);
|
||||||
|
this.sendImageAttachment = this.sendImageAttachment.bind(this);
|
||||||
|
this.sendFileAttachment = this.sendFileAttachment.bind(this);
|
||||||
|
this.sendKeyPress = this.sendKeyPress.bind(this);
|
||||||
this.handleScrollReference = this.handleScrollReference.bind(this);
|
this.handleScrollReference = this.handleScrollReference.bind(this);
|
||||||
this.handleScrollEvent = this.handleScrollEvent.bind(this);
|
this.handleScrollEvent = this.handleScrollEvent.bind(this);
|
||||||
this.handleDescChange = this.handleDescChange.bind(this);
|
this.handleDescChange = this.handleDescChange.bind(this);
|
||||||
@@ -68,7 +73,8 @@ class MessagesView extends React.Component {
|
|||||||
this.handleNewMessage = this.handleNewMessage.bind(this);
|
this.handleNewMessage = this.handleNewMessage.bind(this);
|
||||||
this.handleAllMessagesReceived = this.handleAllMessagesReceived.bind(this);
|
this.handleAllMessagesReceived = this.handleAllMessagesReceived.bind(this);
|
||||||
this.handleInfoReceipt = this.handleInfoReceipt.bind(this);
|
this.handleInfoReceipt = this.handleInfoReceipt.bind(this);
|
||||||
this.handleImagePreview = this.handleImagePreview.bind(this);
|
this.handlePreImagePreview = this.handlePreImagePreview.bind(this);
|
||||||
|
this.handlePostImagePreview = this.handlePostImagePreview.bind(this);
|
||||||
this.handleCloseImagePreview = this.handleCloseImagePreview.bind(this);
|
this.handleCloseImagePreview = this.handleCloseImagePreview.bind(this);
|
||||||
this.handleFormResponse = this.handleFormResponse.bind(this);
|
this.handleFormResponse = this.handleFormResponse.bind(this);
|
||||||
this.handleContextClick = this.handleContextClick.bind(this);
|
this.handleContextClick = this.handleContextClick.bind(this);
|
||||||
@@ -77,7 +83,6 @@ class MessagesView extends React.Component {
|
|||||||
this.handleEnablePeer = this.handleEnablePeer.bind(this);
|
this.handleEnablePeer = this.handleEnablePeer.bind(this);
|
||||||
this.handleAttachFile = this.handleAttachFile.bind(this);
|
this.handleAttachFile = this.handleAttachFile.bind(this);
|
||||||
this.handleAttachImage = this.handleAttachImage.bind(this);
|
this.handleAttachImage = this.handleAttachImage.bind(this);
|
||||||
this.handleNewImagePreview = this.handleNewImagePreview.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@@ -172,7 +177,8 @@ class MessagesView extends React.Component {
|
|||||||
topic: null,
|
topic: null,
|
||||||
title: '',
|
title: '',
|
||||||
avatar: null,
|
avatar: null,
|
||||||
imagePreview: null,
|
imagePrePreview: null,
|
||||||
|
imagePostPreview: null,
|
||||||
typingIndicator: false,
|
typingIndicator: false,
|
||||||
scrollPosition: 0,
|
scrollPosition: 0,
|
||||||
fetchingMessages: false,
|
fetchingMessages: false,
|
||||||
@@ -182,7 +188,8 @@ class MessagesView extends React.Component {
|
|||||||
const topic = nextProps.tinode.getTopic(nextProps.topic);
|
const topic = nextProps.tinode.getTopic(nextProps.topic);
|
||||||
nextState = {
|
nextState = {
|
||||||
topic: nextProps.topic,
|
topic: nextProps.topic,
|
||||||
imagePreview: null,
|
imagePrePreview: null,
|
||||||
|
imagePostPreview: null,
|
||||||
typingIndicator: false,
|
typingIndicator: false,
|
||||||
scrollPosition: 0,
|
scrollPosition: 0,
|
||||||
fetchingMessages: false
|
fetchingMessages: false
|
||||||
@@ -435,12 +442,12 @@ class MessagesView extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleImagePreview(content) {
|
handlePostImagePreview(content) {
|
||||||
this.setState({ imagePreview: content });
|
this.setState({ imagePostPreview: content });
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCloseImagePreview() {
|
handleCloseImagePreview() {
|
||||||
this.setState({ imagePreview: null });
|
this.setState({ imagePostPreview: null, imagePrePreview: null });
|
||||||
}
|
}
|
||||||
|
|
||||||
handleFormResponse(action, text, data) {
|
handleFormResponse(action, text, data) {
|
||||||
@@ -495,7 +502,14 @@ class MessagesView extends React.Component {
|
|||||||
this.props.onChangePermissions(this.state.topic, DEFAULT_P2P_ACCESS_MODE, this.state.topic);
|
this.props.onChangePermissions(this.state.topic, DEFAULT_P2P_ACCESS_MODE, this.state.topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleAttachFile(mime, bits, fname, size, uploadCompletionPromise, uploader) {
|
sendKeyPress() {
|
||||||
|
const topic = this.props.tinode.getTopic(this.state.topic);
|
||||||
|
if (topic.isSubscribed()) {
|
||||||
|
topic.noteKeyPress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendFileAttachment(mime, bits, fname, size, uploadCompletionPromise, uploader) {
|
||||||
if (uploadCompletionPromise) {
|
if (uploadCompletionPromise) {
|
||||||
// Format data and initiate upload.
|
// Format data and initiate upload.
|
||||||
const msg = Drafty.attachFile(null, mime, null, fname, size, uploadCompletionPromise);
|
const msg = Drafty.attachFile(null, mime, null, fname, size, uploadCompletionPromise);
|
||||||
@@ -506,9 +520,42 @@ class MessagesView extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleNewImagePreview(content) {
|
handleAttachFile(file) {
|
||||||
this.setState({ imagePreview: content });
|
if (file.size > MAX_EXTERN_ATTACHMENT_SIZE) {
|
||||||
// this.props.sendMessage(Drafty.insertImage(null, 0, mime, bits, width, height, fname));
|
// Too large.
|
||||||
|
this.props.onError(formatMessage(messages.file_attachment_too_large,
|
||||||
|
{size: bytesToHumanSize(file.size), limit: bytesToHumanSize(MAX_EXTERN_ATTACHMENT_SIZE)}), 'err');
|
||||||
|
} else if (file.size > MAX_INBAND_ATTACHMENT_SIZE) {
|
||||||
|
// Too large to send inband - uploading out of band and sending as a link.
|
||||||
|
const uploader = this.props.tinode.getLargeFileHelper();
|
||||||
|
if (!uploader) {
|
||||||
|
this.props.onError(formatMessage(messages.cannot_initiate_upload));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Pass data and the uploader to the TinodeWeb.
|
||||||
|
this.sendFileAttachment(file.type, null, file.name, file.size, uploadCompletionPromise, uploader);
|
||||||
|
} else {
|
||||||
|
// Small enough to send inband.
|
||||||
|
fileToBase64(file,
|
||||||
|
(mime, bits, fname) => {
|
||||||
|
this.sendFileAttachment(mime, bits, fname);
|
||||||
|
},
|
||||||
|
this.props.onError
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendImageAttachment(caption, mime, bits, width, height, fname) {
|
||||||
|
let msg = Drafty.insertImage(null, 0, mime, bits, width, height, fname);
|
||||||
|
if (caption) {
|
||||||
|
msg = Drafty.appendLineBreak(msg);
|
||||||
|
msg = Drafty.append(msg, Drafty.init(caption));
|
||||||
|
}
|
||||||
|
this.props.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePreImagePreview(content) {
|
||||||
|
this.setState({ imagePrePreview: content });
|
||||||
}
|
}
|
||||||
|
|
||||||
handleAttachImage(file) {
|
handleAttachImage(file) {
|
||||||
@@ -518,8 +565,9 @@ class MessagesView extends React.Component {
|
|||||||
imageFileScaledToBase64(file, MAX_IMAGE_DIM, MAX_IMAGE_DIM, false,
|
imageFileScaledToBase64(file, MAX_IMAGE_DIM, MAX_IMAGE_DIM, false,
|
||||||
// Success
|
// Success
|
||||||
(bits, mime, width, height, fname) => {
|
(bits, mime, width, height, fname) => {
|
||||||
this.handleNewImagePreview({
|
this.handlePreImagePreview({
|
||||||
url: URL.createObjectURL(file),
|
url: URL.createObjectURL(file),
|
||||||
|
bits: bits,
|
||||||
filename: fname,
|
filename: fname,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
@@ -536,8 +584,9 @@ class MessagesView extends React.Component {
|
|||||||
imageFileToBase64(file,
|
imageFileToBase64(file,
|
||||||
// Success
|
// Success
|
||||||
(bits, mime, width, height, fname) => {
|
(bits, mime, width, height, fname) => {
|
||||||
this.handleNewImagePreview({
|
this.handlePreImagePreview({
|
||||||
url: URL.createObjectURL(file),
|
url: URL.createObjectURL(file),
|
||||||
|
bits: bits,
|
||||||
filename: fname,
|
filename: fname,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
@@ -567,13 +616,20 @@ class MessagesView extends React.Component {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let component2;
|
let component2;
|
||||||
if (this.state.imagePreview) {
|
if (this.state.imagePrePreview) {
|
||||||
|
// Preview image before sending.
|
||||||
component2 = (
|
component2 = (
|
||||||
<ImagePreview
|
<ImagePreview
|
||||||
content={this.state.imagePreview}
|
content={this.state.imagePrePreview}
|
||||||
downloadable={true}
|
|
||||||
onClose={this.handleCloseImagePreview}
|
onClose={this.handleCloseImagePreview}
|
||||||
onSendMessage={this.props.sendMessage} />
|
onSendMessage={this.sendImageAttachment} />
|
||||||
|
);
|
||||||
|
} else if (this.state.imagePostPreview) {
|
||||||
|
// Expand received image.
|
||||||
|
component2 = (
|
||||||
|
<ImagePreview
|
||||||
|
content={this.state.imagePostPreview}
|
||||||
|
onClose={this.handleCloseImagePreview} />
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const topic = this.props.tinode.getTopic(this.state.topic);
|
const topic = this.props.tinode.getTopic(this.state.topic);
|
||||||
@@ -627,7 +683,7 @@ class MessagesView extends React.Component {
|
|||||||
sequence={sequence} received={deliveryStatus} uploader={msg._uploader}
|
sequence={sequence} received={deliveryStatus} uploader={msg._uploader}
|
||||||
viewportWidth={this.props.viewportWidth}
|
viewportWidth={this.props.viewportWidth}
|
||||||
showContextMenu={this.handleShowContextMenuMessage}
|
showContextMenu={this.handleShowContextMenuMessage}
|
||||||
onImagePreview={this.handleImagePreview}
|
onImagePreview={this.handlePostImagePreview}
|
||||||
onFormResponse={this.handleFormResponse}
|
onFormResponse={this.handleFormResponse}
|
||||||
onError={this.props.onError}
|
onError={this.props.onError}
|
||||||
key={msg.seq} />
|
key={msg.seq} />
|
||||||
@@ -723,6 +779,7 @@ class MessagesView extends React.Component {
|
|||||||
topic={this.props.topic}
|
topic={this.props.topic}
|
||||||
disabled={!this.state.isWriter}
|
disabled={!this.state.isWriter}
|
||||||
onSendMessage={this.props.sendMessage}
|
onSendMessage={this.props.sendMessage}
|
||||||
|
onKeyPress={this.sendKeyPress}
|
||||||
onAttachFile={this.handleAttachFile}
|
onAttachFile={this.handleAttachFile}
|
||||||
onAttachImage={this.handleAttachImage}
|
onAttachImage={this.handleAttachImage}
|
||||||
onError={this.props.onError} />}
|
onError={this.props.onError} />}
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ export default class ImagePreview extends React.PureComponent {
|
|||||||
width: 0,
|
width: 0,
|
||||||
height: 0
|
height: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.handleSendImage = this.handleSendImage.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
assignWidth(node) {
|
assignWidth(node) {
|
||||||
@@ -26,6 +28,12 @@ export default class ImagePreview extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleSendImage(caption) {
|
||||||
|
this.props.onClose();
|
||||||
|
this.props.onSendMessage(caption, this.props.content.type, this.props.content.bits,
|
||||||
|
this.props.content.width, this.props.content.height, this.props.content.filename);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.props.content) {
|
if (!this.props.content) {
|
||||||
return null;
|
return null;
|
||||||
@@ -47,15 +55,16 @@ export default class ImagePreview extends React.PureComponent {
|
|||||||
const width = this.props.content.width || '-';
|
const width = this.props.content.width || '-';
|
||||||
const height = this.props.content.height || '-';
|
const height = this.props.content.height || '-';
|
||||||
return (
|
return (
|
||||||
<div id="image-preview" onClick={this.props.onClose}>
|
<div id="image-preview">
|
||||||
<div id="image-preview-caption-panel">
|
<div id="image-preview-caption-panel">
|
||||||
{this.props.downloadable ?
|
{!this.props.onSendMessage ?
|
||||||
<a href={this.props.content.url} download={this.props.content.filename}>
|
<a href={this.props.content.url} download={this.props.content.filename}>
|
||||||
<i className="material-icons">file_download</i> <FormattedMessage
|
<i className="material-icons">file_download</i> <FormattedMessage
|
||||||
id="download_action" defaultMessage="download" description="Call to action [download]" />
|
id="download_action" defaultMessage="download" description="Call to action [download]" />
|
||||||
</a>
|
</a>
|
||||||
:
|
:
|
||||||
null}
|
<span>{this.props.content.filename}</span>
|
||||||
|
}
|
||||||
<a href="#" onClick={(e) => {e.preventDefault(); this.props.onClose();}}><i className="material-icons gray">close</i></a>
|
<a href="#" onClick={(e) => {e.preventDefault(); this.props.onClose();}}><i className="material-icons gray">close</i></a>
|
||||||
</div>
|
</div>
|
||||||
<div id="image-preview-container" ref={(node) => this.assignWidth(node)}>
|
<div id="image-preview-container" ref={(node) => this.assignWidth(node)}>
|
||||||
@@ -65,7 +74,9 @@ export default class ImagePreview extends React.PureComponent {
|
|||||||
<SendMessage
|
<SendMessage
|
||||||
tinode={this.props.tinode}
|
tinode={this.props.tinode}
|
||||||
topic={this.props.topic}
|
topic={this.props.topic}
|
||||||
onSendMessage={this.props.onSendMessage}
|
messagePrompt="add_image_caption"
|
||||||
|
acceptBlank={true}
|
||||||
|
onSendMessage={this.handleSendImage}
|
||||||
onError={this.props.onError} />
|
onError={this.props.onError} />
|
||||||
:
|
:
|
||||||
<div id="image-preview-footer">
|
<div id="image-preview-footer">
|
||||||
|
|||||||
@@ -3,9 +3,8 @@ import React from 'react';
|
|||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
import { Drafty } from 'tinode-sdk';
|
import { Drafty } from 'tinode-sdk';
|
||||||
|
|
||||||
import { KEYPRESS_DELAY, MAX_EXTERN_ATTACHMENT_SIZE, MAX_INBAND_ATTACHMENT_SIZE } from '../config.js';
|
import { KEYPRESS_DELAY } from '../config.js';
|
||||||
import { filePasted, fileToBase64 } from '../lib/blob-helpers.js';
|
import { filePasted } from '../lib/blob-helpers.js';
|
||||||
import { bytesToHumanSize } from '../lib/strformat.js';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
'messaging_disabled': {
|
'messaging_disabled': {
|
||||||
@@ -16,7 +15,12 @@ const messages = defineMessages({
|
|||||||
'type_new_message': {
|
'type_new_message': {
|
||||||
id: 'new_message_prompt',
|
id: 'new_message_prompt',
|
||||||
defaultMessage: 'New message',
|
defaultMessage: 'New message',
|
||||||
description: 'Prompt in SendMessage in read-only topic'
|
description: 'Prompt in send message field'
|
||||||
|
},
|
||||||
|
'add_image_caption': {
|
||||||
|
id: 'image_caption_prompt',
|
||||||
|
defaultMessage: 'Image caption',
|
||||||
|
description: 'Prompt in SendMessage for attached image'
|
||||||
},
|
},
|
||||||
'file_attachment_too_large': {
|
'file_attachment_too_large': {
|
||||||
id: 'file_attachment_too_large',
|
id: 'file_attachment_too_large',
|
||||||
@@ -90,29 +94,7 @@ class SendMessage extends React.PureComponent {
|
|||||||
handleAttachFile(e) {
|
handleAttachFile(e) {
|
||||||
const {formatMessage} = this.props.intl;
|
const {formatMessage} = this.props.intl;
|
||||||
if (e.target.files && e.target.files.length > 0) {
|
if (e.target.files && e.target.files.length > 0) {
|
||||||
const file = e.target.files[0];
|
this.props.onAttachFile(e.target.files[0]);
|
||||||
if (file.size > MAX_EXTERN_ATTACHMENT_SIZE) {
|
|
||||||
// Too large.
|
|
||||||
this.props.onError(formatMessage(messages.file_attachment_too_large,
|
|
||||||
{size: bytesToHumanSize(file.size), limit: bytesToHumanSize(MAX_EXTERN_ATTACHMENT_SIZE)}), 'err');
|
|
||||||
} else if (file.size > MAX_INBAND_ATTACHMENT_SIZE) {
|
|
||||||
// Too large to send inband - uploading out of band and sending as a link.
|
|
||||||
const uploader = this.props.tinode.getLargeFileHelper();
|
|
||||||
if (!uploader) {
|
|
||||||
this.props.onError(formatMessage(messages.cannot_initiate_upload));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Pass data and the uploader to the TinodeWeb.
|
|
||||||
this.props.onAttachFile(file.type, null, file.name, file.size, uploadCompletionPromise, uploader);
|
|
||||||
} else {
|
|
||||||
// Small enough to send inband.
|
|
||||||
fileToBase64(file,
|
|
||||||
(mime, bits, fname) => {
|
|
||||||
this.props.onAttachFile(mime, bits, fname);
|
|
||||||
},
|
|
||||||
this.props.onError
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Clear the value so the same file can be uploaded again.
|
// Clear the value so the same file can be uploaded again.
|
||||||
e.target.value = '';
|
e.target.value = '';
|
||||||
@@ -121,8 +103,8 @@ class SendMessage extends React.PureComponent {
|
|||||||
handleSend(e) {
|
handleSend(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const message = this.state.message.trim();
|
const message = this.state.message.trim();
|
||||||
if (message) {
|
if (message || this.props.acceptBlank) {
|
||||||
this.props.onSendMessage(this.state.message.trim());
|
this.props.onSendMessage(message);
|
||||||
this.setState({message: ''});
|
this.setState({message: ''});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,13 +125,12 @@ class SendMessage extends React.PureComponent {
|
|||||||
|
|
||||||
handleMessageTyping(e) {
|
handleMessageTyping(e) {
|
||||||
const newState = {message: e.target.value};
|
const newState = {message: e.target.value};
|
||||||
const now = new Date().getTime();
|
if (this.props.onKeyPress) {
|
||||||
if (now - this.state.keypressTimestamp > KEYPRESS_DELAY) {
|
const now = new Date().getTime();
|
||||||
const topic = this.props.tinode.getTopic(this.props.topic);
|
if (now - this.state.keypressTimestamp > KEYPRESS_DELAY) {
|
||||||
if (topic.isSubscribed()) {
|
this.props.onKeyPress();
|
||||||
topic.noteKeyPress();
|
newState.keypressTimestamp = now;
|
||||||
}
|
}
|
||||||
newState.keypressTimestamp = now;
|
|
||||||
}
|
}
|
||||||
this.setState(newState);
|
this.setState(newState);
|
||||||
}
|
}
|
||||||
@@ -158,7 +139,9 @@ class SendMessage extends React.PureComponent {
|
|||||||
const {formatMessage} = this.props.intl;
|
const {formatMessage} = this.props.intl;
|
||||||
const prompt = this.props.disabled ?
|
const prompt = this.props.disabled ?
|
||||||
formatMessage(messages.messaging_disabled) :
|
formatMessage(messages.messaging_disabled) :
|
||||||
formatMessage(messages.type_new_message);
|
(this.props.messagePrompt ?
|
||||||
|
formatMessage(messages[this.props.messagePrompt]) :
|
||||||
|
formatMessage(messages.type_new_message));
|
||||||
return (
|
return (
|
||||||
<div id="send-message-panel">
|
<div id="send-message-panel">
|
||||||
{this.props.onAttachFile ?
|
{this.props.onAttachFile ?
|
||||||
|
|||||||
+119
-74
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+63
-3
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user