pdfjs
This commit is contained in:
@@ -62,7 +62,7 @@ const DesktopPreviewCard = ({
|
||||
}: DesktopPreviewCardProps): JSX.Element => {
|
||||
const navigator = useAssetNavigator({
|
||||
document: doc,
|
||||
assetType: 'preview',
|
||||
assetType: 'thumbnail',
|
||||
ensureAssetUrl: shouldLoad ? ensureAssetUrl : null,
|
||||
getAsset: getDocumentAsset,
|
||||
prefetch,
|
||||
|
||||
@@ -8,6 +8,7 @@ import React, {
|
||||
useSyncExternalStore,
|
||||
} from 'react';
|
||||
import { resolveDocumentAssetUrl } from '../asset_manager';
|
||||
import type { EnsureAssetUrl, GetAsset } from '../asset_manager';
|
||||
import { formatTransform } from './math';
|
||||
import useDocumentDrag from './useDocumentDrag';
|
||||
import PreviewZoomOverlay from '../detail/PreviewZoomOverlay';
|
||||
@@ -31,6 +32,8 @@ import '../styles/workspace/workspace-cards.css';
|
||||
type Identifier = string | number;
|
||||
|
||||
type TagLike = { id?: Identifier | null; label?: string; color?: string | null } | null;
|
||||
type PreviewEntryLike = { url?: string | null; contentType?: string | null };
|
||||
type OverlaySource = { url: string; alt?: string | null; contentType?: string | null };
|
||||
|
||||
export interface DeskDocument {
|
||||
id?: Identifier | null;
|
||||
@@ -49,6 +52,7 @@ interface NavigatorSnapshot {
|
||||
ordinal?: number | null;
|
||||
width?: number | null;
|
||||
height?: number | null;
|
||||
contentType?: string | null;
|
||||
}
|
||||
|
||||
type OverlayOriginHint = {
|
||||
@@ -124,8 +128,8 @@ interface DesktopWorkspaceProps {
|
||||
onDocumentStackSelect?: (docIds: Identifier[]) => void;
|
||||
onPromoteSelection?: (...args: unknown[]) => void;
|
||||
onAssignTagToDocument?: (...args: unknown[]) => void;
|
||||
ensureAssetUrl?: (...args: unknown[]) => Promise<unknown> | unknown;
|
||||
getDocumentAsset?: (...args: unknown[]) => unknown;
|
||||
ensureAssetUrl?: EnsureAssetUrl;
|
||||
getDocumentAsset?: GetAsset;
|
||||
activeTagIds?: Array<Identifier | null>;
|
||||
selectedDocumentIds?: Identifier[];
|
||||
onClearSelection?: () => void;
|
||||
@@ -193,6 +197,8 @@ interface DesktopWorkspaceViewProps {
|
||||
|
||||
const DEBUG_DRAG = false;
|
||||
const DEBUG_FOCUS = false;
|
||||
const defaultGetDocumentAsset: GetAsset = () => null;
|
||||
|
||||
const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
|
||||
documents = [],
|
||||
searchResults = null,
|
||||
@@ -202,7 +208,7 @@ const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
|
||||
onPromoteSelection = null,
|
||||
onAssignTagToDocument = null,
|
||||
ensureAssetUrl = null,
|
||||
getDocumentAsset = () => null,
|
||||
getDocumentAsset = defaultGetDocumentAsset,
|
||||
activeTagIds = [],
|
||||
selectedDocumentIds = [],
|
||||
onClearSelection = null,
|
||||
@@ -210,6 +216,8 @@ const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
|
||||
onCloseDetailPanel = null,
|
||||
tenantId = null,
|
||||
viewId = 'default',
|
||||
previewEntries,
|
||||
ensureDownloadUrl,
|
||||
}) => {
|
||||
const items = useMemo<DeskDocument[]>(
|
||||
() => (searchResults ? searchResults : documents),
|
||||
@@ -217,6 +225,7 @@ const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
|
||||
);
|
||||
|
||||
const allowLayoutPersistence = Boolean(tenantId && viewId && viewId.startsWith('folder:'));
|
||||
const previewEntryMap = previewEntries instanceof Map ? previewEntries : null;
|
||||
|
||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
const itemRefs = useRef<Map<string, HTMLDivElement | null>>(new Map());
|
||||
@@ -226,9 +235,8 @@ const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
|
||||
const [overlayOriginTransform, setOverlayOriginTransform] = useState<OverlayOriginTransform | null>(
|
||||
null,
|
||||
);
|
||||
const [previewSnapshots, setPreviewSnapshots] = useState<Map<string, NavigatorSnapshot>>(
|
||||
() => new Map(),
|
||||
);
|
||||
const [overlaySource, setOverlaySource] = useState<OverlaySource | null>(null);
|
||||
const [, setPreviewSnapshots] = useState<Map<string, NavigatorSnapshot>>(() => new Map());
|
||||
const [docSizeVersion, setDocSizeVersion] = useState(0);
|
||||
const docSizeMapRef = useRef<Map<string, DocumentSizeInfo>>(new Map());
|
||||
const ensureDocumentSize = useCallback((doc: DeskDocument | null): DocumentSizeInfo | null => {
|
||||
@@ -444,7 +452,7 @@ const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
|
||||
if (!doc) {
|
||||
return;
|
||||
}
|
||||
resolveDocumentAssetUrl(doc, 'preview', {
|
||||
resolveDocumentAssetUrl(doc, 'thumbnail', {
|
||||
ensureAssetUrl,
|
||||
getAsset: getDocumentAsset,
|
||||
});
|
||||
@@ -546,30 +554,77 @@ const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
|
||||
}
|
||||
}, [items, previewMetadata]);
|
||||
|
||||
const overlayDisplay = useMemo<OverlayDisplay | null>(() => {
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
if (!overlayDocId) {
|
||||
return null;
|
||||
setOverlaySource(null);
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}
|
||||
const snapshot = previewSnapshots.get(overlayDocId);
|
||||
if (!snapshot || !snapshot.url) {
|
||||
return null;
|
||||
|
||||
const doc = documentLookup.get(overlayDocId) || null;
|
||||
const docIdentifier = doc?.id ?? null;
|
||||
if (!docIdentifier || !doc) {
|
||||
setOverlaySource(null);
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}
|
||||
const doc = documentLookup.get(overlayDocId);
|
||||
const alt = snapshot.alt || (doc?.title as string | undefined);
|
||||
return {
|
||||
url: snapshot.url,
|
||||
alt,
|
||||
canGoPrev: snapshot.canGoPrev,
|
||||
canGoNext: snapshot.canGoNext,
|
||||
goPrev: snapshot.goPrev,
|
||||
goNext: snapshot.goNext,
|
||||
|
||||
const docContentType = doc?.content_type ?? null;
|
||||
const versionContentType = (doc?.current_version as { version?: { content_type?: string | null } } | null)?.version?.content_type ?? null;
|
||||
|
||||
const applyEntry = (entry?: PreviewEntryLike | null) => {
|
||||
if (!entry?.url) {
|
||||
setOverlaySource(null);
|
||||
return;
|
||||
}
|
||||
setOverlaySource({
|
||||
url: entry.url,
|
||||
alt: doc.title as string | undefined,
|
||||
contentType: entry.contentType || docContentType || versionContentType || undefined,
|
||||
});
|
||||
};
|
||||
}, [overlayDocId, previewSnapshots, documentLookup]);
|
||||
|
||||
const cachedEntry = previewEntryMap?.get(docIdentifier) || null;
|
||||
if (cachedEntry?.url) {
|
||||
applyEntry(cachedEntry);
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}
|
||||
|
||||
if (!ensureDownloadUrl) {
|
||||
setOverlaySource(null);
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}
|
||||
|
||||
ensureDownloadUrl(docIdentifier)
|
||||
.then((entry) => {
|
||||
if (cancelled) {
|
||||
return;
|
||||
}
|
||||
applyEntry(entry);
|
||||
})
|
||||
.catch(() => {
|
||||
if (!cancelled) {
|
||||
setOverlaySource(null);
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [overlayDocId, documentLookup, previewEntryMap, ensureDownloadUrl]);
|
||||
|
||||
const closeOverlay = useCallback(() => {
|
||||
setOverlayDocId(null);
|
||||
setOverlayOriginRect(null);
|
||||
setOverlayOriginTransform(null);
|
||||
setOverlaySource(null);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -611,24 +666,32 @@ const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
|
||||
}
|
||||
}, [draggingId, items, setDraggingId]);
|
||||
|
||||
const overlayDisplay = useMemo<OverlayDisplay | null>(() => {
|
||||
if (!overlaySource) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
...overlaySource,
|
||||
canGoPrev: false,
|
||||
canGoNext: false,
|
||||
};
|
||||
}, [overlaySource]);
|
||||
|
||||
const openOverlayForDoc = useCallback(
|
||||
(docId: Identifier | null, originInfo: OverlayOriginHint | null = null) => {
|
||||
if (!docId) {
|
||||
return;
|
||||
}
|
||||
const docKey = String(docId);
|
||||
const snapshot = previewSnapshots.get(docKey);
|
||||
if (!snapshot || !snapshot.url) {
|
||||
return;
|
||||
}
|
||||
const container = itemRefs.current.get(docKey);
|
||||
const imageNode = container
|
||||
? container.querySelector<HTMLImageElement>('.desk-item__card img')
|
||||
: null;
|
||||
if (!container || !imageNode) {
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
const imageNode = container.querySelector<HTMLImageElement>('.desk-item__card img');
|
||||
const rect = (imageNode || container).getBoundingClientRect();
|
||||
if (!rect) {
|
||||
return;
|
||||
}
|
||||
const rect = imageNode.getBoundingClientRect();
|
||||
let originTransform = null;
|
||||
if (originInfo) {
|
||||
const { rotation = 0, scale = 1, width: originWidth, height: originHeight } = originInfo;
|
||||
@@ -666,7 +729,6 @@ const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
|
||||
},
|
||||
[
|
||||
bringToFront,
|
||||
previewSnapshots,
|
||||
itemRefs,
|
||||
setOverlayOriginTransform,
|
||||
ensureDocumentSize,
|
||||
|
||||
@@ -61,6 +61,8 @@ interface UseDeskWorkspacePropsArgs {
|
||||
searchQuery?: string;
|
||||
activeCorrespondentFilters?: Identifier[];
|
||||
selectedFolder?: Identifier | string | null;
|
||||
previewEntries?: Map<Identifier, { url?: string | null; contentType?: string | null }>;
|
||||
ensureDownloadUrl?: (documentId: Identifier, options?: { force?: boolean }) => Promise<{ url?: string | null; contentType?: string | null } | null>;
|
||||
}
|
||||
|
||||
const useDeskWorkspaceProps = ({
|
||||
@@ -108,6 +110,8 @@ const useDeskWorkspaceProps = ({
|
||||
searchQuery = '',
|
||||
activeCorrespondentFilters = [],
|
||||
selectedFolder,
|
||||
previewEntries,
|
||||
ensureDownloadUrl,
|
||||
}: UseDeskWorkspacePropsArgs) => {
|
||||
const handleDeskDocumentStackSelect: DeskDocumentStackSelectHandler = useCallback(
|
||||
(docIds) => {
|
||||
@@ -200,6 +204,8 @@ const useDeskWorkspaceProps = ({
|
||||
onMoveDocumentsToFolder: moveDocumentsToFolder,
|
||||
searchIncludeDescendants,
|
||||
onToggleSearchIncludeDescendants: toggleSearchIncludeDescendants,
|
||||
previewEntries,
|
||||
ensureDownloadUrl,
|
||||
}),
|
||||
[
|
||||
documents,
|
||||
@@ -240,6 +246,8 @@ const useDeskWorkspaceProps = ({
|
||||
moveDocumentsToFolder,
|
||||
searchIncludeDescendants,
|
||||
toggleSearchIncludeDescendants,
|
||||
previewEntries,
|
||||
ensureDownloadUrl,
|
||||
],
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user