import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import throttle from 'lodash.throttle';
import { useDrag } from 'react-dnd';
import { classes } from '@ohif/core';
import ImageThumbnail from './ImageThumbnail';
import classNames from 'classnames';
import { Icon } from './../../elements/Icon';
import { Tooltip } from './../tooltip';
import { OverlayTrigger } from './../overlayTrigger';
import './Thumbnail.styl';
const StudyLoadingListener = classes.StudyLoadingListener;
function ThumbnailFooter({
SeriesDescription,
SeriesNumber,
numImageFrames,
hasWarnings,
hasDerivedDisplaySets,
}) {
const [inconsistencyWarnings, inconsistencyWarningsSet] = useState([]);
const [derivedDisplaySetsActive, derivedDisplaySetsActiveSet] = useState([]);
useEffect(() => {
let unmounted = false;
hasWarnings.then(response => {
if (!unmounted) {
inconsistencyWarningsSet(response);
}
});
hasDerivedDisplaySets.then(response => {
if (!unmounted) {
derivedDisplaySetsActiveSet(response);
}
});
return () => {
unmounted = true;
};
}, [hasWarnings, hasDerivedDisplaySets]);
const infoOnly = !SeriesDescription;
const getInfo = (value, icon, className = '') => {
return (
);
};
const getWarningContent = inconsistencyWarnings => {
if (Array.isArray(inconsistencyWarnings)) {
const listedWarnings = inconsistencyWarnings.map((warn, index) => {
return {warn};
});
return {listedWarnings}
;
} else {
return {inconsistencyWarnings};
}
};
const getWarningInfo = (SeriesNumber, inconsistencyWarnings) => {
return (
{inconsistencyWarnings && inconsistencyWarnings.length != 0 ? (
Series Inconsistencies
{getWarningContent(inconsistencyWarnings)}
}
>
) : (
)}
);
};
const getDerivedInfo = derivedDisplaySetsActive => {
return (
{derivedDisplaySetsActive ? (
) : (
)}
);
};
const getSeriesInformation = (
SeriesNumber,
numImageFrames,
inconsistencyWarnings,
derivedDisplaySetsActive
) => {
if (!SeriesNumber && !numImageFrames) {
return;
}
const seriesInformation = (
{SeriesNumber !== undefined ? (
getInfo(SeriesNumber, 'S:')
) : (
)}
{numImageFrames !== undefined ? (
getInfo(numImageFrames, '', 'image-frames')
) : (
)}
{getDerivedInfo(derivedDisplaySetsActive)}
{getWarningInfo(SeriesNumber, inconsistencyWarnings)}
);
return seriesInformation;
};
return (
{SeriesDescription}
{getSeriesInformation(
SeriesNumber,
numImageFrames,
inconsistencyWarnings,
derivedDisplaySetsActive
)}
);
}
function Thumbnail(props) {
const {
active,
altImageText,
error,
displaySetInstanceUID,
imageId,
imageSrc,
StudyInstanceUID,
onClick,
onDoubleClick,
onMouseDown,
supportsDrag,
showProgressBar,
} = props;
const [stackPercentComplete, setStackPercentComplete] = useState(0);
useEffect(() => {
const onProgressChange = throttle(({ detail }) => {
const { progressId, progressData } = detail;
if (`StackProgress:${displaySetInstanceUID}` === progressId) {
const percent = progressData ? progressData.percentComplete : 0;
if (percent > stackPercentComplete) {
setStackPercentComplete(percent);
}
}
}, 100);
document.addEventListener(
StudyLoadingListener.events.OnProgress,
onProgressChange
);
return () => {
document.removeEventListener(
StudyLoadingListener.events.OnProgress,
onProgressChange
);
};
}, [displaySetInstanceUID]);
const [collectedProps, drag, dragPreview] = useDrag({
// `droppedItem` in `dropTarget`
// The only data it will have access to
item: {
StudyInstanceUID,
displaySetInstanceUID,
type: 'thumbnail', // Has to match `dropTarget`'s type
},
canDrag: function(monitor) {
return supportsDrag;
},
});
const hasImage = imageSrc || imageId;
const hasAltText = altImageText !== undefined;
return (
{/* SHOW IMAGE */}
{hasImage && (
)}
{/* SHOW TEXT ALTERNATIVE */}
{!hasImage && hasAltText && (
{altImageText}
)}
{ThumbnailFooter(props)}
);
}
const noop = () => {};
Thumbnail.propTypes = {
supportsDrag: PropTypes.bool,
id: PropTypes.string.isRequired,
displaySetInstanceUID: PropTypes.string.isRequired,
StudyInstanceUID: PropTypes.string.isRequired,
imageSrc: PropTypes.string,
imageId: PropTypes.string,
error: PropTypes.bool,
active: PropTypes.bool,
stackPercentComplete: PropTypes.number,
/**
altImageText will be used when no imageId or imageSrc is provided.
It will be displayed inside the . This is useful when it is difficult
to make a preview for a type of DICOM series (e.g. DICOM-SR)
*/
altImageText: PropTypes.string,
SeriesDescription: PropTypes.string,
SeriesNumber: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
hasWarnings: PropTypes.instanceOf(Promise),
hasDerivedDisplaySets: PropTypes.instanceOf(Promise),
numImageFrames: PropTypes.number,
onDoubleClick: PropTypes.func,
onClick: PropTypes.func,
onMouseDown: PropTypes.func,
showProgressBar: PropTypes.bool,
};
Thumbnail.defaultProps = {
supportsDrag: false,
active: false,
error: false,
stackPercentComplete: 0,
onDoubleClick: noop,
onClick: noop,
onMouseDown: noop,
};
export { Thumbnail };