Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include lattice state in server payload #742

Merged
merged 1 commit into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading