feat(draft): serialize sigit and save/load to local storage

This commit is contained in:
en 2025-02-17 19:06:19 +01:00
parent 0834e52316
commit 13b88516ca
4 changed files with 134 additions and 0 deletions

19
src/types/draft.ts Normal file
View File

@ -0,0 +1,19 @@
import { SigitFile } from '../utils/file'
import { User } from './core'
import { DrawnField } from './drawing'
export interface SigitFileDraft {
name: string
file: string
pages: DrawnField[][]
}
export interface SigitDraft {
title: string
users: User[]
files: SigitFile[]
}
export interface SerializedSigitDraft {
title: string
users: User[]
files: SigitFileDraft[]
}

View File

@ -4,3 +4,5 @@ export * from './nostr'
export * from './relay'
export * from './zip'
export * from './event'
export * from './drawing'
export * from './draft'

112
src/utils/draft.ts Normal file
View File

@ -0,0 +1,112 @@
import {
DrawnField,
SerializedSigitDraft,
SigitDraft,
SigitFileDraft
} from '../types'
import {
getMediaType,
extractFileExtension,
toFile,
getSigitFile
} from './file'
let saveSigitDraftTimeout: number | null = null
const serializeSigitDraft = async (
draft: SigitDraft
): Promise<SerializedSigitDraft> => {
const serializedFiles = draft.files.map((file) => {
return new Promise<SigitFileDraft>((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => {
const pages = file.pages
? file.pages.map((page) =>
page.drawnFields.map(
(field) =>
({
left: field.left,
top: field.top,
width: field.width,
height: field.height,
type: field.type,
counterpart: field.counterpart
}) as DrawnField
)
)
: []
resolve({
name: file.name,
pages: pages,
file: reader.result as string
})
}
reader.onerror = (error) => reject(error)
reader.readAsDataURL(file)
})
})
const serializedFileDraft = await Promise.all(serializedFiles)
return {
title: draft.title,
users: [...draft.users],
files: serializedFileDraft
}
}
const deserializeSigitDraft = async (
serializedDraft: SerializedSigitDraft
): Promise<SigitDraft> => {
const files = await Promise.all(
serializedDraft.files.map(async (draft) => {
const response = await fetch(draft.file)
const arrayBuffer = await response.arrayBuffer()
const type = getMediaType(extractFileExtension(draft.name))
const file = toFile(arrayBuffer, draft.name, type)
const sigitFile = await getSigitFile(file)
if (draft.pages) {
for (let i = 0; i < draft.pages.length; i++) {
const drawnFields = draft.pages[i]
if (sigitFile.pages) sigitFile.pages[i].drawnFields = [...drawnFields]
}
}
return sigitFile
})
)
return {
...serializedDraft,
files: files
}
}
export const saveSigitDraft = (draft: SigitDraft) => {
if (saveSigitDraftTimeout) {
clearTimeout(saveSigitDraftTimeout)
}
saveSigitDraftTimeout = window.setTimeout(() => {
serializeSigitDraft(draft)
.then((draftToSave) => {
localStorage.setItem('sigitDraft', JSON.stringify(draftToSave))
})
.catch((error) => {
console.log(`Error while saving sigit draft. Error: `, error)
})
}, 1000)
}
export const getSigitDraft = async () => {
const sigitDraft = localStorage.getItem('sigitDraft')
if (!sigitDraft) return null
try {
const serializedDraft = JSON.parse(sigitDraft) as SerializedSigitDraft
return await deserializeSigitDraft(serializedDraft)
} catch {
return null
}
}
export const clearSigitDraft = () => {
localStorage.removeItem('sigitDraft')
}

View File

@ -12,3 +12,4 @@ export * from './string'
export * from './url'
export * from './utils'
export * from './zip'
export * from './draft'