trying ot get the images to load

This commit is contained in:
Sharon Kennedy
2020-03-18 20:35:59 -04:00
parent 47d546a8d4
commit d8e482a689
6 changed files with 174 additions and 51 deletions

View File

@@ -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} />
)
})
}

View File

@@ -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;

View File

@@ -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
View 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;