mirror of
https://github.com/CharaChorder/DeviceManager.git
synced 2026-01-04 17:12:51 +00:00
@@ -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 => `<kbd>${KEYMAP_CODES[it].id}</kbd>`).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 => `<kbd>${KEYMAP_CODES[it].id}</kbd>`).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<void>(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<number>(({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<void>(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<number>(({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"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user