forked from Github/ocrcc-chatbox
trying ot get the images to load
This commit is contained in:
parent
47d546a8d4
commit
d8e482a689
@ -116,6 +116,8 @@
|
|||||||
"webpack-serve": "3.2.0"
|
"webpack-serve": "3.2.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"browser-encrypt-attachment": "^0.3.0",
|
||||||
|
"isomorphic-fetch": "^2.2.1",
|
||||||
"linkifyjs": "^2.1.9",
|
"linkifyjs": "^2.1.9",
|
||||||
"matrix-js-sdk": "^4.0.0",
|
"matrix-js-sdk": "^4.0.0",
|
||||||
"node-localstorage": "^2.1.5",
|
"node-localstorage": "^2.1.5",
|
||||||
|
@ -341,8 +341,11 @@ class ChatBox extends React.Component {
|
|||||||
sender: event.getSender(),
|
sender: event.getSender(),
|
||||||
roomId: event.getRoomId(),
|
roomId: event.getRoomId(),
|
||||||
content: event.getContent(),
|
content: event.getContent(),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('message ===========>', message)
|
||||||
|
|
||||||
const messages = [...this.state.messages]
|
const messages = [...this.state.messages]
|
||||||
messages.push(message)
|
messages.push(message)
|
||||||
this.setState({ messages })
|
this.setState({ messages })
|
||||||
@ -479,7 +482,7 @@ class ChatBox extends React.Component {
|
|||||||
{
|
{
|
||||||
messages.map((message, index) => {
|
messages.map((message, index) => {
|
||||||
return(
|
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,31 +1,53 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import Linkify from 'linkifyjs/react';
|
import Linkify from 'linkifyjs/react';
|
||||||
|
import decryptFile from '../utils/decryptFile'
|
||||||
|
|
||||||
const Message = ({ message, userId, botId }) => {
|
|
||||||
|
|
||||||
const senderClass = () => {
|
class Message extends React.Component {
|
||||||
switch (message.sender) {
|
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':
|
case 'from-me':
|
||||||
return 'from-me'
|
return 'from-me'
|
||||||
case userId:
|
case this.props.userId:
|
||||||
return 'from-me'
|
return 'from-me'
|
||||||
case botId:
|
case this.props.botId:
|
||||||
return 'from-bot'
|
return 'from-bot'
|
||||||
default:
|
default:
|
||||||
return 'from-support'
|
return 'from-support'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderTextMessage = () => {
|
||||||
if (message.content.formatted_body) {
|
|
||||||
return (
|
|
||||||
<div className={`message ${senderClass()}`}>
|
|
||||||
<div className="text" dangerouslySetInnerHTML={{__html: message.content.formatted_body}} />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const linkifyOpts = {
|
const linkifyOpts = {
|
||||||
linkAttributes: {
|
linkAttributes: {
|
||||||
rel: 'noreferrer noopener',
|
rel: 'noreferrer noopener',
|
||||||
@ -33,12 +55,59 @@ const Message = ({ message, userId, botId }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`message ${senderClass()}`}>
|
<div className={`message ${this.senderClass()}`}>
|
||||||
<div className="text">
|
<div className="text">
|
||||||
<Linkify options={linkifyOpts}>{ message.content.body }</Linkify>
|
<Linkify options={linkifyOpts}>{ this.props.message.content.body }</Linkify>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderHtmlMessage = () => {
|
||||||
|
return (
|
||||||
|
<div className={`message ${this.senderClass()}`}>
|
||||||
|
<div className="text" dangerouslySetInnerHTML={{__html: this.props.message.content.formatted_body}} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
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>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
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;
|
37
yarn.lock
37
yarn.lock
@ -3237,6 +3237,11 @@ brorand@^1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
|
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
|
||||||
integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
|
integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
|
||||||
|
|
||||||
|
browser-encrypt-attachment@^0.3.0:
|
||||||
|
version "0.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/browser-encrypt-attachment/-/browser-encrypt-attachment-0.3.0.tgz#205a94caadf0dc7e81413941812f655bd190ff1c"
|
||||||
|
integrity sha1-IFqUyq3w3H6BQTlBgS9lW9GQ/xw=
|
||||||
|
|
||||||
browser-process-hrtime@^0.1.2:
|
browser-process-hrtime@^0.1.2:
|
||||||
version "0.1.3"
|
version "0.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4"
|
resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4"
|
||||||
@ -4789,6 +4794,13 @@ encodeurl@^1.0.2, encodeurl@~1.0.2:
|
|||||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
||||||
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
|
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
|
||||||
|
|
||||||
|
encoding@^0.1.11:
|
||||||
|
version "0.1.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
|
||||||
|
integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=
|
||||||
|
dependencies:
|
||||||
|
iconv-lite "~0.4.13"
|
||||||
|
|
||||||
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
|
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
|
||||||
version "1.4.4"
|
version "1.4.4"
|
||||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
|
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
|
||||||
@ -6492,7 +6504,7 @@ humanize-url@^1.0.0:
|
|||||||
normalize-url "^1.0.0"
|
normalize-url "^1.0.0"
|
||||||
strip-url-auth "^1.0.0"
|
strip-url-auth "^1.0.0"
|
||||||
|
|
||||||
iconv-lite@0.4.24, iconv-lite@^0.4.24:
|
iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@~0.4.13:
|
||||||
version "0.4.24"
|
version "0.4.24"
|
||||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
||||||
@ -7051,7 +7063,7 @@ is-set@^2.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43"
|
resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43"
|
||||||
integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==
|
integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==
|
||||||
|
|
||||||
is-stream@^1.1.0:
|
is-stream@^1.0.1, is-stream@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||||
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
||||||
@ -7140,6 +7152,14 @@ isobject@^4.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0"
|
resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0"
|
||||||
integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==
|
integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==
|
||||||
|
|
||||||
|
isomorphic-fetch@^2.2.1:
|
||||||
|
version "2.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
|
||||||
|
integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=
|
||||||
|
dependencies:
|
||||||
|
node-fetch "^1.0.1"
|
||||||
|
whatwg-fetch ">=0.10.0"
|
||||||
|
|
||||||
isstream@~0.1.2:
|
isstream@~0.1.2:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
||||||
@ -8653,6 +8673,14 @@ node-dir@^0.1.10:
|
|||||||
dependencies:
|
dependencies:
|
||||||
minimatch "^3.0.2"
|
minimatch "^3.0.2"
|
||||||
|
|
||||||
|
node-fetch@^1.0.1:
|
||||||
|
version "1.7.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
|
||||||
|
integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==
|
||||||
|
dependencies:
|
||||||
|
encoding "^0.1.11"
|
||||||
|
is-stream "^1.0.1"
|
||||||
|
|
||||||
node-fetch@^2.3.0, node-fetch@^2.6.0:
|
node-fetch@^2.3.0, node-fetch@^2.6.0:
|
||||||
version "2.6.0"
|
version "2.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
|
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
|
||||||
@ -12408,6 +12436,11 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
iconv-lite "0.4.24"
|
iconv-lite "0.4.24"
|
||||||
|
|
||||||
|
whatwg-fetch@>=0.10.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb"
|
||||||
|
integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==
|
||||||
|
|
||||||
whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0:
|
whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
|
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
|
||||||
|
Loading…
Reference in New Issue
Block a user