cleanup
This commit is contained in:
+17
-117
@@ -1,10 +1,10 @@
|
|||||||
import type { Identifier } from './types/identifiers';
|
import type { Identifier } from './types/identifiers';
|
||||||
import type { AssetObject, AssetLike } from './types/assets';
|
import type { Asset } from './types/assets';
|
||||||
import type { DocumentVersion, Document } from './types/documents';
|
import type { DocumentVersion, Document } from './types/documents';
|
||||||
|
|
||||||
type Nullable<T> = T | null;
|
type Nullable<T> = T | null;
|
||||||
|
|
||||||
export type { AssetObject, AssetLike, DocumentVersion as DocumentVersionLike, Document };
|
export type { Asset, DocumentVersion as DocumentVersionLike, Document };
|
||||||
|
|
||||||
export const resolveAssetExpiresAt = (asset?: { download?: { expires_at: number } | null } | null): number | null =>
|
export const resolveAssetExpiresAt = (asset?: { download?: { expires_at: number } | null } | null): number | null =>
|
||||||
asset?.download?.expires_at ?? null;
|
asset?.download?.expires_at ?? null;
|
||||||
@@ -14,16 +14,16 @@ export const resolveAssetUrl = (asset?: { download?: { url: string } | null } |
|
|||||||
|
|
||||||
export type EnsureAssetUrl = (
|
export type EnsureAssetUrl = (
|
||||||
documentId: Identifier,
|
documentId: Identifier,
|
||||||
asset: AssetLike,
|
asset: Asset,
|
||||||
options?: { force?: boolean;[key: string]: unknown },
|
options?: { force?: boolean;[key: string]: unknown },
|
||||||
) => Promise<unknown>;
|
) => Promise<unknown>;
|
||||||
|
|
||||||
export type GetAsset = (document: Document, assetType: string) => Nullable<AssetLike>;
|
export type GetAsset = (document: Document, assetType: string) => Nullable<Asset>;
|
||||||
|
|
||||||
export const getAssetFromGroup = (
|
export const getAssetFromGroup = (
|
||||||
assets?: AssetLike[] | Record<string, AssetLike> | null,
|
assets?: Asset[] | Record<string, Asset> | null,
|
||||||
assetType: string = '',
|
assetType: string = '',
|
||||||
): Nullable<AssetLike> => {
|
): Nullable<Asset> => {
|
||||||
if (!assetType || !assets) {
|
if (!assetType || !assets) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -42,97 +42,7 @@ export const getAssetFromVersion = (currentVersion: Nullable<DocumentVersion>, a
|
|||||||
return getAssetFromGroup(currentVersion.assets, assetType);
|
return getAssetFromGroup(currentVersion.assets, assetType);
|
||||||
};
|
};
|
||||||
|
|
||||||
const normalizeAssetObjects = (objects?: AssetObject[] | null): AssetObject[] => {
|
|
||||||
if (!Array.isArray(objects)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
return objects
|
|
||||||
.filter((entry) => Number.isInteger(entry?.ordinal))
|
|
||||||
.slice()
|
|
||||||
.sort((a, b) => a.ordinal - b.ordinal);
|
|
||||||
};
|
|
||||||
|
|
||||||
export class AssetView {
|
|
||||||
asset: AssetLike | null;
|
|
||||||
private _objectsRef: AssetObject[] | null;
|
|
||||||
private _sortedObjects: AssetObject[];
|
|
||||||
|
|
||||||
constructor(asset?: AssetLike | null) {
|
|
||||||
this.asset = asset || null;
|
|
||||||
this._objectsRef = null;
|
|
||||||
this._sortedObjects = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
getCardinality(): number {
|
|
||||||
if (!this.asset) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const objectsCount = this.getObjects().length;
|
|
||||||
if (objectsCount > 0) {
|
|
||||||
return objectsCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.asset.url || this.asset.metadata) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
getObjects(): AssetObject[] {
|
|
||||||
if (!this.asset || !Array.isArray(this.asset.objects) || this.asset.objects.length === 0) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._objectsRef === this.asset.objects) {
|
|
||||||
return this._sortedObjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._objectsRef = this.asset.objects;
|
|
||||||
this._sortedObjects = normalizeAssetObjects(this.asset.objects);
|
|
||||||
return this._sortedObjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
getObject(ordinal = 1): AssetObject | null {
|
|
||||||
const fromObjects = this.getObjects().find((entry) => entry.ordinal === ordinal);
|
|
||||||
if (fromObjects) {
|
|
||||||
return fromObjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ordinal === 1 && this.asset) {
|
|
||||||
const primaryUrl = resolveAssetUrl(this.asset);
|
|
||||||
if (primaryUrl || this.asset.metadata) {
|
|
||||||
return {
|
|
||||||
ordinal: 1,
|
|
||||||
url: primaryUrl || null,
|
|
||||||
metadata: this.asset.metadata || null,
|
|
||||||
expires_at: resolveAssetExpiresAt(this.asset),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
getPrimaryObject(): AssetObject | null {
|
|
||||||
return this.getObject(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
getPrimaryMetadata(): Record<string, unknown> | null {
|
|
||||||
return this.getPrimaryObject()?.metadata || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
getPrimaryUrl(): string | null {
|
|
||||||
return this.getPrimaryObject()?.url || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasObject(ordinal: number): boolean {
|
|
||||||
return Boolean(this.getObject(ordinal));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const createAssetView = (asset?: AssetLike | null): AssetView => new AssetView(asset);
|
|
||||||
|
|
||||||
export const resolveDocumentAssetUrl = (
|
export const resolveDocumentAssetUrl = (
|
||||||
doc: Nullable<Document>,
|
doc: Nullable<Document>,
|
||||||
@@ -154,10 +64,8 @@ export const resolveDocumentAssetUrl = (
|
|||||||
if (!asset) {
|
if (!asset) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const view = createAssetView(asset);
|
const url = resolveAssetUrl(asset);
|
||||||
const object = view.getPrimaryObject();
|
const expiresAt = resolveAssetExpiresAt(asset);
|
||||||
const url = object?.url || view.getPrimaryUrl();
|
|
||||||
const expiresAt = object?.expires_at ?? resolveAssetExpiresAt(asset);
|
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
if (url && (!expiresAt || expiresAt > now)) {
|
if (url && (!expiresAt || expiresAt > now)) {
|
||||||
return url;
|
return url;
|
||||||
@@ -174,22 +82,22 @@ export const resolveDocumentAssetUrl = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
class AssetManager {
|
class AssetManager {
|
||||||
fetchAsset: ((id: Identifier) => Promise<AssetLike | null>) | null;
|
fetchAsset: ((id: Identifier) => Promise<Asset | null>) | null;
|
||||||
|
|
||||||
assetCache: Map<Identifier, AssetLike>;
|
assetCache: Map<Identifier, Asset>;
|
||||||
assetInflight: Map<string, Promise<AssetLike | null>>;
|
assetInflight: Map<string, Promise<Asset | null>>;
|
||||||
|
|
||||||
constructor({ fetchAsset }: { fetchAsset: ((id: Identifier) => Promise<AssetLike | null>) | null }) {
|
constructor({ fetchAsset }: { fetchAsset: ((id: Identifier) => Promise<Asset | null>) | null }) {
|
||||||
this.fetchAsset = fetchAsset;
|
this.fetchAsset = fetchAsset;
|
||||||
this.assetCache = new Map();
|
this.assetCache = new Map();
|
||||||
this.assetInflight = new Map();
|
this.assetInflight = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
setFetchAsset(fetchAsset: ((id: Identifier) => Promise<AssetLike | null>) | null) {
|
setFetchAsset(fetchAsset: ((id: Identifier) => Promise<Asset | null>) | null) {
|
||||||
this.fetchAsset = fetchAsset;
|
this.fetchAsset = fetchAsset;
|
||||||
}
|
}
|
||||||
|
|
||||||
rememberAsset(entry?: Nullable<AssetLike>) {
|
rememberAsset(entry?: Nullable<Asset>) {
|
||||||
if (entry?.id) {
|
if (entry?.id) {
|
||||||
this.assetCache.set(entry.id, entry);
|
this.assetCache.set(entry.id, entry);
|
||||||
}
|
}
|
||||||
@@ -197,26 +105,18 @@ class AssetManager {
|
|||||||
|
|
||||||
ensureAsset(
|
ensureAsset(
|
||||||
documentId?: Identifier | null,
|
documentId?: Identifier | null,
|
||||||
asset?: Nullable<AssetLike>,
|
asset?: Nullable<Asset>,
|
||||||
{ force = false }: { force?: boolean } = {},
|
{ force = false }: { force?: boolean } = {},
|
||||||
): Promise<Nullable<AssetLike>> {
|
): Promise<Nullable<Asset>> {
|
||||||
if (!documentId || !asset?.id) {
|
if (!documentId || !asset?.id) {
|
||||||
return Promise.resolve(asset);
|
return Promise.resolve(asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseAsset = this.assetCache.get(asset.id) || asset;
|
const baseAsset = this.assetCache.get(asset.id) || asset;
|
||||||
const view = createAssetView(baseAsset);
|
|
||||||
const assetExpiresAt = resolveAssetExpiresAt(baseAsset);
|
const assetExpiresAt = resolveAssetExpiresAt(baseAsset);
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
|
|
||||||
const isPrimarySatisfied = () => {
|
const isPrimarySatisfied = () => {
|
||||||
const object = view.getObject(1);
|
|
||||||
if (object?.url) {
|
|
||||||
const objectExpiresAt = object.expires_at ?? null;
|
|
||||||
if (!objectExpiresAt || objectExpiresAt > now) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const assetUrl = resolveAssetUrl(baseAsset);
|
const assetUrl = resolveAssetUrl(baseAsset);
|
||||||
if (assetUrl && (!assetExpiresAt || assetExpiresAt > now)) {
|
if (assetUrl && (!assetExpiresAt || assetExpiresAt > now)) {
|
||||||
return true;
|
return true;
|
||||||
@@ -243,7 +143,7 @@ class AssetManager {
|
|||||||
return Promise.reject(new Error('AssetManager fetcher is not configured.'));
|
return Promise.reject(new Error('AssetManager fetcher is not configured.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const request: Promise<AssetLike | null> = this.fetchAsset(asset.id)
|
const request: Promise<Asset | null> = this.fetchAsset(asset.id)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (!data) return null;
|
if (!data) return null;
|
||||||
const cachedEntry = this.assetCache.get(asset.id) || baseAsset;
|
const cachedEntry = this.assetCache.get(asset.id) || baseAsset;
|
||||||
|
|||||||
@@ -1,24 +1,18 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect, useMemo } from 'react';
|
||||||
import type { JSX } from 'react';
|
import type { JSX } from 'react';
|
||||||
import { useAssetNavigator } from '../hooks/useAssetNavigator';
|
import { resolveDocumentAssetUrl } from '../asset_manager';
|
||||||
import type { Identifier } from '../types/identifiers';
|
import type { Identifier } from '../types/identifiers';
|
||||||
import type { Document } from '../types/documents';
|
import type { Document } from '../types/documents';
|
||||||
|
|
||||||
interface AssetLike {
|
import type { Asset } from '../types/assets';
|
||||||
id?: Identifier;
|
|
||||||
url?: string | null;
|
|
||||||
expires_at?: number | null;
|
|
||||||
metadata?: Record<string, unknown> | null;
|
|
||||||
[key: string]: unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
type EnsureAssetUrl = (
|
type EnsureAssetUrl = (
|
||||||
documentId: Identifier,
|
documentId: Identifier,
|
||||||
asset: AssetLike,
|
asset: Asset,
|
||||||
options?: { force?: boolean;[key: string]: unknown },
|
options?: { force?: boolean;[key: string]: unknown },
|
||||||
) => Promise<unknown>;
|
) => Promise<unknown>;
|
||||||
|
|
||||||
type GetDocumentAsset = (document: Document | null, assetType: string) => AssetLike | null;
|
type GetDocumentAsset = (document: Document | null, assetType: string) => Asset | null;
|
||||||
|
|
||||||
interface NavigatorSnapshot {
|
interface NavigatorSnapshot {
|
||||||
url: string | null;
|
url: string | null;
|
||||||
@@ -44,14 +38,19 @@ const DesktopPreviewCard = ({
|
|||||||
onNavigatorSnapshot,
|
onNavigatorSnapshot,
|
||||||
shouldLoad = true,
|
shouldLoad = true,
|
||||||
}: DesktopPreviewCardProps): JSX.Element => {
|
}: DesktopPreviewCardProps): JSX.Element => {
|
||||||
const navigator = useAssetNavigator({
|
const currentUrl = useMemo(() => {
|
||||||
document: doc,
|
if (!doc) return null;
|
||||||
assetType: 'thumbnail',
|
return resolveDocumentAssetUrl(doc, 'thumbnail', {
|
||||||
ensureAssetUrl: shouldLoad ? ensureAssetUrl : null,
|
ensureAssetUrl: shouldLoad && ensureAssetUrl ? ensureAssetUrl : undefined,
|
||||||
getAsset: getDocumentAsset,
|
getAsset: getDocumentAsset,
|
||||||
});
|
});
|
||||||
|
}, [doc, ensureAssetUrl, getDocumentAsset, shouldLoad]);
|
||||||
|
|
||||||
const { currentUrl, currentMetadata } = navigator;
|
const currentMetadata = useMemo(() => {
|
||||||
|
if (!doc || !getDocumentAsset) return null;
|
||||||
|
const asset = getDocumentAsset(doc, 'thumbnail');
|
||||||
|
return asset?.metadata || null;
|
||||||
|
}, [doc, getDocumentAsset]);
|
||||||
const docId = doc?.id ?? null;
|
const docId = doc?.id ?? null;
|
||||||
|
|
||||||
const metadataWidth = Number((currentMetadata as { width?: number } | null)?.width);
|
const metadataWidth = Number((currentMetadata as { width?: number } | null)?.width);
|
||||||
|
|||||||
@@ -2,10 +2,7 @@ import { useEffect, useState, useRef } from 'react';
|
|||||||
import type { DocumentId } from '../../types/identifiers';
|
import type { DocumentId } from '../../types/identifiers';
|
||||||
import type { Document } from '../../types/documents';
|
import type { Document } from '../../types/documents';
|
||||||
|
|
||||||
interface AssetLike {
|
import type { Asset } from '../../types/assets';
|
||||||
id?: string;
|
|
||||||
[key: string]: unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PreviewMetadataEntry {
|
interface PreviewMetadataEntry {
|
||||||
docId: DocumentId;
|
docId: DocumentId;
|
||||||
@@ -13,8 +10,8 @@ interface PreviewMetadataEntry {
|
|||||||
height: number;
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetDocumentAsset = (doc: Document, type: string) => AssetLike | null;
|
type GetDocumentAsset = (doc: Document, type: string) => Asset | null;
|
||||||
type EnsureAssetUrl = (docId: DocumentId, asset: AssetLike, options?: { force?: boolean }) => Promise<AssetLike | null>;
|
type EnsureAssetUrl = (docId: DocumentId, asset: Asset, options?: { force?: boolean }) => Promise<Asset | null>;
|
||||||
|
|
||||||
const usePreviewMetadata = (
|
const usePreviewMetadata = (
|
||||||
documents: Document[] | null,
|
documents: Document[] | null,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
} from '../asset_manager';
|
} from '../asset_manager';
|
||||||
import { DEFAULT_THUMBNAIL_SIZE } from '../constants/documents';
|
import { DEFAULT_THUMBNAIL_SIZE } from '../constants/documents';
|
||||||
import type {
|
import type {
|
||||||
AssetLike as AssetManagerAssetLike,
|
Asset as AssetManagerAsset,
|
||||||
EnsureAssetUrl as AssetManagerEnsureAssetUrl,
|
EnsureAssetUrl as AssetManagerEnsureAssetUrl,
|
||||||
GetAsset as AssetManagerGetAsset,
|
GetAsset as AssetManagerGetAsset,
|
||||||
} from '../asset_manager';
|
} from '../asset_manager';
|
||||||
@@ -72,7 +72,7 @@ const getPageCount = (doc?: Document | null) => {
|
|||||||
return Number.isFinite(count) ? Number(count) : null;
|
return Number.isFinite(count) ? Number(count) : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
type AssetLike = AssetManagerAssetLike;
|
type Asset = AssetManagerAsset;
|
||||||
type EnsureAssetUrl = AssetManagerEnsureAssetUrl;
|
type EnsureAssetUrl = AssetManagerEnsureAssetUrl;
|
||||||
type GetDocumentAsset = AssetManagerGetAsset;
|
type GetDocumentAsset = AssetManagerGetAsset;
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ const DocumentThumbnailImage = ({
|
|||||||
const { ref: visibilityRef, isVisible } = useLazyVisibility(scrollRootRef, documentId);
|
const { ref: visibilityRef, isVisible } = useLazyVisibility(scrollRootRef, documentId);
|
||||||
const resolvedMaxSize = Math.max(1, Math.round(maxSize || 1));
|
const resolvedMaxSize = Math.max(1, Math.round(maxSize || 1));
|
||||||
|
|
||||||
const thumbnailAsset = useMemo<AssetLike | null>(
|
const thumbnailAsset = useMemo<Asset | null>(
|
||||||
() => getAssetFromVersion(document?.current_version, 'thumbnail'),
|
() => getAssetFromVersion(document?.current_version, 'thumbnail'),
|
||||||
[document?.current_version],
|
[document?.current_version],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,113 +0,0 @@
|
|||||||
|
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
|
||||||
import { resolveAssetUrl } from '../asset_manager';
|
|
||||||
import type { Identifier } from '../types/identifiers';
|
|
||||||
import type { Document } from '../types/documents';
|
|
||||||
|
|
||||||
type AssetObject = {
|
|
||||||
url?: string | null;
|
|
||||||
metadata?: Record<string, unknown> | null;
|
|
||||||
expires_at?: number | null;
|
|
||||||
[key: string]: unknown;
|
|
||||||
};
|
|
||||||
|
|
||||||
type AssetLike = {
|
|
||||||
id?: Identifier;
|
|
||||||
url?: string | null;
|
|
||||||
expires_at?: number | null;
|
|
||||||
metadata?: Record<string, unknown> | null;
|
|
||||||
objects?: AssetObject[];
|
|
||||||
[key: string]: unknown;
|
|
||||||
};
|
|
||||||
|
|
||||||
type EnsureAssetUrl = (
|
|
||||||
documentId: Identifier,
|
|
||||||
asset: AssetLike,
|
|
||||||
options?: { force?: boolean;[key: string]: unknown },
|
|
||||||
) => Promise<unknown>;
|
|
||||||
|
|
||||||
type GetAsset = (document: Document, assetType: string) => AssetLike | null;
|
|
||||||
|
|
||||||
type AssetViewLike = {
|
|
||||||
url: string | null;
|
|
||||||
metadata: Record<string, unknown> | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
interface UseAssetNavigatorOptions {
|
|
||||||
document?: Document | null;
|
|
||||||
assetType: string;
|
|
||||||
ensureAssetUrl?: EnsureAssetUrl | null;
|
|
||||||
getAsset?: GetAsset;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface AssetNavigatorReturn {
|
|
||||||
document: Document | null;
|
|
||||||
documentId: Identifier | null;
|
|
||||||
asset: AssetLike | null;
|
|
||||||
assetType: string;
|
|
||||||
currentUrl: string | null;
|
|
||||||
currentMetadata: Record<string, unknown> | null;
|
|
||||||
isLoading: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useAssetNavigator = ({
|
|
||||||
document,
|
|
||||||
assetType,
|
|
||||||
ensureAssetUrl,
|
|
||||||
getAsset,
|
|
||||||
}: UseAssetNavigatorOptions): AssetNavigatorReturn => {
|
|
||||||
const documentId = (document?.id ?? null) as Identifier | null;
|
|
||||||
|
|
||||||
const asset = useMemo<AssetLike | null>(() => {
|
|
||||||
if (!document || !getAsset) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return getAsset(document, assetType) || null;
|
|
||||||
}, [document, assetType, getAsset]);
|
|
||||||
|
|
||||||
const view = useMemo<AssetViewLike>(
|
|
||||||
() => ({
|
|
||||||
url: resolveAssetUrl(asset),
|
|
||||||
metadata: (asset?.metadata as Record<string, unknown> | null) || null,
|
|
||||||
}),
|
|
||||||
[asset],
|
|
||||||
);
|
|
||||||
|
|
||||||
const currentUrl = view.url || null;
|
|
||||||
const currentMetadata = view.metadata || null;
|
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!ensureAssetUrl || !documentId || !asset) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (currentUrl) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
let cancelled = false;
|
|
||||||
setIsLoading(true);
|
|
||||||
ensureAssetUrl(documentId, asset, { force: true })
|
|
||||||
.catch(() => { })
|
|
||||||
.finally(() => {
|
|
||||||
if (!cancelled) {
|
|
||||||
setIsLoading(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return () => {
|
|
||||||
cancelled = true;
|
|
||||||
};
|
|
||||||
}, [asset, currentUrl, documentId, ensureAssetUrl]);
|
|
||||||
|
|
||||||
return {
|
|
||||||
document,
|
|
||||||
documentId,
|
|
||||||
asset,
|
|
||||||
assetType,
|
|
||||||
currentUrl,
|
|
||||||
currentMetadata,
|
|
||||||
isLoading,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useAssetNavigator;
|
|
||||||
@@ -27,14 +27,15 @@ import useViewerLayoutMode from './useViewerLayoutMode';
|
|||||||
import { usePanelResizeBindings } from '../app/PanelManagerContext';
|
import { usePanelResizeBindings } from '../app/PanelManagerContext';
|
||||||
import type { DocumentId, FolderId } from '../types/identifiers';
|
import type { DocumentId, FolderId } from '../types/identifiers';
|
||||||
import type { Document } from '../types/documents';
|
import type { Document } from '../types/documents';
|
||||||
import type { AssetLike } from '../types/assets';
|
import type { Asset } from '../types/assets';
|
||||||
|
|
||||||
type SidebarMode = 'overlay' | 'inline';
|
type SidebarMode = 'overlay' | 'inline';
|
||||||
|
|
||||||
interface DocumentViewerPanelProps extends DocumentSummarySectionProps {
|
interface DocumentViewerPanelProps extends DocumentSummarySectionProps {
|
||||||
document: Document | null;
|
document: Document | null;
|
||||||
ensureAssetUrl?: (docId: DocumentId, asset: AssetLike, options?: { force?: boolean }) => Promise<unknown>;
|
|
||||||
getDocumentAsset?: (doc: Document | null, type: string) => AssetLike | null;
|
ensureAssetUrl?: (documentId: DocumentId, asset: Asset, options?: { force?: boolean }) => Promise<unknown>;
|
||||||
|
getDocumentAsset?: (doc: Document | null, type: string) => Asset | null;
|
||||||
ensurePreviewData?: (docId: DocumentId, options?: { signal?: AbortSignal }) => Promise<Document | null>;
|
ensurePreviewData?: (docId: DocumentId, options?: { signal?: AbortSignal }) => Promise<Document | null>;
|
||||||
notifyApiError?: (error: unknown, fallbackMessage?: string) => void;
|
notifyApiError?: (error: unknown, fallbackMessage?: string) => void;
|
||||||
sidebarToggle?: ReactNode;
|
sidebarToggle?: ReactNode;
|
||||||
|
|||||||
@@ -1,21 +1,10 @@
|
|||||||
import type { Identifier } from './identifiers';
|
import type { Identifier } from './identifiers';
|
||||||
import type { Download } from './common';
|
import type { Download } from './common';
|
||||||
|
|
||||||
export interface AssetObject {
|
export interface Asset {
|
||||||
ordinal?: number;
|
|
||||||
url?: string | null;
|
|
||||||
metadata?: Record<string, unknown> | null;
|
|
||||||
expires_at?: number;
|
|
||||||
[key: string]: unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AssetLike {
|
|
||||||
id?: Identifier;
|
id?: Identifier;
|
||||||
asset_type?: string;
|
asset_type?: string;
|
||||||
cardinality?: number | null;
|
|
||||||
download?: Download | null;
|
download?: Download | null;
|
||||||
metadata?: Record<string, unknown> | null;
|
metadata?: Record<string, unknown> | null;
|
||||||
assets?: Record<string, AssetLike> | AssetLike[] | null;
|
|
||||||
objects?: AssetObject[] | null;
|
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { Identifier } from './identifiers';
|
import type { Identifier } from './identifiers';
|
||||||
import type { AssetLike } from './assets';
|
import type { Asset } from './assets';
|
||||||
import type { Download } from './common';
|
import type { Download } from './common';
|
||||||
|
|
||||||
export interface DocumentTag {
|
export interface DocumentTag {
|
||||||
@@ -15,7 +15,7 @@ export interface DocumentCorrespondent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface DocumentVersion {
|
export interface DocumentVersion {
|
||||||
assets?: Record<string, AssetLike> | AssetLike[] | null;
|
assets?: Record<string, Asset> | Asset[] | null;
|
||||||
metadata?: Record<string, unknown> & { page_count?: number } | null;
|
metadata?: Record<string, unknown> & { page_count?: number } | null;
|
||||||
size_bytes?: number | string | null;
|
size_bytes?: number | string | null;
|
||||||
checksum?: string | null;
|
checksum?: string | null;
|
||||||
|
|||||||
@@ -6,16 +6,16 @@ import type {
|
|||||||
Document,
|
Document,
|
||||||
DocumentVersion,
|
DocumentVersion,
|
||||||
} from '../types/documents';
|
} from '../types/documents';
|
||||||
import type { AssetLike } from '../types/assets';
|
import type { Asset } from '../types/assets';
|
||||||
|
|
||||||
export type { Document, DocumentVersion, AssetLike };
|
export type { Document, DocumentVersion, Asset };
|
||||||
|
|
||||||
export type EnsurePreviewData = (id: string) => Promise<Document | null>;
|
export type EnsurePreviewData = (id: string) => Promise<Document | null>;
|
||||||
export type EnsureAssetUrl = (
|
export type EnsureAssetUrl = (
|
||||||
id: string,
|
id: string,
|
||||||
asset: AssetLike,
|
asset: Asset,
|
||||||
options?: { force?: boolean },
|
options?: { force?: boolean },
|
||||||
) => Promise<AssetLike | null>;
|
) => Promise<Asset | null>;
|
||||||
export type GetDocumentAsset = AssetManagerGetAsset;
|
export type GetDocumentAsset = AssetManagerGetAsset;
|
||||||
|
|
||||||
interface ResolveTextContentUrlOptions {
|
interface ResolveTextContentUrlOptions {
|
||||||
@@ -25,7 +25,7 @@ interface ResolveTextContentUrlOptions {
|
|||||||
ensureAssetUrl?: EnsureAssetUrl;
|
ensureAssetUrl?: EnsureAssetUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pickAsset = (doc?: Document | null, getDocumentAsset?: GetDocumentAsset): AssetLike | null => {
|
const pickAsset = (doc?: Document | null, getDocumentAsset?: GetDocumentAsset): Asset | null => {
|
||||||
if (!doc || !getDocumentAsset) {
|
if (!doc || !getDocumentAsset) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@ export async function resolveTextContentUrl({
|
|||||||
const baseUrl = resolveAssetUrl(asset);
|
const baseUrl = resolveAssetUrl(asset);
|
||||||
const hasUrl = Boolean(baseUrl);
|
const hasUrl = Boolean(baseUrl);
|
||||||
|
|
||||||
let entry: AssetLike = asset;
|
let entry: Asset = asset;
|
||||||
if (ensureAssetUrl) {
|
if (ensureAssetUrl) {
|
||||||
const ensureOptions = { force: !hasUrl };
|
const ensureOptions = { force: !hasUrl };
|
||||||
const ensured = await ensureAssetUrl(docRef.id!, asset, ensureOptions);
|
const ensured = await ensureAssetUrl(docRef.id!, asset, ensureOptions);
|
||||||
|
|||||||
Reference in New Issue
Block a user