at main
5 folders
9 files
feat(social): comments, mentions, notifications, live reactions
Add a full social layer on top of the AppView + PDS + Jetstream stack.
Lexicons
- fm.atradio.comment (station snapshot, text, mention facets, optional GIF)
- fm.atradio.reaction (ephemeral emoji reaction)
- defs: commentView, notificationView, comment#gif, comment#mention
- queries getComments/getNotifications, procedure updateSeen
- TS types, zod schemas, buildComment/buildReaction mappers, LiveEvent types
API
- comments, reactions, notifications, notification_seen tables (+migration)
- Jetstream consumer indexes comments/reactions and fans out notifications
(mentions -> mentioned actors; comments -> custom-station owner)
- Redis-pub/sub-or-in-process live bus + SSE GET /live/:stationId
- XRPC getComments, getNotifications (unread count), POST updateSeen
Web
- putComment/putReaction to PDS; appview clients + SSE subscribe
- Klipy media client (GIFs / stickers / clips) for comment embeds
- mention richtext: facet resolution, segment rendering, live @-typeahead
- CommentComposer, CommentsPanel (live + optimistic), CommentsModal
- NotificationBell with floating unread badge that resets on open
- StationReactions: macOS-dock emoji picker (hover/click, login-gated)
- PlayerReactionRain: full-screen bottom->top emoji rain, real time
- wired into Player (mini + fullscreen), StationCard, Navbar, Layout
- OAuth scope adds repo:fm.atradio.comment + repo:fm.atradio.reaction
fix(web): keep the Rockbox DSP/EQ in the signal path + match CLI compressor
The EQ/DSP had no audible effect on most stations. Cross-origin radio hosts
rarely send CORS headers, so the decoder worker's direct fetch was blocked, the
engine errored, and playback silently fell back to a bare <audio> element that
is not in the Rockbox DSP graph — bypassing EQ, bass, crossfeed, everything.
The CLI decodes natively (no CORS), so it always applied the full chain.
- proxiedStreamUrl now routes every absolute http(s) stream through the
CORS-enabled /api/stream proxy (except HLS and relative/same-origin URLs), so
the worker can always fetch it and the DSP stays in the path.
- Fix the compressor params to match the CLI: makeup=1, ratio as the 0–3 index
(compRatioIndex), knee=2, release=200ms, attack=5ms — was makeup=0, raw ratio,
and zeroed knee/attack/release. Shared via applyCompressor().
The EQ gain math itself was already correct/identical to the CLI (both
rockbox-dsp versions apply the ×10 fixed-point convention internally).
feat(social): comments, mentions, notifications, live reactions
Add a full social layer on top of the AppView + PDS + Jetstream stack.
Lexicons
- fm.atradio.comment (station snapshot, text, mention facets, optional GIF)
- fm.atradio.reaction (ephemeral emoji reaction)
- defs: commentView, notificationView, comment#gif, comment#mention
- queries getComments/getNotifications, procedure updateSeen
- TS types, zod schemas, buildComment/buildReaction mappers, LiveEvent types
API
- comments, reactions, notifications, notification_seen tables (+migration)
- Jetstream consumer indexes comments/reactions and fans out notifications
(mentions -> mentioned actors; comments -> custom-station owner)
- Redis-pub/sub-or-in-process live bus + SSE GET /live/:stationId
- XRPC getComments, getNotifications (unread count), POST updateSeen
Web
- putComment/putReaction to PDS; appview clients + SSE subscribe
- Klipy media client (GIFs / stickers / clips) for comment embeds
- mention richtext: facet resolution, segment rendering, live @-typeahead
- CommentComposer, CommentsPanel (live + optimistic), CommentsModal
- NotificationBell with floating unread badge that resets on open
- StationReactions: macOS-dock emoji picker (hover/click, login-gated)
- PlayerReactionRain: full-screen bottom->top emoji rain, real time
- wired into Player (mini + fullscreen), StationCard, Navbar, Layout
- OAuth scope adds repo:fm.atradio.comment + repo:fm.atradio.reaction
feat(social): comments, mentions, notifications, live reactions
Add a full social layer on top of the AppView + PDS + Jetstream stack.
Lexicons
- fm.atradio.comment (station snapshot, text, mention facets, optional GIF)
- fm.atradio.reaction (ephemeral emoji reaction)
- defs: commentView, notificationView, comment#gif, comment#mention
- queries getComments/getNotifications, procedure updateSeen
- TS types, zod schemas, buildComment/buildReaction mappers, LiveEvent types
API
- comments, reactions, notifications, notification_seen tables (+migration)
- Jetstream consumer indexes comments/reactions and fans out notifications
(mentions -> mentioned actors; comments -> custom-station owner)
- Redis-pub/sub-or-in-process live bus + SSE GET /live/:stationId
- XRPC getComments, getNotifications (unread count), POST updateSeen
Web
- putComment/putReaction to PDS; appview clients + SSE subscribe
- Klipy media client (GIFs / stickers / clips) for comment embeds
- mention richtext: facet resolution, segment rendering, live @-typeahead
- CommentComposer, CommentsPanel (live + optimistic), CommentsModal
- NotificationBell with floating unread badge that resets on open
- StationReactions: macOS-dock emoji picker (hover/click, login-gated)
- PlayerReactionRain: full-screen bottom->top emoji rain, real time
- wired into Player (mini + fullscreen), StationCard, Navbar, Layout
- OAuth scope adds repo:fm.atradio.comment + repo:fm.atradio.reaction
feat(social): comments, mentions, notifications, live reactions
Add a full social layer on top of the AppView + PDS + Jetstream stack.
Lexicons
- fm.atradio.comment (station snapshot, text, mention facets, optional GIF)
- fm.atradio.reaction (ephemeral emoji reaction)
- defs: commentView, notificationView, comment#gif, comment#mention
- queries getComments/getNotifications, procedure updateSeen
- TS types, zod schemas, buildComment/buildReaction mappers, LiveEvent types
API
- comments, reactions, notifications, notification_seen tables (+migration)
- Jetstream consumer indexes comments/reactions and fans out notifications
(mentions -> mentioned actors; comments -> custom-station owner)
- Redis-pub/sub-or-in-process live bus + SSE GET /live/:stationId
- XRPC getComments, getNotifications (unread count), POST updateSeen
Web
- putComment/putReaction to PDS; appview clients + SSE subscribe
- Klipy media client (GIFs / stickers / clips) for comment embeds
- mention richtext: facet resolution, segment rendering, live @-typeahead
- CommentComposer, CommentsPanel (live + optimistic), CommentsModal
- NotificationBell with floating unread badge that resets on open
- StationReactions: macOS-dock emoji picker (hover/click, login-gated)
- PlayerReactionRain: full-screen bottom->top emoji rain, real time
- wired into Player (mini + fullscreen), StationCard, Navbar, Layout
- OAuth scope adds repo:fm.atradio.comment + repo:fm.atradio.reaction