Commit Graph
21 Commits
Author SHA1 Message Date
chrisandClaude Opus 5.5 68ec5a8d99 Slim song cards with an expand arrow, and lyrics
Feed and profile cards now show one slim line (small artwork, title,
artist, Open button) with the progress bar and reactions. The arrow
opens the rest: album, your other services, Share, and lyrics.

Lyrics come from LRCLIB (open source; LRCLIB_URL can point at a
self-hosted copy, or be empty to turn lyrics off). The server looks each
song up once and caches it, including misses (retried after a week).
Timed lyrics follow along with the song; otherwise the first lines show
with "All lyrics".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:19:56 -04:00
chrisandClaude Opus 5.5 d00eb6674e Pick the music services you use
CI / check (push) Canceled after 0s
Songs offered links to all five services. Settings now has "Your music
services": pick the ones you use and songs only show those, with the
main one as the big button. Until someone picks, they still see all of
them. Onboarding sets it to the app you said you listen with.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 20:45:29 -04:00
chrisandClaude Opus 5.5 08631589e3 Friends tab shows who you follow and who follows you
The app's Friends tab was only a search box. It now lists Following and
Followers (with Follow / Remove buttons) until you type a search. The
website gets the same Friends page and tab; search moves there from the
top of the feed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 20:43:03 -04:00
chrisandClaude Opus 5.5 773e6f0e3f Feed: show everyone you follow
CI / check (push) Canceled after 0s
The feed only listed people who had played something, so following
someone who hadn't connected a service yet looked like it did nothing.
Under the feed, a "Following" row now shows everyone else you follow,
linking to their profiles, and the empty message says why it's empty.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
2026-10-06 15:25:41 -04:00
chrisandClaude Opus 5.5 601398acd6 Tidy the header and Settings; remove a featured song
CI / check (push) Canceled after 0s
- Web header is just the logo and Feed / Profile / Settings (current page
  highlighted). On phones those move to a bottom tab bar. Log out, Admin
  and Support moved into Settings.
- The bottom of Settings (web and app) is now one Account list: email,
  password, blocked accounts, admin, support, privacy, terms, log out and
  delete, each a row that opens in place (web) or a screen (app).
- Featured song shows what's featured now, with Change and Remove.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
2026-10-06 14:15:14 -04:00
chrisandClaude Opus 5.5 d2edad4b0d Emoji reactions on songs
CI / check (push) Canceled after 0s
React to a friend's current song or any of their recent plays: tap an
emoji to add yours (or take it back), "☺+" for the quick six, and a full
picker with search and categories (Unicode emoji up to 13.1, generated
into the shared package so web and mobile match). One reaction per person
per play; a new one replaces the old. Chips show counts and, on hover/
long label, who reacted; yours is highlighted. Listeners and followers get
the update live. Not on your own plays, not across a block (blocking also
clears reactions between the two people).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
2026-10-06 13:39:26 -04:00
chrisandClaude Opus 5.5 edc0c7b999 Share songs, with link previews
CI / check (push) Canceled after 0s
- "Share ↗" on every song (web and mobile): the phone's share sheet, or
  copy the link on desktop. Links go to a new song page, /t/<id>?from=you,
  with big artwork and open-in buttons for every service.
- Server-rendered previews (Open Graph / Twitter cards) for song pages and
  profiles: title, who shared it or what they're playing, and the album
  art, avatar or logo. The web server fetches from the API over the
  compose network (INTERNAL_API_URL).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
2026-10-06 13:31:47 -04:00
chrisandClaude Opus 5.5 50f00f922b Privacy policy and terms
CI / check (push) Canceled after 0s
/privacy and /terms describe what the app actually collects and shows
(public profiles and listening, 50 recent plays, encrypted service tokens,
stripped profile pictures, Android reader scope, song lookups that carry no
identity, 14-day backups, 13+), linked from a web footer, the sign-up
forms and mobile Settings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
2026-10-06 13:07:54 -04:00
chrisandClaude Opus 5.5 85e1643c29 Email confirmation, change email/password, show/hide passwords
CI / check (push) Canceled after 0s
- 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
2026-10-06 13:05:26 -04:00
chrisandClaude Opus 5.5 45a7bd190a Safety screens: followers, blocking, reporting, admin
CI / check (push) Canceled after 0s
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
2026-10-06 12:53:28 -04:00
chrisandClaude Opus 5.5 13df568348 Keep progress bars aligned
CI / check (push) Canceled after 0s
The server now sends each fresh position on every poll that has one, and
sends positions advanced to send time; clients count only the time since
they received it. Bars realign every poll and no longer drift by however
far the viewer's clock is off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
2026-10-06 12:48:29 -04:00
chrisandClaude Opus 5.5 be0a00a2c1 Song progress bar, and poll right after a track ends
CI / check (push) Canceled after 0s
- Feed and profile cards show a progress bar with elapsed/total time, only
  when the source reports a real position (Plex, Jellyfin, the Android
  reader). It ticks locally between updates. Apple Music's guessed
  position is no longer reported.
- The Android reader advances MediaSession's stale position to now, stamps
  when it was read (the server corrects for upload delay), and reports
  seeks. The server pushes an update to watchers when a position jumps.
- When a polled source says where in the song someone is, the next poll is
  scheduled just after the song ends (never sooner than 5s), instead of
  waiting out the full interval.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
2026-10-06 01:24:20 -04:00
chrisandClaude Opus 5.5 1f0cdb68f5 Password reset by email
CI / check (push) Canceled after 0s
"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
2026-10-06 01:05:30 -04:00
chrisandClaude Opus 5.5 2b02aa8e89 Profile pictures, display name default, coloured service names
CI / check (push) Canceled after 0s
- Upload a profile picture on web and mobile. The API square-crops it to
  512px WebP, strips metadata (phone photos carry GPS), stores it in
  Postgres and serves it with immutable caching. Avatar URLs are stored as
  paths, so they survive moving the API. Arbitrary avatar URLs are no
  longer accepted (they'd let a profile track its viewers).
- New accounts get the username as typed as their display name; existing
  accounts are backfilled, and clearing it falls back to the username.
- Service names in Settings get a brand-coloured badge and larger type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
2026-10-05 23:38:00 -04:00
chrisandClaude Opus 5.5 17ae36064c Web: redesign, logo, PWA, QR codes, Spotify guidance
- Album-art-tinted cards that crossfade on song change, equalizer bars,
  live avatar rings, drifting ambient colour, Space Grotesk display font,
  brand purple-to-blue gradient from the logo
- Feed cards rise in and glide to new positions (motion); respects
  reduced-motion
- New logo as nav mark, favicon and Apple touch icon
- Installable PWA: manifest, maskable icons, small service worker
  (cached build assets + offline page), security headers
- Show-QR-code on your own profile; centred profile header with stats
- Settings explains connecting Spotify via Last.fm or ListenBrainz

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
2026-10-05 19:16:40 -04:00
chrisandClaude Opus 5.5 63d618f0e3 Unlock everything, add a donation link, credit Last.fm, nudge re-linking
- Every feature is free for everyone (the plan system stays for later);
  remaining limits are abuse guards
- Optional website donation link (NEXT_PUBLIC_DONATION_URL). Not shown in
  the mobile apps, where tips to the developer generally need in-app
  purchase
- Last.fm/ListenBrainz-sourced plays link to the user's profile, as
  Last.fm's API terms require
- Connections track when they last saw activity; a scrobbler silent for
  over a week prompts re-linking Spotify (its link expires every 6 months)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
2026-10-04 08:13:54 -04:00
chrisandClaude Opus 5.5 507cffbe57 Web: Sign in with Last.fm and explain the Spotify beta limit
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
2026-10-04 07:12:19 -04:00
chrisandClaude Opus 5.5 23faffc251 Add pause controls and app attribution to the web app
Settings gets a Sharing card (pause 1 hour / until tomorrow / until
turned back on); the feed shows a resume banner while paused. Now-playing
cards say which app a phone reported, e.g. "via Spotify".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
2026-10-03 17:37:30 -04:00
chrisandClaude Opus 5.5 ece9c4fd64 Add recently played to profiles
A play is recorded when a new track starts (pausing and resuming doesn't
count; returning after 10+ minutes does). Profiles show the last 10,
excluding the track playing now; 50 are kept per user. Recent plays are
free on every plan; the paid flag is renamed to fullHistory.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
2026-10-03 16:02:38 -04:00
chrisandClaude Opus 5.5 87353ccca3 Show your own now-playing at the top of the feed
The feed only listed people you follow, so with no follows it looked like
nothing was being picked up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
2026-10-03 16:02:38 -04:00
chrisandClaude Opus 5.5 5004beb10d Add Next.js web app
Feed with live updates and pinning, profiles with follow/pin, featured song
picker, settings for all music services, and account deletion.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
2026-10-03 09:59:02 -04:00