trying ot get the images to load
This commit is contained in:
@@ -341,8 +341,11 @@ class ChatBox extends React.Component {
|
||||
sender: event.getSender(),
|
||||
roomId: event.getRoomId(),
|
||||
content: event.getContent(),
|
||||
|
||||
}
|
||||
|
||||
console.log('message ===========>', message)
|
||||
|
||||
const messages = [...this.state.messages]
|
||||
messages.push(message)
|
||||
this.setState({ messages })
|
||||
@@ -479,7 +482,7 @@ class ChatBox extends React.Component {
|
||||
{
|
||||
messages.map((message, index) => {
|
||||
return(
|
||||
<Message key={message.id} message={message} userId={userId} botId={this.props.botUsername} />
|
||||
<Message key={message.id} message={message} userId={userId} botId={this.props.botUsername} client={this.state.client} />
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,44 +1,113 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import Linkify from 'linkifyjs/react';
|
||||
import decryptFile from '../utils/decryptFile'
|
||||
|
||||
const Message = ({ message, userId, botId }) => {
|
||||
|
||||
const senderClass = () => {
|
||||
switch (message.sender) {
|
||||
class Message extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
decryptedUrl: null,
|
||||
decryptedFile: null,
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const needsDecryption = ['m.file', 'm.image'];
|
||||
if (needsDecryption.includes(this.props.message.content.msgtype)) {
|
||||
decryptFile(this.props.message.content.file, this.props.client)
|
||||
.then((decryptedBlob) => {
|
||||
const decryptedUrl = URL.createObjectURL(decryptedBlob)
|
||||
this.setState({
|
||||
decryptedUrl: decryptedUrl,
|
||||
decryptedBlob: decryptedBlob
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.state.decryptedUrl) {
|
||||
URL.revokeObjectURL(this.state.decryptedUrl);
|
||||
}
|
||||
}
|
||||
|
||||
senderClass = () => {
|
||||
switch (this.props.message.sender) {
|
||||
case 'from-me':
|
||||
return 'from-me'
|
||||
case userId:
|
||||
case this.props.userId:
|
||||
return 'from-me'
|
||||
case botId:
|
||||
case this.props.botId:
|
||||
return 'from-bot'
|
||||
default:
|
||||
return 'from-support'
|
||||
}
|
||||
}
|
||||
|
||||
renderTextMessage = () => {
|
||||
const linkifyOpts = {
|
||||
linkAttributes: {
|
||||
rel: 'noreferrer noopener',
|
||||
},
|
||||
}
|
||||
|
||||
if (message.content.formatted_body) {
|
||||
return (
|
||||
<div className={`message ${senderClass()}`}>
|
||||
<div className="text" dangerouslySetInnerHTML={{__html: message.content.formatted_body}} />
|
||||
<div className={`message ${this.senderClass()}`}>
|
||||
<div className="text">
|
||||
<Linkify options={linkifyOpts}>{ this.props.message.content.body }</Linkify>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const linkifyOpts = {
|
||||
linkAttributes: {
|
||||
rel: 'noreferrer noopener',
|
||||
},
|
||||
renderHtmlMessage = () => {
|
||||
return (
|
||||
<div className={`message ${this.senderClass()}`}>
|
||||
<div className="text" dangerouslySetInnerHTML={{__html: this.props.message.content.formatted_body}} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`message ${senderClass()}`}>
|
||||
<div className="text">
|
||||
<Linkify options={linkifyOpts}>{ message.content.body }</Linkify>
|
||||
renderImageMessage = () => {
|
||||
return (
|
||||
<div className={`message ${this.senderClass()}`}>
|
||||
<div className="text">
|
||||
<a href={this.state.decryptedUrl} target='_blank' rel='noopener noreferrer'>{ this.props.message.content.body }</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
renderFileMessage = () => {
|
||||
return (
|
||||
<div className={`message ${this.senderClass()}`}>
|
||||
<div className="text">
|
||||
<a href={this.state.decryptedUrl} target='_blank' rel='noopener noreferrer'>{ this.props.message.content.body }</a>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
console.log(this.props.message)
|
||||
console.log(this.state)
|
||||
const { message } = this.props;
|
||||
|
||||
switch(message.content.msgtype) {
|
||||
case 'm.file':
|
||||
return this.renderFileMessage()
|
||||
case 'm.image':
|
||||
return this.renderImageMessage()
|
||||
default:
|
||||
if (message.content.formatted_body) {
|
||||
return this.renderHtmlMessage()
|
||||
}
|
||||
return this.renderTextMessage()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Message;
|
||||
@@ -1,30 +0,0 @@
|
||||
function checkFunc(dom, selector) {
|
||||
if (typeof dom.update === 'function') {
|
||||
const el = dom.update().find(selector);
|
||||
if (el.exists()) {
|
||||
return el;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
const els = dom.querySelectorAll(selector);
|
||||
if (els.length !== 0) {
|
||||
return els;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
export async function waitForSelection(dom, selector) {
|
||||
let numSleep = 0;
|
||||
for (;;) {
|
||||
const el = checkFunc(dom, selector);
|
||||
if (el) {
|
||||
return el;
|
||||
}
|
||||
if (numSleep > 2) {
|
||||
throw new Error(`could not find ${selector}`);
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, 250));
|
||||
numSleep += 1;
|
||||
}
|
||||
}
|
||||
46
src/utils/decryptFile.js
Normal file
46
src/utils/decryptFile.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import encrypt from 'browser-encrypt-attachment';
|
||||
import 'isomorphic-fetch';
|
||||
|
||||
const ALLOWED_BLOB_MIMETYPES = {
|
||||
'image/jpeg': true,
|
||||
'image/gif': true,
|
||||
'image/png': true,
|
||||
|
||||
'video/mp4': true,
|
||||
'video/webm': true,
|
||||
'video/ogg': true,
|
||||
|
||||
'audio/mp4': true,
|
||||
'audio/webm': true,
|
||||
'audio/aac': true,
|
||||
'audio/mpeg': true,
|
||||
'audio/ogg': true,
|
||||
'audio/wave': true,
|
||||
'audio/wav': true,
|
||||
'audio/x-wav': true,
|
||||
'audio/x-pn-wav': true,
|
||||
'audio/flac': true,
|
||||
'audio/x-flac': true,
|
||||
};
|
||||
|
||||
const decryptFile = (file, client) => {
|
||||
const url = client.mxcUrlToHttp(file.url);
|
||||
// Download the encrypted file as an array buffer.
|
||||
return Promise.resolve(fetch(url))
|
||||
.then((response) => response.arrayBuffer())
|
||||
.then((responseData) => encrypt.decryptAttachment(responseData, file))
|
||||
.then((dataArray) => {
|
||||
// IMPORTANT: we must not allow scriptable mime-types into Blobs otherwise
|
||||
// they introduce XSS attacks if the Blob URI is viewed directly in the
|
||||
// browser (e.g. by copying the URI into a new tab or window.)
|
||||
let mimetype = file.mimetype ? file.mimetype.split(';')[0].trim() : '';
|
||||
if (!ALLOWED_BLOB_MIMETYPES[mimetype]) {
|
||||
mimetype = 'application/octet-stream';
|
||||
}
|
||||
|
||||
const blob = new Blob([dataArray], { type: mimetype });
|
||||
return blob;
|
||||
});
|
||||
};
|
||||
|
||||
export default decryptFile;
|
||||
Reference in New Issue
Block a user