mirror of
https://github.com/CharaChorder/DeviceManager.git
synced 2026-01-20 08:52:59 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
3dd91a1cea
|
|||
|
cbcf705f71
|
|||
|
4007810c7b
|
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "charachorder-device-manager",
|
"name": "charachorder-device-manager",
|
||||||
"version": "1.5.0",
|
"version": "1.5.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "charachorder-device-manager",
|
"name": "charachorder-device-manager",
|
||||||
"version": "1.5.0",
|
"version": "1.5.1",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@codemirror/autocomplete": "^6.15.0",
|
"@codemirror/autocomplete": "^6.15.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "charachorder-device-manager",
|
"name": "charachorder-device-manager",
|
||||||
"version": "1.5.0",
|
"version": "1.5.1",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"private": true,
|
"private": true,
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "app"
|
name = "app"
|
||||||
version = "1.5.0"
|
version = "1.5.1"
|
||||||
description = "A Tauri App"
|
description = "A Tauri App"
|
||||||
authors = ["Thea Schöbl <dev@theaninova.de>"]
|
authors = ["Thea Schöbl <dev@theaninova.de>"]
|
||||||
license = "AGPL-3"
|
license = "AGPL-3"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"devPath": "http://localhost:5173",
|
"devPath": "http://localhost:5173",
|
||||||
"distDir": "../build"
|
"distDir": "../build"
|
||||||
},
|
},
|
||||||
"package": { "productName": "amacc1ng", "version": "1.5.0" },
|
"package": { "productName": "amacc1ng", "version": "1.5.1" },
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"allowlist": { "all": false },
|
"allowlist": { "all": false },
|
||||||
"bundle": {
|
"bundle": {
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
name: CharaChorder
|
name: CharaChorder
|
||||||
description: CharaChorder specific actions
|
description: CharaChorder specific actions
|
||||||
actions:
|
actions:
|
||||||
|
0:
|
||||||
|
id: "NO_ACTION"
|
||||||
|
display: "No Action"
|
||||||
528:
|
528:
|
||||||
id: "RESTART"
|
id: "RESTART"
|
||||||
title: Restart Device
|
title: Restart Device
|
||||||
@@ -58,6 +61,7 @@ actions:
|
|||||||
544:
|
544:
|
||||||
variantOf: 36
|
variantOf: 36
|
||||||
id: "SPACERIGHT"
|
id: "SPACERIGHT"
|
||||||
|
display: " "
|
||||||
title: Right Spacebar (eg CC Lite)
|
title: Right Spacebar (eg CC Lite)
|
||||||
icon: space_bar
|
icon: space_bar
|
||||||
variant: right
|
variant: right
|
||||||
|
|||||||
@@ -32,5 +32,7 @@
|
|||||||
"You can use Nexus to track words you might want to add to your chord library",
|
"You can use Nexus to track words you might want to add to your chord library",
|
||||||
"The CC1 default layout was 80% science, 20% art",
|
"The CC1 default layout was 80% science, 20% art",
|
||||||
"There is little to no reason to use hjkl in VIM on a CC1 since the arrows keys are so close already",
|
"There is little to no reason to use hjkl in VIM on a CC1 since the arrows keys are so close already",
|
||||||
"The device manager automatically creates a backup for you when you reboot your device into the bootloader"
|
"The device manager automatically creates a backup for you when you reboot your device into the bootloader",
|
||||||
|
"You can use \"compound\", \"macro\", \"suffix\" and \"cursor warp\" in the chord search to find specific types of chords",
|
||||||
|
"You can search for chord inputs by using a leading \"+\", for example \"+a +DUP\" will show all chords with inputs that contain both a and DUP"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
$: dynamicMapping = info.keyCode && $osLayout.get(info.keyCode);
|
$: dynamicMapping = info.keyCode && $osLayout.get(info.keyCode);
|
||||||
|
|
||||||
$: tooltip =
|
$: tooltip =
|
||||||
(info.title ?? info.id ?? `0x${info.code.toString(16)}`) +
|
`<${info.id ?? `0x${info.code.toString(16)}`}> ` +
|
||||||
|
(info.title ?? "") +
|
||||||
(info.variant === "left"
|
(info.variant === "left"
|
||||||
? " (left)"
|
? " (left)"
|
||||||
: info.variant === "right"
|
: info.variant === "right"
|
||||||
|
|||||||
@@ -127,12 +127,11 @@
|
|||||||
const clickedGroup = groupParent.children.item(index) as SVGGElement;
|
const clickedGroup = groupParent.children.item(index) as SVGGElement;
|
||||||
const nextAction = get(layout)[get(activeLayer)]?.[keyInfo.id];
|
const nextAction = get(layout)[get(activeLayer)]?.[keyInfo.id];
|
||||||
const currentAction = get(deviceLayout)[get(activeLayer)]?.[keyInfo.id];
|
const currentAction = get(deviceLayout)[get(activeLayer)]?.[keyInfo.id];
|
||||||
if (!nextAction || !currentAction) return;
|
|
||||||
const component = new ActionSelector({
|
const component = new ActionSelector({
|
||||||
target: document.body,
|
target: document.body,
|
||||||
props: {
|
props: {
|
||||||
currentAction,
|
currentAction,
|
||||||
nextAction: nextAction.isApplied ? undefined : nextAction.action,
|
nextAction: nextAction?.isApplied ? undefined : nextAction?.action,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const dialog = document.querySelector("dialog > div") as HTMLDivElement;
|
const dialog = document.querySelector("dialog > div") as HTMLDivElement;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { KEYMAP_CODES } from "$lib/serial/keymap-codes";
|
import { KEYMAP_CATEGORIES, KEYMAP_CODES } from "$lib/serial/keymap-codes";
|
||||||
import FlexSearch from "flexsearch";
|
import FlexSearch from "flexsearch";
|
||||||
import LL from "../../../i18n/i18n-svelte";
|
import LL from "../../../i18n/i18n-svelte";
|
||||||
import { action } from "$lib/title";
|
import { action } from "$lib/title";
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
resizeObserver?.disconnect();
|
resizeObserver?.disconnect();
|
||||||
});
|
});
|
||||||
|
|
||||||
let index = new FlexSearch.Index({ tokenize: "full" });
|
let index = new FlexSearch.Index();
|
||||||
let searchIndex = writable<FlexSearch.Index | undefined>(undefined);
|
let searchIndex = writable<FlexSearch.Index | undefined>(undefined);
|
||||||
$: {
|
$: {
|
||||||
abortIndexing?.();
|
abortIndexing?.();
|
||||||
@@ -43,22 +43,72 @@
|
|||||||
buildIndex($chords, $osLayout).then(searchIndex.set);
|
buildIndex($chords, $osLayout).then(searchIndex.set);
|
||||||
}
|
}
|
||||||
|
|
||||||
function plainPhrase(phrase: number[], osLayout: Map<string, string>) {
|
function encodeChord(chord: ChordInfo, osLayout: Map<string, string>) {
|
||||||
return phrase
|
const plainPhrase: string[] = [""];
|
||||||
|
const extraActions: string[] = [];
|
||||||
|
const extraCodes: string[] = [];
|
||||||
|
|
||||||
|
for (const actionCode of chord.phrase ?? []) {
|
||||||
|
const action = KEYMAP_CODES.get(actionCode);
|
||||||
|
if (!action) {
|
||||||
|
extraCodes.push(`0x${actionCode.toString(16)}`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const osCode = action.keyCode && osLayout.get(action.keyCode);
|
||||||
|
const token = osCode?.length === 1 ? osCode : action.display || action.id;
|
||||||
|
if (!token) {
|
||||||
|
extraCodes.push(`0x${action.code.toString(16)}`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/^\s$/.test(token) && plainPhrase.at(-1) !== "") {
|
||||||
|
plainPhrase.push("");
|
||||||
|
} else if (token.length === 1) {
|
||||||
|
plainPhrase[plainPhrase.length - 1] =
|
||||||
|
plainPhrase[plainPhrase.length - 1] + token;
|
||||||
|
} else {
|
||||||
|
extraActions.push(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chord.phrase?.[0] === 298) {
|
||||||
|
plainPhrase.push("suffix");
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
["ARROW_LT", "ARROW_RT", "ARROW_UP", "ARROW_DN"].some((it) =>
|
||||||
|
extraActions.includes(it),
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
plainPhrase.push("cursor warp");
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
["CTRL", "ALT", "GUI", "ENTER", "TAB"].some((it) =>
|
||||||
|
extraActions.includes(it),
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
plainPhrase.push("macro");
|
||||||
|
}
|
||||||
|
if (chord.actions[0] !== 0) {
|
||||||
|
plainPhrase.push("compound");
|
||||||
|
}
|
||||||
|
|
||||||
|
const input = chord.actions
|
||||||
|
.slice(chord.actions.lastIndexOf(0) + 1)
|
||||||
.map((it) => {
|
.map((it) => {
|
||||||
const info = KEYMAP_CODES.get(it);
|
const info = KEYMAP_CODES.get(it);
|
||||||
if (!info) return "";
|
if (!info) return `0x${it.toString(16)}`;
|
||||||
|
const osCode = info.keyCode && osLayout.get(info.keyCode);
|
||||||
|
const result = osCode?.length === 1 ? osCode : info.id;
|
||||||
|
return result ?? `0x${it.toString(16)}`;
|
||||||
|
});
|
||||||
|
|
||||||
const bestGuess =
|
return [
|
||||||
(info.keyCode && osLayout.get(info.keyCode)) ||
|
...plainPhrase,
|
||||||
info.display ||
|
`+${input.join("+")}`,
|
||||||
info.id ||
|
...new Set(extraActions),
|
||||||
"";
|
...new Set(extraCodes),
|
||||||
|
].join(" ");
|
||||||
return bestGuess.length === 1 ? bestGuess : "";
|
|
||||||
})
|
|
||||||
.filter((it) => !!it)
|
|
||||||
.join("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function buildIndex(
|
async function buildIndex(
|
||||||
@@ -66,7 +116,23 @@
|
|||||||
osLayout: Map<string, string>,
|
osLayout: Map<string, string>,
|
||||||
): Promise<FlexSearch.Index> {
|
): Promise<FlexSearch.Index> {
|
||||||
if (chords.length === 0 || !browser) return index;
|
if (chords.length === 0 || !browser) return index;
|
||||||
index = new FlexSearch.Index({ tokenize: "full" });
|
index = new FlexSearch.Index({
|
||||||
|
tokenize: "full",
|
||||||
|
encode(phrase: string) {
|
||||||
|
return phrase.split(/\s+/).flatMap((it) => {
|
||||||
|
if (/^[A-Z_]+$/.test(it)) {
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
if (it.startsWith("+")) {
|
||||||
|
return it
|
||||||
|
.slice(1)
|
||||||
|
.split("+")
|
||||||
|
.map((it) => `+${it}`);
|
||||||
|
}
|
||||||
|
return it.toLowerCase();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
let abort = false;
|
let abort = false;
|
||||||
abortIndexing = () => {
|
abortIndexing = () => {
|
||||||
abort = true;
|
abort = true;
|
||||||
@@ -78,7 +144,8 @@
|
|||||||
progress = i;
|
progress = i;
|
||||||
|
|
||||||
if ("phrase" in chord) {
|
if ("phrase" in chord) {
|
||||||
await index.addAsync(i, plainPhrase(chord.phrase, osLayout));
|
console.log(encodeChord(chord, osLayout));
|
||||||
|
await index.addAsync(i, encodeChord(chord, osLayout));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return index;
|
return index;
|
||||||
|
|||||||
Reference in New Issue
Block a user