Skip to content

Commit 781dcd9

Browse files
authored
fix(test): opposite shift mode using wrong keymap (@fehmer) (#8220)
fixes #8218
1 parent 9a1e635 commit 781dcd9

3 files changed

Lines changed: 65 additions & 56 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Accessor, createEffect, createResource } from "solid-js";
2+
import { promiseWithResolvers } from "../utils/misc";
3+
4+
export function useResourceWithPromise<TSource, TData>(
5+
source: Accessor<TSource>,
6+
loader: (source: TSource) => Promise<TData>,
7+
): [() => TData | undefined, { promise: Promise<void>; reset: () => void }] {
8+
const [resource] = createResource(source, loader);
9+
const { promise, reset, resolve, reject } = promiseWithResolvers();
10+
11+
createEffect(() => {
12+
const state = resource.state;
13+
reset();
14+
if (state === "ready") {
15+
resolve();
16+
}
17+
if (state === "errored") {
18+
reject(new Error("failed to fetch resource"));
19+
}
20+
});
21+
22+
return [resource, { promise, reset }];
23+
}

frontend/src/ts/input/handlers/keydown.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export async function handleOppositeShift(event: KeyboardEvent): Promise<void> {
7878
Config.keymapLayout !== "overrideSync"
7979
) {
8080
let keymapLayout = await __nonReactive
81-
.getInputLayout()
81+
.getKeymapLayout()
8282
.catch(() => undefined);
8383
if (keymapLayout === undefined) {
8484
showErrorNotification("Failed to load keymap layout");

frontend/src/ts/states/test.ts

Lines changed: 41 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,20 @@
1-
import {
2-
createSignal,
3-
createEffect,
4-
createMemo,
5-
createResource,
6-
} from "solid-js";
1+
import { createEffect, createMemo, createSignal } from "solid-js";
72
import { getConfig } from "../config/store";
83

9-
import { canQuickRestart } from "../utils/quick-restart";
10-
import { getData as getCustomTextData } from "../test/custom-text";
11-
import { getActivePage, getCustomTextIndicator } from "./core";
12-
import { QuoteWithTextSplit } from "../types/quotes";
4+
import { Challenge } from "@monkeytype/challenges";
5+
import { LayoutObject } from "@monkeytype/schemas/layouts";
136
import { CompletedEvent, IncompleteTest } from "@monkeytype/schemas/results";
7+
import { createStore } from "solid-js/store";
8+
import { keymapEvent } from "../events/keymap";
149
import { createSignalWithSetters } from "../hooks/createSignalWithSetters";
15-
import { Challenge } from "@monkeytype/challenges";
16-
import { replaceUnderscoresWithSpaces } from "../utils/strings";
10+
import { getData as getCustomTextData } from "../test/custom-text";
11+
import { QuoteWithTextSplit } from "../types/quotes";
1712
import { getLayout } from "../utils/json-data";
1813
import { mirrorLayoutKeys } from "../utils/key-converter";
19-
import { createStore } from "solid-js/store";
20-
import { keymapEvent } from "../events/keymap";
21-
import { promiseWithResolvers } from "../utils/misc";
22-
import { LayoutObject } from "@monkeytype/schemas/layouts";
14+
import { canQuickRestart } from "../utils/quick-restart";
15+
import { replaceUnderscoresWithSpaces } from "../utils/strings";
16+
import { getActivePage, getCustomTextIndicator } from "./core";
17+
import { useResourceWithPromise } from "../hooks/useResourceWithPromise";
2318

2419
export const [wordsHaveNewline, setWordsHaveNewline] = createSignal(false);
2520
export const [wordsHaveTab, setWordsHaveTab] = createSignal(false);
@@ -95,17 +90,6 @@ export const getKeymapLayout = createMemo<{
9590
return { layout: layout, layoutNameDisplayString, isMirrored };
9691
});
9792

98-
export const [keymapLayoutObject] = createResource(
99-
getKeymapLayout,
100-
async (layout) => {
101-
const result = await getLayout(layout.layout);
102-
if (layout.isMirrored) {
103-
return mirrorLayoutKeys(result);
104-
}
105-
return result;
106-
},
107-
);
108-
10993
const [getKeymapHighlightKey, setKeymapHighlightKey] = createSignal<
11094
string | undefined
11195
>(undefined);
@@ -133,7 +117,6 @@ keymapEvent.useListener(({ mode, key, correct }) => {
133117
}
134118
});
135119

136-
let inputLayoutPromise = promiseWithResolvers();
137120
const getInputLayout = createMemo<{
138121
layout: string;
139122
isMirrored: boolean;
@@ -144,40 +127,43 @@ const getInputLayout = createMemo<{
144127
};
145128
});
146129

147-
const [inputLayoutObject] = createResource(getInputLayout, async (layout) => {
148-
const result = await getLayout(layout.layout);
149-
if (layout.isMirrored) {
150-
return mirrorLayoutKeys(result);
151-
}
152-
return result;
153-
});
154-
155-
async function waitForInputLayoutReady(): Promise<void> {
156-
await inputLayoutPromise.promise;
157-
if (inputLayoutObject.state === "ready") return;
158-
159-
if (inputLayoutObject.state === "errored") {
160-
throw new Error("Failed to load input layout");
161-
}
162-
}
130+
const [inputLayoutObject, inputLayoutPromise] = useResourceWithPromise(
131+
getInputLayout,
132+
async (layout) => {
133+
const result = await getLayout(layout.layout);
134+
if (layout.isMirrored) {
135+
return mirrorLayoutKeys(result);
136+
}
137+
return result;
138+
},
139+
);
163140

164-
createEffect(() => {
165-
const state = inputLayoutObject.state;
166-
inputLayoutPromise.reset();
167-
if (state === "ready") {
168-
inputLayoutPromise.resolve();
169-
}
170-
if (state === "errored") {
171-
inputLayoutPromise.reject(new Error("failed to fetch input layout"));
172-
}
173-
});
141+
const [keymapLayoutObject, keymapLayoutPromise] = useResourceWithPromise(
142+
getKeymapLayout,
143+
async (layout) => {
144+
const result = await getLayout(layout.layout);
145+
if (layout.isMirrored) {
146+
return mirrorLayoutKeys(result);
147+
}
148+
return result;
149+
},
150+
);
151+
export { keymapLayoutObject };
174152

175153
/**
176154
* Used for non reactive access. Do not use in Solid components.
177155
*/
178156
export const __nonReactive = {
157+
getKeymapLayout: async (): Promise<LayoutObject> => {
158+
await keymapLayoutPromise.promise;
159+
const result = keymapLayoutObject();
160+
if (result === undefined) {
161+
throw new Error("Failed to load keymap layout");
162+
}
163+
return result;
164+
},
179165
getInputLayout: async (): Promise<LayoutObject> => {
180-
await waitForInputLayoutReady();
166+
await inputLayoutPromise.promise;
181167
const result = inputLayoutObject();
182168
if (result === undefined) {
183169
throw new Error("Failed to load input layout");

0 commit comments

Comments
 (0)