diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 00000000..6b783636
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,4 @@
+{
+ "plugins": ["prettier-plugin-svelte"],
+ "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
+}
diff --git a/.prettierrc.cjs b/.prettierrc.cjs
deleted file mode 100644
index d955dd1f..00000000
--- a/.prettierrc.cjs
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = {
- ...require("@theaninova/prettier-config"),
- plugins: ["prettier-plugin-svelte"],
- pluginSearchDirs: ["."],
- overrides: [{files: "*.svelte", options: {parser: "svelte"}}],
-}
diff --git a/icons.config.js b/icons.config.js
index f5ffb0a6..5861f75a 100644
--- a/icons.config.js
+++ b/icons.config.js
@@ -112,6 +112,6 @@ const config = {
stat_minus_2: "e69c",
stat_2: "e699",
},
-}
+};
-export default config
+export default config;
diff --git a/package-lock.json b/package-lock.json
index 8372e176..c83988f4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,7 +24,6 @@
"@sveltejs/vite-plugin-svelte": "^2.4.5",
"@tauri-apps/api": "^1.4.0",
"@tauri-apps/cli": "^1.4.0",
- "@theaninova/prettier-config": "^1.0.0",
"@types/dom-view-transitions": "^1.0.1",
"@types/flexsearch": "^0.7.3",
"@types/w3c-web-serial": "^1.0.3",
@@ -40,8 +39,8 @@
"jsdom": "^22.1.0",
"npm-run-all": "^4.1.5",
"patch-package": "^8.0.0",
- "prettier": "^3.0.3",
- "prettier-plugin-svelte": "^3.0.3",
+ "prettier": "^3.2.5",
+ "prettier-plugin-svelte": "^3.2.2",
"sass": "^1.66.1",
"stylelint": "^15.10.3",
"stylelint-config-clean-order": "^5.2.0",
@@ -3191,12 +3190,6 @@
"node": ">= 10"
}
},
- "node_modules/@theaninova/prettier-config": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@theaninova/prettier-config/-/prettier-config-1.0.0.tgz",
- "integrity": "sha512-DdP5OvUL6Tso+XMNiH+WQJrbvJsIGIudekZKMW4oGt060hqZIzwiASILCiDg6+OigKTC1KObvv4nTBQSjM2g1g==",
- "dev": true
- },
"node_modules/@tootallnate/once": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
@@ -8633,9 +8626,9 @@
"dev": true
},
"node_modules/prettier": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz",
- "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==",
+ "version": "3.2.5",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
+ "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
@@ -8648,13 +8641,13 @@
}
},
"node_modules/prettier-plugin-svelte": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.0.3.tgz",
- "integrity": "sha512-dLhieh4obJEK1hnZ6koxF+tMUrZbV5YGvRpf2+OADyanjya5j0z1Llo8iGwiHmFWZVG/hLEw/AJD5chXd9r3XA==",
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.2.2.tgz",
+ "integrity": "sha512-ZzzE/wMuf48/1+Lf2Ffko0uDa6pyCfgHV6+uAhtg2U0AAXGrhCSW88vEJNAkAxW5qyrFY1y1zZ4J8TgHrjW++Q==",
"dev": true,
"peerDependencies": {
"prettier": "^3.0.0",
- "svelte": "^3.2.0 || ^4.0.0-next.0"
+ "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0"
}
},
"node_modules/pretty-bytes": {
diff --git a/package.json b/package.json
index 5b5b6f57..0eb6046a 100644
--- a/package.json
+++ b/package.json
@@ -27,8 +27,8 @@
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
"minify-icons": "node src/tools/minify-icon-font.js",
"version": "node src/tools/version.js && git add src-tauri/Cargo.toml && git add src-tauri/tauri.conf.json",
- "lint": "prettier --plugin-search-dir . --check .",
- "format": "prettier --plugin-search-dir . --write .",
+ "lint": "prettier --check .",
+ "format": "prettier --write .",
"typesafe-i18n": "typesafe-i18n"
},
"devDependencies": {
@@ -46,7 +46,6 @@
"@sveltejs/vite-plugin-svelte": "^2.4.5",
"@tauri-apps/api": "^1.4.0",
"@tauri-apps/cli": "^1.4.0",
- "@theaninova/prettier-config": "^1.0.0",
"@types/dom-view-transitions": "^1.0.1",
"@types/flexsearch": "^0.7.3",
"@types/w3c-web-serial": "^1.0.3",
@@ -62,8 +61,8 @@
"jsdom": "^22.1.0",
"npm-run-all": "^4.1.5",
"patch-package": "^8.0.0",
- "prettier": "^3.0.3",
- "prettier-plugin-svelte": "^3.0.3",
+ "prettier": "^3.2.5",
+ "prettier-plugin-svelte": "^3.2.2",
"sass": "^1.66.1",
"stylelint": "^15.10.3",
"stylelint-config-clean-order": "^5.2.0",
diff --git a/src/app.d.ts b/src/app.d.ts
index 10e088bf..73efc744 100644
--- a/src/app.d.ts
+++ b/src/app.d.ts
@@ -11,4 +11,4 @@ declare global {
}
}
-export {}
+export {};
diff --git a/src/env.d.ts b/src/env.d.ts
index 087ff922..f634f50e 100644
--- a/src/env.d.ts
+++ b/src/env.d.ts
@@ -1,20 +1,20 @@
///
interface ImportMetaEnv {
- readonly TAURI_FAMILY?: string
- readonly TAURI_PLATFORM_VERSION?: string
- readonly TAURI_TARGET_TRIPLE?: string
- readonly TAURI_ARCH?: string
- readonly TAURI_DEBUG?: boolean
- readonly TAURI_PLATFORM_TYPE?: string
+ readonly TAURI_FAMILY?: string;
+ readonly TAURI_PLATFORM_VERSION?: string;
+ readonly TAURI_TARGET_TRIPLE?: string;
+ readonly TAURI_ARCH?: string;
+ readonly TAURI_DEBUG?: boolean;
+ readonly TAURI_PLATFORM_TYPE?: string;
- readonly VITE_HOMEPAGE_URL: string
- readonly VITE_BUGS_URL: string
- readonly VITE_DOCS_URL: string
- readonly VIET_LEARN_URL: string
- readonly VITE_LATEST_FIRMWARE: string
+ readonly VITE_HOMEPAGE_URL: string;
+ readonly VITE_BUGS_URL: string;
+ readonly VITE_DOCS_URL: string;
+ readonly VIET_LEARN_URL: string;
+ readonly VITE_LATEST_FIRMWARE: string;
}
interface ImportMeta {
- readonly env: ImportMetaEnv
+ readonly env: ImportMetaEnv;
}
diff --git a/src/i18n/de/index.ts b/src/i18n/de/index.ts
index 3be92d6e..b80b2f53 100644
--- a/src/i18n/de/index.ts
+++ b/src/i18n/de/index.ts
@@ -1,4 +1,4 @@
-import type {Translation} from "../i18n-types"
+import type { Translation } from "../i18n-types";
const de = {
TITLE: "CharaChorder Gerätemanager",
@@ -19,7 +19,8 @@ const de = {
backup: {
TITLE: "Lokale Kopie",
INDIVIDUAL: "Einzeldateien",
- DISCLAIMER: "Das Backup in diesem Browser gespeichert und bleibt nur auf diesem Computer.",
+ DISCLAIMER:
+ "Das Backup in diesem Browser gespeichert und bleibt nur auf diesem Computer.",
DOWNLOAD: "Alles herunterladen",
RESTORE: "Wiederherstellen",
},
@@ -34,7 +35,8 @@ const de = {
filter: {
ALL: "Alle",
},
- LIVE_LAYOUT_INFO: "Diese Aktion wurde auf Basis des Systemtastaturlayouts ermittelt.",
+ LIVE_LAYOUT_INFO:
+ "Diese Aktion wurde auf Basis des Systemtastaturlayouts ermittelt.",
SHIFT_WARNING: "Diese Aktion hält shift",
ALT_CODE_WARNING: "Dieses Alt-Code Makro funktioniert nur unter Windows",
},
@@ -70,7 +72,8 @@ const de = {
TITLE: "Bootmenü",
REBOOT: "Neustarten",
BOOTLOADER: "Bootloader",
- POWER_WARNING: "Um vom Bootloader aus neu zu starten muss das Gerät neu verbunden werden.",
+ POWER_WARNING:
+ "Um vom Bootloader aus neu zu starten muss das Gerät neu verbunden werden.",
},
},
browserWarning: {
@@ -82,7 +85,8 @@ const de = {
INFO_BROWSER_PREFIX:
"Auch wenn alle Chromium-basieren Desktop Browser diese Voraussetzung grundsätzlich erfüllen, haben einige Browser ",
INFO_BROWSER_INFIX: "wie zum Beispiel Brave",
- INFO_BROWSER_SUFFIX: " sich bewusst dazu entschieden die API zu deaktivieren.",
+ INFO_BROWSER_SUFFIX:
+ " sich bewusst dazu entschieden die API zu deaktivieren.",
DOWNLOAD_APP:
"Chrome oder Edge werden offiziell unterstützt, andere Browser könnten aber auch funktionieren.",
},
@@ -134,6 +138,6 @@ const de = {
RUN: "Ausführen",
},
},
-} satisfies Translation
+} satisfies Translation;
-export default de
+export default de;
diff --git a/src/i18n/en/index.ts b/src/i18n/en/index.ts
index 333e3650..b933e2b7 100644
--- a/src/i18n/en/index.ts
+++ b/src/i18n/en/index.ts
@@ -1,8 +1,9 @@
-import type {BaseTranslation} from "../i18n-types"
+import type { BaseTranslation } from "../i18n-types";
const en = {
TITLE: "CharaChorder Device Manager",
- DESCRIPTION: "The device manager and configuration tool for CharaChorder devices.",
+ DESCRIPTION:
+ "The device manager and configuration tool for CharaChorder devices.",
saveActions: {
UNDO: "Undo (hold shift to undo all changes)",
REDO: "Redo",
@@ -14,7 +15,8 @@ const en = {
backup: {
TITLE: "Local backup",
INDIVIDUAL: "Individual backups",
- DISCLAIMER: "A backup is made and stored in this browser, and always remains only on your computer.",
+ DISCLAIMER:
+ "A backup is made and stored in this browser, and always remains only on your computer.",
DOWNLOAD: "Download Everything",
RESTORE: "Restore",
},
@@ -64,24 +66,28 @@ const en = {
TERMINAL: "Terminal",
APPLY_SETTINGS: "Flash changes to device",
NO_DEVICE: "No device connected",
- LINUX_PERMISSIONS: "Most Linux based systems need adjusted permissions in order to connect your device.",
+ LINUX_PERMISSIONS:
+ "Most Linux based systems need adjusted permissions in order to connect your device.",
bootMenu: {
TITLE: "Boot Menu",
REBOOT: "Reboot",
BOOTLOADER: "Bootloader",
- POWER_WARNING: "To reboot from bootloader you need to physically reconnect your device.",
+ POWER_WARNING:
+ "To reboot from bootloader you need to physically reconnect your device.",
},
},
browserWarning: {
TITLE: "Warning",
- INFO_SERIAL_PREFIX: "Your current browser is not supported due to this site's unique requirement for ",
+ INFO_SERIAL_PREFIX:
+ "Your current browser is not supported due to this site's unique requirement for ",
INFO_SERIAL_INFIX: "serial connections",
INFO_SERIAL_SUFFIX: ".",
INFO_BROWSER_PREFIX:
"Though all chromium-based desktop browsers fulfill this requirement, some derivations such as Brave ",
INFO_BROWSER_INFIX: "have been known to disable the API intentionally",
INFO_BROWSER_SUFFIX: ".",
- DOWNLOAD_APP: "Chrome or Edge are officially supported, but other browsers might work as well.",
+ DOWNLOAD_APP:
+ "Chrome or Edge are officially supported, but other browsers might work as well.",
},
changes: {
TITLE: "Import changes",
@@ -131,6 +137,6 @@ const en = {
RUN: "Run",
},
},
-} satisfies BaseTranslation
+} satisfies BaseTranslation;
-export default en
+export default en;
diff --git a/src/i18n/formatters.ts b/src/i18n/formatters.ts
index d0e4d44c..80e1342d 100644
--- a/src/i18n/formatters.ts
+++ b/src/i18n/formatters.ts
@@ -1,10 +1,12 @@
-import type {FormattersInitializer} from "typesafe-i18n"
-import type {Locales, Formatters} from "./i18n-types"
+import type { FormattersInitializer } from "typesafe-i18n";
+import type { Locales, Formatters } from "./i18n-types";
-export const initFormatters: FormattersInitializer = (locale: Locales) => {
+export const initFormatters: FormattersInitializer = (
+ locale: Locales,
+) => {
const formatters: Formatters = {
// add your formatter functions here
- }
+ };
- return formatters
-}
+ return formatters;
+};
diff --git a/src/lib/assets/keymaps/keymap.d.ts b/src/lib/assets/keymaps/keymap.d.ts
index e95dbecd..b93c29d1 100644
--- a/src/lib/assets/keymaps/keymap.d.ts
+++ b/src/lib/assets/keymaps/keymap.d.ts
@@ -1,19 +1,19 @@
export interface KeymapCategory {
- name: string
- description: string
- icon?: string
- display?: string
- type?: "unassigned"
- actions: Record>
+ name: string;
+ description: string;
+ icon?: string;
+ display?: string;
+ type?: "unassigned";
+ actions: Record>;
}
export interface ActionInfo {
- id: string
- title: string
- icon: string
- display: string
- description: string
- variant: "left" | "right"
- variantOf: number
- keyCode: string
+ id: string;
+ title: string;
+ icon: string;
+ display: string;
+ description: string;
+ variant: "left" | "right";
+ variantOf: number;
+ keyCode: string;
}
diff --git a/src/lib/assets/layouts/lite.yml b/src/lib/assets/layouts/lite.yml
index f3c33c24..8271e03e 100644
--- a/src/lib/assets/layouts/lite.yml
+++ b/src/lib/assets/layouts/lite.yml
@@ -15,10 +15,10 @@ col:
- key: 64
- key: 65
- key: 66
- size: [ 2, 1 ]
+ size: [2, 1]
- row:
- key: 39
- size: [ 1.5, 1 ]
+ size: [1.5, 1]
- key: 40
- key: 41
- key: 42
@@ -32,10 +32,10 @@ col:
- key: 50
- key: 51
- key: 52
- size: [ 1.5, 1 ]
+ size: [1.5, 1]
- row:
- key: 26
- size: [ 1.75, 1 ]
+ size: [1.75, 1]
- key: 27
- key: 28
- key: 29
@@ -48,10 +48,10 @@ col:
- key: 36
- key: 37
- key: 38
- size: [ 2.25, 1 ]
+ size: [2.25, 1]
- row:
- key: 12
- size: [ 2, 1 ]
+ size: [2, 1]
- key: 13
- key: 14
- key: 15
@@ -68,20 +68,19 @@ col:
- row:
- key: 0
- key: 1
- size: [ 1.25, 1 ]
+ size: [1.25, 1]
- key: 2
- size: [ 1.25, 1 ]
+ size: [1.25, 1]
- key: 3
- size: [ 2, 1 ]
+ size: [2, 1]
- key: 4
- key: 5
- key: 6
- size: [ 2, 1 ]
+ size: [2, 1]
- key: 7
- size: [ 1.25, 1 ]
+ size: [1.25, 1]
- key: 8
- size: [ 1.25, 1 ]
+ size: [1.25, 1]
- key: 9
- key: 10
- key: 11
-
diff --git a/src/lib/backup/backup.ts b/src/lib/backup/backup.ts
index c832ea93..dd5f19e6 100644
--- a/src/lib/backup/backup.ts
+++ b/src/lib/backup/backup.ts
@@ -4,33 +4,45 @@ import type {
CharaFile,
CharaLayoutFile,
CharaSettingsFile,
-} from "$lib/share/chara-file.js"
-import type {Change} from "$lib/undo-redo.js"
-import {changes, ChangeType, chords, layout, settings} from "$lib/undo-redo.js"
-import {get} from "svelte/store"
-import {serialPort} from "../serial/connection"
-import {csvLayoutToJson, isCsvLayout} from "$lib/backup/compat/legacy-layout"
-import {isCsvChords, csvChordsToJson} from "./compat/legacy-chords"
+} from "$lib/share/chara-file.js";
+import type { Change } from "$lib/undo-redo.js";
+import {
+ changes,
+ ChangeType,
+ chords,
+ layout,
+ settings,
+} from "$lib/undo-redo.js";
+import { get } from "svelte/store";
+import { serialPort } from "../serial/connection";
+import { csvLayoutToJson, isCsvLayout } from "$lib/backup/compat/legacy-layout";
+import { isCsvChords, csvChordsToJson } from "./compat/legacy-chords";
export function downloadFile>(contents: T) {
- const downloadUrl = URL.createObjectURL(new Blob([JSON.stringify(contents)], {type: "application/json"}))
- const element = document.createElement("a")
+ const downloadUrl = URL.createObjectURL(
+ new Blob([JSON.stringify(contents)], { type: "application/json" }),
+ );
+ const element = document.createElement("a");
element.setAttribute(
"download",
- `${contents.type}-${get(serialPort)?.device}-${new Date().toISOString()}.json`,
- )
- element.href = downloadUrl
- element.setAttribute("target", "_blank")
- element.click()
- URL.revokeObjectURL(downloadUrl)
+ `${contents.type}-${
+ get(serialPort)?.device
+ }-${new Date().toISOString()}.json`,
+ );
+ element.href = downloadUrl;
+ element.setAttribute("target", "_blank");
+ element.click();
+ URL.revokeObjectURL(downloadUrl);
}
export function downloadBackup() {
downloadFile({
charaVersion: 1,
type: "backup",
- history: [[createChordBackup(), createLayoutBackup(), createSettingsBackup()]],
- })
+ history: [
+ [createChordBackup(), createLayoutBackup(), createSettingsBackup()],
+ ],
+ });
}
export function createLayoutBackup(): CharaLayoutFile {
@@ -38,28 +50,40 @@ export function createLayoutBackup(): CharaLayoutFile {
charaVersion: 1,
type: "layout",
device: get(serialPort)?.device,
- layout: get(layout).map(it => it.map(it => it.action)) as [number[], number[], number[]],
- }
+ layout: get(layout).map((it) => it.map((it) => it.action)) as [
+ number[],
+ number[],
+ number[],
+ ],
+ };
}
export function createChordBackup(): CharaChordFile {
- return {charaVersion: 1, type: "chords", chords: get(chords).map(it => [it.actions, it.phrase])}
+ return {
+ charaVersion: 1,
+ type: "chords",
+ chords: get(chords).map((it) => [it.actions, it.phrase]),
+ };
}
export function createSettingsBackup(): CharaSettingsFile {
- return {charaVersion: 1, type: "settings", settings: get(settings).map(it => it.value)}
+ return {
+ charaVersion: 1,
+ type: "settings",
+ settings: get(settings).map((it) => it.value),
+ };
}
export async function restoreBackup(event: Event) {
- const input = (event.target as HTMLInputElement).files![0]
- if (!input) return
- const text = await input.text()
+ const input = (event.target as HTMLInputElement).files![0];
+ if (!input) return;
+ const text = await input.text();
if (input.name.endsWith(".json")) {
- restoreFromFile(JSON.parse(text))
+ restoreFromFile(JSON.parse(text));
} else if (isCsvLayout(text)) {
- restoreFromFile(csvLayoutToJson(text))
+ restoreFromFile(csvLayoutToJson(text));
} else if (isCsvChords(text)) {
- restoreFromFile(csvChordsToJson(text))
+ restoreFromFile(csvChordsToJson(text));
} else {
}
}
@@ -67,86 +91,90 @@ export async function restoreBackup(event: Event) {
export function restoreFromFile(
file: CharaBackupFile | CharaSettingsFile | CharaLayoutFile | CharaChordFile,
) {
- if (file.charaVersion !== 1) throw new Error("Incompatible backup")
+ if (file.charaVersion !== 1) throw new Error("Incompatible backup");
switch (file.type) {
case "backup": {
- const recent = file.history[0]
+ const recent = file.history[0];
if (recent[1].device !== get(serialPort)?.device) {
- alert("Backup is incompatible with this device")
- throw new Error("Backup is incompatible with this device")
+ alert("Backup is incompatible with this device");
+ throw new Error("Backup is incompatible with this device");
}
- changes.update(changes => {
+ changes.update((changes) => {
changes.push(
...getChangesFromChordFile(recent[0]),
...getChangesFromLayoutFile(recent[1]),
...getChangesFromSettingsFile(recent[2]),
- )
- return changes
- })
- break
+ );
+ return changes;
+ });
+ break;
}
case "chords": {
- changes.update(changes => {
- changes.push(...getChangesFromChordFile(file))
- return changes
- })
- break
+ changes.update((changes) => {
+ changes.push(...getChangesFromChordFile(file));
+ return changes;
+ });
+ break;
}
case "layout": {
- changes.update(changes => {
- changes.push(...getChangesFromLayoutFile(file))
- return changes
- })
- break
+ changes.update((changes) => {
+ changes.push(...getChangesFromLayoutFile(file));
+ return changes;
+ });
+ break;
}
case "settings": {
- changes.update(changes => {
- changes.push(...getChangesFromSettingsFile(file))
- return changes
- })
- break
+ changes.update((changes) => {
+ changes.push(...getChangesFromSettingsFile(file));
+ return changes;
+ });
+ break;
}
default: {
- throw new Error(`Unknown backup type "${(file as CharaFile).type}"`)
+ throw new Error(
+ `Unknown backup type "${(file as CharaFile).type}"`,
+ );
}
}
}
export function getChangesFromChordFile(file: CharaChordFile) {
- const changes: Change[] = []
- const existingChords = new Set(get(chords).map(({phrase, actions}) => JSON.stringify([actions, phrase])))
+ const changes: Change[] = [];
+ const existingChords = new Set(
+ get(chords).map(({ phrase, actions }) => JSON.stringify([actions, phrase])),
+ );
for (const [input, output] of file.chords) {
if (existingChords.has(JSON.stringify([input, output]))) {
- continue
+ continue;
}
changes.push({
type: ChangeType.Chord,
actions: input,
phrase: output,
id: input,
- })
+ });
}
- return changes
+ return changes;
}
export function getChangesFromSettingsFile(file: CharaSettingsFile) {
- const changes: Change[] = []
+ const changes: Change[] = [];
for (const [id, value] of file.settings.entries()) {
- const setting = get(settings)[id]
+ const setting = get(settings)[id];
if (setting !== undefined && setting.value !== value) {
changes.push({
type: ChangeType.Setting,
id,
setting: value,
- })
+ });
}
}
- return changes
+ return changes;
}
export function getChangesFromLayoutFile(file: CharaLayoutFile) {
- const changes: Change[] = []
+ const changes: Change[] = [];
for (const [layer, keys] of file.layout.entries()) {
for (const [id, action] of keys.entries()) {
if (get(layout)[layer][id].action !== action) {
@@ -155,9 +183,9 @@ export function getChangesFromLayoutFile(file: CharaLayoutFile) {
layer,
id,
action,
- })
+ });
}
}
}
- return changes
+ return changes;
}
diff --git a/src/lib/backup/compat/legacy-chords.ts b/src/lib/backup/compat/legacy-chords.ts
index 2777a271..2450975c 100644
--- a/src/lib/backup/compat/legacy-chords.ts
+++ b/src/lib/backup/compat/legacy-chords.ts
@@ -1,7 +1,7 @@
-import {KEYMAP_IDS} from "$lib/serial/keymap-codes"
-import type {CharaChordFile} from "$lib/share/chara-file"
+import { KEYMAP_IDS } from "$lib/serial/keymap-codes";
+import type { CharaChordFile } from "$lib/share/chara-file";
-const SPECIAL_KEYS = new Map([[" ", "SPACE"]])
+const SPECIAL_KEYS = new Map([[" ", "SPACE"]]);
export function csvChordsToJson(csv: string): CharaChordFile {
return {
@@ -10,22 +10,22 @@ export function csvChordsToJson(csv: string): CharaChordFile {
chords: csv
.trim()
.split("\n")
- .map(line => {
- const [input, output] = line.split(/,(?=[^,]*$)/, 2)
+ .map((line) => {
+ const [input, output] = line.split(/,(?=[^,]*$)/, 2);
return [
input
.split("+")
- .map(it => KEYMAP_IDS.get(it.trim())?.code ?? 0)
+ .map((it) => KEYMAP_IDS.get(it.trim())?.code ?? 0)
.sort((a, b) => a - b),
output
.trim()
.split("")
- .map(it => KEYMAP_IDS.get(SPECIAL_KEYS.get(it) ?? it)?.code ?? 0),
- ]
+ .map((it) => KEYMAP_IDS.get(SPECIAL_KEYS.get(it) ?? it)?.code ?? 0),
+ ];
}),
- }
+ };
}
export function isCsvChords(csv: string): boolean {
- return /^([^+]+( *\+ *[^+]+)* *, *[^+, ]+ *(\n|(?=$)))+$/.test(csv)
+ return /^([^+]+( *\+ *[^+]+)* *, *[^+, ]+ *(\n|(?=$)))+$/.test(csv);
}
diff --git a/src/lib/backup/compat/legacy-layout-converted.sample.json b/src/lib/backup/compat/legacy-layout-converted.sample.json
index 451b4572..a82a060d 100644
--- a/src/lib/backup/compat/legacy-layout-converted.sample.json
+++ b/src/lib/backup/compat/legacy-layout-converted.sample.json
@@ -4,21 +4,24 @@
"device": "one",
"layout": [
[
- 309, 304, 312, 303, 306, 290, 282, 301, 266, 285, 289, 270, 281, 272, 262, 288, 277, 298, 307, 264, 287,
- 268, 332, 311, 274, 286, 308, 329, 310, 280, 358, 512, 515, 513, 514, 313, 319, 318, 321, 320, 326, 315,
- 314, 317, 316, 312, 330, 331, 333, 334, 291, 261, 283, 536, 276, 292, 265, 275, 267, 263, 293, 260, 296,
- 544, 279, 294, 271, 299, 269, 273, 295, 284, 297, 302, 278, 357, 516, 519, 517, 518, 327, 336, 338, 335,
- 337, 328, 325, 322, 323, 324
+ 309, 304, 312, 303, 306, 290, 282, 301, 266, 285, 289, 270, 281, 272, 262,
+ 288, 277, 298, 307, 264, 287, 268, 332, 311, 274, 286, 308, 329, 310, 280,
+ 358, 512, 515, 513, 514, 313, 319, 318, 321, 320, 326, 315, 314, 317, 316,
+ 312, 330, 331, 333, 334, 291, 261, 283, 536, 276, 292, 265, 275, 267, 263,
+ 293, 260, 296, 544, 279, 294, 271, 299, 269, 273, 295, 284, 297, 302, 278,
+ 357, 516, 519, 517, 518, 327, 336, 338, 335, 337, 328, 325, 322, 323, 324
],
[
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
],
[
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
]
}
diff --git a/src/lib/backup/compat/legacy-layout.spec.ts b/src/lib/backup/compat/legacy-layout.spec.ts
index d81a8eb8..d898ee3b 100644
--- a/src/lib/backup/compat/legacy-layout.spec.ts
+++ b/src/lib/backup/compat/legacy-layout.spec.ts
@@ -1,18 +1,18 @@
-import {describe, expect, it} from "vitest"
-import legacyLayout from "./legacy-layout.sample.csv?raw"
-import legacyLayoutConverted from "./legacy-layout-converted.sample.json"
-import {csvLayoutToJson, isCsvLayout} from "./legacy-layout"
+import { describe, expect, it } from "vitest";
+import legacyLayout from "./legacy-layout.sample.csv?raw";
+import legacyLayoutConverted from "./legacy-layout-converted.sample.json";
+import { csvLayoutToJson, isCsvLayout } from "./legacy-layout";
describe("legacy layout", () => {
it("should detect a legacy layout", () => {
- expect(isCsvLayout(legacyLayout)).to.be.true
- })
+ expect(isCsvLayout(legacyLayout)).to.be.true;
+ });
it("should not detect chord maps as layouts", () => {
- expect(isCsvLayout("e + h + t,the")).to.be.false
- })
+ expect(isCsvLayout("e + h + t,the")).to.be.false;
+ });
it("should convert legacy layouts", () => {
- expect(csvLayoutToJson(legacyLayout)).to.deep.equal(legacyLayoutConverted)
- })
-})
+ expect(csvLayoutToJson(legacyLayout)).to.deep.equal(legacyLayoutConverted);
+ });
+});
diff --git a/src/lib/backup/compat/legacy-layout.ts b/src/lib/backup/compat/legacy-layout.ts
index bca022ff..2efbb315 100644
--- a/src/lib/backup/compat/legacy-layout.ts
+++ b/src/lib/backup/compat/legacy-layout.ts
@@ -1,25 +1,28 @@
-import type {CharaLayoutFile} from "$lib/share/chara-file"
+import type { CharaLayoutFile } from "$lib/share/chara-file";
/**
* Converts a legacy CSV-based layout to the modern JSON-based format
*/
-export function csvLayoutToJson(csv: string, device: CharaLayoutFile["device"] = "one"): CharaLayoutFile {
+export function csvLayoutToJson(
+ csv: string,
+ device: CharaLayoutFile["device"] = "one",
+): CharaLayoutFile {
const layout: CharaLayoutFile = {
charaVersion: 1,
type: "layout",
device,
layout: [[], [], []],
- }
+ };
for (const layer of csv.trim().split("\n")) {
- const [layerId, key, action] = layer.substring(1).split(",").map(Number)
+ const [layerId, key, action] = layer.substring(1).split(",").map(Number);
- layout.layout[Number(layerId) - 1][Number(key)] = Number(action)
+ layout.layout[Number(layerId) - 1][Number(key)] = Number(action);
}
- return layout
+ return layout;
}
export function isCsvLayout(csv: string): boolean {
- return /^(A[123],\d+,\d+\n?)+$/.test(csv)
+ return /^(A[123],\d+,\d+\n?)+$/.test(csv);
}
diff --git a/src/lib/components/Action.svelte b/src/lib/components/Action.svelte
index 9ca5e393..35674aeb 100644
--- a/src/lib/components/Action.svelte
+++ b/src/lib/components/Action.svelte
@@ -1,24 +1,31 @@
{#if dynamicMapping}
{info.icon ?? info.display ?? info.id ?? `0x${info.code.toString(16)}`}
{:else if display === "inline-keys"}
{#if !info.icon && info.id?.length === 1}
- {info.id}
+ {info.id}
{:else}
- {info.icon ?? info.display ?? info.id ?? `0x${info.code.toString(16)}`}
{/if}
{/if}
diff --git a/src/lib/components/ActionListItem.svelte b/src/lib/components/ActionListItem.svelte
index 4693cb66..380d085a 100644
--- a/src/lib/components/ActionListItem.svelte
+++ b/src/lib/components/ActionListItem.svelte
@@ -1,12 +1,14 @@
diff --git a/src/routes/ConfigTabs.svelte b/src/routes/ConfigTabs.svelte
index 82377325..91a87ef3 100644
--- a/src/routes/ConfigTabs.svelte
+++ b/src/routes/ConfigTabs.svelte
@@ -1,18 +1,34 @@
@@ -118,8 +123,11 @@
{#if page === 0}
| insertChord(detail)} /> | | |
|---|
insertChord(detail)}
+ /> | | |
{/if}
{#if $lastPage !== -1}
diff --git a/src/routes/config/chords/ChordActionEdit.svelte b/src/routes/config/chords/ChordActionEdit.svelte
index 43f1432f..477cdf04 100644
--- a/src/routes/config/chords/ChordActionEdit.svelte
+++ b/src/routes/config/chords/ChordActionEdit.svelte
@@ -1,80 +1,83 @@
chordActions?.[i] !== it)}
+ class:invalid={chord &&
+ chordActions?.some((it, i) => chordActions?.[i] !== it)}
class="chord"
on:click={edit}
on:keydown={keydown}
@@ -93,8 +96,13 @@
→
{/if}
{/if}
-
- add_circle
+
+ add_circle
•
diff --git a/src/routes/config/chords/ChordEdit.svelte b/src/routes/config/chords/ChordEdit.svelte
index 6a0a573b..45adc430 100644
--- a/src/routes/config/chords/ChordEdit.svelte
+++ b/src/routes/config/chords/ChordEdit.svelte
@@ -1,39 +1,46 @@
@@ -67,11 +74,19 @@
{#if !chord.deleted}
- delete
+ delete
{:else}
- restore_from_trash
+ restore_from_trash
{/if}
- undo
+ undo
share
|
diff --git a/src/routes/config/chords/ChordPhraseEdit.svelte b/src/routes/config/chords/ChordPhraseEdit.svelte
index 7f1c8a14..0c397e84 100644
--- a/src/routes/config/chords/ChordPhraseEdit.svelte
+++ b/src/routes/config/chords/ChordPhraseEdit.svelte
@@ -1,102 +1,102 @@
(hasFocus = true)}
- on:focusout={event => {
- if (event.relatedTarget !== button) hasFocus = false
+ on:focusout={(event) => {
+ if (event.relatedTarget !== button) hasFocus = false;
}}
>
{#if hasFocus}
diff --git a/src/routes/config/chords/action-selector.ts b/src/routes/config/chords/action-selector.ts
index 98036a02..5ac19063 100644
--- a/src/routes/config/chords/action-selector.ts
+++ b/src/routes/config/chords/action-selector.ts
@@ -1,50 +1,53 @@
-import ActionSelector from "$lib/components/layout/ActionSelector.svelte"
-import {tick} from "svelte"
+import ActionSelector from "$lib/components/layout/ActionSelector.svelte";
+import { tick } from "svelte";
export function selectAction(
event: MouseEvent | KeyboardEvent,
select: (action: number) => void,
dismissed?: () => void,
) {
- const component = new ActionSelector({target: document.body})
- const dialog = document.querySelector("dialog > div") as HTMLDivElement
- const backdrop = document.querySelector("dialog") as HTMLDialogElement
- const dialogRect = dialog.getBoundingClientRect()
- const groupRect = (event.target as HTMLElement).getBoundingClientRect()
+ const component = new ActionSelector({ target: document.body });
+ const dialog = document.querySelector("dialog > div") as HTMLDivElement;
+ const backdrop = document.querySelector("dialog") as HTMLDialogElement;
+ const dialogRect = dialog.getBoundingClientRect();
+ const groupRect = (event.target as HTMLElement).getBoundingClientRect();
- const scale = 0.5
- const dialogScale = `${1 - scale * (1 - groupRect.width / dialogRect.width)} ${
- 1 - scale * (1 - groupRect.height / dialogRect.height)
- }`
+ const scale = 0.5;
+ const dialogScale = `${
+ 1 - scale * (1 - groupRect.width / dialogRect.width)
+ } ${1 - scale * (1 - groupRect.height / dialogRect.height)}`;
const dialogTranslate = `${scale * (groupRect.x - dialogRect.x)}px ${
scale * (groupRect.y - dialogRect.y)
- }px`
+ }px`;
- const duration = 150
- const options = {duration, easing: "ease"}
+ const duration = 150;
+ const options = { duration, easing: "ease" };
const dialogAnimation = dialog.animate(
[
- {scale: dialogScale, translate: dialogTranslate},
- {translate: "0 0", scale: "1"},
+ { scale: dialogScale, translate: dialogTranslate },
+ { translate: "0 0", scale: "1" },
],
options,
- )
- const backdropAnimation = backdrop.animate([{opacity: 0}, {opacity: 1}], options)
+ );
+ const backdropAnimation = backdrop.animate(
+ [{ opacity: 0 }, { opacity: 1 }],
+ options,
+ );
async function closed() {
- dialogAnimation.reverse()
- backdropAnimation.reverse()
+ dialogAnimation.reverse();
+ backdropAnimation.reverse();
- await dialogAnimation.finished
+ await dialogAnimation.finished;
- component.$destroy()
- await tick()
- dismissed?.()
+ component.$destroy();
+ await tick();
+ dismissed?.();
}
- component.$on("close", closed)
- component.$on("select", ({detail}) => {
- select(detail)
- closed()
- })
+ component.$on("close", closed);
+ component.$on("select", ({ detail }) => {
+ select(detail);
+ closed();
+ });
}
diff --git a/src/routes/config/chords/input-converter.ts b/src/routes/config/chords/input-converter.ts
index a0308005..b12710d6 100644
--- a/src/routes/config/chords/input-converter.ts
+++ b/src/routes/config/chords/input-converter.ts
@@ -1,9 +1,12 @@
-import {KEYMAP_IDS, KEYMAP_KEYCODES} from "$lib/serial/keymap-codes"
+import { KEYMAP_IDS, KEYMAP_KEYCODES } from "$lib/serial/keymap-codes";
-export function inputToAction(event: KeyboardEvent, useKeycodes?: boolean): number | undefined {
+export function inputToAction(
+ event: KeyboardEvent,
+ useKeycodes?: boolean,
+): number | undefined {
if (useKeycodes) {
- return KEYMAP_KEYCODES.get(event.code)
+ return KEYMAP_KEYCODES.get(event.code);
} else {
- return KEYMAP_IDS.get(event.key)?.code ?? KEYMAP_KEYCODES.get(event.code)
+ return KEYMAP_IDS.get(event.key)?.code ?? KEYMAP_KEYCODES.get(event.code);
}
}
diff --git a/src/routes/config/layout/+page.svelte b/src/routes/config/layout/+page.svelte
index 0883c20f..8493d30e 100644
--- a/src/routes/config/layout/+page.svelte
+++ b/src/routes/config/layout/+page.svelte
@@ -1,39 +1,43 @@
diff --git a/src/routes/config/settings/+page.svelte b/src/routes/config/settings/+page.svelte
index bb17fa17..d86a1b14 100644
--- a/src/routes/config/settings/+page.svelte
+++ b/src/routes/config/settings/+page.svelte
@@ -1,9 +1,9 @@
@@ -14,19 +14,26 @@
{#if $serialPort}