import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import { useDrag } from 'react-dnd'; import { Icons } from '../Icons'; import { DisplaySetMessageListTooltip } from '../DisplaySetMessageListTooltip'; import { TooltipTrigger, TooltipContent, Tooltip } from '../Tooltip'; const DraggableThumbnailContent = ({ dragData, children }: any) => { const [, drag] = useDrag({ type: 'displayset', item: { ...dragData }, canDrag: function () { return Object.keys(dragData).length !== 0; }, }); return (
{children}
); }; const StaticThumbnailContent = ({ children }: any) => { return
{children}
; }; /** * Display a thumbnail for a display set. */ const Thumbnail = ({ displaySetInstanceUID, className, children, imageSrc, imageAltText, description, seriesNumber, numInstances, loadingProgress, countIcon, messages, isActive, onClick, onDoubleClick, thumbnailType, modality, viewPreset = 'thumbnails', isHydratedForDerivedDisplaySet = false, isTracked = false, canReject = false, dragData = {}, isDraggable = true, onReject = () => {}, onClickUntrack = () => {}, ThumbnailMenuItems = () => {}, onImageLoadError = () => {}, }: withAppTypes): React.ReactNode => { const [lastTap, setLastTap] = useState(0); const [imageLoadFailed, setImageLoadFailed] = useState(false); useEffect(() => { setImageLoadFailed(false); }, [imageSrc]); const shouldRenderThumbnailImage = Boolean(imageSrc && !imageLoadFailed); const handleTouchEnd = e => { const currentTime = new Date().getTime(); const tapLength = currentTime - lastTap; if (tapLength < 300 && tapLength > 0) { onDoubleClick(e); } else { onClick(e); } setLastTap(currentTime); }; const renderThumbnailPreset = () => { return (
{shouldRenderThumbnailImage ? ( {imageAltText} { setImageLoadFailed(true); onImageLoadError(); }} /> ) : (
{children}
)} {/* bottom left */}
{modality}
{/* top right */}
{isTracked && (
{isTracked ? 'Series is tracked' : 'Series is untracked'}
)}
{/* bottom right */}
{description}
{description}
S:{seriesNumber}
{countIcon ? ( React.createElement(Icons[countIcon] || Icons.MissingIcon, { className: 'w-3' }) ) : ( )}
{numInstances}
); }; const renderListPreset = () => { return (
{modality}
{description}
{description}
S:{seriesNumber}
{' '} {countIcon ? ( React.createElement(Icons[countIcon] || Icons.MissingIcon, { className: 'w-3' }) ) : ( )}
{numInstances}
{isTracked && (
{isTracked ? 'Series is tracked' : 'Series is untracked'}
)}
); }; return (
{isDraggable ? ( {viewPreset === 'thumbnails' && renderThumbnailPreset()} {viewPreset === 'list' && renderListPreset()} ) : ( {viewPreset === 'thumbnails' && renderThumbnailPreset()} {viewPreset === 'list' && renderListPreset()} )}
); }; Thumbnail.propTypes = { displaySetInstanceUID: PropTypes.string.isRequired, className: PropTypes.string, children: PropTypes.node, imageSrc: PropTypes.string, /** * Data the thumbnail should expose to a receiving drop target. Use a matching * `dragData.type` to identify which targets can receive this draggable item. * If this is not set, drag-n-drop will be disabled for this thumbnail. * * Ref: https://react-dnd.github.io/react-dnd/docs/api/use-drag#specification-object-members */ dragData: PropTypes.shape({ /** Must match the "type" a dropTarget expects */ type: PropTypes.string.isRequired, }), imageAltText: PropTypes.string, description: PropTypes.string.isRequired, seriesNumber: PropTypes.any, numInstances: PropTypes.number.isRequired, loadingProgress: PropTypes.number, messages: PropTypes.object, isActive: PropTypes.bool.isRequired, onClick: PropTypes.func.isRequired, onDoubleClick: PropTypes.func.isRequired, viewPreset: PropTypes.string, modality: PropTypes.string, isHydratedForDerivedDisplaySet: PropTypes.bool, isTracked: PropTypes.bool, onClickUntrack: PropTypes.func, countIcon: PropTypes.string, isDraggable: PropTypes.bool, thumbnailType: PropTypes.oneOf(['thumbnail', 'thumbnailTracked', 'thumbnailNoImage']), onImageLoadError: PropTypes.func, }; export { Thumbnail };