diff --git a/src/hooks/useGetVaultEntityId.tsx b/src/hooks/useGetVaultEntityId.tsx new file mode 100644 index 00000000..6cc46320 --- /dev/null +++ b/src/hooks/useGetVaultEntityId.tsx @@ -0,0 +1,25 @@ +import { NormalizedEntity } from "@iiif/vault/*"; +import { useViewerState } from "src/context/viewer-context"; + +declare type ExtendedNormalizedEntity = NormalizedEntity & { id: string }; + +export default function useGetVaultEntityId(id?: string): string | undefined { + const { vault } = useViewerState(); + + try { + const entity: ExtendedNormalizedEntity | undefined | "" = + id && vault.get(id); + + if (!entity) throw new Error(`Vault entity ${id} not found.`); + + /** + * Vault seems to handle storage `id` and `@id` differently based on the entity type. + * Ex: Manifest level rendering items use `id` while Canvas level rendering items use `@id`. + * The following logic returns `@id` if it exists, otherwise falls back to `id`. + */ + return entity?.["@id"] || entity?.id; + } catch (error) { + console.error(error); + return id; + } +} diff --git a/src/hooks/useViewerDownload.tsx b/src/hooks/useViewerDownload.tsx index a14e8a5f..6fb098c8 100644 --- a/src/hooks/useViewerDownload.tsx +++ b/src/hooks/useViewerDownload.tsx @@ -1,5 +1,6 @@ import { RenderingItem } from "src/types/presentation-3"; import { getLabelAsString } from "src/lib/label-helpers"; +import useGetVaultEntityId from "src/hooks/useGetVaultEntityId"; import useRendering from "src/hooks/use-iiif/useRendering"; type DownloadItem = { @@ -12,11 +13,14 @@ function prepareDownloadLinks( items: RenderingItem[], defaultLabel: string, ): DownloadItem[] { - return items.map(({ format, id, label }) => ({ - format, - id, - label: getLabelAsString(label) || defaultLabel, - })); + return items.map(({ format, id, label }) => { + const resourceId = useGetVaultEntityId(id); + return { + format, + id: resourceId, + label: getLabelAsString(label) || defaultLabel, + }; + }); } export default function useViewerDownload() {