Skip to content

feat: add lefthand funbox for left-hand-only typing practice (@gokul1108)#7624

Closed
gokul1108 wants to merge 1 commit into
monkeytypegame:masterfrom
gokul1108:feat/lefthand-funbox
Closed

feat: add lefthand funbox for left-hand-only typing practice (@gokul1108)#7624
gokul1108 wants to merge 1 commit into
monkeytypegame:masterfrom
gokul1108:feat/lefthand-funbox

Conversation

@gokul1108
Copy link
Copy Markdown

Description

Add a new "lefthand" funbox that filters words to only those typeable with the left hand on a QWERTY layout (keys: qwertasdfgzxcvb). Useful for practicing weak left-hand typing.

Changes:

  • packages/schemas/src/configs.ts — Added "lefthand" to FunboxNameSchema
  • packages/funbox/src/list.ts — Added funbox metadata entry
  • frontend/src/ts/test/funbox/funbox-functions.ts — Implemented withWords that filters language words to left-hand-only words

Copilot AI review requested due to automatic review settings March 11, 2026 05:45
@monkeytypegeorge monkeytypegeorge added frontend User interface or web stuff packages Changes in local packages labels Mar 11, 2026
@github-actions github-actions Bot added the waiting for review Pull requests that require a review before continuing label Mar 11, 2026
@fehmer
Copy link
Copy Markdown
Member

fehmer commented Mar 11, 2026

hi @gokul1108 , thank you for your contribution.

You can already use the custom mode to do this:

  • select test type custom
  • press change
  • go to word filter
  • select preset left hand
  • apply and set

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new lefthand funbox to support left-hand-only typing practice by filtering the active word list down to words typeable with left-hand keys.

Changes:

  • Extend FunboxNameSchema with "lefthand".
  • Register lefthand in funbox metadata (description, difficulty, frontend function hook).
  • Implement lefthand.withWords to filter incoming word lists to left-hand-only words.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
packages/schemas/src/configs.ts Adds lefthand to the funbox name enum for config validation/typing.
packages/funbox/src/list.ts Adds funbox metadata entry so it appears in the funbox catalog and compatibility checks.
frontend/src/ts/test/funbox/funbox-functions.ts Implements the frontend withWords hook to perform left-hand-only word filtering.

Comment on lines +569 to +571
const LEFT_HAND_KEYS = new Set("qwertasdfgzxcvb");
const filtered = (words ?? []).filter((w) =>
[...w.toLowerCase()].every((ch) => LEFT_HAND_KEYS.has(ch)),
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LEFT_HAND_KEYS is recreated on every withWords call. Consider hoisting the allowed-chars set/regex to module scope to avoid repeated allocations during word regeneration and keep this function simpler.

Copilot uses AI. Check for mistakes.
Comment on lines +567 to +574
lefthand: {
async withWords(words?: string[]): Promise<Wordset> {
const LEFT_HAND_KEYS = new Set("qwertasdfgzxcvb");
const filtered = (words ?? []).filter((w) =>
[...w.toLowerCase()].every((ch) => LEFT_HAND_KEYS.has(ch)),
);
return new Wordset(filtered.length > 0 ? filtered : ["test"]);
},
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No unit test covers the new lefthand.withWords filtering behavior (allowed letters + empty-result handling). Since the repo already has Vitest coverage for funbox wiring (frontend/__tests__/test/funbox.spec.ts), consider adding a small test that asserts filtering works and that the empty-match case behaves as intended.

Copilot uses AI. Check for mistakes.
description: "Only words typeable with the left hand.",
canGetPb: false,
difficultyLevel: 1,
properties: ["changesWordsFrequency"],
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lefthand is marked changesWordsFrequency, which makes it incompatible with zipf (and any other frequency-changer) via funbox compatibility checks. Since this funbox filters the word list via withWords rather than changing selection frequency, consider removing changesWordsFrequency so lefthand can still be combined with zipf/future frequency modes.

Suggested change
properties: ["changesWordsFrequency"],
properties: [],

Copilot uses AI. Check for mistakes.
name: "weakspot",
},
lefthand: {
description: "Only words typeable with the left hand.",
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Funbox description says "Only words typeable with the left hand." but the implementation hardcodes QWERTY left-hand letters. This is user-facing text; either mention QWERTY explicitly here, or update the implementation to derive left-hand keys from the active layout (similar to the leftHand preset logic in frontend/src/ts/modals/word-filter.ts).

Suggested change
description: "Only words typeable with the left hand.",
description: "Only words typeable with the left hand on QWERTY.",

Copilot uses AI. Check for mistakes.
const filtered = (words ?? []).filter((w) =>
[...w.toLowerCase()].every((ch) => LEFT_HAND_KEYS.has(ch)),
);
return new Wordset(filtered.length > 0 ? filtered : ["test"]);
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the filtered list is empty, this returns new Wordset(["test"]), which silently replaces the user’s language/custom word list with a single placeholder word. Better to surface this as an unsupported scenario (e.g. show a notice, disable the funbox, and/or throw a WordGenError to trigger regeneration) so users aren’t stuck typing "test" repeatedly.

Suggested change
return new Wordset(filtered.length > 0 ? filtered : ["test"]);
if (filtered.length === 0) {
throw new WordGenError(
"No left-hand-only words available for the current word list.",
);
}
return new Wordset(filtered);

Copilot uses AI. Check for mistakes.
@gokul1108
Copy link
Copy Markdown
Author

hi @gokul1108 , thank you for your contribution.

You can already use the custom mode to do this:

  • select test type custom
  • press change
  • go to word filter
  • select preset left hand
  • apply and set

Thanks for pointing that out!

@gokul1108 gokul1108 closed this Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

frontend User interface or web stuff packages Changes in local packages waiting for review Pull requests that require a review before continuing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants