Bluetooth pairing overlay, transport badge, smaller artwork - #31
Bluetooth pairing overlay, transport badge, smaller artwork#31edward-rosado wants to merge 6 commits into
Conversation
Adds a small badge to the connection overlay naming the link that is actually carrying data. The transport is probed, not assumed: /__bt is answered locally by the Bluetooth mux when it owns the client port, so a JSON reply means Bluetooth while a 404 means the request travelled to the server over USB — no server support required, the badge simply reads USB without it. Also prefers Spotify's 300x300 artwork variant over the 640x640 one on the proxied thumbnail path. The panel is 800x480, so the larger asset is wasted bytes — about 0.7s of a saturated ~155KB/s Bluetooth link on every track change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
When the computer initiates pairing, the on-device agent exposes the 6-digit numeric-comparison code at 127.0.0.1:8892/pairing; this overlay polls it and draws the code fullscreen, then flashes the outcome — the original Car Thing pairing experience. On anything that is not a provisioned Car Thing the endpoint does not exist, the first two polls fail, and the overlay permanently stands down. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A pairing exchange can resolve in a couple of seconds; at a 2s poll the overlay could miss the whole window (observed on a real pairing — the device agent captured the code but the screen never showed it). Poll every 500ms so the code is on screen the entire time the person is comparing it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
closeExisting only closed a socket in the OPEN state, so a socket stuck in CONNECTING — which is what happens when the server is unreachable at dial time, the norm on a Bluetooth link that comes up ~80s after the device boots — was abandoned without closing. Those half-open sockets lingered, held a tunnel stream, and kept the client from cleanly reconnecting once the link was finally up. Over USB the server is reachable instantly so this never surfaced. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Companion PRs:
|
The size preference was only applied in the startsWith('http') branch,
but that branch is not the one Spotify artwork takes. The DeskThing
server rewrites thumbnails to a relative /proxy/v1?url=... before
sending them (songCache.ts:124), so the client lands in the
startsWith('/') branch, which only prefixed the host. The optimization
was dead code and the device kept fetching 640x640.
Caught by screenshotting the device and reading the actual <img> src:
ab67616d0000b273 (640px) where 00001e02 (300px) was expected.
Two changes: match the bare Spotify id prefix instead of '/image/<id>',
because by the time we see the URL the slashes are usually percent-
encoded inside the proxy query while the id is not; and apply it in the
relative branch too.
Verified on hardware over Bluetooth: the element now loads
ab67616d00001e02... at 300x276 instead of 640x588, and the art renders.
That is ~110KB down to ~36KB per track change on a link that saturates
at 155KB/s.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Pushed a correction: the artwork optimization in this PR was dead code. It never ran. The size preference was only applied in the Found by screenshotting the device and reading the actual Two changes: match the bare Spotify id prefix rather than Verified on hardware over Bluetooth — the element now loads |
Measured on hardware: 11.9s from page load until the track and artwork were on screen. Two independent causes, both fixed. The client never asked for song state. requestMusicData was only called from inside the handler for an incoming song message, so the only path to data was an unsolicited push — after any (re)connect the screen sat on "Waiting For Track…" until the track happened to change or the server's refresh interval came round. It now requests the current track as soon as the socket reports connected. Reconnect took a flat 15s before even trying. onclose waited 5s before calling reconnect(), which waited a further 10s before dialling, with no fast first attempt — so a link that dropped and returned immediately still cost 15 seconds. Now 250ms to the first attempt and exponential backoff from 500ms to a 10s ceiling, reset on a successful open. Both are general client behaviour, not Bluetooth-specific, but Bluetooth makes them constantly visible: the link legitimately drops when the device is power-cycled, and it has no battery, so every power change is a reconnect. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Pushed The client never asked for the current track. The only path to song data was an unsolicited push, so a freshly-connected client waited for whatever came first — a track change, or the server's refresh cadence. Measured on a Car Thing over Bluetooth: 11,938ms from navigation to a rendered track. Two changes:
Same measurement after: 2,631ms, and repeated runs cluster tightly at 2,460 / 2,495 / 2,525ms. Of what remains, ~2.1s is the page load itself on the device's Chromium 69 — only ~400ms is data fetch. Getting below that means attacking bundle parse time, which is separate work. This matters most over Bluetooth, where the link legitimately drops and returns, but it is not Bluetooth-specific — any client that reconnects hits it. Worth reading alongside ItsRiprod/DeskThing#153, which fixes the server-side half: a track change took a median of ~11s to be noticed at all. Together, a track change now reaches the screen in about a second. I verified the server→device leg separately and it is essentially zero (−0.27s, within clock skew), so the delay was never the radio link. |
Bluetooth pairing overlay, transport badge, smaller artwork
Companion to the server-side Bluetooth transport PR (ItsRiprod/DeskThing#152 — the RFCOMM tunnel that lets a Car Thing run on wall power alone).
What this does
127.0.0.1:8892/pairing); on anything that is not a provisioned Car Thing the endpoint doesn't exist, the first two polls fail, and the overlay permanently stands down.GET /__btis answered locally by the Bluetooth mux when it owns the client port, so a JSON reply means Bluetooth while a 404 means the request travelled to the server over USB. Degrades gracefully without the server-side mux (probe 404s → badge reads USB).🤖 Generated with Claude Code