Browse Source

fixed superzaps

imwald
Silberengel 5 months ago
parent
commit
3519ba5ec8
  1. 3
      src/components/KindFilter/index.tsx
  2. 11
      src/components/Note/Zap.tsx
  3. 1
      src/components/ReplyNote/index.tsx
  4. 103
      src/components/ReplyNoteList/index.tsx
  5. 9
      src/services/local-storage.service.ts

3
src/components/KindFilter/index.tsx

@ -128,7 +128,8 @@ export default function KindFilter({ @@ -128,7 +128,8 @@ export default function KindFilter({
<Button
variant="secondary"
onClick={() => {
setTemporaryShowKinds(SUPPORTED_KINDS)
// Select all supported kinds except reposts (matching default behavior)
setTemporaryShowKinds(SUPPORTED_KINDS.filter(kind => kind !== kinds.Repost))
}}
>
{t('Select All')}

11
src/components/Note/Zap.tsx

@ -32,16 +32,21 @@ export default function Zap({ event, className }: { event: Event; className?: st @@ -32,16 +32,21 @@ export default function Zap({ event, className }: { event: Event; className?: st
{/* Zapped note/profile link in top-right corner */}
{(targetEvent || recipientPubkey) && (
<button
onClick={() => {
onClick={(e) => {
e.stopPropagation()
if (targetEvent) {
push(toNote(targetEvent.id))
} else if (recipientPubkey) {
push(toProfile(recipientPubkey))
}
}}
className="absolute top-2 right-2 text-xs text-muted-foreground hover:text-foreground hover:underline"
className="absolute top-2 right-2 px-2 py-1 bg-white/80 dark:bg-black/40 border border-gray-200 dark:border-gray-700 rounded-md text-xs font-medium text-gray-700 dark:text-gray-300 hover:bg-white dark:hover:bg-black hover:border-gray-300 dark:hover:border-gray-600 hover:text-gray-900 dark:hover:text-gray-100 transition-all duration-200 shadow-sm hover:shadow-md"
>
{targetEvent ? t('Zapped note') : t('Zapped profile')}
{targetEvent ? (
<span className="font-mono text-[10px]">{zapInfo.eventId?.substring(0, 12)}...</span>
) : (
t('Zapped profile')
)}
</button>
)}

1
src/components/ReplyNote/index.tsx

@ -51,6 +51,7 @@ export default function ReplyNote({ @@ -51,6 +51,7 @@ export default function ReplyNote({
return true
}, [showMuted, mutePubkeySet, event, hideContentMentioningMutedUsers])
return (
<div
className={`pb-3 border-b transition-colors duration-500 clickable ${highlight ? 'bg-primary/50' : ''}`}

103
src/components/ReplyNoteList/index.tsx

@ -9,7 +9,6 @@ import { @@ -9,7 +9,6 @@ import {
isReplaceableEvent,
isReplyNoteEvent
} from '@/lib/event'
import { getZapInfoFromEvent } from '@/lib/event-metadata'
import { toNote } from '@/lib/link'
import { generateBech32IdFromETag, tagNameEquals } from '@/lib/tag'
import { useSecondaryPage } from '@/PageManager'
@ -18,7 +17,6 @@ import { useMuteList } from '@/providers/MuteListProvider' @@ -18,7 +17,6 @@ import { useMuteList } from '@/providers/MuteListProvider'
import { useNostr } from '@/providers/NostrProvider'
import { useReply } from '@/providers/ReplyProvider'
import { useUserTrust } from '@/providers/UserTrustProvider'
import { useZap } from '@/providers/ZapProvider'
import client from '@/services/client.service'
import noteStatsService from '@/services/note-stats.service'
import { Filter, Event as NEvent, kinds } from 'nostr-tools'
@ -44,8 +42,6 @@ function ReplyNoteList({ index, event, sort = 'oldest' }: { index?: number; even @@ -44,8 +42,6 @@ function ReplyNoteList({ index, event, sort = 'oldest' }: { index?: number; even
const { relayList: userRelayList } = useNostr()
const [rootInfo, setRootInfo] = useState<TRootInfo | undefined>(undefined)
const { repliesMap, addReplies } = useReply()
const [zapEvents, setZapEvents] = useState<NEvent[]>([])
const { zapReplyThreshold } = useZap()
// Helper function to get vote score for a reply
const getReplyVoteScore = (reply: NEvent) => {
@ -87,10 +83,6 @@ function ReplyNoteList({ index, event, sort = 'oldest' }: { index?: number; even @@ -87,10 +83,6 @@ function ReplyNoteList({ index, event, sort = 'oldest' }: { index?: number; even
return totalAmount
}
const replies = useMemo(() => {
console.log(`[ReplyNoteList] Processing replies for event ${event.id.slice(0, 8)}...`)
console.log(`[ReplyNoteList] zapEvents.length: ${zapEvents.length}`)
console.log(`[ReplyNoteList] zapReplyThreshold: ${zapReplyThreshold}`)
const replyIdSet = new Set<string>()
const replyEvents: NEvent[] = []
const currentEventKey = isReplaceableEvent(event.kind)
@ -110,44 +102,6 @@ function ReplyNoteList({ index, event, sort = 'oldest' }: { index?: number; even @@ -110,44 +102,6 @@ function ReplyNoteList({ index, event, sort = 'oldest' }: { index?: number; even
parentEventKeys = events.map((evt) => evt.id)
}
// Add zap receipts that are above the threshold
console.log(`========== ZAP FILTERING START ==========`)
console.log(`Processing ${zapEvents.length} zap events with threshold ${zapReplyThreshold} sats`)
zapEvents.forEach((zapEvt) => {
console.log(`\n--- Processing zap: ${zapEvt.id.slice(0, 8)}... ---`)
console.log(`Created: ${new Date(zapEvt.created_at * 1000).toISOString()}`)
if (replyIdSet.has(zapEvt.id)) {
console.log(`❌ Already in set, skipping`)
return
}
if (mutePubkeySet.has(zapEvt.pubkey)) {
console.log(`❌ From muted user, skipping`)
return
}
const zapInfo = getZapInfoFromEvent(zapEvt)
if (!zapInfo) {
console.log(`❌ No valid zapInfo`)
return
}
console.log(`💰 Zap amount: ${zapInfo.amount} sats`)
console.log(`🎯 Threshold: ${zapReplyThreshold} sats`)
console.log(`🔢 Comparison: ${zapInfo.amount} >= ${zapReplyThreshold} = ${zapInfo.amount >= zapReplyThreshold}`)
if (zapInfo.amount >= zapReplyThreshold) {
console.log(`✅ PASSED - Adding to replies`)
replyIdSet.add(zapEvt.id)
replyEvents.push(zapEvt)
} else {
console.log(`❌ FILTERED OUT - ${zapInfo.amount} < ${zapReplyThreshold}`)
}
})
console.log(`\n========== ZAP FILTERING END ==========`)
console.log(`Total zaps that passed: ${replyEvents.filter(e => e.kind === kinds.Zap).length}`)
console.log(`Total reply events: ${replyEvents.length}`)
// Apply sorting based on the sort parameter
switch (sort) {
@ -188,7 +142,7 @@ function ReplyNoteList({ index, event, sort = 'oldest' }: { index?: number; even @@ -188,7 +142,7 @@ function ReplyNoteList({ index, event, sort = 'oldest' }: { index?: number; even
default:
return replyEvents.sort((a, b) => b.created_at - a.created_at)
}
}, [event.id, repliesMap, zapEvents, zapReplyThreshold, mutePubkeySet, hideContentMentioningMutedUsers, sort])
}, [event.id, repliesMap, mutePubkeySet, hideContentMentioningMutedUsers, sort])
const [timelineKey, setTimelineKey] = useState<string | undefined>(undefined)
const [until, setUntil] = useState<number | undefined>(undefined)
const [loading, setLoading] = useState<boolean>(false)
@ -267,7 +221,6 @@ function ReplyNoteList({ index, event, sort = 'oldest' }: { index?: number; even @@ -267,7 +221,6 @@ function ReplyNoteList({ index, event, sort = 'oldest' }: { index?: number; even
setLoading(true)
try {
console.log(`[ReplyNoteList] Starting init with rootInfo:`, rootInfo)
// Privacy: Only use user's own relays + defaults, never connect to other users' relays
const userRelays = userRelayList?.read || []
@ -324,27 +277,6 @@ function ReplyNoteList({ index, event, sort = 'oldest' }: { index?: number; even @@ -324,27 +277,6 @@ function ReplyNoteList({ index, event, sort = 'oldest' }: { index?: number; even
})
}
// Fetch zap receipts for the event
if (rootInfo.type === 'E') {
console.log(`[ReplyNoteList] Adding zap filter for E type: #e=[${rootInfo.id}], kinds=[${kinds.Zap}]`)
filters.push({
'#e': [rootInfo.id],
kinds: [kinds.Zap],
limit: LIMIT
})
} else if (rootInfo.type === 'A') {
console.log(`[ReplyNoteList] Adding zap filter for A type: #a=[${rootInfo.id}], kinds=[${kinds.Zap}]`)
filters.push({
'#a': [rootInfo.id],
kinds: [kinds.Zap],
limit: LIMIT
})
}
console.log(`[ReplyNoteList] Total filters: ${filters.length}`)
filters.forEach((filter, i) => {
console.log(`[ReplyNoteList] Filter ${i}:`, filter)
})
const { closer, timelineKey } = await client.subscribeTimeline(
filters.map((filter) => ({
@ -352,41 +284,18 @@ function ReplyNoteList({ index, event, sort = 'oldest' }: { index?: number; even @@ -352,41 +284,18 @@ function ReplyNoteList({ index, event, sort = 'oldest' }: { index?: number; even
filter
})),
{
onEvents: (evts, eosed) => {
if (evts.length > 0) {
const regularReplies = evts.filter((evt) => isReplyNoteEvent(evt))
const zaps = evts.filter((evt) => evt.kind === kinds.Zap)
console.log(`[ReplyNoteList] Received ${evts.length} events: ${regularReplies.length} regular replies, ${zaps.length} zaps`)
addReplies(regularReplies)
if (zaps.length > 0) {
console.log(`[ReplyNoteList] Adding ${zaps.length} new zap events`)
setZapEvents(prev => {
const zapIdSet = new Set(prev.map(z => z.id))
const newZaps = zaps.filter(z => !zapIdSet.has(z.id))
console.log(`[ReplyNoteList] ${newZaps.length} are actually new (not duplicates)`)
return [...prev, ...newZaps]
})
onEvents: (evts, eosed) => {
if (evts.length > 0) {
const regularReplies = evts.filter((evt) => isReplyNoteEvent(evt))
addReplies(regularReplies)
}
}
if (eosed) {
setUntil(evts.length >= LIMIT ? evts[evts.length - 1].created_at - 1 : undefined)
setLoading(false)
}
},
onNew: (evt) => {
if (evt.kind === kinds.Zap) {
console.log(`[ReplyNoteList] New zap event received: ${evt.id.slice(0, 8)}...`)
setZapEvents(prev => {
if (prev.some(z => z.id === evt.id)) {
console.log(`[ReplyNoteList] Zap ${evt.id.slice(0, 8)} already exists, skipping`)
return prev
}
console.log(`[ReplyNoteList] Adding new zap: ${evt.id.slice(0, 8)}...`)
return [...prev, evt]
})
} else if (isReplyNoteEvent(evt)) {
if (isReplyNoteEvent(evt)) {
addReplies([evt])
}
}

9
src/services/local-storage.service.ts

@ -178,10 +178,17 @@ class LocalStorageService { @@ -178,10 +178,17 @@ class LocalStorageService {
if (showKindsVersion < 2) {
showKinds.push(ExtendedKind.ZAP_RECEIPT)
}
if (showKindsVersion < 3) {
// Remove reposts from existing users' filters
const repostIndex = showKinds.indexOf(kinds.Repost)
if (repostIndex !== -1) {
showKinds.splice(repostIndex, 1)
}
}
this.showKinds = showKinds
}
window.localStorage.setItem(StorageKey.SHOW_KINDS, JSON.stringify(this.showKinds))
window.localStorage.setItem(StorageKey.SHOW_KINDS_VERSION, '2')
window.localStorage.setItem(StorageKey.SHOW_KINDS_VERSION, '3')
this.hideContentMentioningMutedUsers =
window.localStorage.getItem(StorageKey.HIDE_CONTENT_MENTIONING_MUTED_USERS) === 'true'

Loading…
Cancel
Save