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
This commit is contained in:
2026-10-06 13:39:26 -04:00
co-authored by Claude Opus 5.5
parent edc0c7b999
commit d2edad4b0d
28 changed files with 2200 additions and 30 deletions
+16
View File
@@ -242,6 +242,22 @@ export const featuredSongs = pgTable('featured_songs', {
.default(sql`now()`),
});
/** One emoji per person per play. Deleted with the play (only the latest 50 plays are kept). */
export const reactions = pgTable(
'reactions',
{
listenId: uuid('listen_id')
.notNull()
.references(() => listens.id, { onDelete: 'cascade' }),
userId: uuid('user_id')
.notNull()
.references(() => users.id, { onDelete: 'cascade' }),
emoji: varchar('emoji', { length: 32 }).notNull(),
createdAt: createdAt(),
},
(t) => [primaryKey({ columns: [t.listenId, t.userId] })],
);
/** Email confirmation links (sign-up and email changes). Only a hash of the token is stored. */
export const emailVerifications = pgTable(
'email_verifications',