import type { TrackDTO, UserSummaryDTO } from './dto'; export const NOTIFICATION_TYPES = ['reaction', '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', follow: 'New followers', share: 'Songs sent to you', }; /** Missing settings mean on. */ export const notificationPrefs = (stored: Partial | null | undefined): NotificationPrefs => ({ reaction: stored?.reaction ?? true, follow: stored?.follow ?? true, share: stored?.share ?? true, }); export interface NotificationDTO { id: string; type: NotificationType; actor: UserSummaryDTO; track: TrackDTO | 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 '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 === 'share' || n.type === 'reaction') && n.track) return `/t/${n.track.id}`; return `/u/${n.actor.username}`; }