Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion frontend/__tests__/test/funbox/funbox-validation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ describe("funbox-validation", () => {
"rAnDoMcAsE", //changesCapitalisation
"nospace", //nospace
"plus_one", //toPush:
"read_ahead_easy", //changesWordVisibility
"read_ahead_easy", //changesWordsVisibility
"tunnel_vision", //changesWordsVisibility
"tts", //speaks
"layout_mirror", //changesLayout
"zipf", //changesWordsFrequency
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/ts/elements/caret.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ export class Caret {
easing?: string;
};
}): void {
if (this.style === "off") return;
if (this.style === "off" && !this.isMainCaret) return;
requestDebouncedAnimationFrame(`caret.${this.id}.goTo`, () => {
const word = wordsCache.qs(
`.word[data-wordindex="${options.wordIndex}"]`,
Expand Down
50 changes: 50 additions & 0 deletions frontend/src/ts/test/funbox/funbox-functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,31 @@ async function readAheadHandleKeydown(event: KeyboardEvent): Promise<void> {
}
}

let tunnelVisionObserver: MutationObserver | undefined;
let tunnelVisionFrame: number | undefined;

function requestCaretPositionUpdate(): void {
if (tunnelVisionFrame !== undefined) return;
tunnelVisionFrame = requestAnimationFrame(() => {
tunnelVisionFrame = undefined;

const caret = document.getElementById("caret");
const words = document.getElementById("words");
if (caret === null || words === null) return;

const caretRect = caret.getBoundingClientRect();
const wordsRect = words.getBoundingClientRect();
words.style.setProperty(
"--caret-center-x",
`${caretRect.left + caretRect.width / 2 - wordsRect.left}px`,
);
words.style.setProperty(
"--caret-center-y",
`${caretRect.top + caretRect.height / 2 - wordsRect.top}px`,
);
});
}
Comment on lines +78 to +98

//todo move to its own file
class CharDistribution {
public chars: Record<string, number>;
Expand Down Expand Up @@ -502,6 +527,31 @@ const list: Partial<Record<FunboxName, FunboxFunctions>> = {
await readAheadHandleKeydown(event);
},
},
tunnel_vision: {
applyConfig(): void {
if (tunnelVisionObserver !== undefined) return;

const caret = document.getElementById("caret");
if (caret === null) return;

tunnelVisionObserver = new MutationObserver(requestCaretPositionUpdate);
tunnelVisionObserver.observe(caret, {
attributes: true,
attributeFilter: ["class", "style"],
});
window.addEventListener("resize", requestCaretPositionUpdate);
},
clearGlobal(): void {
tunnelVisionObserver?.disconnect();
tunnelVisionObserver = undefined;
window.removeEventListener("resize", requestCaretPositionUpdate);

if (tunnelVisionFrame !== undefined) {
cancelAnimationFrame(tunnelVisionFrame);
tunnelVisionFrame = undefined;
}
},
},
memory: {
applyConfig(): void {
qs("#wordsWrapper")?.hide();
Expand Down
13 changes: 13 additions & 0 deletions frontend/static/funbox/tunnel_vision.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#words {
/* em keeps the visible area proportional to the current typing font size. */
--tunnel-vision-radius: 3em;
--tunnel-vision-softness: 0.8em;

mask-image: radial-gradient(
circle at var(--caret-center-x, 50%) var(--caret-center-y, 50%),
#000 0,
#000 var(--tunnel-vision-radius),
transparent
calc(var(--tunnel-vision-radius) + var(--tunnel-vision-softness))
);
}
Comment on lines +1 to +13
9 changes: 9 additions & 0 deletions packages/funbox/src/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,15 @@ const list: Record<FunboxName, FunboxMetadata> = {
frontendFunctions: ["rememberSettings", "handleKeydown"],
name: "read_ahead_hard",
},
tunnel_vision: {
description: "Only the area around the caret is visible.",
canGetPb: true,
difficultyLevel: 2,
properties: ["changesWordsVisibility", "hasCssFile"],
frontendFunctions: ["applyConfig", "clearGlobal"],
name: "tunnel_vision",
cssModifications: ["words"],
},
memory: {
description: "Test your memory. Remember the words and type them blind.",
canGetPb: true,
Expand Down
11 changes: 10 additions & 1 deletion packages/schemas/__tests__/config.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { describe, it, expect } from "vitest";
import { CustomBackgroundSchema } from "@monkeytype/schemas/configs";
import {
CustomBackgroundSchema,
FunboxNameSchema,
} from "@monkeytype/schemas/configs";

describe("config schema", () => {
describe("CustomBackgroundSchema", () => {
Expand Down Expand Up @@ -80,4 +83,10 @@ describe("config schema", () => {
}
});
});

describe("FunboxNameSchema", () => {
it("accepts tunnel vision", () => {
expect(FunboxNameSchema.safeParse("tunnel_vision").success).toBe(true);
});
});
});
1 change: 1 addition & 0 deletions packages/schemas/src/configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ export const FunboxNameSchema = z.enum([
"read_ahead_easy",
"read_ahead",
"read_ahead_hard",
"tunnel_vision",
"memory",
"nospace",
"poetry",
Expand Down
Loading