Merge pull request #36 from Permissionless-Software-Foundation/dh-profile-fill

feat(nostr): Fill in Nostr Profile form with existing data
This commit is contained in:
Chris Troutner
2025-07-20 06:23:18 -07:00
committed by GitHub
@@ -3,17 +3,19 @@ Component for posting nostr information on kind 0.
*/ */
// Global npm libraries // Global npm libraries
import React, { useState } from 'react' import React, { useState, useEffect } from 'react'
import { Container, Form, Button, Spinner } from 'react-bootstrap' import { Container, Form, Button, Spinner } from 'react-bootstrap'
import Accordion from 'react-bootstrap/Accordion' import Accordion from 'react-bootstrap/Accordion'
import { finalizeEvent } from 'nostr-tools/pure' import { finalizeEvent } from 'nostr-tools/pure'
import { Relay } from 'nostr-tools/relay' import { Relay } from 'nostr-tools/relay'
import { hexToBytes } from '@noble/hashes/utils' // already an installed dependency import { hexToBytes } from '@noble/hashes/utils' // already an installed dependency
import { RelayPool } from 'nostr'
function ProfilePost (props) { function ProfilePost (props) {
const { bchWalletState } = props.appData
const [accordionKey, setAccordionKey] = useState(null) const [accordionKey, setAccordionKey] = useState(null)
const [onFetch, setOnFetch] = useState(false) const [onFetch, setOnFetch] = useState(false)
const { bchWalletState } = props.appData const [formLoaded, setFormLoaded] = useState(false)
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
name: '', name: '',
about: '', about: '',
@@ -27,6 +29,43 @@ function ProfilePost (props) {
const [errorMsg, setErrorMsg] = useState('') const [errorMsg, setErrorMsg] = useState('')
const [successMsg, setSuccessMsg] = useState('') const [successMsg, setSuccessMsg] = useState('')
useEffect(() => {
// Get Last post from
const getLastPost = () => {
const { nostrKeyPair } = bchWalletState
const psf = 'wss://nostr-relay.psfoundation.info'
const pool = RelayPool([psf])
pool.on('open', relay => {
relay.subscribe('subid', { limit: 1, kinds: [0], authors: [nostrKeyPair.pubHex] })
setFormLoaded(true)
})
pool.on('eose', relay => {
console.log('Closing Relay')
setFormLoaded(true)
relay.close()
})
pool.on('event', (relay, subId, ev) => {
console.log('Received event:', ev)
// setPosts(currentPosts => [...currentPosts, ev])
try {
const data = JSON.parse(ev.content)
console.log('data', data)
setFormData(data)
} catch (error) {
}
})
}
if (!formLoaded) {
getLastPost()
}
}, [bchWalletState, formLoaded])
const handleInputChange = (e) => { const handleInputChange = (e) => {
const { name, value } = e.target const { name, value } = e.target
setFormData({ setFormData({
@@ -78,7 +117,6 @@ function ProfilePost (props) {
// Close the connection to the relay. // Close the connection to the relay.
relay.close() relay.close()
resetForm()
setSuccessMsg('Post successfully published!') setSuccessMsg('Post successfully published!')
setOnFetch(false) setOnFetch(false)
} catch (error) { } catch (error) {
@@ -92,18 +130,6 @@ function ProfilePost (props) {
setAccordionKey(key) setAccordionKey(key)
} }
const resetForm = () => {
setFormData({
name: '',
about: '',
picture: '',
display_name: '',
website: '',
banner: '',
bot: false
})
}
return ( return (
<> <>
<Container className='mt-4'> <Container className='mt-4'>
@@ -121,103 +147,111 @@ function ProfilePost (props) {
{successMsg} {successMsg}
</div> </div>
)} )}
<Form onSubmit={handleSubmit}> {formLoaded && (
<Form.Group className='mb-3'> <Form onSubmit={handleSubmit}>
<Form.Label>Name</Form.Label> <Form.Group className='mb-3'>
<Form.Control <Form.Label>Name</Form.Label>
type='text' <Form.Control
placeholder='Enter your name' type='text'
name='name' placeholder='Enter your name'
value={formData.name} name='name'
onChange={handleInputChange} value={formData.name}
required onChange={handleInputChange}
/> required
</Form.Group> />
</Form.Group>
<Form.Group className='mb-3'> <Form.Group className='mb-3'>
<Form.Label>About</Form.Label> <Form.Label>About</Form.Label>
<Form.Control <Form.Control
as='textarea' as='textarea'
rows={3} rows={3}
placeholder='Tell us about yourself' placeholder='Tell us about yourself'
name='about' name='about'
value={formData.about} value={formData.about}
onChange={handleInputChange} onChange={handleInputChange}
required required
/> />
</Form.Group> </Form.Group>
<Form.Group className='mb-3'> <Form.Group className='mb-3'>
<Form.Label>Profile Picture URL</Form.Label> <Form.Label>Profile Picture URL</Form.Label>
<Form.Control <Form.Control
type='url' type='url'
placeholder='Enter URL to your profile picture' placeholder='Enter URL to your profile picture'
name='picture' name='picture'
value={formData.picture} value={formData.picture}
onChange={handleInputChange} onChange={handleInputChange}
/> />
</Form.Group> </Form.Group>
<Form.Group className='mb-3'> <Form.Group className='mb-3'>
<Form.Label>Display Name</Form.Label> <Form.Label>Display Name</Form.Label>
<Form.Control <Form.Control
type='text' type='text'
placeholder='Enter your display name' placeholder='Enter your display name'
name='display_name' name='display_name'
value={formData.display_name} value={formData.display_name}
onChange={handleInputChange} onChange={handleInputChange}
/> />
</Form.Group> </Form.Group>
<Form.Group className='mb-3'> <Form.Group className='mb-3'>
<Form.Label>Website</Form.Label> <Form.Label>Website</Form.Label>
<Form.Control <Form.Control
type='url' type='url'
placeholder='Enter your website URL' placeholder='Enter your website URL'
name='website' name='website'
value={formData.website} value={formData.website}
onChange={handleInputChange} onChange={handleInputChange}
/> />
</Form.Group> </Form.Group>
<Form.Group className='mb-3'> <Form.Group className='mb-3'>
<Form.Label>Banner URL</Form.Label> <Form.Label>Banner URL</Form.Label>
<Form.Control <Form.Control
type='url' type='url'
placeholder='Enter URL to your banner picture (1024x768 pixels)' placeholder='Enter URL to your banner picture (1024x768 pixels)'
name='banner' name='banner'
value={formData.banner} value={formData.banner}
onChange={handleInputChange} onChange={handleInputChange}
/> />
</Form.Group> </Form.Group>
<Form.Group className='mb-3'> <Form.Group className='mb-3'>
<Form.Check <Form.Check
type='checkbox' type='checkbox'
label='This account is for a bot' label='This account is for a bot'
name='bot' name='bot'
checked={formData.bot} checked={formData.bot}
onChange={(e) => { onChange={(e) => {
setFormData({ setFormData({
...formData, ...formData,
bot: e.target.checked bot: e.target.checked
}) })
setSuccessMsg('') setSuccessMsg('')
setErrorMsg('') setErrorMsg('')
}} }}
/> />
</Form.Group> </Form.Group>
<div className='d-flex justify-content-center'> <div className='d-flex justify-content-center'>
{!onFetch && ( {!onFetch && (
<Button variant='primary' type='submit' disabled={onFetch}> <Button variant='primary' type='submit' disabled={onFetch}>
Post Post
</Button> </Button>
)} )}
{onFetch && <Spinner animation='border' variant='primary' />} {onFetch && <Spinner animation='border' variant='primary' />}
</div>
</Form>
)}
{!formLoaded && (
<div className='text-center'>
<Spinner animation='border' variant='primary' />
</div> </div>
)}
</Form>
</Accordion.Body> </Accordion.Body>
</Accordion.Item> </Accordion.Item>
</Accordion> </Accordion>