diff --git a/platform/ui/src/components/studyBrowser/ImageThumbnail.js b/platform/ui/src/components/studyBrowser/ImageThumbnail.js index c80855232..8f48b4545 100644 --- a/platform/ui/src/components/studyBrowser/ImageThumbnail.js +++ b/platform/ui/src/components/studyBrowser/ImageThumbnail.js @@ -2,7 +2,7 @@ import './ImageThumbnail.styl'; import { utils } from '@ohif/core'; -import React, { PureComponent } from 'react'; +import React, { useState, useEffect, createRef } from 'react'; import PropTypes from 'prop-types'; import ViewportErrorIndicator from '../../viewer/ViewportErrorIndicator'; @@ -13,114 +13,132 @@ import ViewportLoadingIndicator from '../../viewer/ViewportLoadingIndicator'; // - Set as external dependency? // - Pass in the entire load and render function as a prop? //import cornerstone from 'cornerstone-core'; +function ImageThumbnail(props) { + const { + width, + height, + imageSrc, + imageId, + stackPercentComplete, + error: propsError, + } = props; -export default class ImageThumbnail extends PureComponent { - static propTypes = { - imageSrc: PropTypes.string, - imageId: PropTypes.string, - error: PropTypes.bool.isRequired, - width: PropTypes.number.isRequired, - height: PropTypes.number.isRequired, - stackPercentComplete: PropTypes.number.isRequired, + const [isLoading, setLoading] = useState(false); + const [error, setError] = useState(false); + const [image, setImage] = useState({}); + const canvasRef = createRef(); + + let loadingOrError; + let cancelablePromise; + + if (propsError || error) { + loadingOrError = ; + } else if (isLoading) { + loadingOrError = ; + } + + const showStackLoadingProgressBar = stackPercentComplete !== undefined; + + const shouldRenderToCanvas = () => { + return imageId && !imageSrc; }; - static defaultProps = { - error: false, - stackPercentComplete: 0, - width: 217, - height: 123, + 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); + }); }; - constructor(props) { - super(props); - this.cancelablePromises = []; - this.canvas = React.createRef(); - this.state = { - loading: this.shouldRenderToCanvas(), + const setImagePromise = () => { + if (shouldRenderToCanvas()) { + cancelablePromise = utils.makeCancelable( + cornerstone.loadAndCacheImage(imageId) + ); + } + }; + + const purgeCancelablePromise = () => { + if (cancelablePromise) { + cancelablePromise.cancel(); + } + }; + + useEffect(() => { + return () => { + purgeCancelablePromise(); }; - } + }, []); - 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); - }); + useEffect(() => { + if (image.imageId) { + cornerstone.renderToCanvas(canvasRef.current, image); + setLoading(false); } - } + }, [image.imageId]); - componentWillUnmount() { - while (this.cancelablePromises.length > 0) { - this.cancelablePromises.pop().cancel(); + useEffect(() => { + if (!image.imageId || image.imageId !== imageId) { + purgeCancelablePromise(); + setImagePromise(); + fetchImagePromise(); } - } + }, [imageId]); - render() { - let loadingOrError; - if (this.props.error) { - loadingOrError = ; - } else if (this.state.loading) { - loadingOrError = ; - } - - const showStackLoadingProgressBar = - this.props.stackPercentComplete !== undefined; - - return ( -
-
- {this.shouldRenderToCanvas() ? ( - - ) : ( - {''} - )} -
- {loadingOrError} - {showStackLoadingProgressBar && ( -
-
-
- )} - {this.state.loading && ( -
+ return ( +
+
+ {shouldRenderToCanvas() ? ( + + ) : ( + {''} )}
- ); - } + {loadingOrError} + {showStackLoadingProgressBar && ( +
+
+
+ )} + {isLoading &&
} +
+ ); } + +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; diff --git a/platform/ui/src/components/studyBrowser/StudyBrowser.js b/platform/ui/src/components/studyBrowser/StudyBrowser.js index d5b38ba6c..fdacf3ec4 100644 --- a/platform/ui/src/components/studyBrowser/StudyBrowser.js +++ b/platform/ui/src/components/studyBrowser/StudyBrowser.js @@ -32,7 +32,7 @@ function StudyBrowser(props) { return (