feat: add setting for notification list style

This commit is contained in:
codytseng
2025-09-06 13:49:13 +08:00
parent 71994be407
commit fc138609a1
24 changed files with 257 additions and 29 deletions

View File

@@ -1,8 +1,10 @@
import ParentNotePreview from '@/components/ParentNotePreview'
import { NOTIFICATION_LIST_STYLE } from '@/constants'
import { getEmbeddedPubkeys, getParentBech32Id } from '@/lib/event'
import { toNote } from '@/lib/link'
import { useSecondaryPage } from '@/PageManager'
import { useNostr } from '@/providers/NostrProvider'
import { useUserPreferences } from '@/providers/UserPreferencesProvider'
import { AtSign, MessageCircle, Quote } from 'lucide-react'
import { Event } from 'nostr-tools'
import { useMemo } from 'react'
@@ -19,6 +21,7 @@ export function MentionNotification({
const { t } = useTranslation()
const { push } = useSecondaryPage()
const { pubkey } = useNostr()
const { notificationListStyle } = useUserPreferences()
const isMention = useMemo(() => {
if (!pubkey) return false
const mentions = getEmbeddedPubkeys(notification)
@@ -42,6 +45,7 @@ export function MentionNotification({
sentAt={notification.created_at}
targetEvent={notification}
middle={
notificationListStyle === NOTIFICATION_LIST_STYLE.DETAILED &&
parentEventId && (
<ParentNotePreview
eventId={parentEventId}

View File

@@ -4,11 +4,13 @@ import NoteStats from '@/components/NoteStats'
import { Skeleton } from '@/components/ui/skeleton'
import UserAvatar from '@/components/UserAvatar'
import Username from '@/components/Username'
import { NOTIFICATION_LIST_STYLE } from '@/constants'
import { toNote, toProfile } from '@/lib/link'
import { cn } from '@/lib/utils'
import { useSecondaryPage } from '@/PageManager'
import { useNostr } from '@/providers/NostrProvider'
import { useNotification } from '@/providers/NotificationProvider'
import { useUserPreferences } from '@/providers/UserPreferencesProvider'
import { NostrEvent } from 'nostr-tools'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
@@ -38,22 +40,52 @@ export default function Notification({
const { push } = useSecondaryPage()
const { pubkey } = useNostr()
const { isNotificationRead, markNotificationAsRead } = useNotification()
const { notificationListStyle } = useUserPreferences()
const unread = useMemo(
() => isNew && !isNotificationRead(notificationId),
[isNew, isNotificationRead, notificationId]
)
const handleClick = () => {
markNotificationAsRead(notificationId)
if (targetEvent) {
push(toNote(targetEvent.id))
} else if (pubkey) {
push(toProfile(pubkey))
}
}
if (notificationListStyle === NOTIFICATION_LIST_STYLE.COMPACT) {
return (
<div
className="flex items-center justify-between cursor-pointer py-2 px-4"
onClick={handleClick}
>
<div className="flex gap-2 items-center flex-1 w-0">
<UserAvatar userId={sender} size="small" />
{icon}
{middle}
{targetEvent && (
<ContentPreview
className={cn(
'truncate flex-1 w-0',
unread ? 'font-semibold' : 'text-muted-foreground'
)}
event={targetEvent}
/>
)}
</div>
<div className="text-muted-foreground shrink-0">
<FormattedTimestamp timestamp={sentAt} short />
</div>
</div>
)
}
return (
<div
className="clickable flex items-start gap-2 cursor-pointer py-2 px-4 border-b"
onClick={() => {
markNotificationAsRead(notificationId)
if (targetEvent) {
push(toNote(targetEvent.id))
} else if (pubkey) {
push(toProfile(pubkey))
}
}}
onClick={handleClick}
>
<div className="flex gap-2 items-center mt-1.5">
{icon}
@@ -95,6 +127,17 @@ export default function Notification({
}
export function NotificationSkeleton() {
const { notificationListStyle } = useUserPreferences()
if (notificationListStyle === NOTIFICATION_LIST_STYLE.COMPACT) {
return (
<div className="flex gap-2 items-center h-11 py-2 px-4">
<Skeleton className="w-7 h-7 rounded-full" />
<Skeleton className="h-6 flex-1 w-0" />
</div>
)
}
return (
<div className="flex items-start gap-2 cursor-pointer py-2 px-4">
<div className="flex gap-2 items-center mt-1.5">

View File

@@ -1,8 +1,9 @@
import { BIG_RELAY_URLS, ExtendedKind } from '@/constants'
import { BIG_RELAY_URLS, ExtendedKind, NOTIFICATION_LIST_STYLE } from '@/constants'
import { compareEvents } from '@/lib/event'
import { usePrimaryPage } from '@/PageManager'
import { useNostr } from '@/providers/NostrProvider'
import { useNotification } from '@/providers/NotificationProvider'
import { useUserPreferences } from '@/providers/UserPreferencesProvider'
import { useUserTrust } from '@/providers/UserTrustProvider'
import client from '@/services/client.service'
import noteStatsService from '@/services/note-stats.service'
@@ -34,6 +35,7 @@ const NotificationList = forwardRef((_, ref) => {
const { pubkey } = useNostr()
const { hideUntrustedNotifications, isUserTrusted } = useUserTrust()
const { getNotificationsSeenAt } = useNotification()
const { notificationListStyle } = useUserPreferences()
const [notificationType, setNotificationType] = useState<TNotificationType>('all')
const [lastReadTime, setLastReadTime] = useState(0)
const [refreshCount, setRefreshCount] = useState(0)
@@ -262,7 +264,7 @@ const NotificationList = forwardRef((_, ref) => {
}}
pullingContent=""
>
<div>
<div className={notificationListStyle === NOTIFICATION_LIST_STYLE.COMPACT ? 'pt-2' : ''}>
{visibleNotifications.map((notification) => (
<NotificationItem
key={notification.id}