diff --git a/src/components/ExporterButtons.vue b/src/components/ExporterButtons.vue index b53902ca..36860ec9 100644 --- a/src/components/ExporterButtons.vue +++ b/src/components/ExporterButtons.vue @@ -3,6 +3,9 @@ import { API_URL, APP_TITLE } from '@/constants' import { exportFile, type ExporterKey } from '@/exporters' import type { ExporterParams } from '@/exporters/base' import { useAudioStore } from '@/stores/audio' +import { useCyclesStore } from '@/stores/edo-cycles' +import { useGridStore } from '@/stores/grid' +import { useJiLatticeStore } from '@/stores/ji-lattice' import { useScaleStore } from '@/stores/scale' import { useStateStore } from '@/stores/state' import { makeEnvelope, sanitizeFilename } from '@/utils' @@ -21,6 +24,9 @@ const ReaperExportModal = defineAsyncComponent( const state = useStateStore() const scale = useScaleStore() const audio = useAudioStore() +const jiLattice = useJiLatticeStore() +const grid = useGridStore() +const cycles = useCyclesStore() const exportTextClipboard = ref( API_URL ? "Copy this scale's unique URL to clipboard" : '[URL sharing disabled]' @@ -34,7 +40,11 @@ const uploadBody = computed(() => { id: scale.id, payload: { scale: scale.toJSON(), - audio: audio.toJSON() + audio: audio.toJSON(), + state: state.toJSON(), + 'ji-lattice': jiLattice.toJSON(), + grid: grid.toJSON(), + 'edo-cycles': cycles.toJSON() }, envelope: makeEnvelope(state.shareStatistics) }) diff --git a/src/stores/edo-cycles.ts b/src/stores/edo-cycles.ts index 5b65b643..918a466d 100644 --- a/src/stores/edo-cycles.ts +++ b/src/stores/edo-cycles.ts @@ -22,18 +22,46 @@ export const useCyclesStore = defineStore('edo-cycles', () => { ) const cycleLength = computed(() => modulus.value / numCycles.value) - return { - // State + const LIVE_STATE = { size, labelOffset, showLabels, valString, - generator, + generator + } + + /** + * Convert live state to a format suitable for storing on the server. + */ + function toJSON() { + const result: any = {} + for (const [key, value] of Object.entries(LIVE_STATE)) { + result[key] = value.value + } + return result + } + + /** + * Apply revived state to current state. + * @param data JSON data as an Object instance. + */ + function fromJSON(data: any) { + for (const key in LIVE_STATE) { + LIVE_STATE[key as keyof typeof LIVE_STATE].value = data[key] + } + } + + return { + // State + ...LIVE_STATE, // Computed state val, modulus, generatorPseudoInverse, numCycles, - cycleLength + cycleLength, + // Methods + toJSON, + fromJSON } }) diff --git a/src/stores/grid.ts b/src/stores/grid.ts index 9b60dbea..15cafbf5 100644 --- a/src/stores/grid.ts +++ b/src/stores/grid.ts @@ -243,8 +243,7 @@ export const useGridStore = defineStore('grid', () => { edgesString.value = '3/2 5/4 6/5 7/4 11/8 13/8' } - return { - // State + const LIVE_STATE = { size, viewCenterX, viewCenterY, @@ -266,7 +265,33 @@ export const useGridStore = defineStore('grid', () => { gridlines1, gridlines2, diagonals1, - diagonals2, + diagonals2 + } + + /** + * Convert live state to a format suitable for storing on the server. + */ + function toJSON() { + const result: any = {} + for (const [key, value] of Object.entries(LIVE_STATE)) { + result[key] = value.value + } + return result + } + + /** + * Apply revived state to current state. + * @param data JSON data as an Object instance. + */ + function fromJSON(data: any) { + for (const key in LIVE_STATE) { + LIVE_STATE[key as keyof typeof LIVE_STATE].value = data[key] + } + } + + return { + // State + ...LIVE_STATE, // Computed state edges, edgesError, @@ -281,6 +306,9 @@ export const useGridStore = defineStore('grid', () => { preset311, // Methods (auto-params) autoSquare, - autoTonnetz + autoTonnetz, + // sw-server + toJSON, + fromJSON } }) diff --git a/src/stores/ji-lattice.ts b/src/stores/ji-lattice.ts index 73f95f1e..f7bbf0ba 100644 --- a/src/stores/ji-lattice.ts +++ b/src/stores/ji-lattice.ts @@ -275,10 +275,8 @@ export const useJiLatticeStore = defineStore('ji-lattice', () => { } } - return { - // State - horizontalCoordinates, - verticalCoordinates, + /** Non-reactive live state */ + const LIVE_STATE = { maxDistance, size, labelOffset, @@ -287,10 +285,54 @@ export const useJiLatticeStore = defineStore('ji-lattice', () => { rotation, drawArrows, grayExtras, + depth + } + + /** + * Convert live state to a format suitable for storing on the server. + */ + function toJSON() { + const result: any = { + horizontalCoordinates, + verticalCoordinates, + xCoords, + yCoords, + zCoords + } + for (const [key, value] of Object.entries(LIVE_STATE)) { + result[key] = value.value + } + return result + } + + /** + * Apply revived state to current state. + * @param data JSON data as an Object instance. + */ + function fromJSON(data: any) { + for (const key in LIVE_STATE) { + LIVE_STATE[key as keyof typeof LIVE_STATE].value = data[key] + } + horizontalCoordinates.length = 0 + horizontalCoordinates.push(...data.horizontalCoordinates) + verticalCoordinates.length = 0 + verticalCoordinates.push(...data.verticalCoordinates) + xCoords.length = 0 + xCoords.push(...data.xCoords) + yCoords.length = 0 + yCoords.push(...data.yCoords) + zCoords.length = 0 + zCoords.push(...data.zCoords) + } + + return { + // State + ...LIVE_STATE, + horizontalCoordinates, + verticalCoordinates, xCoords, yCoords, zCoords, - depth, // Computed state edgeMonzos, edgesError, @@ -310,6 +352,8 @@ export const useJiLatticeStore = defineStore('ji-lattice', () => { sphere, pitch, yaw, - roll + roll, + toJSON, + fromJSON } }) diff --git a/src/stores/state.ts b/src/stores/state.ts index 30f0fc71..46b63f2b 100644 --- a/src/stores/state.ts +++ b/src/stores/state.ts @@ -50,6 +50,21 @@ export const useStateStore = defineStore('state', () => { // Opt-in for user statistics const shareStatistics = ref(storage.getItem('shareStatistics') === 'true') + /** + * Convert live state to a format suitable for storing on the server. + */ + function toJSON() { + return { latticeType: latticeType.value } + } + + /** + * Apply revived state to current state. + * @param data JSON data as an Object instance. + */ + function fromJSON(data: any) { + latticeType.value = data.latticeType + } + // Local storage watchers syncValues({ newline, @@ -110,6 +125,9 @@ export const useStateStore = defineStore('state', () => { equaveDownCode, degreeUpCode, degreeDownCode, - shareStatistics + shareStatistics, + // Methods + toJSON, + fromJSON } }) diff --git a/src/views/LoadScaleView.vue b/src/views/LoadScaleView.vue index 18e17134..5e4d8620 100644 --- a/src/views/LoadScaleView.vue +++ b/src/views/LoadScaleView.vue @@ -1,13 +1,21 @@