diff --git a/.env.development b/.env.development new file mode 100644 index 00000000..8ba9c0cf --- /dev/null +++ b/.env.development @@ -0,0 +1 @@ +VITE_API_URL=http://localhost:17461/ diff --git a/.gitignore b/.gitignore index 78710161..a1040d94 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,6 @@ coverage *.njsproj *.sln *.sw? + +# Production secrets +.env.production diff --git a/package-lock.json b/package-lock.json index 0df40f59..1caef265 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "scale-workshop", - "version": "3.0.0-beta.27", + "version": "3.0.0-beta.28", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "scale-workshop", - "version": "3.0.0-beta.27", + "version": "3.0.0-beta.28", "dependencies": { "isomorphic-qwerty": "^0.0.2", "ji-lattice": "^0.0.3", @@ -14,7 +14,7 @@ "moment-of-symmetry": "^0.5.2", "pinia": "^2.1.7", "qs": "^6.12.0", - "sonic-weave": "^0.1.1", + "sonic-weave": "^0.2.0", "sw-synth": "^0.1.0", "temperaments": "^0.5.3", "values.js": "^2.1.1", @@ -5455,9 +5455,9 @@ } }, "node_modules/sonic-weave": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/sonic-weave/-/sonic-weave-0.1.1.tgz", - "integrity": "sha512-zhCZ046qwdQ8+skDQkRrr70Sf3yNwEwZxxVy+zS4L4c3Vv9u/4MmxiRYr7d7o7LJuZMwE6QmmD1P6fELXjyYmA==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/sonic-weave/-/sonic-weave-0.2.0.tgz", + "integrity": "sha512-dc9Gd0V5hSR2Xc1nXopLjuqas39UcDEfqRDl6GmQQ3riHW/eaLCSlSfhh2Xo91L2sZHnL1n9oJEbnEbxNSmQBw==", "dependencies": { "moment-of-symmetry": "^0.5.3", "xen-dev-utils": "^0.7.0" diff --git a/package.json b/package.json index 0475f02e..76267354 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "scale-workshop", - "version": "3.0.0-beta.27", + "version": "3.0.0-beta.28", "scripts": { "dev": "vite", "build": "run-p type-check \"build-only {@}\" --", @@ -21,7 +21,7 @@ "moment-of-symmetry": "^0.5.2", "pinia": "^2.1.7", "qs": "^6.12.0", - "sonic-weave": "^0.1.1", + "sonic-weave": "^0.2.0", "sw-synth": "^0.1.0", "temperaments": "^0.5.3", "values.js": "^2.1.1", diff --git a/src/App.vue b/src/App.vue index 2fcbb06b..ffc9915b 100644 --- a/src/App.vue +++ b/src/App.vue @@ -313,7 +313,7 @@ function typingKeydown(event: CoordinateKeyboardEvent) { let index = scale.scale.baseMidiNote + scale.scale.size * scale.equaveShift + scale.degreeShift if (scale.keyboardMode === 'isomorphic') { - index += x * state.isomorphicHorizontal + (2 - y) * state.isomorphicVertical + index += x * scale.isomorphicHorizontal + (2 - y) * scale.isomorphicVertical } else { if (scale.qwertyMapping.has(event.code)) { // QWERTY mapping incorporates shifts @@ -356,8 +356,8 @@ onMounted(() => { scale.userBaseFrequency = scaleWorkshopOneData.freq scale.autoFrequency = false scale.baseMidiNote = scaleWorkshopOneData.midi - state.isomorphicHorizontal = scaleWorkshopOneData.horizontal - state.isomorphicVertical = scaleWorkshopOneData.vertical + scale.isomorphicHorizontal = scaleWorkshopOneData.horizontal + scale.isomorphicVertical = scaleWorkshopOneData.vertical if (scaleWorkshopOneData.data !== undefined) { const colors = scaleWorkshopOneData.colors ?? '' @@ -394,8 +394,8 @@ onMounted(() => { scale.userBaseFrequency = decodedState.baseFrequency scale.autoFrequency = false scale.baseMidiNote = decodedState.baseMidiNote - state.isomorphicHorizontal = decodedState.isomorphicHorizontal - state.isomorphicVertical = decodedState.isomorphicVertical + scale.isomorphicHorizontal = decodedState.isomorphicHorizontal + scale.isomorphicVertical = decodedState.isomorphicVertical scale.keyboardMode = decodedState.keyboardMode scale.pianoMode = pianoMode scale.equaveShift = decodedState.equaveShift diff --git a/src/__tests__/util.spec.ts b/src/__tests__/util.spec.ts index 0cd95b97..7869a817 100644 --- a/src/__tests__/util.spec.ts +++ b/src/__tests__/util.spec.ts @@ -1,6 +1,13 @@ import { describe, it, expect } from 'vitest' -import { autoKeyColors, formatExponential, formatHertz, gapKeyColors } from '../utils' +import { + autoKeyColors, + encodeUrlSafe64, + formatExponential, + formatHertz, + gapKeyColors, + randomId +} from '../utils' function naiveExponential(x: number, fractionDigits = 3) { if (Math.abs(x) < 10000) { @@ -92,3 +99,27 @@ describe('Gap key color algorithm', () => { ) }) }) + +describe('URL safe number encoder', () => { + it('encodes the whole range', () => { + const expected = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-~' + for (let i = 0; i < 64; ++i) { + expect(encodeUrlSafe64(i)).toBe(expected[i]) + } + }) +}) + +describe('Unique ID generator', () => { + it('produces a short URL-friendly identifier', () => { + const urlSafe = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-~' + const id = randomId() + expect(id).toHaveLength(9) + for (const char of id) { + expect(urlSafe).toContain(char) + } + }) + + it("won't collide with this particular identifier for 30 years", () => { + expect(randomId()).not.toBe('oKh5gWb04') + }) +}) diff --git a/src/components/ExporterButtons.vue b/src/components/ExporterButtons.vue index 64626b9d..b366b91a 100644 --- a/src/components/ExporterButtons.vue +++ b/src/components/ExporterButtons.vue @@ -1,11 +1,11 @@ diff --git a/src/views/VirtualKeyboardView.vue b/src/views/VirtualKeyboardView.vue index 32c99e98..d42ad5fc 100644 --- a/src/views/VirtualKeyboardView.vue +++ b/src/views/VirtualKeyboardView.vue @@ -39,8 +39,8 @@ type NoteOnCallback = (index: number) => NoteOff v-else :baseIndex="baseIndex" :baseMidiNote="scale.scale.baseMidiNote" - :isomorphicHorizontal="state.isomorphicHorizontal" - :isomorphicVertical="state.isomorphicVertical" + :isomorphicHorizontal="scale.isomorphicHorizontal" + :isomorphicVertical="scale.isomorphicVertical" :colorMap="scale.colorForIndex" :noteOn="noteOn" :heldNotes="state.heldNotes" diff --git a/src/views/VirtualQwerty.vue b/src/views/VirtualQwerty.vue index b557e472..abd44f88 100644 --- a/src/views/VirtualQwerty.vue +++ b/src/views/VirtualQwerty.vue @@ -25,12 +25,12 @@ const baseIndex = computed(