kopia lustrzana https://github.com/Tldraw/Tldraw
119 wiersze
2.9 KiB
TypeScript
119 wiersze
2.9 KiB
TypeScript
import { openDB } from 'idb'
|
|
import { Editor, LegacyTldrawDocument, buildFromV1Document } from 'tldraw'
|
|
|
|
export function isEditorEmpty(editor: Editor) {
|
|
const hasAnyShapes = editor.store.allRecords().some((r) => r.typeName === 'shape')
|
|
return !hasAnyShapes
|
|
}
|
|
|
|
export async function findV1ContentFromIdb(): Promise<{
|
|
document: LegacyTldrawDocument
|
|
clear: () => Promise<void>
|
|
} | null> {
|
|
try {
|
|
const db = await openDB('keyval-store', 1)
|
|
const tx = db.transaction('keyval', 'readonly')
|
|
const store = tx.objectStore('keyval')
|
|
|
|
const home: unknown = await store.get('home')
|
|
await tx.done
|
|
|
|
if (
|
|
home &&
|
|
typeof home === 'object' &&
|
|
'document' in home &&
|
|
home.document &&
|
|
typeof home.document === 'object' &&
|
|
'version' in home.document &&
|
|
typeof home.document.version === 'number'
|
|
) {
|
|
return {
|
|
document: home.document as LegacyTldrawDocument,
|
|
clear: async () => {
|
|
try {
|
|
const tx = db.transaction('keyval', 'readwrite')
|
|
const store = tx.objectStore('keyval')
|
|
store.delete('home')
|
|
await tx.done
|
|
return
|
|
} catch {
|
|
// eh
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
return null
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
export async function importFromV1LocalRoom(
|
|
editor: Editor,
|
|
didCancel: () => boolean
|
|
): Promise<{ didImport: false } | { didImport: true; document: LegacyTldrawDocument }> {
|
|
const v1Doc = await findV1ContentFromIdb()
|
|
if (didCancel() || !v1Doc) return { didImport: false }
|
|
|
|
const hasAnyShapes = Object.values(v1Doc.document.pages).some(
|
|
(page) => Object.values(page.shapes).length > 0
|
|
)
|
|
if (!hasAnyShapes) return { didImport: false }
|
|
|
|
buildFromV1Document(editor, v1Doc.document)
|
|
v1Doc.clear()
|
|
|
|
if (isEditorEmpty(editor)) {
|
|
return { didImport: false }
|
|
}
|
|
|
|
return { didImport: true, document: v1Doc.document }
|
|
}
|
|
|
|
export async function importFromV1MultiplayerRoom(
|
|
editor: Editor,
|
|
roomSlug: string,
|
|
didCancel: () => boolean
|
|
): Promise<{ didImport: false } | { didImport: true; document: LegacyTldrawDocument }> {
|
|
const response = await fetch(`/api/static-legacy-multiplayer?roomSlug=${roomSlug}`)
|
|
if (!response.ok || didCancel()) {
|
|
return { didImport: false }
|
|
}
|
|
|
|
const data = await response.json()
|
|
if (!data.room || didCancel()) {
|
|
return { didImport: false }
|
|
}
|
|
|
|
// TODO: handle weird data formats (TLD-1605) & v1 migrations (TLD-1638)
|
|
const { assets, bindings, shapes, version } = data.room.storage.data
|
|
const PAGE_ID = 'page'
|
|
const document: LegacyTldrawDocument = {
|
|
id: 'doc',
|
|
name: roomSlug,
|
|
version,
|
|
pages: {
|
|
[PAGE_ID]: {
|
|
id: PAGE_ID,
|
|
name: 'Page 1',
|
|
childIndex: 1,
|
|
shapes: shapes?.data,
|
|
bindings: bindings?.data,
|
|
},
|
|
},
|
|
pageStates: {
|
|
[PAGE_ID]: {
|
|
id: PAGE_ID,
|
|
selectedIds: [],
|
|
camera: { point: [0, 0], zoom: 1 },
|
|
},
|
|
},
|
|
assets: assets?.data ?? {},
|
|
}
|
|
buildFromV1Document(editor, document)
|
|
|
|
if (isEditorEmpty(editor)) return { didImport: false }
|
|
return { didImport: true, document }
|
|
}
|