Using the desktop timer
The desktop window is laid out to make starting and stopping a timer the path of least resistance. Once you're signed in, here's what you see and how it works.
The layout
When the app opens, the timer view shows:
- A top bar with the brand wordmark, a Refresh (↻) button, and a Settings (⚙) button that opens a slide-in drawer with the Backend URL and a Sign out button.
- A status strip underneath that. When sync is healthy it reads "✓ N clients loaded · 12:34:56". When something failed it reads "✗ Sync failed, <reason>". This is your most reliable signal that the desktop is talking to the right backend.
- Either a "configure timer" card or a "running timer" card in the middle, depending on whether a timer is currently running.
- A Recent list at the bottom, showing the last few entries returned by the backend (the same data the web's Time entries shows).
There's also a tray icon outside the window, Mac menubar today, Windows tray when that build ships. The tray menu has Show window and Quit GBOSS TAB. The icon stays a single neutral state, it doesn't change colour when a timer is running. (That's a Phase 1E polish item; the comment in tray.rs says "for now we ship a single neutral icon.")
Starting a timer
In the "configure timer" card:
- Client. Required. Pick from the dropdown. If the dropdown is empty after a successful sync, you have no clients assigned, talk to your firm admin (the inline hint says so too).
- Project (optional). Disabled until a client is picked. Includes a + New link that opens the New project modal, name + optional default rate, then create.
- Notes. Free text.
- Click Start timer.
The card flips to the "running timer" card with the client/project/notes context, a big elapsed-time display, and a Stop timer button.
If you click Start while a timer is already running anywhere (web, desktop, even another instance), the backend returns 409 and the desktop shows "A timer is already running." Stop the other one first.
Stopping a timer
- Bring the desktop window forward (tray icon → Show window, or click the dock icon).
- Click Stop timer in the running-timer card.
The entry drops into the Recent list at the bottom in stopped status, and the card flips back to its configure-timer layout.
The idle prompt
Every 10 seconds while a timer is running, the desktop asks the Rust idle sampler how long the user has been idle. If that's above the firm's idle threshold (default 10 minutes, configurable in Admin → Firm settings → Time policies) and no prompt is currently open, a modal appears:
- Keep all time, closes the modal and lets the timer keep running. Use this when you were thinking, reading, or on a phone call.
- Discard idle time, trims the entry back to the moment you went idle AND immediately starts a fresh timer with the same client, project, and notes. Use this when you walked away and want to pick up where you left off without billing the idle minutes. The previous stopped entry shows in Recent; the elapsed counter resets to 00:00:00 on the new entry.
- Stop now, stops the timer entirely at right now. Use this when you came back, realised you'd left it running, and want both the idle gap and the post-idle minutes off the clock.
The threshold is firm-configurable from 1 to 60 minutes. The desktop reads it on startup and on every periodic refresh from /api/v1/users/me, so changes from the admin page take effect on the next sync without a restart. If /users/me ever fails, the desktop falls back to the 10-minute default.
The prompt only fires while a timer is running. There's no "auto-decision", if you ignore it, nothing changes.
The long-running flag
If a running timer's elapsed time crosses 8 hours, the elapsed display goes orange and a warning line appears: "Running over 8h, review or stop." The 8-hour value is hard-coded in the desktop UI (LONG_RUNNING_HRS = 8) and isn't read from the firm's configured threshold, but the backend uses the firm's configured threshold when it computes flagged_long_running at stop time, so the LONG tag on the saved entry will match firm settings even if the desktop's warning kicks in too early or too late.
Switching between timers
No pause/resume in the desktop UI. To switch from one piece of work to another:
- Stop the current timer.
- Change the client / project / notes.
- Start a new one.
The Recent list is your audit trail.
If you forgot to stop the previous timer before starting a new one, no problem, the API and UI prevent two timers at once, so you'll just see the 409 error. Stop the old one first.