* feat(admin): identify Android devices by model in live session view
Android clients that send a bare default User-Agent (e.g.
"Dalvik/2.1.0 (Linux; U; Android 11; AFTKRT Build/RS8180.3729N)")
showed up as "Dalvik" in the admin live-session view, which tells an
operator nothing about the device.
Parse the model code out of the UA (the token between the last ';' and
"Build/") and map the Amazon Fire TV family and NVIDIA Shield to product
names. Unknown but parseable models fall back to "Android · <MODEL>"
instead of "Dalvik"; multi-word models like "Pixel 7" are preserved
whole. This is display-only: the session still stores the raw model code
in its user agent, and no response field or contract changes.
* feat(admin): mark Jellyfin-compat sessions with the JF pill by origin
The admin "JF" pill was derived at read time by substring-matching a
token list against the client name / user agent. A real Jellyfin
client that authenticates through the compat surface but sends a bare
User-Agent and no MediaBrowser client name (e.g. a Fire TV app) got no
pill, even though it plainly came through the Jellyfin API.
Stamp compat origin as immutable identity at session creation and carry
it through to the admin view:
- ClientInfo.IsCompat is set true in the jellycompat auth path; newSession
copies it onto Session.IsJellyfinCompat.
- The flag rides the durable RecipeCard (next to the client metadata that
already exists so the pill survives reconstruction) and is restored in
ReconstructSession, so a server restart keeps the pill.
- buildLiveSessionSync -> worker.SessionSync -> a new compat_origin column
on playback_sessions_sync (added migration); the reconciler upserts,
reloads, and compares it so origin changes still publish and unchanged
rows do not churn.
- The handler ORs the stored origin with the existing name/UA heuristic,
which stays as a fallback for rows written before this column existed.
is_jellyfin_client keeps the same name and type on the wire; it is only
sourced more accurately.
* fix(admin): correct Android device labels
---------
Co-authored-by: Quick <31828688+Quick104@users.noreply.github.com>