import React, { useEffect, useState } from "react"; import { Link } from "react-router-dom"; import { getNotifications, markNotificationsRead } from "../../api/client"; import type { NotificationItem, AnnotationItem } from "../../types"; import { Heart, MessageCircle, Bell, PenTool, Bookmark, UserPlus, AtSign, ExternalLink, } from "lucide-react"; import { formatDistanceToNow } from "date-fns"; import { clsx } from "clsx"; import { Avatar, EmptyState, Skeleton } from "../../components/ui"; function getContentType( uri: string, ): "annotation" | "highlight" | "bookmark" | "reply" | "unknown" { if (uri.includes("/at.margin.annotation/")) return "annotation"; if (uri.includes("/at.margin.highlight/")) return "highlight"; if (uri.includes("/at.margin.bookmark/")) return "bookmark"; if (uri.includes("/at.margin.reply/")) return "reply"; return "unknown"; } function getNotificationVerb( notifType: string, contentType: string, subject?: AnnotationItem, ): string { switch (notifType) { case "like": switch (contentType) { case "annotation": return "liked your annotation"; case "highlight": return "liked your highlight"; case "bookmark": return "liked your bookmark"; case "reply": return "liked your reply"; default: return "liked your post"; } case "reply": { const parentUri = subject?.inReplyTo; const parentIsReply = parentUri ? getContentType(parentUri) === "reply" : false; return parentIsReply ? "replied to your reply" : "replied to your annotation"; } case "mention": return "mentioned you in an annotation"; case "follow": return "followed you"; case "highlight": return "highlighted your page"; default: return notifType; } } const NotificationIcon = ({ type }: { type: string }) => { const base = "p-2 rounded-full"; switch (type) { case "like": return (
“{quote}”
)} {body && ({body}
)} > ); } else if (contentType === "highlight") { const quote = item?.target?.selector?.exact; preview = quote ? (“{quote}”
) : null; } else if (contentType === "bookmark") { const title = item?.title || item?.target?.title; const source = item?.source || item?.target?.source; preview = ( <> {title && ({title}
)} {source && (
{text}
)} {parentUri && (in reply to{" "} e.stopPropagation()} > {parentIsReply ? "a reply" : "an annotation"}
)} > ); } if (!preview) return null; return ( {preview} ); } export default function Notifications() { const [notifications, setNotifications] = useState