Skip to content

Commit

Permalink
Include lattice state in server payload
Browse files Browse the repository at this point in the history
Remove file extensions from the load API.

ref #722
  • Loading branch information
frostburn committed Jun 11, 2024
1 parent 24458ab commit 28fc46b
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 18 deletions.
12 changes: 11 additions & 1 deletion src/components/ExporterButtons.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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]'
Expand All @@ -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)
})
Expand Down
36 changes: 32 additions & 4 deletions src/stores/edo-cycles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
})
36 changes: 32 additions & 4 deletions src/stores/grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -281,6 +306,9 @@ export const useGridStore = defineStore('grid', () => {
preset311,
// Methods (auto-params)
autoSquare,
autoTonnetz
autoTonnetz,
// sw-server
toJSON,
fromJSON
}
})
56 changes: 50 additions & 6 deletions src/stores/ji-lattice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,8 @@ export const useJiLatticeStore = defineStore('ji-lattice', () => {
}
}

return {
// State
horizontalCoordinates,
verticalCoordinates,
/** Non-reactive live state */
const LIVE_STATE = {
maxDistance,
size,
labelOffset,
Expand All @@ -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,
Expand All @@ -310,6 +352,8 @@ export const useJiLatticeStore = defineStore('ji-lattice', () => {
sphere,
pitch,
yaw,
roll
roll,
toJSON,
fromJSON
}
})
20 changes: 19 additions & 1 deletion src/stores/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -110,6 +125,9 @@ export const useStateStore = defineStore('state', () => {
equaveDownCode,
degreeUpCode,
degreeDownCode,
shareStatistics
shareStatistics,
// Methods
toJSON,
fromJSON
}
})
23 changes: 21 additions & 2 deletions src/views/LoadScaleView.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
<script setup lang="ts">
import { API_URL } from '@/constants'
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 { isRandomId, unpackPayload } from '@/utils'
import { onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
const scale = useScaleStore()
const audio = useAudioStore()
const state = useStateStore()
const jiLattice = useJiLatticeStore()
const grid = useGridStore()
const cycles = useCyclesStore()
const router = useRouter()
Expand All @@ -34,8 +42,7 @@ onMounted(async () => {
} else {
try {
// XXX: Dashes are not filesystem friendly, but that's a problem for sw-server to solve.
// XXX: The api should probably be extensionless now that compression negotation makes sw-server bypassing much harder.
const res = await fetch(new URL(`scale/${id}.json.gz`, API_URL))
const res = await fetch(new URL(`scale/${id}`, API_URL))
if (res.ok) {
text.value = 'Scale loaded. Redirecting...'
const body = await res.text()
Expand All @@ -44,6 +51,18 @@ onMounted(async () => {
audio.initialize()
audio.fromJSON(payload.audio)
scale.fromJSON(payload.scale)
if ('state' in payload) {
state.fromJSON(payload.state)
}
if ('ji-lattice' in payload) {
jiLattice.fromJSON(payload['ji-lattice'])
}
if ('grid' in payload) {
grid.fromJSON(payload.grid)
}
if ('edo-cycles' in payload) {
cycles.fromJSON(payload['edo-cycles'])
}
await router.push('/')
} else {
text.value = 'Received empty response from the server.'
Expand Down

0 comments on commit 28fc46b

Please sign in to comment.