import type { TrackDTO, UserSummaryDTO } from './dto'; export const NOTIFICATION_TYPES = ['reaction', 'comment', 'reply', 'follow', 'share'] as const; export type NotificationType = (typeof NOTIFICATION_TYPES)[number]; /** Which notifications get pushed to your phone/browser. */ export type NotificationPrefs = Record; export const NOTIFICATION_PREF_LABELS: Record = { reaction: 'Reactions to your songs', comment: 'Comments on your songs', reply: 'Replies where you commented', follow: 'New followers', share: 'Songs sent to you', }; /** Missing settings mean on. */ export const notificationPrefs = (stored: Partial | null | undefined): NotificationPrefs => ({ reaction: stored?.reaction ?? true, comment: stored?.comment ?? true, reply: stored?.reply ?? true, follow: stored?.follow ?? true, share: stored?.share ?? true, }); export interface NotificationDTO { id: string; type: NotificationType; actor: UserSummaryDTO; track: TrackDTO | null; /** The play a reaction or comment was on, while it exists. */ listenId: string | null; emoji: string | null; message: string | null; read: boolean; createdAt: string; } export interface NotificationListDTO { notifications: NotificationDTO[]; unread: number; /** Pass back as ?cursor= for older ones; null at the end. */ nextCursor: string | null; } /** What a push or a row in the list says. */ export function notificationText(n: Pick): { title: string; body: string; } { const who = n.actor.displayName ?? n.actor.username; const song = n.track ? `${n.track.title} by ${n.track.artist}` : 'a song'; switch (n.type) { case 'reaction': return { title: `${who} reacted ${n.emoji ?? ''}`.trim(), body: `to ${song}` }; case 'comment': return { title: `${who} commented on ${song}`, body: n.message ?? '' }; case 'reply': return { title: `${who} replied on ${song}`, body: n.message ?? '' }; case 'follow': return { title: `${who} followed you`, body: 'Follow back to see what they play.' }; case 'share': return { title: `${who} sent you a song`, body: n.message ? `${song}: “${n.message}”` : song }; } } /** Where tapping it goes, as an app/web path. */ export function notificationPath(n: Pick): string { if ((n.type === 'comment' || n.type === 'reply' || n.type === 'reaction') && n.listenId) return `/play/${n.listenId}`; if ((n.type === 'share' || n.type === 'reaction') && n.track) return `/t/${n.track.id}`; return `/u/${n.actor.username}`; }