Add Now page: live-updating feed via polling - #5
Merged
Conversation
Drizzle's useLiveQuery only exists for drizzle-orm/expo-sqlite (React Native) and PGlite (in-browser Postgres) -- both require the database and the React hook to run in the same process. Ours doesn't: birds.db lives on the Pi's filesystem behind node:sqlite, and the browser is a separate network client, so there's no version of that hook that bridges the gap regardless of driver choice. Polling is the right tool for a server-DB/remote-client setup instead. Added a small reusable usePolledData hook (setInterval + refetch, no new dependency) and wired the Now page to it at a 10-second interval -- the underlying query is small, indexed, and LIMIT-bounded, so this is negligible load even on Pi-class hardware. The page shows the single latest detection as a hero card and a recent- activity feed below; newly-arrived rows get a brief highlight animation (flash-in) so it's visually obvious something just came in, without needing a page reload. Verified end-to-end by inserting a detection directly into the seed database and confirming it appeared live. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a new “Now” route to the web UI that presents the latest BirdNET-Pi detection prominently and keeps the view up-to-date via client-side polling, with a brief visual highlight for newly arrived detections.
Changes:
- Introduces
/nowpage with a “latest detection” hero card and “recent activity” list. - Adds a reusable
usePolledDatahook to refetch server data on an interval. - Adds CSS animations for “new item” highlighting and a live indicator dot, and links the new page in the header/nav.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| web-ui/src/styles.css | Adds flash-in highlight animation and live-dot pulsing indicator styling. |
| web-ui/src/routeTree.gen.ts | Registers the new /now route in the generated route tree/types. |
| web-ui/src/routes/now.tsx | Implements the new Now page UI and “fresh row” highlight tracking. |
| web-ui/src/lib/use-polled-data.ts | Adds polling hook used by the Now page to refetch detections every 10s. |
| web-ui/src/components/Header.tsx | Adds “Now” nav link to the header. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+23
to
+37
| useEffect(() => { | ||
| let cancelled = false; | ||
|
|
||
| const id = setInterval(async () => { | ||
| try { | ||
| const next = await fetcherRef.current(); | ||
| if (!cancelled) { | ||
| setData(next); | ||
| setLastUpdated(new Date()); | ||
| } | ||
| } catch { | ||
| // A transient failure shouldn't kill polling -- just try again | ||
| // on the next tick. | ||
| } | ||
| }, intervalMs); |
| opacity: 0.7; | ||
| box-shadow: 0 0 0 4px transparent; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
usePolledDatahook (plainsetInterval+ refetch, no new dependency).On
useLiveQuery: it only exists fordrizzle-orm/expo-sqlite(React Native) and PGlite (in-browser Postgres) -- both require the database and the React hook to run in the same process. Ours doesn't (birds.db lives on the Pi's filesystem behindnode:sqlite; the browser is a separate network client), so there's no version of that hook that bridges the gap regardless of driver choice. Polling is the right tool for this shape of app instead, and a 10-second interval against a small, indexed,LIMIT-bounded query is negligible load even on Pi-class hardware.Test plan
tsc --noEmitandbiome checkcleannpm run buildsucceedsCo-Authored-By: Claude Sonnet 5 noreply@anthropic.com