Skip to content

Add Focus Timer widget - #403

Merged
AllTerrainDeveloper merged 1 commit into
WordPress:trunkfrom
Alexismlg:feat/focus-timer-widget
Jul 23, 2026
Merged

Add Focus Timer widget#403
AllTerrainDeveloper merged 1 commit into
WordPress:trunkfrom
Alexismlg:feat/focus-timer-widget

Conversation

@Alexismlg

@Alexismlg Alexismlg commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Fixes #410

Summary

Adds a Focus Timer widget — a focus/countdown timer you add from the widget picker. Pick a duration, optionally link it to one of your open windows, and start. When time is up the linked window shakes (via the public Window.shake()) and a gentle alarm rings until you press Stop.

Built following the starter-widget template and using only public APIs + runtime globals — no framework internals touched.

Features

  • Duration presets (5 / 15 / 25 / 45 min) plus ±1-minute steppers (min 1 min, max 3 h).
  • Optionally link the timer to any open window — that window shakes when time is up (looped Window.shake() until dismissed). Only currently-open windows are offered, and closing the linked window while the timer runs cancels it with a toast (the runtime listens for desktop-mode-window-closed).
  • A Web Audio alarm chime that rings until dismissed — synthesized in the browser, no audio files bundled.
  • Show / hide the remaining time while running.
  • The timer keeps running across widget re-renders / re-docks (page-wide runtime singleton) and resumes across a page reload while still counting down (mirrored to ctx.storage).

Implementation

  • src/plugins/focus-timer-widget/
    • index.ts — the view. Uses wpd-select (window picker) + wpd-checkbox-label (toggle) and native buttons, with __/sprintf from src/i18n.
    • timer.ts — a DOM-independent state machine (idle / running / paused / finished) held on window.__desktopModeFocusTimer so it survives re-mounts; persists to ctx.storage.
    • alarm.ts — Web Audio alarm; the AudioContext is primed on the Start click (a user gesture) so it can fire minutes later.
    • desktop.ts — a thin typed accessor over wp.desktop.windowManager to list + shake windows.
    • styles.css — layout only; overrides --desktop-mode-text / --desktop-mode-muted on the dark-glass card (same approach as the Note Pad widget) so the wpd-* components stay legible.
  • includes/widgets/widget-focus-timer.php — registration (no REST, no server state, no external services).
  • Wired into desktop-mode.php, vite.config.js (widget-focus-timer target), and package.json (build:widget-focus-timer + the build chain).

Pure client-side — no REST routes, no server state, no network calls.

Testing

  • npm run build:widget-focus-timer, npm run typecheck, and npm run lint (on the new sources) all pass.
  • Verified in wp-env: the widget appears in the picker, mounts cleanly (no console errors), countdown runs, and the linked-window shake + alarm + Stop flow works.

Notes / open questions

  • Reduced-motion is respected (the finished-state shake/pulse animations drop to a static accent outline).
  • Happy to add unit tests or a docs/example entry if the maintainers would like one for this widget.

A focus countdown widget you add from the widget picker. Pick a duration
(presets 5/15/25/45 min or ±1-min steppers), optionally link it to one of
your open windows, and start. When time is up the linked window shakes
(via the public Window.shake()) and a Web Audio alarm rings until you
press Stop. Option to show or hide the remaining time while running.

The timer lives in a page-wide runtime (window.__desktopModeFocusTimer)
so it survives widget re-renders/re-docks, and mirrors its state to
ctx.storage so a running countdown resumes across a page reload. Pure
client-side: no REST routes, no server state, no external services, no
bundled audio.

Wires src/plugins/focus-timer-widget/ (view + timer + alarm), the PHP
registration in includes/widgets/widget-focus-timer.php, the Vite target,
and the build script.
@AllTerrainDeveloper

Copy link
Copy Markdown
Collaborator

By the PR description it already looks promising! Let me test it!

@AllTerrainDeveloper AllTerrainDeveloper left a comment

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.

This is a great, I have tested it and it does what it promises. And also, I can see it as a core widget for Desktop Mode too :)

Image
Timer.mov

@AllTerrainDeveloper
AllTerrainDeveloper merged commit 920f385 into WordPress:trunk Jul 23, 2026
6 checks passed
@AllTerrainDeveloper

Copy link
Copy Markdown
Collaborator

@Alexismlg You've been honoured in our hall of fame
image

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.

Pomodoro widget should listen to window events

2 participants