feat: Add Download type and document download field, unify preview zoom styling
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { createContext, useContext, useState, useCallback, useMemo, useEffect } from 'react';
|
||||
import React, { createContext, useContext, useState, useCallback, useMemo, useRef } from 'react';
|
||||
import PreviewZoomOverlay from '../detail/PreviewZoomOverlay';
|
||||
import type { Document } from '../types/documents';
|
||||
import type { Identifier } from '../types/identifiers';
|
||||
@@ -20,21 +20,26 @@ export const usePreviewContext = () => {
|
||||
|
||||
interface PreviewProviderProps {
|
||||
children: React.ReactNode;
|
||||
ensureDownloadUrl?: (docId: Identifier) => Promise<any>;
|
||||
onNavigate?: (documentId: Identifier) => void;
|
||||
}
|
||||
|
||||
export const PreviewProvider: React.FC<PreviewProviderProps> = ({ children, ensureDownloadUrl, onNavigate }) => {
|
||||
export const PreviewProvider: React.FC<PreviewProviderProps> = ({ children, onNavigate }) => {
|
||||
const [previewDoc, setPreviewDoc] = useState<Document | null>(null);
|
||||
const [previewUrl, setPreviewUrl] = useState<string | null>(null);
|
||||
const lastFocusedElement = useRef<HTMLElement | null>(null);
|
||||
|
||||
const openPreview = useCallback((doc: Document) => {
|
||||
if (!lastFocusedElement.current) {
|
||||
lastFocusedElement.current = document.activeElement as HTMLElement;
|
||||
}
|
||||
setPreviewDoc(doc);
|
||||
}, []);
|
||||
|
||||
const closePreview = useCallback(() => {
|
||||
setPreviewDoc(null);
|
||||
setPreviewUrl(null);
|
||||
if (lastFocusedElement.current) {
|
||||
lastFocusedElement.current.focus();
|
||||
lastFocusedElement.current = null;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleMaximize = useCallback(() => {
|
||||
@@ -44,46 +49,6 @@ export const PreviewProvider: React.FC<PreviewProviderProps> = ({ children, ensu
|
||||
}
|
||||
}, [previewDoc, onNavigate, closePreview]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!previewDoc) {
|
||||
setPreviewUrl(null);
|
||||
return;
|
||||
}
|
||||
|
||||
let cancelled = false;
|
||||
if (ensureDownloadUrl) {
|
||||
ensureDownloadUrl(previewDoc.id)
|
||||
.then((entry) => {
|
||||
if (!cancelled && entry?.url) {
|
||||
setPreviewUrl(entry.url);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
if (!cancelled) {
|
||||
setPreviewUrl(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [previewDoc, ensureDownloadUrl]);
|
||||
|
||||
const overlayDocument = useMemo(() => {
|
||||
if (!previewDoc || !previewUrl) {
|
||||
return previewDoc;
|
||||
}
|
||||
return {
|
||||
...previewDoc,
|
||||
documentLink: {
|
||||
url: previewUrl,
|
||||
alt: previewDoc.title,
|
||||
mimeType: previewDoc.mime_type,
|
||||
},
|
||||
};
|
||||
}, [previewDoc, previewUrl]);
|
||||
|
||||
const value = useMemo(() => ({
|
||||
openPreview,
|
||||
closePreview,
|
||||
@@ -93,10 +58,10 @@ export const PreviewProvider: React.FC<PreviewProviderProps> = ({ children, ensu
|
||||
<PreviewContext.Provider value={value}>
|
||||
{children}
|
||||
<PreviewZoomOverlay
|
||||
open={Boolean(previewUrl)}
|
||||
open={Boolean(previewDoc)}
|
||||
onClose={closePreview}
|
||||
onMaximize={onNavigate ? handleMaximize : undefined}
|
||||
document={overlayDocument}
|
||||
document={previewDoc}
|
||||
/>
|
||||
</PreviewContext.Provider>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user