diff --git a/apps/dotcom/client/src/tla/app/TldrawApp.ts b/apps/dotcom/client/src/tla/app/TldrawApp.ts index efb60a198084..1c9df267a6dc 100644 --- a/apps/dotcom/client/src/tla/app/TldrawApp.ts +++ b/apps/dotcom/client/src/tla/app/TldrawApp.ts @@ -12,6 +12,7 @@ import { Result, assert, fetch, structuredClone, throttle, uniqueId } from '@tld import pick from 'lodash.pick' import { Signal, + TLDocument, TLSessionStateSnapshot, TLStoreSnapshot, TLUiToastsContextType, @@ -22,6 +23,7 @@ import { createTLUser, defaultUserPreferences, getUserPreferences, + isDocument, objectMapFromEntries, objectMapKeys, react, @@ -245,9 +247,9 @@ export class TldrawApp { return numberOfFiles < this.config.maxNumberOfFiles } - async createFile( + createFile( fileOrId?: string | Partial - ): Promise> { + ): Result<{ file: TlaFile }, 'max number of files reached'> { if (!this.canCreateNewFile()) { return Result.err('max number of files reached') } @@ -355,7 +357,19 @@ export class TldrawApp { // Also create a file state record for the new file this.z.mutate((tx) => { - for (const slug of response.slugs) { + for (let i = 0; i < response.slugs.length; i++) { + const slug = response.slugs[i] + const entries = Object.entries(snapshots[i].store) + const documentEntry = entries.find(([_, value]) => isDocument(value)) as + | [string, TLDocument] + | undefined + const name = documentEntry ? documentEntry[1].name : '' + + const result = this.createFile({ id: slug, name }) + if (!result.ok) { + console.error('Could not create file', result.error) + continue + } tx.file_state.create({ userId: this.userId, fileId: slug, diff --git a/apps/dotcom/client/src/tla/components/dialogs/TlaDeleteFileDialog.tsx b/apps/dotcom/client/src/tla/components/dialogs/TlaDeleteFileDialog.tsx index e1b9a5ade613..ad1c11d31e1a 100644 --- a/apps/dotcom/client/src/tla/components/dialogs/TlaDeleteFileDialog.tsx +++ b/apps/dotcom/client/src/tla/components/dialogs/TlaDeleteFileDialog.tsx @@ -30,12 +30,11 @@ export function TlaDeleteFileDialog({ fileId, onClose }: { fileId: string; onClo await app.deleteOrForgetFile(fileId) const recentFiles = app.getUserRecentFiles() if (recentFiles.length === 0) { - app.createFile().then((res) => { - if (res.ok) { - navigate(getFilePath(res.value.file.id), { state: { mode: 'create' } }) - trackEvent('delete-file', { source: 'file-menu' }) - } - }) + const result = app.createFile() + if (result.ok) { + navigate(getFilePath(result.value.file.id), { state: { mode: 'create' } }) + trackEvent('delete-file', { source: 'file-menu' }) + } } else { navigate(getFilePath(recentFiles[0].fileId)) } diff --git a/apps/dotcom/client/src/tla/pages/local.tsx b/apps/dotcom/client/src/tla/pages/local.tsx index 098679131dc8..054b165c9c3d 100644 --- a/apps/dotcom/client/src/tla/pages/local.tsx +++ b/apps/dotcom/client/src/tla/pages/local.tsx @@ -17,11 +17,10 @@ export function Component() { if (!app) return if (app.getUserRecentFiles().length === 0) { creatingFile.current = true - app.createFile().then((res) => { - if (res.ok) { - navigate(getFilePath(res.value.file.id), { state: { mode: 'create' } }) - } - }) + const result = app.createFile() + if (result.ok) { + navigate(getFilePath(result.value.file.id), { state: { mode: 'create' } }) + } } }, [app, navigate]) diff --git a/packages/tlschema/api-report.md b/packages/tlschema/api-report.md index f186c5ac5385..a9b2beabc665 100644 --- a/packages/tlschema/api-report.md +++ b/packages/tlschema/api-report.md @@ -350,6 +350,9 @@ export function isBinding(record?: UnknownRecord): record is TLBinding; // @public (undocumented) export function isBindingId(id?: string): id is TLBindingId; +// @public (undocumented) +export function isDocument(record?: UnknownRecord): record is TLDocument; + // @public (undocumented) export function isPageId(id: string): id is TLPageId; diff --git a/packages/tlschema/src/index.ts b/packages/tlschema/src/index.ts index a49d6c2e7c6f..4063eb927bc9 100644 --- a/packages/tlschema/src/index.ts +++ b/packages/tlschema/src/index.ts @@ -71,7 +71,12 @@ export { type TLUnknownBinding, } from './records/TLBinding' export { CameraRecordType, type TLCamera, type TLCameraId } from './records/TLCamera' -export { DocumentRecordType, TLDOCUMENT_ID, type TLDocument } from './records/TLDocument' +export { + DocumentRecordType, + TLDOCUMENT_ID, + isDocument, + type TLDocument, +} from './records/TLDocument' export { TLINSTANCE_ID, pluckPreservingValues, diff --git a/packages/tlschema/src/records/TLDocument.ts b/packages/tlschema/src/records/TLDocument.ts index bc2ff10aa86e..8e899e3b55a6 100644 --- a/packages/tlschema/src/records/TLDocument.ts +++ b/packages/tlschema/src/records/TLDocument.ts @@ -4,6 +4,7 @@ import { createRecordMigrationSequence, createRecordType, RecordId, + UnknownRecord, } from '@tldraw/store' import { JsonObject } from '@tldraw/utils' import { T } from '@tldraw/validate' @@ -31,6 +32,12 @@ export const documentValidator: T.Validator = T.model( }) ) +/** @public */ +export function isDocument(record?: UnknownRecord): record is TLDocument { + if (!record) return false + return record.typeName === 'document' +} + /** @public */ export const documentVersions = createMigrationIds('com.tldraw.document', { AddName: 1,