diff --git a/package.json b/package.json index 1fdff57..6f69a3d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lagrange", - "version": "0.2.1", + "version": "0.2.2", "private": true, "type": "module", "scripts": { diff --git a/src/core/import.helper.ts b/src/core/import.helper.ts new file mode 100644 index 0000000..a478211 --- /dev/null +++ b/src/core/import.helper.ts @@ -0,0 +1,42 @@ +import type { IDBPlanet } from '@/dexie.config' +import PlanetData from './models/planet-data.model' +import pako from 'pako' +import { nanoid } from 'nanoid' + +export function readFileData(buf: ArrayBuffer): IDBPlanet | undefined { + const rawData = JSON.parse(pako.inflate(buf, { to: 'string' })) + if (rawData.version || rawData.data) { + return readFileV2(rawData) + } else { + return readFileV1(rawData) // Only v1 files have no version attached + } +} + +function readFileV2(rawData: IDBPlanet): IDBPlanet | undefined { + try { + const newIdb: IDBPlanet = { + id: rawData.id, + data: PlanetData.createFrom(rawData.data), + preview: rawData.preview, + } + console.debug('[import] Read file data as version 2') + return newIdb + } catch (err) { + console.error(err) + return undefined + } +} + +function readFileV1(rawData: PlanetData): IDBPlanet | undefined { + try { + const newIdb: IDBPlanet = { + id: nanoid(), + data: PlanetData.createFrom(rawData), + } + console.debug('[import] Read file data as version 1') + return newIdb + } catch (err) { + console.error(err) + return undefined + } +} diff --git a/src/dexie.config.ts b/src/dexie.config.ts index fb56644..4d5cb4e 100644 --- a/src/dexie.config.ts +++ b/src/dexie.config.ts @@ -28,6 +28,7 @@ interface IDBSettings { interface IDBPlanet { id: string + version?: string preview?: string data: PlanetData } diff --git a/src/views/CodexView.vue b/src/views/CodexView.vue index cdc3bec..19a1b35 100644 --- a/src/views/CodexView.vue +++ b/src/views/CodexView.vue @@ -64,6 +64,7 @@ import { saveAs } from 'file-saver' import PlanetData from '@/core/models/planet-data.model' import JSZip from 'jszip' import NewCardElement from '@/components/elements/NewCardElement.vue' +import { readFileData } from '@/core/import.helper' const i18n = useI18n() const fileInput: Ref = ref(null) @@ -125,17 +126,10 @@ async function importPlanetFile(event: Event) { const reader = new FileReader() return new Promise((resolve, reject) => { reader.onload = async (e) => { - try { - const data = JSON.parse(pako.inflate(e.target?.result as ArrayBuffer, { to: 'string' })) as IDBPlanet - const newIdb: IDBPlanet = { - id: data.id, - data: PlanetData.createFrom(data.data), - preview: data.preview, - } - console.info(`Imported planet (ID=${newIdb.id}): [${newIdb.data.planetName}]`) - resolve(newIdb) - } catch (err) { - console.error(err) + const data = readFileData(e.target?.result as ArrayBuffer) + if (data) { + resolve(data) + } else { reject() } } @@ -145,21 +139,28 @@ async function importPlanetFile(event: Event) { try { const newPlanets: PromiseSettledResult[] = await Promise.allSettled(readPromises) - if (newPlanets.every((p) => p.status === 'rejected')) { + const rejectedFiles = newPlanets.filter((p) => p.status === 'rejected') + if (rejectedFiles.length === newPlanets.length) { EventBus.sendToastEvent('warn', 'toast.import_failure', 3000) return } - await idb.planets.bulkAdd( + + const allAdded = await idb.planets.bulkPut( newPlanets .filter((np) => np.status === 'fulfilled') - .map((np: PromiseSettledResult) => (np as PromiseFulfilledResult).value), + .map((np: PromiseSettledResult) => (np as PromiseFulfilledResult).value) + .map((np) => ({ ...np, version: np.version ?? '1' })), ) + if (allAdded && rejectedFiles.length === 0) { + EventBus.sendToastEvent('success', 'toast.import_success', 3000) + } else { + EventBus.sendToastEvent('warn', 'toast.import_partial', 3000) + } } catch (_) { EventBus.sendToastEvent('warn', 'toast.import_partial', 3000) } finally { await loadPlanets() fileInput.value!.value = '' - EventBus.sendToastEvent('success', 'toast.import_success', 3000) } } diff --git a/src/views/PlanetEditorView.vue b/src/views/PlanetEditorView.vue index 05b737c..df0328b 100644 --- a/src/views/PlanetEditorView.vue +++ b/src/views/PlanetEditorView.vue @@ -318,6 +318,7 @@ async function savePlanet() { const localData = toRaw(JSON.stringify(LG_PLANET_DATA.value)) const idbData: IDBPlanet = { id: $planetEntityId.value.length > 0 ? $planetEntityId.value : nanoid(), + version: '2', data: JSON.parse(localData), preview: previewDataString, }