diff --git a/src/api/backup/Backup.ts b/src/api/backup/Backup.ts
index 0a93d686..cee53329 100644
--- a/src/api/backup/Backup.ts
+++ b/src/api/backup/Backup.ts
@@ -6,7 +6,14 @@ import { Neuron } from "@Renderer/types/neurons";
import { BackupType } from "@Renderer/types/backups";
import { VirtualType } from "@Renderer/types/virtual";
import Device from "../comms/Device";
-import { rgb2w } from "../color";
+import {
+ convertColormapRtoR2,
+ convertKeymapRtoR2,
+ convertPaletteRtoR2,
+ parseColormapRaw,
+ parseKeymapRaw,
+ parsePaletteRaw,
+} from "../parsers";
// eslint-disable-next-line @typescript-eslint/no-var-requires
const glob = require(`glob`);
@@ -288,7 +295,7 @@ export default class Backup {
static convertRaiseToRaise2 = (backup: BackupType, dev: Device) => {
log.info("converting Raise Backup to Raise2");
const keyLayerSize = 80;
- const ColorLayerSize = 132;
+ const colorLayerSize = 132;
const localBackup: BackupType = JSON.parse(JSON.stringify(backup));
localBackup.neuron.device = dev.device;
@@ -296,123 +303,15 @@ export default class Backup {
const paletteIndex = localBackup.backup.findIndex(c => c.command === "palette");
const colormapIndex = localBackup.backup.findIndex(c => c.command === "colormap.map");
- const custom = localBackup.backup[keymapIndex].data
- .split(" ")
- .filter(v => v.length > 0)
- .map((k: string) => parseInt(k, 10))
- .reduce((resultArray, item, index) => {
- const localResult = resultArray;
- const chunkIndex = Math.floor(index / keyLayerSize);
+ const custom = parseKeymapRaw(localBackup.backup[keymapIndex].data, keyLayerSize);
+ const palette = parsePaletteRaw(localBackup.backup[paletteIndex].data, false);
+ const colormap = parseColormapRaw(localBackup.backup[colormapIndex].data, colorLayerSize);
- if (!localResult[chunkIndex]) {
- localResult[chunkIndex] = []; // start a new chunk
- }
- localResult[chunkIndex].push(item);
- return localResult;
- }, []);
- // log.info("CONVERSION 1:", paletteIndex, colormapIndex);
- const palette = localBackup.backup[paletteIndex].data
- .split(" ")
- .filter(v => v.length > 0)
- .map((k: string) => parseInt(k, 10))
- .reduce((resultArray, item, index) => {
- const localResult = resultArray;
- const chunkIndex = Math.floor(index / 3);
-
- if (!localResult[chunkIndex]) {
- localResult[chunkIndex] = []; // start a new chunk
- }
- localResult[chunkIndex].push(item);
- return localResult;
- }, [])
- .map(color => ({
- r: color[0],
- g: color[1],
- b: color[2],
- rgb: `rgb(${color[0]}, ${color[1]}, ${color[2]})`,
- }));
- // log.info("CONVERSION 2:", palette);
- const colormap = localBackup.backup[colormapIndex].data
- .split(" ")
- .filter(v => v.length > 0)
- .map((k: string) => parseInt(k, 10))
- .reduce((resultArray, item, index) => {
- const localResult = resultArray;
- const chunkIndex = Math.floor(index / ColorLayerSize);
-
- if (!localResult[chunkIndex]) {
- localResult[chunkIndex] = []; // start a new chunk
- }
- localResult[chunkIndex].push(item);
- return localResult;
- }, []);
-
- // log.info("CONVERSION 3:", colormap);
- const keymapFinal = custom.map((layer: number[]) => {
- let localLayer = [...layer];
- // restoring thumbcluster
- const preT = localLayer.slice(0, 69);
- const remT = localLayer[69];
- const movT = localLayer.slice(70, 72);
- const restT = localLayer.slice(72);
- localLayer = preT.concat(movT.concat(remT)).concat(restT);
-
- // if ansi
- if (dev.device.info.keyboardType === "ANSI") {
- // Move enter (31<>47)
- const symbolK = localLayer[31];
- const enterK = localLayer[47];
-
- localLayer[31] = enterK;
- localLayer[47] = symbolK;
- // Move shift (48<>49)
- const shiftK = localLayer[48];
- const extraK = localLayer[49];
-
- localLayer[48] = extraK;
- localLayer[49] = shiftK;
- }
-
- // if layout !== layout, solve shift & enter
- return localLayer;
- });
-
- // log.info("CONVERSION 4:", colormap);
- const colormapFinal = colormap.map((layer: number[]) => {
- const color = layer[130];
- const rest = layer.slice(0, -1);
- const result = rest.concat(new Array(45).fill(color));
-
- if (dev.device.info.keyboardType === "ANSI") {
- // Move enter (31<>47)
- const symbolC = result[40];
- const enterC = result[48];
-
- result[40] = enterC;
- result[48] = symbolC;
- }
-
- if (dev.device.info.keyboardType === "ANSI" && backup.neuron.device.info.keyboardType === "ISO") {
- // Move shift (48<>49)
- const shiftC = result[19];
- const extraC = result[20];
-
- result[20] = extraC;
- result[19] = shiftC;
- }
-
- return result;
- });
-
- // log.info("CONVERSION 5:", colormap);
- const paletteFinal = palette
- .map(color => {
- const rgbw = rgb2w(color);
- return [rgbw.r, rgbw.g, rgbw.b, rgbw.w];
- })
- .flat()
- .map(v => v.toString())
- .join(" ");
+ const keymapFinal = custom.map((layer: number[]) => convertKeymapRtoR2(layer, dev.device.info.keyboardType));
+ const colormapFinal = colormap.map((layer: number[]) =>
+ convertColormapRtoR2(layer, dev.device.info.keyboardType, backup.neuron.device.info.keyboardType),
+ );
+ const paletteFinal = palette.map(color => convertPaletteRtoR2(color));
// log.info("CONVERSION 6:", paletteFinal, colormapFinal);
localBackup.backup[colormapIndex].data = colormapFinal
@@ -423,7 +322,10 @@ export default class Backup {
.flat()
.map(k => k.toString())
.join(" ");
- localBackup.backup[paletteIndex].data = paletteFinal;
+ localBackup.backup[paletteIndex].data = paletteFinal
+ .flat()
+ .map(v => v.toString())
+ .join(" ");
log.info("Final Backup:", localBackup.backup);
return localBackup.backup;
diff --git a/src/api/parsers/colormap.ts b/src/api/parsers/colormap.ts
new file mode 100644
index 00000000..fb8249e3
--- /dev/null
+++ b/src/api/parsers/colormap.ts
@@ -0,0 +1,15 @@
+export const parseColormapRaw = (colormap: string, ColorLayerSize: number): number[][] =>
+ colormap
+ .split(" ")
+ .filter(v => v.length > 0)
+ .map((k: string) => parseInt(k, 10))
+ .reduce((resultArray, item, index) => {
+ const localResult: number[][] = resultArray;
+ const chunkIndex = Math.floor(index / ColorLayerSize);
+
+ if (!localResult[chunkIndex]) {
+ localResult[chunkIndex] = []; // start a new chunk
+ }
+ localResult[chunkIndex].push(item);
+ return localResult;
+ }, []);
diff --git a/src/api/parsers/conversions/raiseToRaise2.ts b/src/api/parsers/conversions/raiseToRaise2.ts
new file mode 100644
index 00000000..6910f041
--- /dev/null
+++ b/src/api/parsers/conversions/raiseToRaise2.ts
@@ -0,0 +1,62 @@
+import { PaletteType } from "@Renderer/types/layout";
+import { rgb2w } from "../../color";
+
+export const convertKeymapRtoR2 = (layer: number[], keyboardType: string) => {
+ let localLayer = [...layer];
+ // restoring thumbcluster
+ const preT = localLayer.slice(0, 69);
+ const remT = localLayer[69];
+ const movT = localLayer.slice(70, 72);
+ const restT = localLayer.slice(72);
+ localLayer = preT.concat(movT.concat(remT)).concat(restT);
+
+ // if ansi
+ if (keyboardType === "ANSI") {
+ // Move enter (31<>47)
+ const symbolK = localLayer[31];
+ const enterK = localLayer[47];
+
+ localLayer[31] = enterK;
+ localLayer[47] = symbolK;
+ // Move shift (48<>49)
+ const shiftK = localLayer[48];
+ const extraK = localLayer[49];
+
+ localLayer[48] = extraK;
+ localLayer[49] = shiftK;
+ }
+
+ // if layout !== layout, solve shift & enter
+ return localLayer;
+};
+
+export const convertColormapRtoR2 = (layer: number[], keyboardType: string, backupKeyboardType: string) => {
+ const color = layer[130];
+ const rest = layer.slice(0, -1);
+ const result = rest.concat(new Array(45).fill(color));
+
+ if (keyboardType === "ANSI") {
+ // Move enter (31<>47)
+ const symbolC = result[40];
+ const enterC = result[48];
+
+ result[40] = enterC;
+ result[48] = symbolC;
+ }
+
+ if (keyboardType === "ANSI" && backupKeyboardType === "ISO") {
+ // Move shift (48<>49)
+ const shiftC = result[19];
+ const extraC = result[20];
+
+ result[20] = extraC;
+ result[19] = shiftC;
+ }
+
+ return result;
+};
+
+export const convertPaletteRtoR2 = (color: PaletteType) => {
+ const rgbw = rgb2w(color);
+ return [rgbw.r, rgbw.g, rgbw.b, rgbw.w];
+};
diff --git a/src/api/parsers/index.ts b/src/api/parsers/index.ts
new file mode 100644
index 00000000..a092943c
--- /dev/null
+++ b/src/api/parsers/index.ts
@@ -0,0 +1,23 @@
+// Parsers
+import { parseKeymapRaw, serializeKeymap } from "./keymap";
+import { parsePaletteRaw } from "./palette";
+import { parseColormapRaw } from "./colormap";
+import { parseMacrosRaw, serializeMacros } from "./macros";
+import { parseSuperkeysRaw, serializeSuperkeys } from "./superkeys";
+
+// Converters
+import { convertKeymapRtoR2, convertColormapRtoR2, convertPaletteRtoR2 } from "./conversions/raiseToRaise2";
+
+export {
+ parseKeymapRaw,
+ serializeKeymap,
+ parsePaletteRaw,
+ parseColormapRaw,
+ parseMacrosRaw,
+ serializeMacros,
+ parseSuperkeysRaw,
+ serializeSuperkeys,
+ convertKeymapRtoR2,
+ convertColormapRtoR2,
+ convertPaletteRtoR2,
+};
diff --git a/src/api/parsers/keymap.ts b/src/api/parsers/keymap.ts
new file mode 100644
index 00000000..41287f2e
--- /dev/null
+++ b/src/api/parsers/keymap.ts
@@ -0,0 +1,26 @@
+import { KeyType } from "@Renderer/types/layout";
+import { KeymapDB } from "../keymap";
+
+const keymapDB = new KeymapDB();
+
+export const parseKeymapRaw = (keymap: string, keyLayerSize: number): number[][] =>
+ keymap
+ .split(" ")
+ .filter(v => v.length > 0)
+ .map((k: string) => parseInt(k, 10))
+ .reduce((resultArray, item, index) => {
+ const localResult = resultArray;
+ const chunkIndex = Math.floor(index / keyLayerSize);
+
+ if (!localResult[chunkIndex]) {
+ localResult[chunkIndex] = []; // start a new chunk
+ }
+ localResult[chunkIndex].push(item);
+ return localResult;
+ }, []);
+
+export const serializeKeymap = (keymap: KeyType[][]) =>
+ keymap
+ .flat()
+ .map(k => (typeof k === "number" ? String(k) : keymapDB.serialize(k).toString()))
+ .join(" ");
diff --git a/src/api/parsers/macros.ts b/src/api/parsers/macros.ts
new file mode 100644
index 00000000..39dbcec4
--- /dev/null
+++ b/src/api/parsers/macros.ts
@@ -0,0 +1,121 @@
+/* eslint-disable no-bitwise */
+import { MacroActionsType, MacrosType } from "@Renderer/types/macros";
+import { KeymapDB } from "../keymap";
+
+const macrosEraser = (tMem: number) => Array(tMem).fill("255").join(" ");
+
+export const parseMacrosRaw = (raw: string, storedMacros?: MacrosType[]) => {
+ const keymapDB = new KeymapDB();
+ const macrosArray = raw.split(" 0 0")[0].split(" ").map(Number);
+
+ // Translate received macros to human readable text
+ const macros: MacrosType[] = [];
+ let iter = 0;
+ // macros are `0` terminated or when end of macrosArray has been reached, the outer loop
+ // must cycle once more than the inner
+ while (iter <= macrosArray.length) {
+ const actions: MacroActionsType[] = [];
+ while (iter < macrosArray.length) {
+ const type = macrosArray[iter];
+ if (type === 0) {
+ break;
+ }
+
+ switch (type) {
+ case 1:
+ actions.push({
+ type,
+ keyCode: [
+ (macrosArray[(iter += 1)] << 8) + macrosArray[(iter += 1)],
+ (macrosArray[(iter += 1)] << 8) + macrosArray[(iter += 1)],
+ ],
+ });
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ actions.push({ type, keyCode: (macrosArray[(iter += 1)] << 8) + macrosArray[(iter += 1)] });
+ break;
+ case 6:
+ case 7:
+ case 8:
+ actions.push({ type, keyCode: macrosArray[(iter += 1)] });
+ break;
+ default:
+ break;
+ }
+
+ iter += 1;
+ }
+ macros.push({
+ actions,
+ name: "",
+ macro: "",
+ });
+ iter += 1;
+ }
+ macros.forEach((m, idx) => {
+ const aux = m;
+ aux.id = idx;
+ macros[idx] = aux;
+ });
+
+ // TODO: Check if stored macros match the received ones, if they match, retrieve name and apply it to current macros
+ const stored = storedMacros;
+ if (stored === undefined || stored.length === 0) {
+ return macros;
+ }
+ return macros.map((macro, i) => {
+ if (stored.length < i) {
+ return macro;
+ }
+
+ return {
+ ...macro,
+ name: stored[i]?.name,
+ macro: macro.actions.map(k => keymapDB.parse(k.keyCode as number).label).join(" "),
+ };
+ });
+};
+
+export const serializeMacros = (macros: MacrosType[], tMem: number) => {
+ // log.info(
+ // "Macros map function",
+ // macros,
+ // macrosEraser,
+ // macros.length === 0,
+ // macros.length === 1 && Array.isArray(macros[0].actions),
+ // );
+ if (macros.length === 0 || (macros.length === 1 && !Array.isArray(macros[0].actions))) {
+ return macrosEraser(tMem);
+ }
+ const mapAction = (action: MacroActionsType): number[] => {
+ switch (action.type) {
+ case 1:
+ return [
+ action.type,
+ (action.keyCode as number[])[0] >> 8,
+ (action.keyCode as number[])[0] & 255,
+ (action.keyCode as number[])[1] >> 8,
+ (action.keyCode as number[])[1] & 255,
+ ];
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ return [action.type, (action.keyCode as number) >> 8, (action.keyCode as number) & 255];
+ default:
+ return [action.type, action.keyCode as number];
+ }
+ };
+ const result: string = macros
+ .map(macro => macro.actions.map((action: MacroActionsType) => mapAction(action)).concat([0]))
+ .flat()
+ .concat([0])
+ .join(" ")
+ .split(",")
+ .join(" ");
+ // log.info("MACROS GOING TO BE SAVED", result);
+ return result;
+};
diff --git a/src/api/parsers/palette.ts b/src/api/parsers/palette.ts
new file mode 100644
index 00000000..1b7f7b26
--- /dev/null
+++ b/src/api/parsers/palette.ts
@@ -0,0 +1,47 @@
+import { rgbw2b } from "../color";
+
+export const parsePaletteRaw = (palette: string, isRGBW: boolean) =>
+ isRGBW
+ ? palette
+ .split(" ")
+ .filter(v => v.length > 0)
+ .map((k: string) => parseInt(k, 10))
+ .reduce((resultArray, item, index) => {
+ const localResult = resultArray;
+ const chunkIndex = Math.floor(index / 4);
+
+ if (!localResult[chunkIndex]) {
+ localResult[chunkIndex] = []; // start a new chunk
+ }
+ localResult[chunkIndex].push(item);
+ return localResult;
+ }, [])
+ .map(color => {
+ const coloraux = rgbw2b({ r: color[0], g: color[1], b: color[2], w: color[3] });
+ return {
+ r: coloraux.r,
+ g: coloraux.g,
+ b: coloraux.b,
+ rgb: coloraux.rgb,
+ };
+ })
+ : palette
+ .split(" ")
+ .filter(v => v.length > 0)
+ .map((k: string) => parseInt(k, 10))
+ .reduce((resultArray, item, index) => {
+ const localResult = resultArray;
+ const chunkIndex = Math.floor(index / 3);
+
+ if (!localResult[chunkIndex]) {
+ localResult[chunkIndex] = []; // start a new chunk
+ }
+ localResult[chunkIndex].push(item);
+ return localResult;
+ }, [])
+ .map(color => ({
+ r: color[0],
+ g: color[1],
+ b: color[2],
+ rgb: `rgb(${color[0]}, ${color[1]}, ${color[2]})`,
+ }));
diff --git a/src/api/parsers/superkeys.ts b/src/api/parsers/superkeys.ts
new file mode 100644
index 00000000..b5f7e94c
--- /dev/null
+++ b/src/api/parsers/superkeys.ts
@@ -0,0 +1,79 @@
+import log from "electron-log/renderer";
+import { SuperkeysType } from "@Renderer/types/superkeys";
+
+export const parseSuperkeysRaw = (raw: string, stored: SuperkeysType[]) => {
+ const superArray = raw.split(" 0 0")[0].split(" ").map(Number);
+
+ let superkey: number[] = [];
+ const superkeys: SuperkeysType[] = [];
+ let iter = 0;
+ let superindex = 0;
+
+ if (superArray.length < 1) {
+ log.warn("Discarded Superkeys due to short length of string", raw, raw.length);
+ return [];
+ }
+ // log.info(raw, raw.length);
+ while (superArray.length > iter) {
+ // log.info(iter, raw[iter], superkey);
+ if (superArray[iter] === 0) {
+ superkeys[superindex] = { actions: superkey, name: "", id: superindex };
+ superindex += 1;
+ superkey = [];
+ } else {
+ superkey.push(superArray[iter]);
+ }
+ iter += 1;
+ }
+ superkeys[superindex] = { actions: superkey, name: "", id: superindex };
+
+ if (superkeys[0].actions.length === 0 || superkeys[0].actions.length > 5) {
+ log.warn(`Superkeys were empty`);
+ return [];
+ }
+ // log.info(`Got Superkeys:${JSON.stringify(superkeys)} from ${raw}`);
+ // TODO: Check if stored superKeys match the received ones, if they match, retrieve name and apply it to current superKeys
+ let finalSuper: SuperkeysType[] = [];
+ finalSuper = superkeys.map((superky, i) => {
+ const superk = superky;
+ if (stored.length > i && stored.length > 0) {
+ const aux = superk;
+ aux.name = stored[i].name;
+ return aux;
+ }
+ return superk;
+ });
+ log.info("final superkeys", finalSuper);
+ return finalSuper;
+};
+
+export const serializeSuperkeys = (superkeys: SuperkeysType[]) => {
+ if (
+ superkeys.length === 0 ||
+ (superkeys.length === 1 && superkeys[0].actions.length === 0) ||
+ (superkeys.length === 1 && superkeys[0].actions.length === 1 && superkeys[0].actions[0] === 0)
+ ) {
+ return Array(512).fill("65535").join(" ");
+ }
+ let keyMap = JSON.parse(JSON.stringify(superkeys));
+ // log.info("First", JSON.stringify(keyMap));
+ keyMap = keyMap.map((sky: SuperkeysType) => {
+ const sk = sky;
+ sk.actions = sk.actions.map(act => {
+ if (act === 0 || act === null || act === undefined) return 1;
+ return act;
+ });
+ if (sk.actions.length < 5) sk.actions = sk.actions.concat(Array(5 - sk.actions.length).fill(1));
+ return sk;
+ });
+ // log.info("Third", JSON.parse(JSON.stringify(keyMap)));
+ const mapped = keyMap
+ .map((superkey: SuperkeysType) => superkey.actions.filter(act => act !== 0).concat([0]))
+ .flat()
+ .concat([0])
+ .join(" ")
+ .split(",")
+ .join(" ");
+ log.info("Mapped superkeys: ", mapped, keyMap);
+ return mapped;
+};
diff --git a/src/renderer/modules/KeysTabs/SuperkeysTab.tsx b/src/renderer/modules/KeysTabs/SuperkeysTab.tsx
index 50ab3746..179f412f 100644
--- a/src/renderer/modules/KeysTabs/SuperkeysTab.tsx
+++ b/src/renderer/modules/KeysTabs/SuperkeysTab.tsx
@@ -181,23 +181,22 @@ const SuperkeysTab = ({ macros, keyCode, onKeySelect, superkeys, disabled }: Sup
{superkeys[selected.current] !== undefined ? (
{superKeysActions.map((item, index) => (
- <>
+
>}
title={item.title}
description=""
elementActive={false}
- onClick={() => console.log("onClick")}
+ onClick={() => "onClick"}
macros={macros}
keymapDB={keymapDB}
- updateAction={() => console.log("update action")}
+ updateAction={() => "update action"}
variant="subtle"
/>
- >
+
))}
) : null}
diff --git a/src/renderer/types/dygmaDefs.ts b/src/renderer/types/dygmaDefs.ts
index 01a3e746..322d9f21 100644
--- a/src/renderer/types/dygmaDefs.ts
+++ b/src/renderer/types/dygmaDefs.ts
@@ -1,14 +1,16 @@
+export type DygmaDeviceInfoType = {
+ vendor: "Dygma";
+ product: "Raise" | "Defy" | "Raise2";
+ keyboardType: string;
+ displayName: string;
+ urls: {
+ name: string;
+ url: string;
+ }[];
+};
+
export type DygmaDeviceType = {
- info: {
- vendor: "Dygma";
- product: "Raise" | "Defy" | "Raise2";
- keyboardType: string;
- displayName: string;
- urls: {
- name: string;
- url: string;
- }[];
- };
+ info: DygmaDeviceInfoType;
usb: {
vendorId: number;
productId: number;
diff --git a/src/renderer/types/macroEditor.ts b/src/renderer/types/macroEditor.ts
index 00325468..9902a4b9 100644
--- a/src/renderer/types/macroEditor.ts
+++ b/src/renderer/types/macroEditor.ts
@@ -34,8 +34,9 @@ export interface MacroEditorInitialStateType {
macros: MacrosType[];
superkeys: SuperkeysType[];
storedMacros: MacrosType[];
+ storedSuper: SuperkeysType[];
neurons: Neuron[];
- neuronIdx: number;
+ neuronID: string;
maxMacros: number;
modified: boolean;
selectedMacro: number;
diff --git a/src/renderer/types/superkeyseditor.ts b/src/renderer/types/superkeyseditor.ts
index 5b9db43d..89312b22 100644
--- a/src/renderer/types/superkeyseditor.ts
+++ b/src/renderer/types/superkeyseditor.ts
@@ -32,6 +32,7 @@ export interface SuperkeysEditorInitialStateType {
macros: MacrosType[];
superkeys: SuperkeysType[];
storedMacros: MacrosType[];
+ storedSuper: SuperkeysType[];
neurons: Neuron[];
neuronID: string;
kbtype: string;
diff --git a/src/renderer/views/LayoutEditor.tsx b/src/renderer/views/LayoutEditor.tsx
index 82fcd880..ef3d33d3 100644
--- a/src/renderer/views/LayoutEditor.tsx
+++ b/src/renderer/views/LayoutEditor.tsx
@@ -35,7 +35,7 @@ import { useDevice } from "@Renderer/DeviceContext";
import { LayerType, Neuron } from "@Renderer/types/neurons";
import { ColormapType, KeymapType, KeyType, LayoutEditorProps, PaletteType, SegmentedKeyType } from "@Renderer/types/layout";
import { SuperkeysType } from "@Renderer/types/superkeys";
-import { MacroActionsType, MacrosType } from "@Renderer/types/macros";
+import { MacrosType } from "@Renderer/types/macros";
import { DeviceClass } from "@Renderer/types/devices";
// Modules
@@ -53,10 +53,21 @@ import { i18n } from "@Renderer/i18n";
import Store from "@Renderer/utils/Store";
import getLanguage from "@Renderer/utils/language";
import { ClearLayerDialog } from "@Renderer/components/molecules/CustomModal/ClearLayerDialog";
+import { DygmaDeviceInfoType } from "@Renderer/types/dygmaDefs";
import BlankTable from "../../api/keymap/db/blanks";
import Keymap, { KeymapDB } from "../../api/keymap";
-import { rgb2w, rgbw2b } from "../../api/color";
+import { rgb2w } from "../../api/color";
import Backup from "../../api/backup";
+import {
+ convertColormapRtoR2,
+ convertKeymapRtoR2,
+ parseColormapRaw,
+ parseKeymapRaw,
+ parseMacrosRaw,
+ parsePaletteRaw,
+ parseSuperkeysRaw,
+ serializeKeymap,
+} from "../../api/parsers";
const store = Store.getStore();
@@ -519,237 +530,15 @@ const LayoutEditor = (props: LayoutEditorProps) => {
store.set("neurons", neurons);
};
- const superTranslator = (raw: string, sSuper: SuperkeysType[]): SuperkeysType[] => {
- const superArray = raw.split(" 0 0")[0].split(" ").map(Number);
-
- let skAction: number[] = [];
- const sKeys: SuperkeysType[] = [];
- let iter = 0;
- let superindex = 0;
-
- if (superArray.length < 1) {
- log.info("Discarded Superkeys due to short length of string", raw, raw.length);
- return [];
- }
- while (superArray.length > iter) {
- // log.info(iter, raw[iter], superkey);
- if (superArray[iter] === 0) {
- sKeys[superindex] = { actions: skAction, name: "", id: superindex };
- superindex += 1;
- skAction = [];
- } else {
- skAction.push(superArray[iter]);
- }
- iter += 1;
- }
- sKeys[superindex] = { actions: skAction, name: "", id: superindex };
-
- if (sKeys[0].actions.length === 0 || sKeys[0].actions.length > 5) {
- log.info(`Superkeys were empty`);
- return [];
- }
- log.info(`Got Superkeys:${JSON.stringify(sKeys)} from ${raw}`);
- // TODO: Check if stored superKeys match the received ones, if they match, retrieve name and apply it to current superKeys
- let finalSuper: SuperkeysType[] = [];
- finalSuper = sKeys.map((superky, i) => {
- const superk = superky;
- superk.id = i;
- if (sSuper.length > i && sSuper.length > 0) {
- const aux = superk;
- aux.name = sSuper[i].name;
- return aux;
- }
- return superk;
- });
- log.info("final superkeys", finalSuper);
- return finalSuper;
- };
-
- const macroTranslator = useCallback(
- (raw: string | number[], storeMacros: MacrosType[]) => {
- if (raw === "") {
- return [
- {
- actions: [
- { keyCode: 229, type: 6, id: 0 },
- { keyCode: 11, type: 8, id: 1 },
- { keyCode: 229, type: 7, id: 2 },
- { keyCode: 8, type: 8, id: 3 },
- { keyCode: 28, type: 8, id: 4 },
- { keyCode: 54, type: 8, id: 5 },
- { keyCode: 44, type: 8, id: 6 },
- { keyCode: 229, type: 6, id: 7 },
- { keyCode: 7, type: 8, id: 8 },
- { keyCode: 229, type: 7, id: 9 },
- { keyCode: 28, type: 8, id: 10 },
- { keyCode: 10, type: 8, id: 11 },
- { keyCode: 16, type: 8, id: 12 },
- { keyCode: 4, type: 8, id: 13 },
- { keyCode: 23, type: 8, id: 14 },
- { keyCode: 8, type: 8, id: 15 },
- ],
- id: 0,
- macro: "RIGHT SHIFT H RIGHT SHIFT E Y , SPACE RIGHT SHIFT D RIGHT SHIFT Y G M A T E",
- name: "Hey, Dygmate!",
- },
- ];
- }
- // Translate received macros to human readable text
- let i = 0;
- let iter = 0;
- let kcs = 0;
- let type = 0;
- let keyCode = [];
- let actions = new Array();
- const mcros = new Array();
- actions = [];
- while (raw.length > iter) {
- if (kcs > 0) {
- keyCode.push((raw as number[])[iter]);
- kcs -= 1;
- } else {
- if (iter !== 0 && type !== 0) {
- actions.push({
- type,
- keyCode,
- id: undefined,
- });
- keyCode = [];
- }
- type = (raw as number[])[iter];
- switch (type) {
- case 0:
- kcs = 0;
- mcros[i] = { actions, id: i, name: "", macro: "" };
- i += 1;
- actions = [];
- break;
- case 1:
- kcs = 4;
- break;
- case 2:
- case 3:
- case 4:
- case 5:
- kcs = 2;
- break;
- default:
- kcs = 1;
- }
- }
- iter += 1;
- }
- actions.push({
- type,
- keyCode,
- id: undefined,
- });
- mcros[i] = {
- actions,
- id: i,
- name: "",
- macro: "",
- };
- const localMacros = mcros.map(m => {
- const aux: MacroActionsType[] = m.actions.map((action, idx) => {
- if (Array.isArray(action.keyCode))
- switch (action.type) {
- case 1:
- return {
- type: action.type,
- keyCode: [(action.keyCode[0] << 8) + action.keyCode[1], (action.keyCode[2] << 8) + action.keyCode[3]],
- id: idx,
- };
- case 2:
- case 3:
- case 4:
- case 5:
- return {
- type: action.type,
- keyCode: (action.keyCode[0] << 8) + action.keyCode[1],
- id: idx,
- };
- default:
- return {
- type: action.type,
- keyCode: action.keyCode[0],
- id: idx,
- };
- }
- return action;
- });
- return { ...m, actions: aux };
- });
- // TODO: Check if stored macros match the received ones, if they match, retrieve name and apply it to current macros
- let finalMacros = [];
- log.info("Checking Macros", localMacros, storeMacros);
- if (storeMacros === undefined) {
- return localMacros;
- }
- finalMacros = localMacros.map((m, idx) => {
- if (storeMacros.length > idx && storeMacros.length > 0) {
- const aux = m;
- aux.name = storeMacros[idx].name;
- aux.macro = m.actions.map(k => keymapDB.parse(k.keyCode as number).label).join(" ");
- return aux;
- }
- return m;
- });
-
- return finalMacros;
- },
- [keymapDB],
- );
-
const getColormap = useCallback(async (): Promise => {
const { currentDevice } = state;
const layerSize = currentDevice.device.keyboardUnderglow.rows * currentDevice.device.keyboardUnderglow.columns;
- const chunk = (a: number[], chunkSize: number) => {
- const R = [];
- for (let i = 0; i < a.length; i += chunkSize) R.push(a.slice(i, i + chunkSize));
- return R;
- };
-
const paletteData = (await currentDevice?.command("palette")) as string;
const colorMapData = (await currentDevice?.command("colormap.map")) as string;
- const plette =
- currentDevice?.device.RGBWMode !== true
- ? chunk(
- paletteData
- .split(" ")
- .filter((v: string) => v.length > 0)
- .map((k: string) => parseInt(k, 10)),
- 3,
- ).map(color => ({
- r: color[0],
- g: color[1],
- b: color[2],
- rgb: `rgb(${color[0]}, ${color[1]}, ${color[2]})`,
- }))
- : chunk(
- paletteData
- .split(" ")
- .filter((v: string) => v.length > 0)
- .map((k: string) => parseInt(k, 10)),
- 4,
- ).map(color => {
- const coloraux = rgbw2b({ r: color[0], g: color[1], b: color[2], w: color[3] });
- return {
- r: coloraux.r,
- g: coloraux.g,
- b: coloraux.b,
- rgb: coloraux.rgb,
- };
- });
-
- const colMap = chunk(
- colorMapData
- .split(" ")
- .filter((v: string) => v.length > 0)
- .map((k: string) => parseInt(k, 10)),
- layerSize,
- );
+ const plette = parsePaletteRaw(paletteData, currentDevice?.device.RGBWMode);
+ log.info("PARSED PALETTE: ", paletteData, plette, currentDevice?.device.RGBWMode);
+ const colMap = parseColormapRaw(colorMapData, layerSize);
return {
palette: plette,
@@ -941,34 +730,8 @@ const LayoutEditor = (props: LayoutEditorProps) => {
};
const layerSize = currentDevice.device.keyboard.rows * currentDevice.device.keyboard.columns;
- KeyMap.custom = custom
- .split(" ")
- .filter(v => v.length > 0)
- .map((k: string) => keymapDB.parse(parseInt(k, 10)))
- .reduce((resultArray, item, index) => {
- const localResult = resultArray;
- const chunkIndex = Math.floor(index / layerSize);
-
- if (!localResult[chunkIndex]) {
- localResult[chunkIndex] = []; // start a new chunk
- }
- localResult[chunkIndex].push(item);
- return localResult;
- }, []);
- KeyMap.default = defaults
- .split(" ")
- .filter(v => v.length > 0)
- .map((k: string) => keymapDB.parse(parseInt(k, 10)))
- .reduce((resultArray, item, index) => {
- const localResult = resultArray;
- const chunkIndex = Math.floor(index / layerSize);
-
- if (!localResult[chunkIndex]) {
- localResult[chunkIndex] = []; // start a new chunk
- }
- localResult[chunkIndex].push(item);
- return localResult;
- }, []);
+ KeyMap.custom = parseKeymapRaw(custom, layerSize).map(l => l.map((k: number) => keymapDB.parse(k)));
+ KeyMap.default = parseKeymapRaw(defaults, layerSize).map(l => l.map((k: number) => keymapDB.parse(k)));
KeyMap.onlyCustom = onlyCustom;
let empty = true;
@@ -999,18 +762,13 @@ const LayoutEditor = (props: LayoutEditorProps) => {
// loading Macros
setScanningStep(7);
- let raw: string | number[] = (await currentDevice?.command("macros.map")) as string;
- if (raw.search(" 0 0") !== -1) {
- raw = raw.split(" 0 0")[0].split(" ").map(Number);
- } else {
- raw = "";
- }
- const parsedMacros = macroTranslator(raw, neuronData.storedMacros);
+ const rawMacros = (await currentDevice?.command("macros.map")) as string;
+ const parsedMacros = parseMacrosRaw(rawMacros, neuronData.storedMacros);
// Loading Superkeys
setScanningStep(8);
- const raw2: string = (await currentDevice?.command("superkeys.map")) as string;
- const parsedSuper = superTranslator(raw2, neuronData.storedSuper);
+ const rawSuper = (await currentDevice?.command("superkeys.map")) as string;
+ const parsedSuper = parseSuperkeysRaw(rawSuper, neuronData.storedSuper);
setScanningStep(9);
let showMM = false;
@@ -1050,7 +808,7 @@ const LayoutEditor = (props: LayoutEditorProps) => {
onDisconnect();
}
},
- [state, setLoading, AnalizeChipID, restoredOk, getColormap, macroTranslator, handleSetRestoredOk, keymapDB, onDisconnect],
+ [state, setLoading, AnalizeChipID, restoredOk, getColormap, handleSetRestoredOk, keymapDB, onDisconnect],
);
const onKeyChange = (keyCode: number) => {
@@ -1158,8 +916,7 @@ const LayoutEditor = (props: LayoutEditorProps) => {
try {
setLoading(true);
setIsSaving(true);
- const args = flatten(keymap.custom).map(k => keymapDB.serialize(k).toString());
- await currentDevice?.command("keymap.custom", ...args);
+ await currentDevice?.command("keymap.custom", serializeKeymap(keymap.custom));
await currentDevice?.command("keymap.onlyCustom", keymap.onlyCustom ? "1" : "0");
await updateColormap(currentDevice, colorMap);
await updatePalette(currentDevice, palette);
@@ -1429,12 +1186,15 @@ const LayoutEditor = (props: LayoutEditorProps) => {
};
const importLayer = (data: {
+ device: DygmaDeviceInfoType;
+ language: string;
layerNames: LayerType[];
layerName: string;
keymap: KeyType[];
colormap: number[];
palette: PaletteType[];
}) => {
+ const { currentDevice } = state;
log.info("not loading the palette: ", palette);
// if (data.palette.length > 0) state.palette = data.palette;
const lNames = layerNames.slice();
@@ -1447,19 +1207,30 @@ const LayoutEditor = (props: LayoutEditorProps) => {
}
setLayerNames(lNames);
}
- const parsedKeymap = data.keymap.map(key => {
- let localKey = key;
- if (typeof localKey.extraLabel === "object" || typeof localKey.label === "object")
- localKey = keymapDB.parse(localKey.keyCode);
- return localKey;
- });
+ let cleanKeymap: KeyType[];
+ let cleanColormap: number[];
+ if (currentDevice?.device.info.product === "Raise2" && data.device.product === "Raise") {
+ cleanKeymap = convertKeymapRtoR2(
+ data.keymap.map(k => k.keyCode),
+ currentDevice?.device.info.keyboardType,
+ ).map(k => keymapDB.parse(k));
+ cleanColormap = convertColormapRtoR2(data.colormap, currentDevice?.device.info.keyboardType, data.device.keyboardType);
+ } else {
+ cleanKeymap = data.keymap.map(key => {
+ let localKey = key;
+ if (typeof localKey.extraLabel === "object" || typeof localKey.label === "object")
+ localKey = keymapDB.parse(localKey.keyCode);
+ return localKey;
+ });
+ cleanColormap = data.colormap;
+ }
if (data.keymap.length > 0 && data.colormap.length > 0) {
if (keymap.onlyCustom) {
if (currentLayer >= 0) {
const newKeymap = keymap.custom.slice();
- newKeymap[currentLayer] = parsedKeymap;
+ newKeymap[currentLayer] = cleanKeymap;
const newColormap = colorMap.slice();
- newColormap[currentLayer] = data.colormap.slice();
+ newColormap[currentLayer] = cleanColormap;
setKeymap({
default: keymap.default,
custom: newKeymap,
@@ -1470,9 +1241,9 @@ const LayoutEditor = (props: LayoutEditorProps) => {
} else if (currentLayer >= keymap.default.length) {
const defLength = keymap.default.length;
const newKeymap = keymap.custom.slice();
- newKeymap[currentLayer - defLength] = parsedKeymap;
+ newKeymap[currentLayer - defLength] = cleanKeymap;
const newColormap = colorMap.slice();
- newColormap[currentLayer - defLength] = data.colormap.slice();
+ newColormap[currentLayer - defLength] = cleanColormap;
setKeymap({
default: keymap.default,
diff --git a/src/renderer/views/MacroEditor.tsx b/src/renderer/views/MacroEditor.tsx
index e65e2e70..20fa8205 100644
--- a/src/renderer/views/MacroEditor.tsx
+++ b/src/renderer/views/MacroEditor.tsx
@@ -34,7 +34,6 @@ import {
} from "@Renderer/types/macroEditor";
import { Neuron } from "@Renderer/types/neurons";
import { KeymapType } from "@Renderer/types/layout";
-import { SuperkeysType } from "@Renderer/types/superkeys";
import { MacroActionsType, MacrosType } from "@Renderer/types/macros";
// Components
@@ -59,6 +58,14 @@ import Keymap, { KeymapDB } from "../../api/keymap";
import Store from "../utils/Store";
import getLanguage from "../utils/language";
+import {
+ parseKeymapRaw,
+ serializeKeymap,
+ parseMacrosRaw,
+ parseSuperkeysRaw,
+ serializeMacros,
+ serializeSuperkeys,
+} from "../../api/parsers";
const store = Store.getStore();
@@ -108,15 +115,14 @@ function MacroEditor(props: MacroEditorProps) {
const bkp = new Backup();
const [isSaving, setIsSaving] = useState(false);
- const flatten = (arr: unknown[]) => [].concat(...arr);
-
const initialState: MacroEditorInitialStateType = {
keymap: undefined,
macros: [],
superkeys: [],
storedMacros: [],
+ storedSuper: [],
neurons: [],
- neuronIdx: 0,
+ neuronID: "",
maxMacros: 128,
modified: false,
selectedMacro: 0,
@@ -138,126 +144,6 @@ function MacroEditor(props: MacroEditorProps) {
const { state: deviceState } = useDevice();
const timelineRef = useRef(null);
- const superTranslator = (raw: string) => {
- const { neurons, neuronIdx } = state;
- const superArray = raw.split(" 0 0")[0].split(" ").map(Number);
-
- let skAction: number[] = [];
- const superkeys: SuperkeysType[] = [];
- let iter = 0;
- let superindex = 0;
-
- if (superArray.length < 1) {
- log.info("Discarded Superkeys due to short length of string", raw, raw.length);
- return [{ actions: [53, 2101, 1077, 41, 0], name: "Welcome to superkeys", id: superindex }];
- }
- while (superArray.length > iter) {
- // log.info(iter, raw[iter], superkey);
- if (superArray[iter] === 0) {
- superkeys[superindex] = { actions: skAction, name: "", id: superindex };
- superindex += 1;
- skAction = [];
- } else {
- skAction.push(superArray[iter]);
- }
- iter += 1;
- }
- superkeys[superindex] = { actions: skAction, name: "", id: superindex };
-
- if (superkeys[0].actions.length === 0 || superkeys[0].actions.length > 5) {
- log.info(`Superkeys were empty`);
- return [];
- }
- log.info(`Got Superkeys:${JSON.stringify(superkeys)} from ${raw}`);
- // TODO: Check if stored superKeys match the received ones, if they match, retrieve name and apply it to current superKeys
- let finalSuper: SuperkeysType[] = [];
- const stored = neurons[neuronIdx].superkeys;
- finalSuper = superkeys.map((superky, i) => {
- const superk = superky;
- superk.id = i;
- if (stored.length > i && stored.length > 0) {
- const aux = superk;
- aux.name = stored[i].name;
- return aux;
- }
- return superk;
- });
- log.info("final superkeys", finalSuper);
- return finalSuper;
- };
-
- const superkeyMap = (superkeys: SuperkeysType[]) => {
- if (
- superkeys.length === 0 ||
- (superkeys.length === 1 && superkeys[0].actions.length === 0) ||
- (superkeys.length === 1 && superkeys[0].actions.length === 1 && superkeys[0].actions[0] === 0)
- ) {
- return Array(512).fill("65535").join(" ");
- }
- let keyMap = JSON.parse(JSON.stringify(superkeys));
- // log.info("First", JSON.stringify(keyMap));
- keyMap = keyMap.map((sky: SuperkeysType) => {
- const sk = sky;
- sk.actions = sk.actions.map(act => {
- if (act === 0 || act === null || act === undefined) return 1;
- return act;
- });
- if (sk.actions.length < 5) sk.actions = sk.actions.concat(Array(5 - sk.actions.length).fill(1));
- return sk;
- });
- const mapped = keyMap
- .map((superkey: SuperkeysType) => superkey.actions.filter(act => act !== 0).concat([0]))
- .flat()
- .concat([0])
- .join(" ")
- .split(",")
- .join(" ");
- log.info("Mapped superkeys: ", mapped, keyMap);
- return mapped;
- };
-
- const macrosMap = (macros: MacrosType[]) => {
- const { macrosEraser } = state;
- log.info(
- "Macros map function",
- macros,
- macrosEraser,
- macros.length === 0,
- macros.length === 1 && Array.isArray(macros[0].actions),
- );
- if (macros.length === 0 || (macros.length === 1 && !Array.isArray(macros[0].actions))) {
- return macrosEraser;
- }
- const mapAction = (action: MacroActionsType): number[] => {
- switch (action.type) {
- case 1:
- return [
- action.type,
- (action.keyCode as number[])[0] >> 8,
- (action.keyCode as number[])[0] & 255,
- (action.keyCode as number[])[1] >> 8,
- (action.keyCode as number[])[1] & 255,
- ];
- case 2:
- case 3:
- case 4:
- case 5:
- return [action.type, (action.keyCode as number) >> 8, (action.keyCode as number) & 255];
- default:
- return [action.type, action.keyCode as number];
- }
- };
- const result: string = macros
- .map(macro => macro.actions.map((action: MacroActionsType) => mapAction(action)).concat([0]))
- .flat()
- .concat([0])
- .join(" ")
- .split(",")
- .join(" ");
- log.info("MACROS GOING TO BE SAVED", result);
- return result;
- };
-
const addToActions = (actions: MacroActionsType[]) => {
const { startContext } = props;
const { macros, selectedMacro } = state;
@@ -333,7 +219,7 @@ function MacroEditor(props: MacroEditorProps) {
};
const writeMacros = async () => {
- const { macros, neurons, neuronIdx, keymap, superkeys } = state;
+ const { macros, neurons, neuronID, keymap, superkeys } = state;
const { setLoading, cancelContext } = props;
const { currentDevice } = deviceState;
setIsSaving(true);
@@ -341,15 +227,15 @@ function MacroEditor(props: MacroEditorProps) {
log.info("saving Macros:", macros, keymap, superkeys);
const newMacros = macros;
const localNeurons = [...neurons];
- localNeurons[neuronIdx].macros = newMacros;
+ localNeurons[localNeurons.findIndex(n => n.id === neuronID)].macros = newMacros;
store.set("neurons", localNeurons);
try {
- await currentDevice.command("macros.map", macrosMap(newMacros));
- const args = flatten(keymap.custom).map(k => keymapDB.serialize(k).toString());
- await currentDevice.command("keymap.custom", ...args);
- await currentDevice.command("superkeys.map", superkeyMap(superkeys));
+ await currentDevice.command("macros.map", serializeMacros(newMacros, state.totalMemory));
+ log.info(keymap.custom);
+ await currentDevice.command("keymap.custom", serializeKeymap(keymap.custom));
+ await currentDevice.command("superkeys.map", serializeSuperkeys(superkeys));
const commands = await Backup.Commands(currentDevice);
- const backup = await bkp.DoBackup(commands, neurons[neuronIdx].id, currentDevice);
+ const backup = await bkp.DoBackup(commands, neurons[neurons.findIndex(n => n.id === neuronID)].id, currentDevice);
Backup.SaveBackup(backup, currentDevice);
toast.success(} />, {
autoClose: 2000,
@@ -531,81 +417,6 @@ function MacroEditor(props: MacroEditorProps) {
updateMacros(localMacros);
};
- const macroTranslator = (raw: string) => {
- const { storedMacros } = state;
- const macrosArray = raw.split(" 0 0")[0].split(" ").map(Number);
-
- // Translate received macros to human readable text
- const macros: MacrosType[] = [];
- let iter = 0;
- // macros are `0` terminated or when end of macrosArray has been reached, the outer loop
- // must cycle once more than the inner
- while (iter <= macrosArray.length) {
- const actions: MacroActionsType[] = [];
- while (iter < macrosArray.length) {
- const type = macrosArray[iter];
- if (type === 0) {
- break;
- }
-
- switch (type) {
- case 1:
- actions.push({
- type,
- keyCode: [
- (macrosArray[(iter += 1)] << 8) + macrosArray[(iter += 1)],
- (macrosArray[(iter += 1)] << 8) + macrosArray[(iter += 1)],
- ],
- });
- break;
- case 2:
- case 3:
- case 4:
- case 5:
- actions.push({ type, keyCode: (macrosArray[(iter += 1)] << 8) + macrosArray[(iter += 1)] });
- break;
- case 6:
- case 7:
- case 8:
- actions.push({ type, keyCode: macrosArray[(iter += 1)] });
- break;
- default:
- break;
- }
-
- iter += 1;
- }
- macros.push({
- actions,
- name: "",
- macro: "",
- });
- iter += 1;
- }
- macros.forEach((m, idx) => {
- const aux = m;
- aux.id = idx;
- macros[idx] = aux;
- });
-
- // TODO: Check if stored macros match the received ones, if they match, retrieve name and apply it to current macros
- const stored = storedMacros;
- if (stored === undefined || stored.length === 0) {
- return macros;
- }
- return macros.map((macro, i) => {
- if (stored.length < i) {
- return macro;
- }
-
- return {
- ...macro,
- name: stored[i]?.name,
- macro: macro.actions.map(k => keymapDB.parse(k.keyCode as number).label).join(" "),
- };
- });
- };
-
const loadMacros = async () => {
const { onDisconnect, cancelContext, setLoading } = props;
const { currentDevice } = deviceState;
@@ -618,8 +429,9 @@ function MacroEditor(props: MacroEditorProps) {
chipID = chipID.replace(/\s/g, "");
const neurons = store.get("neurons") as Neuron[];
state.neurons = neurons;
- state.neuronIdx = neurons.findIndex(n => n.id === chipID);
- state.storedMacros = neurons[state.neuronIdx].macros;
+ state.neuronID = chipID;
+ state.storedMacros = neurons[neurons.findIndex(n => n.id === chipID)].macros;
+ state.storedSuper = neurons[neurons.findIndex(n => n.id === chipID)].superkeys;
setState({ ...state });
const deviceLang = { ...currentDevice.device, language: true };
currentDevice.commands.keymap = new Keymap(deviceLang);
@@ -645,41 +457,14 @@ function MacroEditor(props: MacroEditorProps) {
const custom = await currentDevice.command("keymap.custom");
const onlyCustom = Boolean(parseInt(await currentDevice.command("keymap.onlyCustom"), 10));
const keymap: KeymapType = { custom: undefined, default: undefined, onlyCustom: false };
-
const layerSize = currentDevice.device.keyboard.rows * currentDevice.device.keyboard.columns;
- keymap.custom = custom
- .split(" ")
- .filter(v => v.length > 0)
- .map(k => keymapDB.parse(parseInt(k, 10)))
- .reduce((resultArray, item, index) => {
- const localResultArray = resultArray;
- const chunkIndex = Math.floor(index / layerSize);
-
- if (!localResultArray[chunkIndex]) {
- localResultArray[chunkIndex] = []; // start a new chunk
- }
- localResultArray[chunkIndex].push(item);
- return localResultArray;
- }, []);
- keymap.default = defaults
- .split(" ")
- .filter(v => v.length > 0)
- .map(k => keymapDB.parse(parseInt(k, 10)))
- .reduce((resultArray, item, index) => {
- const localResultArray = resultArray;
- const chunkIndex = Math.floor(index / layerSize);
-
- if (!localResultArray[chunkIndex]) {
- localResultArray[chunkIndex] = []; // start a new chunk
- }
- localResultArray[chunkIndex].push(item);
- return localResultArray;
- }, []);
+ keymap.custom = parseKeymapRaw(custom, layerSize).map(l => l.map(k => keymapDB.parse(k)));
+ keymap.default = parseKeymapRaw(defaults, layerSize).map(l => l.map(k => keymapDB.parse(k)));
keymap.onlyCustom = onlyCustom;
const macrosRaw = await currentDevice.command("macros.map");
- const parsedMacros = macroTranslator(macrosRaw);
+ const parsedMacros = parseMacrosRaw(macrosRaw, state.storedMacros);
const supersRaw = await currentDevice.command("superkeys.map");
- const parsedSuper = superTranslator(supersRaw);
+ const parsedSuper = parseSuperkeysRaw(supersRaw, state.storedSuper);
state.macros = parsedMacros;
state.superkeys = parsedSuper;
state.keymap = keymap;
@@ -687,7 +472,6 @@ function MacroEditor(props: MacroEditorProps) {
state.modified = false;
state.usedMemory = parsedMacros.map(m => m.actions).flat().length;
state.totalMemory = tMem;
- state.macrosEraser = Array(tMem).fill("255").join(" ");
state.loading = false;
setState({ ...state });
cancelContext();
diff --git a/src/renderer/views/SuperkeysEditor.tsx b/src/renderer/views/SuperkeysEditor.tsx
index 85d4e95c..b2e61768 100644
--- a/src/renderer/views/SuperkeysEditor.tsx
+++ b/src/renderer/views/SuperkeysEditor.tsx
@@ -40,7 +40,6 @@ import { KeyPickerKeyboard } from "@Renderer/modules/KeyPickerKeyboard";
// Types
import { SuperkeysEditorInitialStateType, SuperkeysEditorProps } from "@Renderer/types/superkeyseditor";
-import { MacrosType } from "@Renderer/types/macros";
import { SuperkeysType } from "@Renderer/types/superkeys";
import { Neuron } from "@Renderer/types/neurons";
import { KeymapType } from "@Renderer/types/layout";
@@ -52,6 +51,7 @@ import Store from "@Renderer/utils/Store";
import getLanguage from "@Renderer/utils/language";
import Keymap, { KeymapDB } from "../../api/keymap";
import Backup from "../../api/backup";
+import { parseMacrosRaw, parseSuperkeysRaw, serializeKeymap, serializeSuperkeys } from "../../api/parsers";
const store = Store.getStore();
@@ -92,39 +92,12 @@ function SuperkeysEditor(props: SuperkeysEditorProps) {
const [isSaving, setIsSaving] = useState(false);
const [mouseWheel, setMouseWheel] = useState(0);
- const flatten = (arr: unknown[]) => [].concat(...arr);
-
- const defaultMacro = [
- {
- actions: [
- { keyCode: 229, type: 6, id: 0 },
- { keyCode: 11, type: 8, id: 1 },
- { keyCode: 229, type: 7, id: 2 },
- { keyCode: 8, type: 8, id: 3 },
- { keyCode: 28, type: 8, id: 4 },
- { keyCode: 54, type: 8, id: 5 },
- { keyCode: 44, type: 8, id: 6 },
- { keyCode: 229, type: 6, id: 7 },
- { keyCode: 7, type: 8, id: 8 },
- { keyCode: 229, type: 7, id: 9 },
- { keyCode: 28, type: 8, id: 10 },
- { keyCode: 10, type: 8, id: 11 },
- { keyCode: 16, type: 8, id: 12 },
- { keyCode: 4, type: 8, id: 13 },
- { keyCode: 23, type: 8, id: 14 },
- { keyCode: 8, type: 8, id: 15 },
- ],
- id: 0,
- macro: "RIGHT SHIFT H RIGHT SHIFT E Y , SPACE RIGHT SHIFT D RIGHT SHIFT Y G M A T E",
- name: "Hey, Dygmate!",
- },
- ];
-
const initialState: SuperkeysEditorInitialStateType = {
keymap: undefined,
macros: [],
superkeys: [],
storedMacros: [],
+ storedSuper: [],
neurons: [],
neuronID: "",
kbtype: "iso",
@@ -144,132 +117,6 @@ function SuperkeysEditor(props: SuperkeysEditorProps) {
const [state, setState] = useState(initialState);
const { state: deviceState } = useDevice();
- const macroTranslator = (raw: string) => {
- const { storedMacros } = state;
- if (typeof raw === "string" && raw.search(" 0 0") === -1) {
- return defaultMacro;
- }
- const macrosArray = raw.split(" 0 0")[0].split(" ").map(Number);
-
- // Translate received macros to human readable text
- const macros = [];
- let iter = 0;
- // macros are `0` terminated or when end of macrosArray has been reached, the outer loop
- // must cycle once more than the inner
- while (iter <= macrosArray.length) {
- const actions = [];
- while (iter < macrosArray.length) {
- const type = macrosArray[iter];
- if (type === 0) {
- break;
- }
-
- switch (type) {
- case 1:
- actions.push({
- type,
- keyCode: [
- (macrosArray[(iter += 1)] << 8) + macrosArray[(iter += 1)],
- (macrosArray[(iter += 1)] << 8) + macrosArray[(iter += 1)],
- ],
- });
- break;
- case 2:
- case 3:
- case 4:
- case 5:
- actions.push({ type, keyCode: (macrosArray[(iter += 1)] << 8) + macrosArray[(iter += 1)] });
- break;
- case 6:
- case 7:
- case 8:
- actions.push({ type, keyCode: macrosArray[(iter += 1)] });
- break;
- default:
- break;
- }
-
- iter += 1;
- }
- macros.push({
- actions,
- name: "",
- macro: "",
- });
- iter += 1;
- }
- macros.forEach((m, idx) => {
- const aux: MacrosType = m;
- aux.id = idx;
- macros[idx] = aux;
- });
-
- // TODO: Check if stored macros match the received ones, if they match, retrieve name and apply it to current macros
- const stored = storedMacros;
- if (stored === undefined || stored.length === 0) {
- return macros;
- }
- return macros.map((macro, i) => {
- if (stored.length < i) {
- return macro;
- }
-
- return {
- ...macro,
- name: stored[i]?.name,
- macro: macro.actions.map(k => keymapDB.parse(k.keyCode as number).label).join(" "),
- };
- });
- };
-
- const superTranslator = (raw: string) => {
- const { neurons, neuronID } = state;
- const superArray = raw.split(" 0 0")[0].split(" ").map(Number);
-
- let superkey: number[] = [];
- const superkeys: SuperkeysType[] = [];
- let iter = 0;
- let superindex = 0;
-
- if (superArray.length < 1) {
- log.info("Discarded Superkeys due to short length of string", raw, raw.length);
- return [{ actions: [53, 2101, 1077, 41, 0], name: "Welcome to superkeys", id: superindex }];
- }
- // log.info(raw, raw.length);
- while (superArray.length > iter) {
- // log.info(iter, raw[iter], superkey);
- if (superArray[iter] === 0) {
- superkeys[superindex] = { actions: superkey, name: "", id: superindex };
- superindex += 1;
- superkey = [];
- } else {
- superkey.push(superArray[iter]);
- }
- iter += 1;
- }
- superkeys[superindex] = { actions: superkey, name: "", id: superindex };
-
- if (superkeys[0].actions.length === 0 || superkeys[0].actions.length > 5) {
- log.info(`Superkeys were empty`);
- return [];
- }
- log.info(`Got Superkeys:${JSON.stringify(superkeys)} from ${raw}`);
- // TODO: Check if stored superKeys match the received ones, if they match, retrieve name and apply it to current superKeys
- let finalSuper: SuperkeysType[] = [];
- const stored = neurons.find(n => n.id === neuronID).superkeys;
- finalSuper = superkeys.map((superky, i) => {
- const superk = superky;
- if (stored.length > i && stored.length > 0) {
- const aux = superk;
- aux.name = stored[i].name;
- return aux;
- }
- return superk;
- });
- log.info("final superkeys", finalSuper);
- return finalSuper;
- };
-
const onKeyChange = (keyCode: number) => {
const { superkeys, selectedSuper, selectedAction } = state;
const { startContext } = props;
@@ -300,6 +147,7 @@ function SuperkeysEditor(props: SuperkeysEditorProps) {
state.neurons = neurons;
state.neuronID = chipID;
state.storedMacros = neuron.macros;
+ state.storedSuper = neuron.superkeys;
setState({ ...state });
const deviceLang = { ...currentDevice.device, language: true };
currentDevice.commands.keymap = new Keymap(deviceLang);
@@ -347,9 +195,9 @@ function SuperkeysEditor(props: SuperkeysEditorProps) {
keymap.onlyCustom = onlyCustom;
// Macros
const macrosRaw = await currentDevice.command("macros.map");
- const parsedMacros = macroTranslator(macrosRaw);
+ const parsedMacros = parseMacrosRaw(macrosRaw, state.storedMacros);
const supersRaw = await currentDevice.command("superkeys.map");
- const parsedSuper = superTranslator(supersRaw);
+ const parsedSuper = parseSuperkeysRaw(supersRaw, state.storedSuper);
state.modified = false;
state.macros = parsedMacros;
state.superkeys = parsedSuper;
@@ -370,37 +218,6 @@ function SuperkeysEditor(props: SuperkeysEditorProps) {
return true;
};
- const superkeyMap = (superkeys: SuperkeysType[]) => {
- if (
- superkeys.length === 0 ||
- (superkeys.length === 1 && superkeys[0].actions.length === 0) ||
- (superkeys.length === 1 && superkeys[0].actions.length === 1 && superkeys[0].actions[0] === 0)
- ) {
- return Array(512).fill("65535").join(" ");
- }
- let keyMap = JSON.parse(JSON.stringify(superkeys));
- log.info("First", JSON.stringify(keyMap));
- keyMap = keyMap.map((sky: SuperkeysType) => {
- const sk = sky;
- sk.actions = sk.actions.map(act => {
- if (act === 0 || act === null || act === undefined) return 1;
- return act;
- });
- if (sk.actions.length < 5) sk.actions = sk.actions.concat(Array(5 - sk.actions.length).fill(1));
- return sk;
- });
- log.info("Third", JSON.parse(JSON.stringify(keyMap)));
- const mapped = keyMap
- .map((superkey: SuperkeysType) => superkey.actions.filter(act => act !== 0).concat([0]))
- .flat()
- .concat([0])
- .join(" ")
- .split(",")
- .join(" ");
- log.info("Mapped superkeys: ", mapped, keyMap);
- return mapped;
- };
-
const changeSelected = (id: number) => {
state.selectedSuper = id < 0 ? 0 : id;
state.selectedAction = -1;
@@ -465,15 +282,11 @@ function SuperkeysEditor(props: SuperkeysEditorProps) {
log.info("Loaded neurons: ", JSON.stringify(localNeurons));
try {
store.set("neurons", localNeurons);
- const sendSK = superkeyMap(superkeys);
+ const sendSK = serializeSuperkeys(superkeys);
log.info("Mod superK", sendSK);
await currentDevice.command("superkeys.map", sendSK);
if (modifiedKeymap) {
- const args = flatten(keymap.custom)
- .map(k => keymapDB.serialize(k))
- .join(" ");
- log.info("Mod keymap", args);
- await currentDevice.command("keymap.custom", args);
+ await currentDevice.command("keymap.custom", serializeKeymap(keymap.custom));
}
state.modified = false;
state.modifiedKeymap = false;