Inspired by a dashboard design the user shared.
- App: new palette and fonts, borderless rounded panels with soft shadows, a pink-to-blue
gradient card for your own song (text and controls switch to white on it), flat cards for
friends, a 'Hi Chris, welcome back' header, an outline bell, and a pink pill on the active tab.
- Website: the same look, plus a wide-screen layout with a sidebar, the page in a rounded panel,
and a right column with your profile, recent activity and recent plays. Phones keep the top
bar and bottom tabs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Y2iUsKEWDuRGjK5FPmcUP
- Anyone who can see a play can read its comments; the player and the people they follow can write.
The author, the player and admins can delete; comments can be reported (admins see the text).
- Notifications: "commented on" for the player, "replied on" for earlier commenters, each with its
own setting. Reaction and comment notifications now open the play.
- A 💬 chip with the count next to reactions on the feed and recent plays, opening the thread on
the app (/play/[id]) and the website. Threads refresh every few seconds while open.
- Blocking removes comments between the two people. Plays with comments survive history trimming.
- Privacy page updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Y2iUsKEWDuRGjK5FPmcUP
- API: GET /app/android/latest reads the latest Gitea release (ANDROID_RELEASES_URL, optional token for a
private repo) with the APK's SHA-256 from SHA256SUMS; GET /app/android/apk/:name streams that APK.
- App (modules/updater): downloads in the background, checks the SHA-256, and installs through
PackageInstaller: quietly once when leaving the app (Android 12+), otherwise from the feed banner or
Settings > App version. F-Droid builds leave it out and drop the install permissions.
- CI: the release notes come from the fastlane changelog; the app shows the part above ---.
- Settings: Create-account and Link Spotify buttons for Last.fm and ListenBrainz.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reactions to your songs, new followers, and songs sent to you are now
notifications: a bell on the feed (app and website) with an unread
count that updates live, and a list that marks them read. "Send ✉" on
a song sends it to people who follow you, with an optional note.
Settings picks which kinds to be notified about.
Push delivery uses no third-party accounts:
- Android: UnifiedPush through a distributor app (ntfy), pointed at
our own ntfy server (docker-compose.ntfy.yml). Works the same in
the F-Droid build; no Firebase.
- Browsers: standard Web Push from the existing service worker.
Both use Web Push encryption with a VAPID key pair the server makes
and keeps in the database. Push addresses are checked like any other
user-supplied URL. Setup is in docs/PUSH.md; the privacy page covers
the new data.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Sign-up emails a confirmation link (24h); unconfirmed accounts see a
banner on the web with "send it again", and status in Settings.
- Change email (needs the password): the new address gets a confirmation
link and only replaces the old one once clicked; the old address gets a
heads-up with a reset-password link. Pending changes can be cancelled.
- Change password (needs the current one): signs out other sessions.
- Password fields have Show/Hide on web and mobile.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
Web and mobile:
- Follower/following lists (tap the counts), with Follow buttons and
"Remove" on your own followers.
- Profile ⋯ menu: block (with confirmation) / unblock, and report with a
reason and optional note. "Follows you" label, "Follow back", and a
banner on profiles you've blocked.
- Blocked accounts list in Settings, with unblock.
Web only: /admin for the admin account: stats, open/resolved reports,
resolve, suspend/unsuspend.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
"Forgot your password?" on web and mobile sends a one-time link (1 hour)
to the account's email; the website's reset page sets the new password,
signs out every other session and signs in. The request responds the same
whether or not the email has an account, and the email goes out in the
background so timing doesn't reveal it either. Only a hash of the link
token is stored. Sends through SMTP_* settings; without them, emails are
logged (and captured in tests).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
- Redesign matching the web: album-art backdrops, Reanimated equalizer,
spinning live ring, drifting ambient background, gradient buttons with
spring press feedback and haptics, Space Grotesk headings, animated feed
(enter + layout transitions); fix invisible tab labels
- Four-step onboarding for new accounts: which app you listen with (sets
where songs open), the matching share setup, find friends (search,
scan, invite), and a featured song. Skippable; stored server-side
- QR codes: My code (share link) and an in-app scanner (camera only, no
microphone permission)
- Spotify setup via Last.fm or ListenBrainz with guided linking; Android
shares Spotify automatically through the phone reader
- New logo as app icon, adaptive/monochrome icon and splash
- app.config.ts allows cleartext only for local http:// test builds
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
- Local Expo module (Swift): MusicKit authorization, Music User Token via
MusicUserTokenProvider, and live Music app now-playing while the app is
open (MediaPlayer notifications), reported through the device endpoint
- One-tap Apple Music onboarding on iOS; Apple Music row in Settings
- Sign in with Last.fm, plus a guided Spotify-via-Last.fm flow when direct
Spotify sign-in is capped
- Device registration moved to shared code used by Android and iOS
Not yet compiled for iOS (no Xcode here); needs an EAS build.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
A local Expo module listens to system media sessions (the only way
Android exposes other apps' playback, gated by notification access; we
never read notifications). It filters to known music apps, debounces and
deduplicates changes, sends a heartbeat while playing, and delivers
reports through WorkManager so they survive the app being closed.
- One-screen onboarding that doubles as Google Play's prominent
disclosure, opening straight to the app's toggle in Android settings
- Only media notifications are pre-ticked on that settings screen
- Device registration is single-flight (several screens react to the
same permission change) and self-heals if the server revokes a token
- Sign-out revokes the phone's token; resuming sharing re-sends the
current track immediately
- Pause controls in Settings and on the feed
- Fix invisible tab icons and labels on Android
- Keep Metro out of build output so it doesn't exhaust file watchers
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
Native tabs for feed, friend search, profile and settings, with feature
parity with the web app. Sessions are stored in SecureStore, realtime
disconnects in the background, and Spotify/Plex sign-in returns to the app
via the URL scheme.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8