at main
7 folders
4 files
feat: atradio Connect — cross-device remote control
Spotify-Connect-style remote control across web + CLI. Every logged-in
client opens a WebSocket to a new hub in apps/api, is grouped by account
DID (verified via atproto service-auth JWT), and can list and control the
other devices on the account.
- api: WebSocket Connect hub (/connect) with per-DID device registry,
command routing, presence tracking, Redis cross-instance relay, and a
did:web service document. Service-auth JWTs verified with
@atproto/xrpc-server + @atproto/identity.
- web: device picker (navbar) + bottom "Playing on …" banner, transport
routing to the selected remote, transfer-here/there, and WS-driven
deletion of the actor.status record when no player is online.
- cli: remote module (tokio-tungstenite) making the TUI both controllable
and a controller, a device-picker overlay + text indicator, a headless
`--no-tui` daemon mode, and a settings.toml-configurable device name.
- tests: hub integration tests (ws) + web routing/transfer + device
helper tests; new GitHub Actions workflow runs web + api suites.
- i18n: new `connect` namespace for en/fr/pt.
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
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: atradio Connect — cross-device remote control
Spotify-Connect-style remote control across web + CLI. Every logged-in
client opens a WebSocket to a new hub in apps/api, is grouped by account
DID (verified via atproto service-auth JWT), and can list and control the
other devices on the account.
- api: WebSocket Connect hub (/connect) with per-DID device registry,
command routing, presence tracking, Redis cross-instance relay, and a
did:web service document. Service-auth JWTs verified with
@atproto/xrpc-server + @atproto/identity.
- web: device picker (navbar) + bottom "Playing on …" banner, transport
routing to the selected remote, transfer-here/there, and WS-driven
deletion of the actor.status record when no player is online.
- cli: remote module (tokio-tungstenite) making the TUI both controllable
and a controller, a device-picker overlay + text indicator, a headless
`--no-tui` daemon mode, and a settings.toml-configurable device name.
- tests: hub integration tests (ws) + web routing/transfer + device
helper tests; new GitHub Actions workflow runs web + api suites.
- i18n: new `connect` namespace for en/fr/pt.