Allow deselecting a chosen problem card by clicking it again
Maintainers usually reply within 1 day
@woohsin is already working on this.
Since Oct 21, 2026.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 68/100
Research direction
Start at the landing page code that renders the “Choose a specific problem instead” section and handles problem card clicks. Trace how the selected problem is stored and how the default recommended problem is chosen. Toggle the current selection off on a second click while keeping the section open; done when selecting a card and clicking it again restores the default.
Written by the indexing model from the issue text.
Description
Here is the detailed analysis of the current lobby selection flow and the consolidated proposal based on web/app.js.
1. Current Implementation Analysis
-
Event Listener & State (
web/app.js:246-254):
Inweb/app.js, cards are derived from[data-problem]buttons and initialized withmark(card.button, false). Clicking a card executes:for (const card of cards) { card.button.addEventListener("click", () => { manualProblem = true; setProblem(card); setDuration(suggestedDuration(new Set([card.difficulty]))); nodes.recommendation.textContent = `Selected problem: ${title(card)}.`; }); } -
The Issue:
The listener unconditionally setsmanualProblem = true, updatesproblem = card, marks the button viamark(card.button, true)insidesetProblem(), and updates the recommendation prompt. It does not check whethermanualProblem && problem === card. Clicking the active card re-applies the manual override. -
Fallback Behavior:
recommend(note = "", mode = "recommend")returns early without updating recommendation elements whenevermanualProblemis active. Currently, the only way a candidate can revert to the automatic recommendation engine is by clicking#random-problem(nodes.randomProblem), which resetsmanualProblem = falseand callsrecommend("", "random"), or by reloading the page.
2. Consolidated Proposal
-
Toggle Selection on Card Click:
Update the click handler inweb/app.jsto inspect whether the clicked card is already active (manualProblem && problem === card):-
When selecting a new card: Preserve the current behavior (
manualProblem = true,setProblem(card), update duration, and setnodes.recommendation.textContent). -
When clicking the currently selected card: Toggle it off by resetting
manualProblem = false, clearing the card mark viamark(card.button, false), clearing or resettingproblem = null, and invokingrecommend()to restore the default overdue/unseen recommendation and lobby controls.
for (const card of cards) { card.button.addEventListener("click", () => { if (manualProblem && problem === card) { manualProblem = false; mark(card.button, false); problem = null; recommend(); return; } manualProblem = true; setProblem(card); setDuration(suggestedDuration(new Set([card.difficulty]))); nodes.recommendation.textContent = `Selected problem: ${title(card)}.`; }); } -
-
Orthogonality with #394:
Issue #394 movesdetails.problem-pickerbelow the setup panels and adjusts.lobby .problem-gridinweb/styles.css. Because card event binding inweb/app.jsqueries[data-problem]buttons directly and operates onproblemandmanualProblemstate flags, this toggle logic does not depend on DOM hierarchy or CSS layout, making it completely orthogonal to and forward-compatible with #394.
3. Test Plan
Add browser-level Playwright tests in tests/browser/lobby.test.js:
-
Verify clicking a
.problem-cardapplies.selected, setsaria-pressed="true", and displays"Selected problem: ..."innodes.recommendation. -
Verify clicking the same active card removes
.selected, resetsaria-pressed="false", clearsmanualProblem, and restores the default recommendation prompt. -
Verify launching an interview after deselecting proceeds with the recommended practice problem without an explicit
?problem=query parameter.
- Dominant language
- Rust
- Stars
- 177
- Forks
- 100
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 168
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from sysprog21/codetrial
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Python tests lose every result when the solution returns inf or NaNPossibly taken @shensyuan claimed this 1 day ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
sysprog21/codetrial#419 · 3 comments · 1 assignee ·
Maintainers usually reply within 1 day
-
Audio output can be confirmed without playing a test soundPossibly taken @ChenYingHan1121 claimed this 3 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
sysprog21/codetrial#359 · 5 comments · 1 assignee ·
Maintainers usually reply within 1 day
-
Add a Copy code button to the final reportPossibly taken @yansawu claimed this 4 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 80/100
sysprog21/codetrial#318 · 5 comments · 2 reactions · 1 assignee ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 76/100
Maintainers usually reply within 1 day
All issues in sysprog21/codetrial
Similar issues
-
bug cli p3
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 3 days
-
Telegram and Twitch adapters panic when splitting long messages with multibyte charactersPossibly taken @RaphaelFakhri claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
spacedriveapp/spacebot#661 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
project-robius/robrix#1177 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
ClickHouse/clickhouse-rs#497 ·
Maintainers usually reply within 1 day