diff --git a/mysteries/barricelli-phone-note/mystery.json b/mysteries/barricelli-phone-note/mystery.json new file mode 100644 index 0000000..d21d636 --- /dev/null +++ b/mysteries/barricelli-phone-note/mystery.json @@ -0,0 +1,20 @@ +{ + "slug": "barricelli-phone-note", + "name": "Phone note", + "title": "Phone note", + "subtitle": "", + "brief": { "body": "", "concepts": [] }, + "documents": [], + "folders": [], + "notes": [ + { + "title": "Note", + "content": "PHONE FOR GLITCH HUNTER\n\nCall: 5550100", + "presentation": "luggage", + "x": 420, + "y": 260, + "width": 230, + "height": 180 + } + ] +} diff --git a/scripts/importMysteryTemplate.ts b/scripts/importMysteryTemplate.ts index 9987aef..12d448f 100644 --- a/scripts/importMysteryTemplate.ts +++ b/scripts/importMysteryTemplate.ts @@ -2,7 +2,7 @@ import { randomUUID } from 'node:crypto' import { readFile } from 'node:fs/promises' import path from 'node:path' import { fileURLToPath } from 'node:url' -import type { CaseDocument, CaseState, ClaimExhibit, DocumentCaptureKind, PartyKind, SourceFileType } from '../src/types.js' +import type { CaseDocument, CaseState, ClaimExhibit, DocumentCaptureKind, NoteExhibit, NotePresentation, PartyKind, SourceFileType } from '../src/types.js' type MysteryDocument = { key: string @@ -41,12 +41,13 @@ type MysteryManifest = { slug: string name: string title: string - subtitle: string + subtitle?: string timelineRange?: { start: string; end: string } - brief: { body: string; concepts: { label: string; context: string; expectedPartyKind: PartyKind }[] } - documents: MysteryDocument[] - folders: { key: string; title: string; content: string; x: number; y: number; width: number; members: string[] }[] + brief?: { body: string; concepts: { label: string; context: string; expectedPartyKind: PartyKind }[] } + documents?: MysteryDocument[] + folders?: { key: string; title: string; content: string; x: number; y: number; width: number; members: string[] }[] claims?: { key:string;statement:string;x:number;y:number;width?:number;height?:number }[] + notes?: { title?:string;content:string;presentation?:NotePresentation;x:number;y:number;width?:number;height?:number }[] report?: { title?:string;requiredForCompletion?:boolean } goals?: MysteryGoal[] evidenceMatchRules?: MysteryEvidenceMatchRule[] @@ -84,14 +85,15 @@ export async function importMysteryTemplate(manifestPath: string, baseUrl = 'htt const headers = { 'content-type': 'application/json', ...(authorization ? { authorization } : {}) } const createdResponse = await requireOk(await fetch(`${baseUrl}/api/levels`, { method: 'POST', headers, - body: JSON.stringify({ id: authoringId, title: manifest.title, subtitle: manifest.subtitle }), + body: JSON.stringify({ id: authoringId, title: manifest.title, subtitle: manifest.subtitle || '' }), }), 'Create authoring level') const state = await createdResponse.json() as CaseState const documentPositions = new Map() - manifest.folders.forEach((folder, folderIndex) => folder.members.forEach((key, memberIndex) => documentPositions.set(key, { x: folder.x + 70 + memberIndex * 205, y: folder.y + 230 + folderIndex * 35 }))) + const manifestFolders = manifest.folders || [] + manifestFolders.forEach((folder, folderIndex) => folder.members.forEach((key, memberIndex) => documentPositions.set(key, { x: folder.x + 70 + memberIndex * 205, y: folder.y + 230 + folderIndex * 35 }))) const documents = new Map() - for (const source of manifest.documents) { + for (const source of manifest.documents || []) { const uploaded = await uploadAsset(baseUrl, state.id, manifestDir, source, authorization) documents.set(source.key, { id: uploaded?.id || randomUUID(), type: 'document', title: source.title, publishedAt: source.publishedAt, @@ -103,17 +105,19 @@ export async function importMysteryTemplate(manifestPath: string, baseUrl = 'htt }) } - const folderIds = new Map(manifest.folders.map(folder => [folder.key, randomUUID()])) - state.brief = { body: manifest.brief.body, concepts: manifest.brief.concepts.map(concept => ({ id: randomUUID(), ...concept })) } + const folderIds = new Map(manifestFolders.map(folder => [folder.key, randomUUID()])) + if (manifest.brief) state.brief = { body: manifest.brief.body, concepts: manifest.brief.concepts.map(concept => ({ id: randomUUID(), ...concept })) } state.views = state.views.map(view => view.type === 'timeline' ? { ...view, rangeMode: manifest.timelineRange ? 'fixed' : 'auto', range: manifest.timelineRange } : view) - const folders = manifest.folders.map(folder => ({ + const folders = manifestFolders.map(folder => ({ id: folderIds.get(folder.key)!, type: 'folder', title: folder.title, content: folder.content, x: folder.x, y: folder.y, width: folder.width, height: 166, rotation: 0, zIndex: 1, hidden: false, isOpen: false, } as const)) const claims:ClaimExhibit[]=(manifest.claims || []).map(claim => ({ id:randomUUID(),type:'claim',title:claim.statement,statement:claim.statement, x:claim.x,y:claim.y,width:claim.width || 310,height:claim.height || 180,rotation:0,zIndex:2,hidden:false })) - state.exhibits = [...documents.values(), ...folders,...claims] - state.relations = manifest.folders.flatMap(folder => folder.members.map((key, memberIndex) => { + const notes:NoteExhibit[]=(manifest.notes || []).map(note => ({ id:randomUUID(),type:'note',title:note.title || 'NOTE',content:note.content, + presentation:note.presentation || 'luggage',x:note.x,y:note.y,width:note.width || 230,height:note.height || 180,rotation:0,zIndex:2,hidden:false })) + state.exhibits = [...documents.values(), ...folders,...claims,...notes] + state.relations = manifestFolders.flatMap(folder => folder.members.map((key, memberIndex) => { const document = documents.get(key) if (!document) throw new Error(`Folder ${folder.key} refers to unknown document ${key}`) return {