147 lines
3.5 KiB
TypeScript
147 lines
3.5 KiB
TypeScript
import { createAssetView, resolveDocumentAssetUrl } from '../asset_manager';
|
|
import type {
|
|
DocumentLike as AssetManagerDocumentLike,
|
|
DocumentVersionLike,
|
|
AssetLike as AssetManagerAssetLike,
|
|
GetAsset as AssetManagerGetAsset,
|
|
} from '../asset_manager';
|
|
|
|
const BASE_FETCH_OPTIONS = { start: 1, limit: 1 } as const;
|
|
|
|
interface DocumentVersion extends DocumentVersionLike {
|
|
download_path?: string | null;
|
|
}
|
|
|
|
export interface DocumentLike extends AssetManagerDocumentLike {
|
|
current_version?: DocumentVersion | null;
|
|
}
|
|
|
|
export type AssetLike = AssetManagerAssetLike;
|
|
|
|
export type EnsurePreviewData = (id: string | number) => Promise<DocumentLike | null | undefined>;
|
|
export type EnsureAssetUrl = (
|
|
id: string | number,
|
|
asset: AssetLike,
|
|
options?: { start?: number; limit?: number; force?: boolean },
|
|
) => Promise<AssetLike | null | undefined>;
|
|
export type GetDocumentAsset = AssetManagerGetAsset;
|
|
|
|
interface ResolveOcrTextUrlOptions {
|
|
document: DocumentLike | null;
|
|
ensurePreviewData?: EnsurePreviewData;
|
|
getDocumentAsset?: GetDocumentAsset;
|
|
ensureAssetUrl?: EnsureAssetUrl;
|
|
}
|
|
|
|
const pickAsset = (doc: DocumentLike | null | undefined, getDocumentAsset?: GetDocumentAsset): AssetLike | null => {
|
|
if (!doc || !getDocumentAsset) {
|
|
return null;
|
|
}
|
|
return getDocumentAsset(doc, 'ocr-text') || null;
|
|
};
|
|
|
|
export async function resolveOcrTextUrl({
|
|
document,
|
|
ensurePreviewData,
|
|
getDocumentAsset,
|
|
ensureAssetUrl,
|
|
}: ResolveOcrTextUrlOptions): Promise<string | null> {
|
|
if (!document?.id) {
|
|
return null;
|
|
}
|
|
|
|
let docRef = document;
|
|
let asset = pickAsset(docRef, getDocumentAsset);
|
|
|
|
if (!asset && ensurePreviewData) {
|
|
const refreshed = await ensurePreviewData(docRef.id);
|
|
if (refreshed) {
|
|
docRef = refreshed;
|
|
}
|
|
asset = pickAsset(docRef, getDocumentAsset);
|
|
}
|
|
|
|
if (!asset) {
|
|
return null;
|
|
}
|
|
|
|
const baseView = createAssetView(asset);
|
|
const hasUrl = Boolean(baseView.getPrimaryUrl());
|
|
|
|
let entry: AssetLike = asset;
|
|
if (ensureAssetUrl) {
|
|
const ensureOptions = { ...BASE_FETCH_OPTIONS, force: !hasUrl };
|
|
const ensured = await ensureAssetUrl(docRef.id!, asset, ensureOptions);
|
|
if (ensured) {
|
|
entry = ensured;
|
|
}
|
|
}
|
|
|
|
const ensuredView = createAssetView(entry);
|
|
const directUrl = ensuredView.getPrimaryUrl();
|
|
if (directUrl) {
|
|
return directUrl;
|
|
}
|
|
|
|
return (
|
|
resolveDocumentAssetUrl(docRef, 'ocr-text', {
|
|
ensureAssetUrl,
|
|
getAsset: getDocumentAsset,
|
|
ensureOptions: { ...BASE_FETCH_OPTIONS, force: true },
|
|
objectOrdinal: 1,
|
|
}) || null
|
|
);
|
|
}
|
|
|
|
export async function openOcrTextInNewTab(options: ResolveOcrTextUrlOptions): Promise<boolean> {
|
|
const popup = window.open('', '_blank');
|
|
const popupAvailable = Boolean(popup);
|
|
|
|
if (popupAvailable) {
|
|
try {
|
|
popup.opener = null;
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
}
|
|
|
|
try {
|
|
const url = await resolveOcrTextUrl(options);
|
|
if (!url) {
|
|
if (popupAvailable) {
|
|
popup.close();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
if (popupAvailable) {
|
|
try {
|
|
popup.location.replace(url);
|
|
} catch {
|
|
try {
|
|
popup.location.href = url;
|
|
} catch (secondError) {
|
|
popup.close();
|
|
throw secondError;
|
|
}
|
|
}
|
|
} else {
|
|
const finalWindow = window.open(url, '_blank');
|
|
if (finalWindow) {
|
|
try {
|
|
finalWindow.opener = null;
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
} catch (error) {
|
|
if (popupAvailable) {
|
|
popup.close();
|
|
}
|
|
throw error;
|
|
}
|
|
}
|