Skip to content

Split Pocket playground routes and add temporary /pocket redirect#86

Merged
nedtwigg merged 4 commits into
mainfrom
codex/revised-pocket-url-architecture
May 23, 2026
Merged

Split Pocket playground routes and add temporary /pocket redirect#86
nedtwigg merged 4 commits into
mainfrom
codex/revised-pocket-url-architecture

Conversation

@nedtwigg
Copy link
Copy Markdown
Member

Summary

  • Split the playground into canonical /playground/desktop and /playground/pocket routes with a shared dispatcher at /playground
  • Keep /pocket as a temporary redirect to the Pocket playground while preserving the old desktop Pocket marketing copy on /playground/pocket
  • Update the breakpoint logic so coarse pointers always prefer Pocket, while desktop remains available down to 250px wide
  • Sync the tutorial, mobile UI, and theme specs with the new URL architecture

Testing

  • pnpm --filter dormouse-website test passed
  • pnpm --filter dormouse-website build passed
  • Local browser verification covered /pocket redirect behavior and the 249px vs 250px desktop playground breakpoint

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 22, 2026

Deploying mouseterm with  Cloudflare Pages  Cloudflare Pages

Latest commit: 950a93f
Status: ✅  Deploy successful!
Preview URL: https://9fc279cd.mouseterm.pages.dev
Branch Preview URL: https://codex-revised-pocket-url-arc.mouseterm.pages.dev

View logs

Copy link
Copy Markdown
Collaborator

@dormouse-bot dormouse-bot left a comment

Choose a reason for hiding this comment

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

Reviewing as a draft — flagging anything that looks worth a quick fix. Mark ready for a full review.

One discrepancy worth resolving before this lands: the breakpoint is inconsistent across the diff. The spec, the unavailable-page copy, and the PR description all describe a 250px-wide cutoff (spec: (max-width: 249px), (pointer: coarse)), but playground-routing.ts ships (max-width: 700px), (pointer: coarse). Since PlaygroundDesktop also calls usePreferredPlayground, the practical effect with the 700px query is that any non-coarse viewport ≤ 700px wide gets routed to DesktopPlaygroundUnavailable — which then tells the user to make the window "at least 250px wide", even though they're already at e.g. 600px. Either pick 249 to match the docs (inline suggestion below) or leave 700 in the code and update the spec/copy.


export type PreferredPlayground = "desktop" | "pocket";

const POCKET_PLAYGROUND_QUERY = "(max-width: 700px), (pointer: coarse)";
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The spec says (max-width: 249px), (pointer: coarse) and the unavailable page tells users to make the window "at least 250px wide", so the 700 here looks like a stale value from before the tune commit.

Suggested change
const POCKET_PLAYGROUND_QUERY = "(max-width: 700px), (pointer: coarse)";
const POCKET_PLAYGROUND_QUERY = "(max-width: 249px), (pointer: coarse)";

nedtwigg and others added 2 commits May 22, 2026 14:14
- usePreferredPlayground: initialize state synchronously so SSG bakes
  the desktop variant into /pocket and /playground/pocket HTML; pre-PR
  Pocket used useState(false) and shipped marketing copy to crawlers.
- Open POCKET_PLAYGROUND_PATH directly from Flappy Term [p] instead of
  /pocket, avoiding the redirect chain in the new tab.
- Update Home.tsx 'Coming next: Dormouse Pocket' link to skip /pocket.
- Restore Playground nav link on the desktop Pocket marketing page by
  passing activePath="/pocket" (SiteHeader hides /playground when
  activePath==="/playground").
- Restore ShareUrlButton hover:scale-120 and gap-1 styling that the
  extraction had silently changed; preserve current location's query
  and hash when sharing a fixed path; clear the copied-flag timer on
  unmount and on rapid re-trigger.
- Use POCKET_THEME_ID constant (now exported) instead of the literal
  Kimbie ID in PlaygroundDesktop.
- Use react-router Link instead of a plain <a> in
  DesktopPlaygroundUnavailable and drop the misleading '250px' copy
  (the actual breakpoint is 700px).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Spec should not pin the exact media query — code is the source of
truth. Describes the rule (coarse pointer or narrow viewport → Pocket)
and points at website/src/lib/playground-routing.ts for the value.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@nedtwigg nedtwigg marked this pull request as ready for review May 22, 2026 21:53
Copy link
Copy Markdown
Collaborator

@dormouse-bot dormouse-bot left a comment

Choose a reason for hiding this comment

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

A couple of mismatches between the docs/PR-summary and the code in playground-routing.ts.

The PR summary still says "desktop remains available down to 250px wide" and lists "249px vs 250px desktop playground breakpoint" under Testing, but the query in website/src/lib/playground-routing.ts is (max-width: 700px), (pointer: coarse) — so any fine-pointer viewport ≤ 700px wide is routed to Pocket / shown the unavailable page, not just sub-250px. Last commit moved the spec to "the exact media query lives in the routing file" so the intent reads as "700 is the source of truth"; if that's right, the PR description is just stale and worth updating before merge so reviewers/readers don't expect a 250px floor that isn't there.

Separately, docs/specs/tutorial.md L39 says onOpenPocket wires window.open("/pocket", …), but the wired callbacks in PlaygroundDesktop.tsx and PocketTerminalExperience.tsx now both open POCKET_PLAYGROUND_PATH (/playground/pocket). Inline suggestion below.

Minor: PocketPlayground.tsx passes activePath="/pocket" to SiteHeader (the same string used by the old Pocket.tsx). Since /pocket isn't in NAV_LINKS, it's a no-op rather than a bug, but the page now lives at /playground/pocket so the string is stale.

Comment thread docs/specs/tutorial.md
The top-level menu also includes `Starred on GitHub`, which sits directly below `Copy paste` without a blank spacer, and shows `[not yet]` until selected and `[thanks ⭐]` after it has been resolved. Pressing Enter on that row calls `onOpenGithub`, which `/playground/desktop` and the Pocket playground wire to `window.open("https://github.com/diffplug/dormouse", "_blank", "noopener,noreferrer")`.

After `Starred on GitHub`, the top-level menu shows the mystery row. It is `🐭 ??? 🐭` with `[LOCKED N/M]` while any section task is incomplete. `N/M` is computed from section checklist items only; `Starred on GitHub` and the mystery row do not count. When all section tasks are complete, the row becomes `🐭 Flappy Term 🐭` with a `[High score: N]` readout. Pressing Enter on the unlocked row opens Flappy Term, a runner-local mini-game: `Space`/`Up`/`Enter` flaps the bird, scoring persists as the high score, and `Esc` returns to the top-level menu. On the game-over screen, `Enter` restarts and `p` calls `onOpenPocket`, which `/playground` and the mobile tether page wire to `window.open("https://dormouse.sh/pocket", "_blank", "noopener,noreferrer")`.
After `Starred on GitHub`, the top-level menu shows the mystery row. It is `🐭 ??? 🐭` with `[LOCKED N/M]` while any section task is incomplete. `N/M` is computed from section checklist items only; `Starred on GitHub` and the mystery row do not count. When all section tasks are complete, the row becomes `🐭 Flappy Term 🐭` with a `[High score: N]` readout. Pressing Enter on the unlocked row opens Flappy Term, a runner-local mini-game: `Space`/`Up`/`Enter` flaps the bird, scoring persists as the high score, and `Esc` returns to the top-level menu. On the game-over screen, `Enter` restarts and `p` calls `onOpenPocket`, which `/playground/desktop` and the Pocket playground wire to `window.open("/pocket", "_blank", "noopener,noreferrer")`. The game-over prompt reads `Read about Dormouse Pocket [p]`.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
After `Starred on GitHub`, the top-level menu shows the mystery row. It is `🐭 ??? 🐭` with `[LOCKED N/M]` while any section task is incomplete. `N/M` is computed from section checklist items only; `Starred on GitHub` and the mystery row do not count. When all section tasks are complete, the row becomes `🐭 Flappy Term 🐭` with a `[High score: N]` readout. Pressing Enter on the unlocked row opens Flappy Term, a runner-local mini-game: `Space`/`Up`/`Enter` flaps the bird, scoring persists as the high score, and `Esc` returns to the top-level menu. On the game-over screen, `Enter` restarts and `p` calls `onOpenPocket`, which `/playground/desktop` and the Pocket playground wire to `window.open("/pocket", "_blank", "noopener,noreferrer")`. The game-over prompt reads `Read about Dormouse Pocket [p]`.
After `Starred on GitHub`, the top-level menu shows the mystery row. It is `🐭 ??? 🐭` with `[LOCKED N/M]` while any section task is incomplete. `N/M` is computed from section checklist items only; `Starred on GitHub` and the mystery row do not count. When all section tasks are complete, the row becomes `🐭 Flappy Term 🐭` with a `[High score: N]` readout. Pressing Enter on the unlocked row opens Flappy Term, a runner-local mini-game: `Space`/`Up`/`Enter` flaps the bird, scoring persists as the high score, and `Esc` returns to the top-level menu. On the game-over screen, `Enter` restarts and `p` calls `onOpenPocket`, which `/playground/desktop` and the Pocket playground wire to `window.open("/playground/pocket", "_blank", "noopener,noreferrer")`. The game-over prompt reads `Read about Dormouse Pocket [p]`.

@nedtwigg nedtwigg merged commit 242ecb0 into main May 23, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants