Browse Source

more bug-fixes

imwald
Silberengel 5 months ago
parent
commit
8670b25a4d
  1. 8
      src/components/NoteCard/MainNoteCard.tsx
  2. 6
      src/components/NoteStats/DiscussionNoteStats.tsx
  3. 11
      src/components/NoteStats/VoteButtons.tsx
  4. 12
      src/components/ReactionList/index.tsx
  5. 6
      src/pages/primary/DiscussionsPage/ThreadCard.tsx

8
src/components/NoteCard/MainNoteCard.tsx

@ -1,12 +1,10 @@
import { Separator } from '@/components/ui/separator' import { Separator } from '@/components/ui/separator'
import { ExtendedKind } from '@/constants'
import { toNote } from '@/lib/link' import { toNote } from '@/lib/link'
import { useSecondaryPage } from '@/PageManager' import { useSecondaryPage } from '@/PageManager'
import { Event } from 'nostr-tools' import { Event } from 'nostr-tools'
import Collapsible from '../Collapsible' import Collapsible from '../Collapsible'
import Note from '../Note' import Note from '../Note'
import NoteStats from '../NoteStats' import NoteStats from '../NoteStats'
import DiscussionNoteStats from '../NoteStats/DiscussionNoteStats'
import RepostDescription from './RepostDescription' import RepostDescription from './RepostDescription'
export default function MainNoteCard({ export default function MainNoteCard({
@ -43,11 +41,7 @@ export default function MainNoteCard({
/> />
</Collapsible> </Collapsible>
{!embedded && ( {!embedded && (
event.kind === ExtendedKind.DISCUSSION ? ( <NoteStats className="mt-3 px-4" event={event} />
<DiscussionNoteStats className="mt-3 px-4" event={event} />
) : (
<NoteStats className="mt-3 px-4" event={event} />
)
)} )}
</div> </div>
{!embedded && <Separator />} {!embedded && <Separator />}

6
src/components/NoteStats/DiscussionNoteStats.tsx

@ -5,8 +5,6 @@ import noteStatsService from '@/services/note-stats.service'
import { Event } from 'nostr-tools' import { Event } from 'nostr-tools'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import VoteButtons from './VoteButtons' import VoteButtons from './VoteButtons'
import ReplyButton from './ReplyButton'
import SeenOnButton from './SeenOnButton'
export default function DiscussionNoteStats({ export default function DiscussionNoteStats({
event, event,
@ -42,9 +40,7 @@ export default function DiscussionNoteStats({
)} )}
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
> >
<ReplyButton event={event} />
<VoteButtons event={event} /> <VoteButtons event={event} />
<SeenOnButton event={event} />
</div> </div>
</div> </div>
) )
@ -57,11 +53,9 @@ export default function DiscussionNoteStats({
className={cn('flex items-center gap-2', loading ? 'animate-pulse' : '')} className={cn('flex items-center gap-2', loading ? 'animate-pulse' : '')}
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
> >
<ReplyButton event={event} />
</div> </div>
<div className="flex items-center gap-2" onClick={(e) => e.stopPropagation()}> <div className="flex items-center gap-2" onClick={(e) => e.stopPropagation()}>
<VoteButtons event={event} /> <VoteButtons event={event} />
<SeenOnButton event={event} />
</div> </div>
</div> </div>
</div> </div>

11
src/components/NoteStats/VoteButtons.tsx

@ -40,6 +40,11 @@ export default function VoteButtons({ event }: { event: Event }) {
checkLogin(async () => { checkLogin(async () => {
if (voting || !pubkey) return if (voting || !pubkey) return
// Prevent voting if user already voted (no toggling allowed)
if (userVote) {
return // User already voted, don't allow multiple votes
}
setVoting(type) setVoting(type)
const timer = setTimeout(() => setVoting(null), 10_000) const timer = setTimeout(() => setVoting(null), 10_000)
@ -48,7 +53,7 @@ export default function VoteButtons({ event }: { event: Event }) {
await noteStatsService.fetchNoteStats(event, pubkey) await noteStatsService.fetchNoteStats(event, pubkey)
} }
// If user is voting the same way again, remove the vote (toggle) // Create the vote reaction
const emoji = type === 'up' ? '⬆' : '⬇' const emoji = type === 'up' ? '⬆' : '⬇'
// Check if user already voted this way // Check if user already voted this way
@ -92,13 +97,13 @@ export default function VoteButtons({ event }: { event: Event }) {
userVote === 'up' ? 'bg-orange-100 text-orange-600' : 'text-muted-foreground' userVote === 'up' ? 'bg-orange-100 text-orange-600' : 'text-muted-foreground'
}`} }`}
onClick={() => vote('up')} onClick={() => vote('up')}
disabled={voting !== null} disabled={voting !== null || userVote !== null}
> >
<ChevronUp className="h-4 w-4" /> <ChevronUp className="h-4 w-4" />
</Button> </Button>
<span className={`text-xs font-medium min-w-[20px] text-center ${ <span className={`text-xs font-medium min-w-[20px] text-center ${
score > 0 ? 'text-orange-600' : score < 0 ? 'text-blue-600' : 'text-muted-foreground' score > 0 ? 'text-green-600' : score < 0 ? 'text-red-600' : 'text-muted-foreground'
}`}> }`}>
{score} {score}
</span> </span>

12
src/components/ReactionList/index.tsx

@ -1,4 +1,5 @@
import { useSecondaryPage } from '@/PageManager' import { useSecondaryPage } from '@/PageManager'
import { ExtendedKind } from '@/constants'
import { useNoteStatsById } from '@/hooks/useNoteStatsById' import { useNoteStatsById } from '@/hooks/useNoteStatsById'
import { toProfile } from '@/lib/link' import { toProfile } from '@/lib/link'
import { useScreenSize } from '@/providers/ScreenSizeProvider' import { useScreenSize } from '@/providers/ScreenSizeProvider'
@ -21,10 +22,17 @@ export default function ReactionList({ event }: { event: Event }) {
const { hideUntrustedInteractions, isUserTrusted } = useUserTrust() const { hideUntrustedInteractions, isUserTrusted } = useUserTrust()
const noteStats = useNoteStatsById(event.id) const noteStats = useNoteStatsById(event.id)
const filteredLikes = useMemo(() => { const filteredLikes = useMemo(() => {
return (noteStats?.likes ?? []) let likes = noteStats?.likes ?? []
// For discussion events (kind 11), only show up/down arrow reactions
if (event.kind === ExtendedKind.DISCUSSION) {
likes = likes.filter(like => like.emoji === '⬆' || like.emoji === '⬇')
}
return likes
.filter((like) => !hideUntrustedInteractions || isUserTrusted(like.pubkey)) .filter((like) => !hideUntrustedInteractions || isUserTrusted(like.pubkey))
.sort((a, b) => b.created_at - a.created_at) .sort((a, b) => b.created_at - a.created_at)
}, [noteStats, event.id, hideUntrustedInteractions, isUserTrusted]) }, [noteStats, event.id, hideUntrustedInteractions, isUserTrusted, event.kind])
const [showCount, setShowCount] = useState(SHOW_COUNT) const [showCount, setShowCount] = useState(SHOW_COUNT)
const bottomRef = useRef<HTMLDivElement | null>(null) const bottomRef = useRef<HTMLDivElement | null>(null)

6
src/pages/primary/DiscussionsPage/ThreadCard.tsx

@ -1,7 +1,7 @@
import { Card, CardContent, CardHeader } from '@/components/ui/card' import { Card, CardContent, CardHeader } from '@/components/ui/card'
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge' import { Badge } from '@/components/ui/badge'
import { MessageCircle, User, Clock, Hash, Server } from 'lucide-react' import { User, Clock, Hash, Server } from 'lucide-react'
import { NostrEvent } from 'nostr-tools' import { NostrEvent } from 'nostr-tools'
import { formatDistanceToNow } from 'date-fns' import { formatDistanceToNow } from 'date-fns'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
@ -93,10 +93,6 @@ export default function ThreadCard({ thread, onThreadClick, className }: ThreadC
</div> </div>
</div> </div>
</div> </div>
<div className="flex items-center gap-1 text-sm text-muted-foreground shrink-0">
<MessageCircle className="w-4 h-4" />
<span>0</span> {/* TODO: Add reply count */}
</div>
</div> </div>
</CardHeader> </CardHeader>

Loading…
Cancel
Save