feat: profile support

This commit is contained in:
2025-07-11 16:27:19 +02:00
parent 782f1fc38b
commit 74ce6af318
20 changed files with 301 additions and 232 deletions

View File

@@ -48,10 +48,14 @@
$syncStatus = "uploading";
const layoutChanges = $overlay.layout.reduce(
(acc, layer) => acc + layer.size,
(acc, profile) =>
acc + profile.reduce((acc, layer) => acc + layer.size, 0),
0,
);
const settingChanges = $overlay.settings.reduce(
(acc, profile) => acc + profile.size,
0,
);
const settingChanges = $overlay.settings.size;
const chordChanges = $overlay.chords.size;
const needsCommit = settingChanges > 0 || layoutChanges > 0;
const progressMax = layoutChanges + settingChanges + chordChanges;
@@ -63,6 +67,8 @@
current: progressCurrent,
});
console.log($overlay);
for (const [id, chord] of $overlay.chords) {
if (!chord.deleted) {
if (id !== JSON.stringify(chord.actions)) {
@@ -105,9 +111,26 @@
});
}
for (const [layer, actions] of $overlay.layout.entries()) {
for (const [id, action] of actions) {
await port.setLayoutKey(layer + 1, id, action);
for (const [profile, layout] of $overlay.layout.entries()) {
if (layout === undefined) continue;
for (const [layer, actions] of layout.entries()) {
if (actions === undefined) continue;
for (const [id, action] of actions) {
if (action === undefined) continue;
await port.setLayoutKey(profile, layer + 1, id, action);
syncProgress.set({
max: progressMax,
current: progressCurrent++,
});
}
}
}
for (const [profile, settings] of $overlay.settings.entries()) {
if (settings === undefined) continue;
for (const [id, setting] of settings.entries()) {
if (setting === undefined) continue;
await port.setSetting(profile, id, setting);
syncProgress.set({
max: progressMax,
current: progressCurrent++,
@@ -115,14 +138,6 @@
}
}
for (const [id, setting] of $overlay.settings) {
await port.setSetting(id, setting);
syncProgress.set({
max: progressMax,
current: progressCurrent++,
});
}
// 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.
@@ -134,13 +149,15 @@
await port.commit();
}
$deviceLayout = $layout.map((layer) =>
layer.map<number>(({ action }) => action),
) as [number[], number[], number[]];
$deviceLayout = $layout.map((profile) =>
profile.map((layer) => layer.map<number>(({ action }) => action)),
);
$deviceChords = $chords
.filter(({ deleted }) => !deleted)
.map(({ actions, phrase }) => ({ actions, phrase }));
$deviceSettings = $settings.map(({ value }) => value);
$deviceSettings = $settings.map((profile) =>
profile.map(({ value }) => value),
);
$changes = [];
} catch (e) {
alert(e);

View File

@@ -2,6 +2,7 @@
import { fly } from "svelte/transition";
import { canShare, triggerShare } from "$lib/share";
import { action } from "$lib/title";
import { activeProfile, serialPort } from "$lib/serial/connection";
import LL from "$i18n/i18n-svelte";
import EditActions from "./EditActions.svelte";
</script>
@@ -11,6 +12,23 @@
<EditActions />
</div>
<div class="profiles">
{#if $serialPort}
{#if $serialPort.profileCount > 1}
{#each Array.from({ length: $serialPort.profileCount }, (_, i) => i) as profile}
<label
><input
type="radio"
name="profile"
checked={profile == $activeProfile}
onclick={() => ($activeProfile = profile)}
/>{String.fromCodePoint("A".codePointAt(0)! + profile)}</label
>
{/each}
{/if}
{/if}
</div>
<div class="actions">
{#if $canShare}
<button
@@ -37,7 +55,7 @@
<style lang="scss">
nav {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-columns: 1fr auto 1fr;
width: calc(min(100%, 28cm));
margin-block: 8px;
@@ -76,6 +94,13 @@
}
}
.profiles {
display: flex;
gap: 2px;
align-items: center;
justify-content: center;
}
:disabled {
pointer-events: none;
opacity: 0.5;

View File

@@ -6,7 +6,6 @@
import { charaFileToUriComponent } from "$lib/share/share-url";
import SharePopup from "../SharePopup.svelte";
import type { VisualLayoutConfig } from "$lib/components/layout/visual-layout";
import { writable } from "svelte/store";
import { layout } from "$lib/undo-redo";
async function shareLayout(event: Event) {
@@ -49,8 +48,6 @@
fontSize: 9,
iconFontSize: 14,
});
setContext("active-layer", writable(0));
</script>
<svelte:head>