import { type PropertyBag, type PropertyValue, textOf } from '../model/Properties'; import { findPixelFrame } from '../model/pixelart'; import { findAsset, type Project } from '../model/Project'; import { findFrame } from '../model/texture'; import { isKindWith } from './kinds'; import type { PropertyDef } from './PropertySchema'; /** * The asset a reference field points at, null when it names nothing or no longer resolves. A frame * names the texture or pixel art it was cut from – that is the asset one can open (#221). */ export function referencedAssetId(project: Project, def: PropertyDef, value: PropertyValue): string | null { if (!isKindWith('reference', def.kind)) return null; const id = textOf(value); if (id === '') return null; if (findAsset(project, id)) return id; if (def.kind !== 'texture') return null; return findFrame(project, id)?.asset.id ?? findPixelFrame(project, id)?.asset.id ?? null; } export interface Reference { label: string; assetId: string; } /** Every reference of a bag that resolves, in schema order – the "Open …" entries of a menu. */ export function referencesOf( project: Project, schema: readonly PropertyDef[], values: PropertyBag, ): Reference[] { return schema.flatMap((def) => { const value = values[def.key]; const assetId = value === undefined ? null : referencedAssetId(project, def, value); return assetId ? [{ label: def.label, assetId }] : []; }); }