feat: make block number link that will refernce to the event
This commit is contained in:
parent
5c36554b66
commit
37bc205ce4
@ -6,9 +6,10 @@ import {
|
|||||||
validateEvent,
|
validateEvent,
|
||||||
verifyEvent,
|
verifyEvent,
|
||||||
Event,
|
Event,
|
||||||
EventTemplate
|
EventTemplate,
|
||||||
|
nip19
|
||||||
} from 'nostr-tools'
|
} from 'nostr-tools'
|
||||||
import { ProfileMetadata, RelaySet } from '../types'
|
import { NostrJoiningBlock, ProfileMetadata, RelaySet } from '../types'
|
||||||
import { NostrController } from '.'
|
import { NostrController } from '.'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
import { queryNip05 } from '../utils'
|
import { queryNip05 } from '../utils'
|
||||||
@ -166,14 +167,16 @@ export class MetadataController {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public getNostrJoiningBlockNumber = async (hexKey: string) => {
|
public getNostrJoiningBlockNumber = async (
|
||||||
|
hexKey: string
|
||||||
|
): Promise<NostrJoiningBlock | null> => {
|
||||||
const relaySet = await this.findRelayListMetadata(hexKey)
|
const relaySet = await this.findRelayListMetadata(hexKey)
|
||||||
|
|
||||||
const relays: string[] = []
|
const userRelays: string[] = []
|
||||||
|
|
||||||
// find user's relays
|
// find user's relays
|
||||||
if (relaySet.write.length > 0) {
|
if (relaySet.write.length > 0) {
|
||||||
relays.push(...relaySet.write)
|
userRelays.push(...relaySet.write)
|
||||||
} else {
|
} else {
|
||||||
const metadata = await this.findMetadata(hexKey)
|
const metadata = await this.findMetadata(hexKey)
|
||||||
const metadataContent = this.extractProfileMetadataContent(metadata)
|
const metadataContent = this.extractProfileMetadataContent(metadata)
|
||||||
@ -182,12 +185,12 @@ export class MetadataController {
|
|||||||
const nip05Profile = await queryNip05(metadataContent.nip05)
|
const nip05Profile = await queryNip05(metadataContent.nip05)
|
||||||
|
|
||||||
if (nip05Profile && nip05Profile.pubkey === hexKey) {
|
if (nip05Profile && nip05Profile.pubkey === hexKey) {
|
||||||
relays.push(...nip05Profile.relays)
|
userRelays.push(...nip05Profile.relays)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (relays.length === 0) return null
|
if (userRelays.length === 0) return null
|
||||||
|
|
||||||
// filter for finding user's first kind 1 event
|
// filter for finding user's first kind 1 event
|
||||||
const eventFilter: Filter = {
|
const eventFilter: Filter = {
|
||||||
@ -198,7 +201,7 @@ export class MetadataController {
|
|||||||
const pool = new SimplePool()
|
const pool = new SimplePool()
|
||||||
|
|
||||||
// find user's kind 1 events published on user's relays
|
// find user's kind 1 events published on user's relays
|
||||||
const events = await pool.querySync(relays, eventFilter)
|
const events = await pool.querySync(userRelays, eventFilter)
|
||||||
if (events && events.length) {
|
if (events && events.length) {
|
||||||
// sort events by created_at time in ascending order
|
// sort events by created_at time in ascending order
|
||||||
events.sort((a, b) => a.created_at - b.created_at)
|
events.sort((a, b) => a.created_at - b.created_at)
|
||||||
@ -270,10 +273,20 @@ export class MetadataController {
|
|||||||
'#p': [jobSignedEvent.pubkey]
|
'#p': [jobSignedEvent.pubkey]
|
||||||
})
|
})
|
||||||
|
|
||||||
// asynchronously get block number from dvm job with 10 seconds timeout
|
// asynchronously get block number from dvm job with 20 seconds timeout
|
||||||
const dvmJobResult = await subscribeWithTimeout(sub, 10000)
|
const dvmJobResult = await subscribeWithTimeout(sub, 20000)
|
||||||
|
|
||||||
return parseInt(dvmJobResult)
|
const encodedEventPointer = nip19.neventEncode({
|
||||||
|
id: event.id,
|
||||||
|
relays: userRelays,
|
||||||
|
author: event.pubkey,
|
||||||
|
kind: event.kind
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
block: parseInt(dvmJobResult),
|
||||||
|
encodedEventPointer
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
|
@ -9,11 +9,11 @@ import {
|
|||||||
} from '@mui/material'
|
} from '@mui/material'
|
||||||
import { UnsignedEvent, nip19, kinds, VerifiedEvent } from 'nostr-tools'
|
import { UnsignedEvent, nip19, kinds, VerifiedEvent } from 'nostr-tools'
|
||||||
import { useEffect, useMemo, useState } from 'react'
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
import { useParams } from 'react-router-dom'
|
import { Link, useParams } from 'react-router-dom'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
import placeholderAvatar from '../../assets/images/nostr-logo.jpg'
|
import placeholderAvatar from '../../assets/images/nostr-logo.jpg'
|
||||||
import { MetadataController, NostrController } from '../../controllers'
|
import { MetadataController, NostrController } from '../../controllers'
|
||||||
import { ProfileMetadata } from '../../types'
|
import { NostrJoiningBlock, ProfileMetadata } from '../../types'
|
||||||
import styles from './style.module.scss'
|
import styles from './style.module.scss'
|
||||||
import { useDispatch, useSelector } from 'react-redux'
|
import { useDispatch, useSelector } from 'react-redux'
|
||||||
import { State } from '../../store/rootReducer'
|
import { State } from '../../store/rootReducer'
|
||||||
@ -34,7 +34,8 @@ export const ProfilePage = () => {
|
|||||||
const nostrController = NostrController.getInstance()
|
const nostrController = NostrController.getInstance()
|
||||||
|
|
||||||
const [pubkey, setPubkey] = useState<string>()
|
const [pubkey, setPubkey] = useState<string>()
|
||||||
const [blockNumber, setBlockNumber] = useState<number | null>(null)
|
const [nostrJoiningBlock, setNostrJoiningBlock] =
|
||||||
|
useState<NostrJoiningBlock | null>(null)
|
||||||
const [profileMetadata, setProfileMetadata] = useState<ProfileMetadata>()
|
const [profileMetadata, setProfileMetadata] = useState<ProfileMetadata>()
|
||||||
const [savingProfileMetadata, setSavingProfileMetadata] = useState(false)
|
const [savingProfileMetadata, setSavingProfileMetadata] = useState(false)
|
||||||
const metadataState = useSelector((state: State) => state.metadata)
|
const metadataState = useSelector((state: State) => state.metadata)
|
||||||
@ -64,7 +65,7 @@ export const ProfilePage = () => {
|
|||||||
metadataController
|
metadataController
|
||||||
.getNostrJoiningBlockNumber(pubkey)
|
.getNostrJoiningBlockNumber(pubkey)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
setBlockNumber(res)
|
setNostrJoiningBlock(res)
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
// todo: handle error
|
// todo: handle error
|
||||||
@ -239,15 +240,18 @@ export const ProfilePage = () => {
|
|||||||
src={profileMetadata.picture || placeholderAvatar}
|
src={profileMetadata.picture || placeholderAvatar}
|
||||||
alt='Profile Image'
|
alt='Profile Image'
|
||||||
/>
|
/>
|
||||||
{blockNumber && (
|
{nostrJoiningBlock && (
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
color: theme.palette.getContrastText(
|
color: theme.palette.getContrastText(
|
||||||
theme.palette.background.paper
|
theme.palette.background.paper
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
component={Link}
|
||||||
|
to={`https://njump.me/${nostrJoiningBlock.encodedEventPointer}`}
|
||||||
|
target='_blank'
|
||||||
>
|
>
|
||||||
On nostr since {blockNumber.toLocaleString()}
|
On nostr since {nostrJoiningBlock.block.toLocaleString()}
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
@ -12,3 +12,8 @@ export interface RelaySet {
|
|||||||
read: string[]
|
read: string[]
|
||||||
write: string[]
|
write: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface NostrJoiningBlock {
|
||||||
|
block: number
|
||||||
|
encodedEventPointer: string
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user