display reactions, comments, and zap data in mod cards #44

Merged
freakoverse merged 2 commits from staging into master 2024-09-23 16:29:01 +00:00
3 changed files with 74 additions and 49 deletions
Showing only changes of commit a10e9aafd1 - Show all commits

46
src/hooks/useComments.ts Normal file
View File

@ -0,0 +1,46 @@
import {
MetadataController,
RelayController,
UserRelaysType
} from 'controllers'
import { Filter, kinds } from 'nostr-tools'
import { useState } from 'react'
import { CommentEvent, ModDetails } from 'types'
import { useDidMount } from './useDidMount'
export const useComments = (mod: ModDetails) => {
const [commentEvents, setCommentEvents] = useState<CommentEvent[]>([])
useDidMount(async () => {
const metadataController = await MetadataController.getInstance()
const authorReadRelays = await metadataController.findUserRelays(
mod.author,
UserRelaysType.Read
)
const filter: Filter = {
kinds: [kinds.ShortTextNote],
'#a': [mod.aTag]
}
RelayController.getInstance().subscribeForEvents(
filter,
authorReadRelays,
(event) => {
setCommentEvents((prev) => {
if (prev.find((e) => e.id === event.id)) {
return [...prev]
}
return [event, ...prev]
})
}
)
})
return {
commentEvents,
setCommentEvents
}
}

View File

@ -6,19 +6,24 @@ import {
} from 'controllers' } from 'controllers'
import { formatDate } from 'date-fns' import { formatDate } from 'date-fns'
import { useAppSelector, useDidMount, useReactions } from 'hooks' import { useAppSelector, useDidMount, useReactions } from 'hooks'
import { import { useComments } from 'hooks/useComments'
Event, import { Event, kinds, nip19, UnsignedEvent } from 'nostr-tools'
kinds, import React, {
nip19, Dispatch,
Filter as NostrEventFilter, SetStateAction,
UnsignedEvent useEffect,
} from 'nostr-tools' useMemo,
import React, { useEffect, useMemo } from 'react' useState
import { Dispatch, SetStateAction, useState } from 'react' } from 'react'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import { toast } from 'react-toastify' import { toast } from 'react-toastify'
import { getProfilePageRoute } from 'routes' import { getProfilePageRoute } from 'routes'
import { ModDetails, UserProfile } from 'types' import {
CommentEvent,
CommentEventStatus,
ModDetails,
UserProfile
} from 'types/index.ts'
import { abbreviateNumber, hexToNpub, log, LogType, now } from 'utils' import { abbreviateNumber, hexToNpub, log, LogType, now } from 'utils'
enum SortByEnum { enum SortByEnum {
@ -36,23 +41,13 @@ type FilterOptions = {
author: AuthorFilterEnum author: AuthorFilterEnum
} }
enum CommentEventStatus {
Publishing = 'Publishing comment...',
Published = 'Published!',
Failed = 'Failed to publish comment.'
}
interface CommentEvent extends Event {
status?: CommentEventStatus
}
type Props = { type Props = {
modDetails: ModDetails modDetails: ModDetails
setCommentCount: Dispatch<SetStateAction<number>> setCommentCount: Dispatch<SetStateAction<number>>
} }
export const Comments = ({ modDetails, setCommentCount }: Props) => { export const Comments = ({ modDetails, setCommentCount }: Props) => {
const [commentEvents, setCommentEvents] = useState<CommentEvent[]>([]) const { commentEvents, setCommentEvents } = useComments(modDetails)
const [filterOptions, setFilterOptions] = useState<FilterOptions>({ const [filterOptions, setFilterOptions] = useState<FilterOptions>({
sort: SortByEnum.Latest, sort: SortByEnum.Latest,
author: AuthorFilterEnum.All_Comments author: AuthorFilterEnum.All_Comments
@ -64,34 +59,6 @@ export const Comments = ({ modDetails, setCommentCount }: Props) => {
const userState = useAppSelector((state) => state.user) const userState = useAppSelector((state) => state.user)
useDidMount(async () => {
const metadataController = await MetadataController.getInstance()
const authorReadRelays = await metadataController.findUserRelays(
modDetails.author,
UserRelaysType.Read
)
const filter: NostrEventFilter = {
kinds: [kinds.ShortTextNote],
'#a': [modDetails.aTag]
}
RelayController.getInstance().subscribeForEvents(
filter,
authorReadRelays,
(event) => {
setCommentEvents((prev) => {
if (prev.find((e) => e.id === event.id)) {
return [...prev]
}
return [event, ...prev]
})
}
)
})
const handleSubmit = async (content: string): Promise<boolean> => { const handleSubmit = async (content: string): Promise<boolean> => {
if (content === '') return false if (content === '') return false

View File

@ -1,3 +1,15 @@
import { Event } from 'nostr-tools'
export enum CommentEventStatus {
Publishing = 'Publishing comment...',
Published = 'Published!',
Failed = 'Failed to publish comment.'
}
export interface CommentEvent extends Event {
status?: CommentEventStatus
}
export type Game = { export type Game = {
'Game Name': string 'Game Name': string
'16 by 9 image': string '16 by 9 image': string