fix: Fix display issues with incorrect thumbnails. Change ImageThumb to functional component. (#1148)

This commit is contained in:
ladeirarodolfo 2019-11-08 07:26:31 -03:00 committed by Erik Ziegler
parent 8481e94d4d
commit d70eae3eb0
2 changed files with 117 additions and 99 deletions

View File

@ -2,7 +2,7 @@
import './ImageThumbnail.styl'; import './ImageThumbnail.styl';
import { utils } from '@ohif/core'; import { utils } from '@ohif/core';
import React, { PureComponent } from 'react'; import React, { useState, useEffect, createRef } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import ViewportErrorIndicator from '../../viewer/ViewportErrorIndicator'; import ViewportErrorIndicator from '../../viewer/ViewportErrorIndicator';
@ -13,114 +13,132 @@ import ViewportLoadingIndicator from '../../viewer/ViewportLoadingIndicator';
// - Set as external dependency? // - Set as external dependency?
// - Pass in the entire load and render function as a prop? // - Pass in the entire load and render function as a prop?
//import cornerstone from 'cornerstone-core'; //import cornerstone from 'cornerstone-core';
function ImageThumbnail(props) {
const {
width,
height,
imageSrc,
imageId,
stackPercentComplete,
error: propsError,
} = props;
export default class ImageThumbnail extends PureComponent { const [isLoading, setLoading] = useState(false);
static propTypes = { const [error, setError] = useState(false);
imageSrc: PropTypes.string, const [image, setImage] = useState({});
imageId: PropTypes.string, const canvasRef = createRef();
error: PropTypes.bool.isRequired,
width: PropTypes.number.isRequired, let loadingOrError;
height: PropTypes.number.isRequired, let cancelablePromise;
stackPercentComplete: PropTypes.number.isRequired,
if (propsError || error) {
loadingOrError = <ViewportErrorIndicator />;
} else if (isLoading) {
loadingOrError = <ViewportLoadingIndicator />;
}
const showStackLoadingProgressBar = stackPercentComplete !== undefined;
const shouldRenderToCanvas = () => {
return imageId && !imageSrc;
}; };
static defaultProps = { const fetchImagePromise = () => {
error: false, if (!cancelablePromise) {
stackPercentComplete: 0, return;
width: 217, }
height: 123,
setLoading(true);
cancelablePromise
.then(response => {
setImage(response);
})
.catch(error => {
if (error.isCanceled) return;
setLoading(false);
setError(true);
throw new Error(error);
});
}; };
constructor(props) { const setImagePromise = () => {
super(props); if (shouldRenderToCanvas()) {
this.cancelablePromises = []; cancelablePromise = utils.makeCancelable(
this.canvas = React.createRef(); cornerstone.loadAndCacheImage(imageId)
this.state = { );
loading: this.shouldRenderToCanvas(), }
};
const purgeCancelablePromise = () => {
if (cancelablePromise) {
cancelablePromise.cancel();
}
};
useEffect(() => {
return () => {
purgeCancelablePromise();
}; };
} }, []);
shouldRenderToCanvas() { useEffect(() => {
return this.props.imageId && !this.props.imageSrc; if (image.imageId) {
} cornerstone.renderToCanvas(canvasRef.current, image);
setLoading(false);
fetchImage() {
const cancelablePromise = utils.makeCancelable(
cornerstone.loadAndCacheImage(this.props.imageId)
);
this.cancelablePromises.push(cancelablePromise);
return cancelablePromise;
}
componentDidMount() {
if (this.shouldRenderToCanvas()) {
this.fetchImage()
.then(image => {
cornerstone.renderToCanvas(this.canvas.current, image);
this.setState({
loading: false,
});
})
.catch(error => {
if (error.isCanceled) return;
this.setState({
loading: false,
error: true,
});
throw new Error(error);
});
} }
} }, [image.imageId]);
componentWillUnmount() { useEffect(() => {
while (this.cancelablePromises.length > 0) { if (!image.imageId || image.imageId !== imageId) {
this.cancelablePromises.pop().cancel(); purgeCancelablePromise();
setImagePromise();
fetchImagePromise();
} }
} }, [imageId]);
render() { return (
let loadingOrError; <div className="ImageThumbnail">
if (this.props.error) { <div className="image-thumbnail-canvas">
loadingOrError = <ViewportErrorIndicator />; {shouldRenderToCanvas() ? (
} else if (this.state.loading) { <canvas ref={canvasRef} width={width} height={height} />
loadingOrError = <ViewportLoadingIndicator />; ) : (
} <img
className="static-image"
const showStackLoadingProgressBar = src={imageSrc}
this.props.stackPercentComplete !== undefined; //width={this.props.width}
height={height}
return ( alt={''}
<div className="ImageThumbnail"> />
<div className="image-thumbnail-canvas">
{this.shouldRenderToCanvas() ? (
<canvas
ref={this.canvas}
width={this.props.width}
height={this.props.height}
/>
) : (
<img
className="static-image"
src={this.props.imageSrc}
//width={this.props.width}
height={this.props.height}
alt={''}
/>
)}
</div>
{loadingOrError}
{showStackLoadingProgressBar && (
<div className="image-thumbnail-progress-bar">
<div
className="image-thumbnail-progress-bar-inner"
style={{ width: `${this.props.stackPercentComplete}%` }}
/>
</div>
)}
{this.state.loading && (
<div className="image-thumbnail-loading-indicator"></div>
)} )}
</div> </div>
); {loadingOrError}
} {showStackLoadingProgressBar && (
<div className="image-thumbnail-progress-bar">
<div
className="image-thumbnail-progress-bar-inner"
style={{ width: `${stackPercentComplete}%` }}
/>
</div>
)}
{isLoading && <div className="image-thumbnail-loading-indicator"></div>}
</div>
);
} }
ImageThumbnail.propTypes = {
imageSrc: PropTypes.string,
imageId: PropTypes.string,
error: PropTypes.bool,
width: PropTypes.number,
height: PropTypes.number,
stackPercentComplete: PropTypes.number.isRequired,
};
ImageThumbnail.defaultProps = {
error: false,
stackPercentComplete: 0,
width: 217,
height: 123,
};
export default ImageThumbnail;

View File

@ -32,7 +32,7 @@ function StudyBrowser(props) {
return ( return (
<div <div
key={`container_${studyIndex}_${thumbIndex}`} key={thumb.displaySetInstanceUid}
className="thumbnail-container" className="thumbnail-container"
data-cy="thumbnail-list" data-cy="thumbnail-list"
> >