Skip to content

radio4000/r4atproto

 
 

Repository files navigation

Radio4000 for AT Protocol (Svelte 5)

Radio4000 on AT Protocol. Save your favorite music links (YouTube, SoundCloud, Vimeo, files) as custom records and play them in the app. (Shared timeline will return later.) The production instance lives at https://4000.radio.

Key features

  • AT Protocol OAuth login (no passwords) with robust fallback.
  • Custom atproto collection com.radio4000.track for tracks.
  • Player for direct files; embedded players for YouTube/Vimeo/SoundCloud; auto-next.
  • Routes inspired by Radio4000: / home hub, /#/@handle author/my tracks, search, track view/edit.
  • Permissions re-consent flow (when server supports fine-grained scopes).

Quick start

npm install
npm run dev
# open http://127.0.0.1:5173

Build & preview

npm run build
npm run preview

Testing

npm test

Routing

  • / — Home hub (timeline temporarily offline; quick actions)
  • /#/add — Add a track
  • /#/@alice.bsky.social — Author/My tracks
  • /#/search — Search actors
  • /#/t/:repo/:rkey — Track view
  • /#/@:handle/:rkey/edit — Track edit (modal route)
  • /#/settings — Manage permissions (re-consent)

Architecture (modular)

  • Svelte 5 components (no styles in templates):
    • Router: src/svelte/Router.svelte, routes: src/svelte/routes.js, matcher: src/svelte/routing/match.js
    • Player: src/svelte/components/Player.svelte, store: src/svelte/player/store.js
  • Pages: src/svelte/pages/… (Author, Search, TrackView/Edit, Settings)
  • Services:
    • OAuth/session: src/libs/bsky-oauth.js
    • R4 data and social: src/libs/r4-service.js
    • URL parsing/embeds: src/libs/url-patterns.js
    • oEmbed/Discogs helpers: src/libs/oembed.js, src/libs/discogs.js

OAuth setup (prod vs dev)

  • Dev (HTTP loopback): handled automatically using loopback client id. Note: AT Protocol OAuth requires HTTPS, so HTTP localhost may not work for actual login.
  • Dev (HTTPS with Tailscale Funnel): Expose your local dev server publicly via Tailscale funnel:
    1. Start your dev server: npm run dev
    2. Run tailscale funnel --bg 443:https+insecure://localhost:5174 (adjust port if needed)
    3. Update public/client-metadata.json with your Tailscale domain (e.g., https://yourname.tailnet.ts.net)
    4. Access your app via the Tailscale funnel URL and OAuth will work
  • Prod (HTTPS): expose public/client-metadata.json at a stable URL.
    • If deploying under a subpath (e.g., GitHub Pages), include both with and without trailing slash in redirect_uris.
    • The app passes a canonical redirect_uri (with trailing slash) for both authorization and callback handling to avoid mismatches.
    • Some servers don't support authorization_details yet; the app falls back to default atproto scope.
  • Optional (force HTTPS client metadata in dev): set VITE_CLIENT_ID in your env to the full URL of a hosted client-metadata.json to request fine-grained scopes even when running locally.

Custom record (com.radio4000.track)

  • Fields: url (string), title (string), optional description, optional discogsUrl, createdAt (ISO string).
  • Create/List/Update/Delete implemented in src/libs/r4-service.js via atproto repo APIs.

Permissions & scopes

  • Custom records only: com.radio4000.track (create, update, delete).
  • Social (optional): app.bsky.graph.follow (create, delete) for follow/unfollow.
  • No feed posting is attempted or requested.
  • If reads or writes fail due to missing scope, you’ll see a clear message and an “Open Settings” button.

Troubleshooting

  • Login redirect mismatch on GitHub Pages (subpath deploys): ensure your public/client-metadata.json includes both the base path with and without trailing slash.
  • "Invalid hostname" error during OAuth: if using Tailscale, make sure you're using tailscale funnel (public) not tailscale serve (private). The OAuth server needs public access to fetch your client metadata.
  • OAuth callback not completing login: check browser console for errors. Ensure your client-metadata.json redirect_uris match exactly (with and without trailing slash).
  • DPoP nonce 401 seen in devtools: we avoid eager profile fetch on hydration; it's harmless if seen intermittently.

License MIT

About

Radio4000 on atproto

Topics

Resources

Stars

Watchers

Forks

Contributors 2

  •  
  •