mirror of
https://github.com/CharaChorder/DeviceManager.git
synced 2026-01-10 03:52:57 +00:00
@@ -35,84 +35,90 @@
|
|||||||
let redoQueue: Change[] = []
|
let redoQueue: Change[] = []
|
||||||
|
|
||||||
async function save() {
|
async function save() {
|
||||||
const port = $serialPort
|
try {
|
||||||
if (!port) return
|
const port = $serialPort
|
||||||
$syncStatus = "uploading"
|
if (!port) return
|
||||||
|
$syncStatus = "uploading"
|
||||||
|
|
||||||
for (const [id, {actions, phrase, deleted}] of $overlay.chords) {
|
for (const [id, {actions, phrase, deleted}] of $overlay.chords) {
|
||||||
if (!deleted) {
|
if (!deleted) {
|
||||||
if (id !== JSON.stringify(actions)) {
|
if (id !== JSON.stringify(actions)) {
|
||||||
const existingChord = await port.getChordPhrase(actions)
|
const existingChord = await port.getChordPhrase(actions)
|
||||||
if (
|
if (
|
||||||
existingChord !== undefined &&
|
existingChord !== undefined &&
|
||||||
!(await askForConfirmation(
|
!(await askForConfirmation(
|
||||||
$LL.configure.chords.conflict.TITLE(),
|
$LL.configure.chords.conflict.TITLE(),
|
||||||
$LL.configure.chords.conflict.DESCRIPTION(
|
$LL.configure.chords.conflict.DESCRIPTION(
|
||||||
actions.map(it => `<kbd>${KEYMAP_CODES[it].id}</kbd>`).join(" "),
|
actions.map(it => `<kbd>${KEYMAP_CODES[it].id}</kbd>`).join(" "),
|
||||||
),
|
),
|
||||||
$LL.configure.chords.conflict.CONFIRM(),
|
$LL.configure.chords.conflict.CONFIRM(),
|
||||||
$LL.configure.chords.conflict.ABORT(),
|
$LL.configure.chords.conflict.ABORT(),
|
||||||
))
|
))
|
||||||
) {
|
) {
|
||||||
changes.update(changes =>
|
changes.update(changes =>
|
||||||
changes.filter(it => !(it.type === ChangeType.Chord && JSON.stringify(it.id) === id)),
|
changes.filter(it => !(it.type === ChangeType.Chord && JSON.stringify(it.id) === id)),
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
await port.deleteChord({actions: JSON.parse(id)})
|
||||||
}
|
}
|
||||||
|
await port.setChord({actions, phrase})
|
||||||
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()
|
|
||||||
} else {
|
} else {
|
||||||
requestAnimationFrame(animate)
|
await port.deleteChord({actions})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
requestAnimationFrame(animate)
|
|
||||||
})
|
|
||||||
await port.commit()
|
|
||||||
|
|
||||||
$deviceLayout = $layout.map(layer => layer.map<number>(({action}) => action)) as [
|
for (const [layer, actions] of $overlay.layout.entries()) {
|
||||||
number[],
|
for (const [id, action] of actions) {
|
||||||
number[],
|
await port.setLayoutKey(layer + 1, id, action)
|
||||||
number[],
|
}
|
||||||
]
|
}
|
||||||
$deviceChords = $chords.filter(({deleted}) => !deleted).map(({actions, phrase}) => ({actions, phrase}))
|
|
||||||
$deviceSettings = $settings.map(({value}) => value)
|
for (const [id, setting] of $overlay.settings) {
|
||||||
$changes = []
|
await port.setSetting(id, setting)
|
||||||
$syncStatus = "done"
|
}
|
||||||
|
|
||||||
|
// 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>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user