diff --git a/backend/package.json b/backend/package.json index 19b57d51d331..0e4aa61d0290 100644 --- a/backend/package.json +++ b/backend/package.json @@ -27,6 +27,7 @@ "@date-fns/utc": "1.2.0", "@monkeytype/contracts": "workspace:*", "@monkeytype/funbox": "workspace:*", + "@monkeytype/schemas": "workspace:*", "@monkeytype/util": "workspace:*", "@ts-rest/core": "3.52.1", "@ts-rest/express": "3.52.1", @@ -64,7 +65,6 @@ "devDependencies": { "@monkeytype/eslint-config": "workspace:*", "@monkeytype/oxlint-config": "workspace:*", - "@monkeytype/schemas": "workspace:*", "@monkeytype/typescript-config": "workspace:*", "@redocly/cli": "2.0.5", "@types/bcrypt": "5.0.2", diff --git a/docker/frontend/updateConfig.sh b/docker/frontend/updateConfig.sh index a35385abd8fc..dd4513458446 100755 --- a/docker/frontend/updateConfig.sh +++ b/docker/frontend/updateConfig.sh @@ -1,12 +1,12 @@ #!/bin/sh cd /usr/share/nginx/html echo "replace firebase config appid: ${FIREBASE_APPID}" -sed -i "s/###FIREBASE_APIKEY###/${FIREBASE_APIKEY}/g" js/firebase.*.js -sed -i "s/###FIREBASE_AUTHDOMAIN###/${FIREBASE_AUTHDOMAIN}/g" js/firebase.*.js -sed -i "s/###FIREBASE_PROJECTID###/${FIREBASE_PROJECTID}/g" js/firebase.*.js -sed -i "s/###FIREBASE_STORAGEBUCKET###/${FIREBASE_STORAGEBUCKET}/g" js/firebase.*.js -sed -i "s/###FIREBASE_MESSAGINGSENDERID###/${FIREBASE_MESSAGINGSENDERID}/g" js/firebase.*.js -sed -i "s/###FIREBASE_APPID###/${FIREBASE_APPID}/g" js/firebase.*.js +sed -i "s/###FIREBASE_APIKEY###/${FIREBASE_APIKEY}/g" js/firebase-config-live.*.js +sed -i "s/###FIREBASE_AUTHDOMAIN###/${FIREBASE_AUTHDOMAIN}/g" js/firebase-config-live.*.js +sed -i "s/###FIREBASE_PROJECTID###/${FIREBASE_PROJECTID}/g" js/firebase-config-live.*.js +sed -i "s/###FIREBASE_STORAGEBUCKET###/${FIREBASE_STORAGEBUCKET}/g" js/firebase-config-live.*.js +sed -i "s/###FIREBASE_MESSAGINGSENDERID###/${FIREBASE_MESSAGINGSENDERID}/g" js/firebase-config-live.*.js +sed -i "s/###FIREBASE_APPID###/${FIREBASE_APPID}/g" js/firebase-config-live.*.js echo "use backend url ${MONKEYTYPE_BACKENDURL}" diff --git a/frontend/package.json b/frontend/package.json index c480709f5e30..0dbe3da6c7b4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -35,7 +35,6 @@ "@fortawesome/fontawesome-free": "5.15.4", "@monkeytype/eslint-config": "workspace:*", "@monkeytype/oxlint-config": "workspace:*", - "@monkeytype/schemas": "workspace:*", "@monkeytype/typescript-config": "workspace:*", "@types/canvas-confetti": "1.4.3", "@types/chartjs-plugin-trendline": "1.0.1", @@ -80,6 +79,7 @@ "@date-fns/utc": "1.2.0", "@monkeytype/contracts": "workspace:*", "@monkeytype/funbox": "workspace:*", + "@monkeytype/schemas": "workspace:*", "@monkeytype/util": "workspace:*", "@sentry/browser": "9.14.0", "@sentry/vite-plugin": "3.3.1", diff --git a/frontend/src/ts/test/pace-caret.ts b/frontend/src/ts/test/pace-caret.ts index 77c96157ff40..9ead86dd567c 100644 --- a/frontend/src/ts/test/pace-caret.ts +++ b/frontend/src/ts/test/pace-caret.ts @@ -18,6 +18,8 @@ type Settings = { timeout: NodeJS.Timeout | null; }; +let startTimestamp = 0; + export let settings: Settings | null = null; export const caret = new Caret( @@ -129,7 +131,7 @@ export async function init(): Promise { }; } -export async function update(duration: number): Promise { +export async function update(expectedStepEnd: number): Promise { if (settings === null || !TestState.isActive || TestState.resultVisible) { return; } @@ -141,6 +143,10 @@ export async function update(duration: number): Promise { incrementLetterIndex(); try { + const now = performance.now(); + const absoluteStepEnd = startTimestamp + expectedStepEnd; + const duration = absoluteStepEnd - now; + caret.goTo({ wordIndex: settings.currentWordIndex, letterIndex: settings.currentLetterIndex, @@ -152,11 +158,13 @@ export async function update(duration: number): Promise { easing: "linear", }, }); + + // Normal case - schedule next step settings.timeout = setTimeout(() => { - update((settings?.spc ?? 0) * 1000).catch(() => { + update(expectedStepEnd + (settings?.spc ?? 0) * 1000).catch(() => { settings = null; }); - }, duration); + }, Math.max(0, duration)); } catch (e) { console.error(e); caret.hide(); @@ -169,6 +177,7 @@ export function reset(): void { clearTimeout(settings.timeout); } settings = null; + startTimestamp = 0; } function incrementLetterIndex(): void { @@ -243,6 +252,8 @@ export function handleSpace(correct: boolean, currentWord: string): void { } export function start(): void { + const now = performance.now(); + startTimestamp = now; void update((settings?.spc ?? 0) * 1000); } diff --git a/frontend/src/ts/utils/caret.ts b/frontend/src/ts/utils/caret.ts index f06db5ead920..40ce95ac9660 100644 --- a/frontend/src/ts/utils/caret.ts +++ b/frontend/src/ts/utils/caret.ts @@ -300,7 +300,10 @@ export class Caret { // we also clamp the letterIndex to be within the range of actual letters // anything beyond just goes to the edge of the word let side: "beforeLetter" | "afterLetter" = "beforeLetter"; - if (options.letterIndex >= letters.length) { + if ( + options.letterIndex >= letters.length || + (Config.blindMode && options.letterIndex >= wordText.length) + ) { side = "afterLetter"; options.letterIndex = letters.length - 1; } @@ -405,9 +408,9 @@ export class Caret { options.isDirectionReversed ); - //if the letter is not visible, use the closest visible letter (but only for full width carets) + //if the letter is not visible, use the closest visible letter const isLetterVisible = options.letter.offsetWidth > 0; - if (!isLetterVisible && this.isFullWidth()) { + if (!isLetterVisible) { const letters = options.word.querySelectorAll("letter"); if (letters.length === 0) { throw new Error("Caret getLeftTopWidth: no letters found in word"); diff --git a/frontend/static/layouts/gallium_nl.json b/frontend/static/layouts/gallium_nl.json new file mode 100644 index 000000000000..1ada155242fd --- /dev/null +++ b/frontend/static/layouts/gallium_nl.json @@ -0,0 +1,62 @@ +{ + "keymapShowTopRow": false, + "type": "ansi", + "keys": { + "row1": [ + ["`", "~"], + ["1", "!"], + ["2", "@"], + ["3", "#"], + ["4", "$"], + ["5", "%"], + ["6", "^"], + ["7", "&"], + ["8", "*"], + ["9", "("], + ["0", ")"], + ["-", "_"], + ["=", "+"] + ], + "row2": [ + ["b", "B"], + ["l", "L"], + ["d", "D"], + ["c", "C"], + ["v", "V"], + ["y", "Y"], + ["p", "P"], + ["u", "U"], + ["o", "O"], + [",", "<"], + ["[", "{"], + ["]", "}"], + ["\\", "|"] + ], + "row3": [ + ["n", "N"], + ["r", "R"], + ["t", "T"], + ["s", "S"], + ["w", "W"], + ["f", "F"], + ["h", "H"], + ["e", "E"], + ["a", "A"], + ["i", "I"], + ["/", "?"] + ], + "row4": [ + ["x", "X"], + ["q", "Q"], + ["m", "M"], + ["g", "G"], + ["j", "J"], + ["z", "Z"], + ["k", "K"], + ["'", "\""], + [";", ":"], + [".", ">"] + ], + "row5": [[" "]] + } +} diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 4396e9abeef1..1bf8ddee76cc 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -11,13 +11,15 @@ "oxlint": "oxlint .", "lint": "npm run oxlint && npm run eslint" }, + "dependencies": { + "@monkeytype/schemas": "workspace:*" + }, "peerDependencies": { "@ts-rest/core": "3.52.1", "zod": "3.23.8" }, "devDependencies": { "@monkeytype/eslint-config": "workspace:*", - "@monkeytype/schemas": "workspace:*", "@monkeytype/tsup-config": "workspace:*", "@monkeytype/typescript-config": "workspace:*", "eslint": "8.57.1", diff --git a/packages/funbox/package.json b/packages/funbox/package.json index 480aedc4176a..023bebe716bf 100644 --- a/packages/funbox/package.json +++ b/packages/funbox/package.json @@ -13,7 +13,6 @@ }, "devDependencies": { "@monkeytype/eslint-config": "workspace:*", - "@monkeytype/schemas": "workspace:*", "@monkeytype/tsup-config": "workspace:*", "@monkeytype/typescript-config": "workspace:*", "eslint": "8.57.1", @@ -24,6 +23,7 @@ "vitest": "3.2.4" }, "dependencies": { + "@monkeytype/schemas": "workspace:*", "@monkeytype/util": "workspace:*" }, "exports": { diff --git a/packages/schemas/src/layouts.ts b/packages/schemas/src/layouts.ts index 08bcc604b5e3..3b3be1bffcf6 100644 --- a/packages/schemas/src/layouts.ts +++ b/packages/schemas/src/layouts.ts @@ -155,6 +155,7 @@ export const LayoutNameSchema = z.enum( "gallium_angle", "gallium_v2", "gallium_v2_matrix", + "gallium_nl", "maya", "gallaya_angle_ansi", "gallaya_angle_iso", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 024b3e2e77cf..1f4c6be19b5c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -62,6 +62,9 @@ importers: '@monkeytype/funbox': specifier: workspace:* version: link:../packages/funbox + '@monkeytype/schemas': + specifier: workspace:* + version: link:../packages/schemas '@monkeytype/util': specifier: workspace:* version: link:../packages/util @@ -168,9 +171,6 @@ importers: '@monkeytype/oxlint-config': specifier: workspace:* version: link:../packages/oxlint-config - '@monkeytype/schemas': - specifier: workspace:* - version: link:../packages/schemas '@monkeytype/typescript-config': specifier: workspace:* version: link:../packages/typescript-config @@ -276,6 +276,9 @@ importers: '@monkeytype/funbox': specifier: workspace:* version: link:../packages/funbox + '@monkeytype/schemas': + specifier: workspace:* + version: link:../packages/schemas '@monkeytype/util': specifier: workspace:* version: link:../packages/util @@ -376,9 +379,6 @@ importers: '@monkeytype/oxlint-config': specifier: workspace:* version: link:../packages/oxlint-config - '@monkeytype/schemas': - specifier: workspace:* - version: link:../packages/schemas '@monkeytype/typescript-config': specifier: workspace:* version: link:../packages/typescript-config @@ -499,6 +499,9 @@ importers: packages/contracts: dependencies: + '@monkeytype/schemas': + specifier: workspace:* + version: link:../schemas '@ts-rest/core': specifier: 3.52.1 version: 3.52.1(@types/node@20.14.11)(zod@3.23.8) @@ -509,9 +512,6 @@ importers: '@monkeytype/eslint-config': specifier: workspace:* version: link:../eslint-config - '@monkeytype/schemas': - specifier: workspace:* - version: link:../schemas '@monkeytype/tsup-config': specifier: workspace:* version: link:../tsup-config @@ -566,6 +566,9 @@ importers: packages/funbox: dependencies: + '@monkeytype/schemas': + specifier: workspace:* + version: link:../schemas '@monkeytype/util': specifier: workspace:* version: link:../util @@ -573,9 +576,6 @@ importers: '@monkeytype/eslint-config': specifier: workspace:* version: link:../eslint-config - '@monkeytype/schemas': - specifier: workspace:* - version: link:../schemas '@monkeytype/tsup-config': specifier: workspace:* version: link:../tsup-config