diff --git a/src/routes/EditActions.svelte b/src/routes/EditActions.svelte index d381905b..b0e3bdb8 100644 --- a/src/routes/EditActions.svelte +++ b/src/routes/EditActions.svelte @@ -35,84 +35,90 @@ let redoQueue: Change[] = [] async function save() { - const port = $serialPort - if (!port) return - $syncStatus = "uploading" + try { + const port = $serialPort + if (!port) return + $syncStatus = "uploading" - for (const [id, {actions, phrase, deleted}] of $overlay.chords) { - if (!deleted) { - if (id !== JSON.stringify(actions)) { - const existingChord = await port.getChordPhrase(actions) - if ( - existingChord !== undefined && - !(await askForConfirmation( - $LL.configure.chords.conflict.TITLE(), - $LL.configure.chords.conflict.DESCRIPTION( - actions.map(it => `${KEYMAP_CODES[it].id}`).join(" "), - ), - $LL.configure.chords.conflict.CONFIRM(), - $LL.configure.chords.conflict.ABORT(), - )) - ) { - changes.update(changes => - changes.filter(it => !(it.type === ChangeType.Chord && JSON.stringify(it.id) === id)), - ) - continue + for (const [id, {actions, phrase, deleted}] of $overlay.chords) { + if (!deleted) { + if (id !== JSON.stringify(actions)) { + const existingChord = await port.getChordPhrase(actions) + if ( + existingChord !== undefined && + !(await askForConfirmation( + $LL.configure.chords.conflict.TITLE(), + $LL.configure.chords.conflict.DESCRIPTION( + actions.map(it => `${KEYMAP_CODES[it].id}`).join(" "), + ), + $LL.configure.chords.conflict.CONFIRM(), + $LL.configure.chords.conflict.ABORT(), + )) + ) { + changes.update(changes => + changes.filter(it => !(it.type === ChangeType.Chord && JSON.stringify(it.id) === id)), + ) + continue + } + + await port.deleteChord({actions: JSON.parse(id)}) } - - await port.deleteChord({actions: JSON.parse(id)}) - } - await port.setChord({actions, phrase}) - } else { - await port.deleteChord({actions}) - } - } - - for (const [layer, actions] of $overlay.layout.entries()) { - for (const [id, action] of actions) { - await port.setLayoutKey(layer + 1, id, action) - } - } - - for (const [id, setting] of $overlay.settings) { - await port.setSetting(id, setting) - } - - // Yes, this is a completely arbitrary and unnecessary delay. - // The only purpose of it is to create a sense of weight, - // aka make it more "energy intensive" to click. - // The only conceivable way users could reach the commit limit in this case - // would be if they click it every time they change a setting. - // Because of that, we don't need to show a fearmongering message such as - // "Your device will break after you click this 10,000 times!" - const virtualWriteTime = 1000 - const startStamp = performance.now() - await new Promise(resolve => { - function animate() { - const delta = performance.now() - startStamp - syncProgress.set({ - max: virtualWriteTime, - current: delta, - }) - if (delta >= virtualWriteTime) { - resolve() + await port.setChord({actions, phrase}) } else { - requestAnimationFrame(animate) + await port.deleteChord({actions}) } } - requestAnimationFrame(animate) - }) - await port.commit() - $deviceLayout = $layout.map(layer => layer.map(({action}) => action)) as [ - number[], - number[], - number[], - ] - $deviceChords = $chords.filter(({deleted}) => !deleted).map(({actions, phrase}) => ({actions, phrase})) - $deviceSettings = $settings.map(({value}) => value) - $changes = [] - $syncStatus = "done" + for (const [layer, actions] of $overlay.layout.entries()) { + for (const [id, action] of actions) { + await port.setLayoutKey(layer + 1, id, action) + } + } + + for (const [id, setting] of $overlay.settings) { + await port.setSetting(id, setting) + } + + // Yes, this is a completely arbitrary and unnecessary delay. + // The only purpose of it is to create a sense of weight, + // aka make it more "energy intensive" to click. + // The only conceivable way users could reach the commit limit in this case + // would be if they click it every time they change a setting. + // Because of that, we don't need to show a fearmongering message such as + // "Your device will break after you click this 10,000 times!" + const virtualWriteTime = 1000 + const startStamp = performance.now() + await new Promise(resolve => { + function animate() { + const delta = performance.now() - startStamp + syncProgress.set({ + max: virtualWriteTime, + current: delta, + }) + if (delta >= virtualWriteTime) { + resolve() + } else { + requestAnimationFrame(animate) + } + } + requestAnimationFrame(animate) + }) + await port.commit() + + $deviceLayout = $layout.map(layer => layer.map(({action}) => action)) as [ + number[], + number[], + number[], + ] + $deviceChords = $chords.filter(({deleted}) => !deleted).map(({actions, phrase}) => ({actions, phrase})) + $deviceSettings = $settings.map(({value}) => value) + $changes = [] + } catch (e) { + alert(e) + console.error(e) + } finally { + $syncStatus = "done" + } }