188 lines
5.1 KiB
TypeScript
188 lines
5.1 KiB
TypeScript
import { langEnum } from "../types/lang"
|
|
|
|
import type { GenericObjectType } from "@contentstack/app-sdk/dist/src/types/common.types"
|
|
import type {
|
|
Config,
|
|
FocalPoint,
|
|
ImageVaultAsset,
|
|
InsertResponse,
|
|
PublishDetails,
|
|
} from "../types/imagevault"
|
|
import type { Lang } from "../types/lang"
|
|
|
|
const metaIds = {
|
|
[langEnum.de]: { altText: 68, title: 77 },
|
|
[langEnum.da]: { altText: 67, title: 76 },
|
|
[langEnum.fi]: { altText: 70, title: 78 },
|
|
[langEnum.no]: { altText: 71, title: 79 },
|
|
[langEnum.sv]: { altText: 74, title: 82 },
|
|
[langEnum.en]: { altText: 69, title: 65 },
|
|
}
|
|
|
|
export function getMetaIds(lang: Lang) {
|
|
return metaIds[lang]
|
|
}
|
|
|
|
export type EntryDataPublishDetails = {
|
|
branch: string
|
|
contentTypeUid: string
|
|
locale: Lang
|
|
stackApiKey: string
|
|
title: string
|
|
uid: string
|
|
}
|
|
|
|
export function getPublishDetails(
|
|
baseUrl: string,
|
|
{
|
|
branch,
|
|
contentTypeUid,
|
|
locale,
|
|
stackApiKey,
|
|
title,
|
|
uid,
|
|
}: EntryDataPublishDetails
|
|
): PublishDetails {
|
|
const text = `${title} (${uid})`
|
|
const url = `${baseUrl}#!/stack/${stackApiKey}/content-type/${contentTypeUid}/${locale}/entry/${uid}/edit?branch=${branch}`
|
|
|
|
return { text, url }
|
|
}
|
|
|
|
export function isInsertResponse(
|
|
res: InsertResponse | GenericObjectType | null | undefined
|
|
): res is InsertResponse {
|
|
return (res as InsertResponse)?.MediaConversions !== undefined
|
|
}
|
|
|
|
export function isImageVaultAsset(
|
|
res: ImageVaultAsset | InsertResponse | GenericObjectType | null | undefined
|
|
): res is ImageVaultAsset {
|
|
return (res as ImageVaultAsset)?.url !== undefined
|
|
}
|
|
|
|
export type ImageVaultDAMConfig = {
|
|
imageVaultUrl: string
|
|
baseUrl: string
|
|
formatId: string
|
|
}
|
|
|
|
export function isImageVaultDAMConfig(
|
|
config: Record<string, string>
|
|
): config is ImageVaultDAMConfig {
|
|
return !!(config.baseUrl && config.formatId && config.imageVaultUrl)
|
|
}
|
|
|
|
// Utility function to get ImageVaultAsset from either InsertResponse or ImageVaultAsset
|
|
// Because we currently have both types saved in Contentstack, we need to account for both when retrieving the data of the asset.
|
|
export function getImageVaultAssetFromData(
|
|
data: InsertResponse | ImageVaultAsset | GenericObjectType | null | undefined
|
|
): ImageVaultAsset | null {
|
|
if (isImageVaultAsset(data)) {
|
|
return data
|
|
}
|
|
if (isInsertResponse(data)) {
|
|
return mapInsertResponseToImageVaultAsset(data, { x: 50, y: 50 })
|
|
}
|
|
return null
|
|
}
|
|
|
|
// Utility function to convert InsertResponse to ImageVaultAsset
|
|
function mapInsertResponseToImageVaultAsset(
|
|
response: InsertResponse,
|
|
focalPoint: FocalPoint
|
|
): ImageVaultAsset {
|
|
let image = response.MediaConversions.find(
|
|
(conversion) =>
|
|
conversion.MediaFormatName === "Original" &&
|
|
conversion.ContentType === "image/jpeg"
|
|
)
|
|
|
|
// We only receive one alt and title is in the response, depending on the language of the entry
|
|
// This is why we're getting the first one found
|
|
const alt =
|
|
response.Metadata?.find((meta) => meta.Name.includes("AltText_"))?.Value ||
|
|
""
|
|
const caption =
|
|
response.Metadata?.find((meta) => meta.Name.includes("Title_"))?.Value || ""
|
|
|
|
if (!image) {
|
|
const imageAsJpeg = response.MediaConversions.find(
|
|
(conversion) => conversion.ContentType === "image/jpeg"
|
|
)
|
|
image = imageAsJpeg || response.MediaConversions[0]
|
|
}
|
|
|
|
return {
|
|
imageVaultId: response.Id,
|
|
url: image.Url,
|
|
meta: {
|
|
alt,
|
|
caption,
|
|
},
|
|
fileName: response.Name,
|
|
dimensions: {
|
|
width: image.Width,
|
|
height: image.Height,
|
|
aspectRatio: image.AspectRatio,
|
|
},
|
|
focalPoint: response.FocalPoint || focalPoint,
|
|
}
|
|
}
|
|
|
|
export type openImageVaultParams = {
|
|
config: ImageVaultDAMConfig
|
|
entryData: EntryDataPublishDetails
|
|
onSuccess: (result: ImageVaultAsset) => void
|
|
onClose?: () => void
|
|
}
|
|
|
|
export function openImageVault({
|
|
config,
|
|
entryData,
|
|
onSuccess,
|
|
onClose,
|
|
}: openImageVaultParams) {
|
|
if (window.ImageVault) {
|
|
const publishDetails = getPublishDetails(config.baseUrl, entryData)
|
|
const metaIdsForLocale = getMetaIds(entryData.locale)
|
|
|
|
const insertMediaWindowOptions: Config = {
|
|
imageVaultUiUrl: config.imageVaultUrl,
|
|
uiLang: "en",
|
|
pageLang: "en",
|
|
publishingSource: config.baseUrl,
|
|
mediaUrlBase: config.imageVaultUrl,
|
|
formatId: config.formatId,
|
|
publishDetails,
|
|
insertMultiple: false,
|
|
success: (result) => {
|
|
const imageVaultAsset = mapInsertResponseToImageVaultAsset(
|
|
result.response,
|
|
{ x: 50, y: 50 }
|
|
)
|
|
onSuccess(imageVaultAsset)
|
|
},
|
|
close: () => {
|
|
if (typeof onClose === "function") {
|
|
onClose()
|
|
}
|
|
windowInserter.containerWindow?.close()
|
|
},
|
|
}
|
|
|
|
if (metaIdsForLocale) {
|
|
const additionalMetadataIds = Object.values(metaIdsForLocale).join(",")
|
|
insertMediaWindowOptions.additionalMetadataIds = additionalMetadataIds
|
|
}
|
|
|
|
const windowInserter = new window.ImageVault.InsertMediaWindow(
|
|
insertMediaWindowOptions,
|
|
`left=0,top=0,width=${window.screen.width},height=${window.screen.height}`
|
|
)
|
|
windowInserter.openImageVault()
|
|
} else {
|
|
console.error("Missing ImageVault global. ImageVault script not loaded?")
|
|
}
|
|
}
|