feat: 💨

This commit is contained in:
codytseng
2025-11-20 21:31:48 +08:00
parent ce72098175
commit 18ae2a5fd4
4 changed files with 17 additions and 12 deletions

View File

@@ -7,6 +7,7 @@ import { useContentPolicy } from '@/providers/ContentPolicyProvider'
import { useDeletedEvent } from '@/providers/DeletedEventProvider' import { useDeletedEvent } from '@/providers/DeletedEventProvider'
import { useMuteList } from '@/providers/MuteListProvider' import { useMuteList } from '@/providers/MuteListProvider'
import { useNostr } from '@/providers/NostrProvider' import { useNostr } from '@/providers/NostrProvider'
import { useReply } from '@/providers/ReplyProvider'
import { useUserTrust } from '@/providers/UserTrustProvider' import { useUserTrust } from '@/providers/UserTrustProvider'
import client from '@/services/client.service' import client from '@/services/client.service'
import { TFeedSubRequest } from '@/types' import { TFeedSubRequest } from '@/types'
@@ -65,6 +66,7 @@ const NoteList = forwardRef(
const { mutePubkeySet } = useMuteList() const { mutePubkeySet } = useMuteList()
const { hideContentMentioningMutedUsers } = useContentPolicy() const { hideContentMentioningMutedUsers } = useContentPolicy()
const { isEventDeleted } = useDeletedEvent() const { isEventDeleted } = useDeletedEvent()
const { addReplies } = useReply()
const [events, setEvents] = useState<Event[]>([]) const [events, setEvents] = useState<Event[]>([])
const [newEvents, setNewEvents] = useState<Event[]>([]) const [newEvents, setNewEvents] = useState<Event[]>([])
const [hasMore, setHasMore] = useState<boolean>(true) const [hasMore, setHasMore] = useState<boolean>(true)
@@ -253,6 +255,7 @@ const NoteList = forwardRef(
if (eosed) { if (eosed) {
setLoading(false) setLoading(false)
setHasMore(events.length > 0) setHasMore(events.length > 0)
addReplies(events)
} }
}, },
onNew: (event) => { onNew: (event) => {
@@ -265,6 +268,7 @@ const NoteList = forwardRef(
[event, ...oldEvents].sort((a, b) => b.created_at - a.created_at) [event, ...oldEvents].sort((a, b) => b.created_at - a.created_at)
) )
} }
addReplies([event])
}, },
onClose: (url, reason) => { onClose: (url, reason) => {
if (!showRelayCloseReason) return if (!showRelayCloseReason) return

View File

@@ -1,8 +1,10 @@
import { BIG_RELAY_URLS, ExtendedKind, NOTIFICATION_LIST_STYLE } from '@/constants' import { BIG_RELAY_URLS, ExtendedKind, NOTIFICATION_LIST_STYLE } from '@/constants'
import { compareEvents } from '@/lib/event' import { compareEvents } from '@/lib/event'
import { isTouchDevice } from '@/lib/utils'
import { usePrimaryPage } from '@/PageManager' import { usePrimaryPage } from '@/PageManager'
import { useNostr } from '@/providers/NostrProvider' import { useNostr } from '@/providers/NostrProvider'
import { useNotification } from '@/providers/NotificationProvider' import { useNotification } from '@/providers/NotificationProvider'
import { useReply } from '@/providers/ReplyProvider'
import { useUserPreferences } from '@/providers/UserPreferencesProvider' import { useUserPreferences } from '@/providers/UserPreferencesProvider'
import client from '@/services/client.service' import client from '@/services/client.service'
import stuffStatsService from '@/services/stuff-stats.service' import stuffStatsService from '@/services/stuff-stats.service'
@@ -20,11 +22,10 @@ import {
} from 'react' } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import PullToRefresh from 'react-simple-pull-to-refresh' import PullToRefresh from 'react-simple-pull-to-refresh'
import { RefreshButton } from '../RefreshButton'
import Tabs from '../Tabs' import Tabs from '../Tabs'
import { NotificationItem } from './NotificationItem' import { NotificationItem } from './NotificationItem'
import { NotificationSkeleton } from './NotificationItem/Notification' import { NotificationSkeleton } from './NotificationItem/Notification'
import { isTouchDevice } from '@/lib/utils'
import { RefreshButton } from '../RefreshButton'
const LIMIT = 100 const LIMIT = 100
const SHOW_COUNT = 30 const SHOW_COUNT = 30
@@ -36,6 +37,7 @@ const NotificationList = forwardRef((_, ref) => {
const { pubkey } = useNostr() const { pubkey } = useNostr()
const { getNotificationsSeenAt } = useNotification() const { getNotificationsSeenAt } = useNotification()
const { notificationListStyle } = useUserPreferences() const { notificationListStyle } = useUserPreferences()
const { addReplies } = useReply()
const [notificationType, setNotificationType] = useState<TNotificationType>('all') const [notificationType, setNotificationType] = useState<TNotificationType>('all')
const [lastReadTime, setLastReadTime] = useState(0) const [lastReadTime, setLastReadTime] = useState(0)
const [refreshCount, setRefreshCount] = useState(0) const [refreshCount, setRefreshCount] = useState(0)
@@ -139,11 +141,13 @@ const NotificationList = forwardRef((_, ref) => {
if (eosed) { if (eosed) {
setLoading(false) setLoading(false)
setUntil(events.length > 0 ? events[events.length - 1].created_at - 1 : undefined) setUntil(events.length > 0 ? events[events.length - 1].created_at - 1 : undefined)
addReplies(events)
stuffStatsService.updateStuffStatsByEvents(events) stuffStatsService.updateStuffStatsByEvents(events)
} }
}, },
onNew: (event) => { onNew: (event) => {
handleNewEvent(event) handleNewEvent(event)
addReplies([event])
} }
} }
) )

View File

@@ -1,4 +1,5 @@
import { BIG_RELAY_URLS, ExtendedKind } from '@/constants' import { BIG_RELAY_URLS, ExtendedKind } from '@/constants'
import { useStuff } from '@/hooks/useStuff'
import { import {
getEventKey, getEventKey,
getKeyFromTag, getKeyFromTag,
@@ -7,8 +8,7 @@ import {
getRootTag, getRootTag,
isMentioningMutedUsers, isMentioningMutedUsers,
isProtectedEvent, isProtectedEvent,
isReplaceableEvent, isReplaceableEvent
isReplyNoteEvent
} from '@/lib/event' } from '@/lib/event'
import { toNote } from '@/lib/link' import { toNote } from '@/lib/link'
import { generateBech32IdFromATag, generateBech32IdFromETag } from '@/lib/tag' import { generateBech32IdFromATag, generateBech32IdFromETag } from '@/lib/tag'
@@ -23,7 +23,6 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { LoadingBar } from '../LoadingBar' import { LoadingBar } from '../LoadingBar'
import ReplyNote, { ReplyNoteSkeleton } from '../ReplyNote' import ReplyNote, { ReplyNoteSkeleton } from '../ReplyNote'
import { useStuff } from '@/hooks/useStuff'
type TRootInfo = type TRootInfo =
| { type: 'E'; id: string; pubkey: string } | { type: 'E'; id: string; pubkey: string }
@@ -185,7 +184,7 @@ export default function ReplyNoteList({
{ {
onEvents: (evts, eosed) => { onEvents: (evts, eosed) => {
if (evts.length > 0) { if (evts.length > 0) {
addReplies(evts.filter((evt) => isReplyNoteEvent(evt))) addReplies(evts)
} }
if (eosed) { if (eosed) {
setUntil(evts.length >= LIMIT ? evts[evts.length - 1].created_at - 1 : undefined) setUntil(evts.length >= LIMIT ? evts[evts.length - 1].created_at - 1 : undefined)
@@ -193,7 +192,6 @@ export default function ReplyNoteList({
} }
}, },
onNew: (evt) => { onNew: (evt) => {
if (!isReplyNoteEvent(evt)) return
addReplies([evt]) addReplies([evt])
} }
} }
@@ -249,10 +247,7 @@ export default function ReplyNoteList({
setLoading(true) setLoading(true)
const events = await client.loadMoreTimeline(timelineKey, until, LIMIT) const events = await client.loadMoreTimeline(timelineKey, until, LIMIT)
const olderEvents = events.filter((evt) => isReplyNoteEvent(evt)) addReplies(events)
if (olderEvents.length > 0) {
addReplies(olderEvents)
}
setUntil(events.length ? events[events.length - 1].created_at - 1 : undefined) setUntil(events.length ? events[events.length - 1].created_at - 1 : undefined)
setLoading(false) setLoading(false)
}, [loading, until, timelineKey]) }, [loading, until, timelineKey])

View File

@@ -1,4 +1,4 @@
import { getEventKey, getKeyFromTag, getParentTag } from '@/lib/event' import { getEventKey, getKeyFromTag, getParentTag, isReplyNoteEvent } from '@/lib/event'
import { Event } from 'nostr-tools' import { Event } from 'nostr-tools'
import { createContext, useCallback, useContext, useState } from 'react' import { createContext, useCallback, useContext, useState } from 'react'
@@ -26,6 +26,8 @@ export function ReplyProvider({ children }: { children: React.ReactNode }) {
const newReplyKeySet = new Set<string>() const newReplyKeySet = new Set<string>()
const newReplyEventMap = new Map<string, Event[]>() const newReplyEventMap = new Map<string, Event[]>()
replies.forEach((reply) => { replies.forEach((reply) => {
if (!isReplyNoteEvent(reply)) return
const key = getEventKey(reply) const key = getEventKey(reply)
if (newReplyKeySet.has(key)) return if (newReplyKeySet.has(key)) return
newReplyKeySet.add(key) newReplyKeySet.add(key)