fix: Fix display issues with incorrect thumbnails. Change ImageThumb to functional component. (#1148)
This commit is contained in:
parent
8481e94d4d
commit
d70eae3eb0
@ -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,97 +13,100 @@ 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,
|
|
||||||
height: PropTypes.number.isRequired,
|
|
||||||
stackPercentComplete: PropTypes.number.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
static defaultProps = {
|
|
||||||
error: false,
|
|
||||||
stackPercentComplete: 0,
|
|
||||||
width: 217,
|
|
||||||
height: 123,
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.cancelablePromises = [];
|
|
||||||
this.canvas = React.createRef();
|
|
||||||
this.state = {
|
|
||||||
loading: this.shouldRenderToCanvas(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldRenderToCanvas() {
|
|
||||||
return this.props.imageId && !this.props.imageSrc;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
while (this.cancelablePromises.length > 0) {
|
|
||||||
this.cancelablePromises.pop().cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let loadingOrError;
|
let loadingOrError;
|
||||||
if (this.props.error) {
|
let cancelablePromise;
|
||||||
|
|
||||||
|
if (propsError || error) {
|
||||||
loadingOrError = <ViewportErrorIndicator />;
|
loadingOrError = <ViewportErrorIndicator />;
|
||||||
} else if (this.state.loading) {
|
} else if (isLoading) {
|
||||||
loadingOrError = <ViewportLoadingIndicator />;
|
loadingOrError = <ViewportLoadingIndicator />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const showStackLoadingProgressBar =
|
const showStackLoadingProgressBar = stackPercentComplete !== undefined;
|
||||||
this.props.stackPercentComplete !== undefined;
|
|
||||||
|
const shouldRenderToCanvas = () => {
|
||||||
|
return imageId && !imageSrc;
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchImagePromise = () => {
|
||||||
|
if (!cancelablePromise) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setLoading(true);
|
||||||
|
cancelablePromise
|
||||||
|
.then(response => {
|
||||||
|
setImage(response);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
if (error.isCanceled) return;
|
||||||
|
setLoading(false);
|
||||||
|
setError(true);
|
||||||
|
throw new Error(error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const setImagePromise = () => {
|
||||||
|
if (shouldRenderToCanvas()) {
|
||||||
|
cancelablePromise = utils.makeCancelable(
|
||||||
|
cornerstone.loadAndCacheImage(imageId)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const purgeCancelablePromise = () => {
|
||||||
|
if (cancelablePromise) {
|
||||||
|
cancelablePromise.cancel();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
purgeCancelablePromise();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (image.imageId) {
|
||||||
|
cornerstone.renderToCanvas(canvasRef.current, image);
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, [image.imageId]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!image.imageId || image.imageId !== imageId) {
|
||||||
|
purgeCancelablePromise();
|
||||||
|
setImagePromise();
|
||||||
|
fetchImagePromise();
|
||||||
|
}
|
||||||
|
}, [imageId]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ImageThumbnail">
|
<div className="ImageThumbnail">
|
||||||
<div className="image-thumbnail-canvas">
|
<div className="image-thumbnail-canvas">
|
||||||
{this.shouldRenderToCanvas() ? (
|
{shouldRenderToCanvas() ? (
|
||||||
<canvas
|
<canvas ref={canvasRef} width={width} height={height} />
|
||||||
ref={this.canvas}
|
|
||||||
width={this.props.width}
|
|
||||||
height={this.props.height}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<img
|
<img
|
||||||
className="static-image"
|
className="static-image"
|
||||||
src={this.props.imageSrc}
|
src={imageSrc}
|
||||||
//width={this.props.width}
|
//width={this.props.width}
|
||||||
height={this.props.height}
|
height={height}
|
||||||
alt={''}
|
alt={''}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -113,14 +116,29 @@ export default class ImageThumbnail extends PureComponent {
|
|||||||
<div className="image-thumbnail-progress-bar">
|
<div className="image-thumbnail-progress-bar">
|
||||||
<div
|
<div
|
||||||
className="image-thumbnail-progress-bar-inner"
|
className="image-thumbnail-progress-bar-inner"
|
||||||
style={{ width: `${this.props.stackPercentComplete}%` }}
|
style={{ width: `${stackPercentComplete}%` }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{this.state.loading && (
|
{isLoading && <div className="image-thumbnail-loading-indicator"></div>}
|
||||||
<div className="image-thumbnail-loading-indicator"></div>
|
|
||||||
)}
|
|
||||||
</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;
|
||||||
|
|||||||
@ -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"
|
||||||
>
|
>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user