fix crash on image with no data
This commit is contained in:
+21
-9
@@ -349,15 +349,21 @@ function quoteImage(data) {
|
||||
// Get the blob from the image data.
|
||||
if (data.val) {
|
||||
const blob = base64ToBlob(data.val, data.mime);
|
||||
promise = blob ? Promise.resolve(blob) : Promise.reject(new Error("Invalid image"));
|
||||
if (!blob) {
|
||||
throw new Error("Invalid image");
|
||||
}
|
||||
promise = Promise.resolve(blob);
|
||||
} else if (data.ref) {
|
||||
promise = fetch(this.authorizeURL(sanitizeImageUrl(data.ref)))
|
||||
.then(evt => {
|
||||
if (evt.ok) {
|
||||
return evt.blob();
|
||||
} else {
|
||||
throw new Error(`Image fetch unsuccessful: ${evt.status} ${evt.statusText}`);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
promise = fetch(this.authorizeURL(sanitizeImageUrl(data.ref))).then(evt => {
|
||||
if (evt.ok) {
|
||||
return evt.blob();
|
||||
} else {
|
||||
throw new Error(`Image fetch unsuccessful: ${evt.status} ${evt.statusText}`);
|
||||
}
|
||||
});
|
||||
throw new Error("Missing image data");
|
||||
}
|
||||
|
||||
// Scale the blob.
|
||||
@@ -392,7 +398,13 @@ function quoteImage(data) {
|
||||
export function replyFormatter(style, data, values, key, stack) {
|
||||
if (style == 'IM') {
|
||||
const attr = inlineImageAttr.call(this, {key: key}, data);
|
||||
attr.whenDone = cancelablePromise(quoteImage.call(this, data));
|
||||
let loadedPromise;
|
||||
try {
|
||||
loadedPromise = cancelablePromise(quoteImage.call(this, data));
|
||||
} catch (error) {
|
||||
loadedPromise = cancelablePromise(error);
|
||||
}
|
||||
attr.whenDone = loadedPromise;
|
||||
values = [React.createElement(LazyImage, attr, null), ' ', attr.alt];
|
||||
return React.createElement(React.Fragment, {key: key}, values);
|
||||
} else if (style == 'QQ') {
|
||||
|
||||
+11
-7
@@ -183,19 +183,23 @@ export function deliveryMarker(received) {
|
||||
}
|
||||
|
||||
// Wraps a promise to make it cancelable.
|
||||
// The parameter can be either a promise or an error. If it's an error, the wrapped promise is
|
||||
// created in a rejected state.
|
||||
export function cancelablePromise(promise) {
|
||||
let hasCanceled = false;
|
||||
|
||||
const wrappedPromise = new Promise((resolve, reject) => {
|
||||
promise.then(
|
||||
result => hasCanceled ? reject({isCanceled: true}) : resolve(result),
|
||||
error => hasCanceled ? reject({isCanceled: true}) : reject(error)
|
||||
);
|
||||
});
|
||||
const wrappedPromise = promise instanceof Error ?
|
||||
Promise.reject(promise) :
|
||||
new Promise((resolve, reject) => {
|
||||
promise.then(
|
||||
result => hasCanceled ? reject({isCanceled: true}) : resolve(result),
|
||||
error => hasCanceled ? reject({isCanceled: true}) : reject(error)
|
||||
);
|
||||
});
|
||||
|
||||
return {
|
||||
promise: wrappedPromise,
|
||||
cancel( ) {
|
||||
cancel() {
|
||||
hasCanceled = true;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -55,7 +55,7 @@ export default class ImagePreview extends React.PureComponent {
|
||||
<div id="image-preview">
|
||||
<div id="image-preview-caption-panel">
|
||||
{!this.props.onSendMessage ?
|
||||
<a href={this.props.content.url} download={this.props.content.name}>
|
||||
<a href={this.props.content.url} download={true}>
|
||||
<i className="material-icons">file_download</i> <FormattedMessage
|
||||
id="download_action" defaultMessage="download" description="Call to action [download]" />
|
||||
</a>
|
||||
|
||||
@@ -31,6 +31,7 @@ export default class LazyImage extends React.PureComponent {
|
||||
if (prevProps.whenDone != this.props.whenDone) {
|
||||
this.setState({src: 'img/placeholder.png', style: {...this.state.style, padding: '4px'}});
|
||||
this.props.whenDone
|
||||
.promise
|
||||
.then(data => this.setState({src: data.src, style: {...this.state.style, padding: 0}}))
|
||||
.catch(() => this.setState({src: 'img/broken_image.png'}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user