mirror of
https://github.com/Permissionless-Software-Foundation/bch-dex-taker-v2.git
synced 2026-09-21 16:52:01 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec4a4f8c41 | ||
|
|
c14f60a36e | ||
|
|
062ad933d9 | ||
|
|
a81dbb70e1 |
@@ -7,43 +7,14 @@ import { Card } from 'react-bootstrap'
|
|||||||
import Jdenticon from '@chris.troutner/react-jdenticon'
|
import Jdenticon from '@chris.troutner/react-jdenticon'
|
||||||
import CopyOnClick from '../../bch-wallet/copy-on-click.js'
|
import CopyOnClick from '../../bch-wallet/copy-on-click.js'
|
||||||
import FollowBtn from './follow-btn.js'
|
import FollowBtn from './follow-btn.js'
|
||||||
import { RelayPool } from 'nostr'
|
|
||||||
|
|
||||||
function ContentCard (props) {
|
function ContentCard (props) {
|
||||||
const [profile, setProfile] = useState([])
|
|
||||||
const [loaded, setLoaded] = useState(false)
|
|
||||||
const { creator, followList, refreshFollowList } = props
|
const { creator, followList, refreshFollowList } = props
|
||||||
|
const [profile, setProfile] = useState(null)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadProfile = async () => {
|
setProfile(creator?.profile || {})
|
||||||
const psf = 'wss://nostr-relay.psfoundation.info'
|
}, [creator.profile])
|
||||||
|
|
||||||
const pool = RelayPool([psf])
|
|
||||||
pool.on('open', relay => {
|
|
||||||
relay.subscribe('subid', { limit: 5, kinds: [0], authors: [creator.pubkey] })
|
|
||||||
})
|
|
||||||
|
|
||||||
pool.on('eose', relay => {
|
|
||||||
console.log('Closing Relay')
|
|
||||||
relay.close()
|
|
||||||
})
|
|
||||||
|
|
||||||
pool.on('event', (relay, subId, ev) => {
|
|
||||||
try {
|
|
||||||
const profile = JSON.parse(ev.content)
|
|
||||||
console.log('profile', profile)
|
|
||||||
setProfile(profile)
|
|
||||||
} catch (error) {
|
|
||||||
console.log('Error parsing profile', error)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
setLoaded(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!loaded && creator.npub) {
|
|
||||||
loadProfile()
|
|
||||||
}
|
|
||||||
}, [loaded, creator])
|
|
||||||
|
|
||||||
const goToProfile = () => {
|
const goToProfile = () => {
|
||||||
const profileUrl = `${window.location.origin}/profile/${creator.npub}`
|
const profileUrl = `${window.location.origin}/profile/${creator.npub}`
|
||||||
@@ -69,8 +40,8 @@ function ContentCard (props) {
|
|||||||
|
|
||||||
{/* Creator Info */}
|
{/* Creator Info */}
|
||||||
<div className='flex-grow-1'>
|
<div className='flex-grow-1'>
|
||||||
<h5 className='mb-2 fw-bold cursor-pointer' onClick={goToProfile}>{profile.name}</h5>
|
<h5 className='mb-2 fw-bold cursor-pointer' onClick={goToProfile}>{profile?.name}</h5>
|
||||||
<p className='text-muted medium mb-3'>{profile.about}</p>
|
<p className='text-muted medium mb-3'>{profile?.about}</p>
|
||||||
|
|
||||||
{/* Nostr Public Key */}
|
{/* Nostr Public Key */}
|
||||||
<div className='mb-2'>
|
<div className='mb-2'>
|
||||||
@@ -126,7 +97,16 @@ function ContentCard (props) {
|
|||||||
Message
|
Message
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<small>Followers: {creator.followerCnt}</small>
|
<div className='d-flex align-items-center justify-content-center gap-2 mt-2'>
|
||||||
|
<span
|
||||||
|
className='badge rounded-pill bg-white border text-dark px-3 py-2 shadow-sm d-flex align-items-center gap-2'
|
||||||
|
style={{ fontSize: '1rem', fontWeight: 600, cursor: 'auto' }}
|
||||||
|
>
|
||||||
|
<i className='bi bi-people-fill text-primary' style={{ fontSize: '1.2rem' }} />
|
||||||
|
<span style={{ fontWeight: 700 }}>{creator.followerCnt}</span>
|
||||||
|
<span className='text-muted' style={{ fontWeight: 400, fontSize: '0.9rem' }}>Followers</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -139,8 +119,8 @@ function ContentCard (props) {
|
|||||||
|
|
||||||
{/* Creator Info */}
|
{/* Creator Info */}
|
||||||
<div className='w-100 mb-3'>
|
<div className='w-100 mb-3'>
|
||||||
<h5 className='mb-2 fw-bold' onClick={goToProfile}>{profile.name}</h5>
|
<h5 className='mb-2 fw-bold' onClick={goToProfile}>{profile?.name}</h5>
|
||||||
<p className='text-muted small mb-3'>{profile.about}</p>
|
<p className='text-muted small mb-3'>{profile?.about}</p>
|
||||||
|
|
||||||
{/* Nostr Public Key */}
|
{/* Nostr Public Key */}
|
||||||
<div className='mb-3'>
|
<div className='mb-3'>
|
||||||
@@ -194,6 +174,13 @@ function ContentCard (props) {
|
|||||||
Message
|
Message
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div className='d-flex align-items-center justify-content-center gap-2 mt-2'>
|
||||||
|
<span className='badge rounded-pill bg-white border text-dark px-3 py-2 shadow-sm d-flex align-items-center gap-2' style={{ fontSize: '1rem', fontWeight: 600 }}>
|
||||||
|
<i className='bi bi-people-fill text-primary' style={{ fontSize: '1.2rem' }} />
|
||||||
|
<span style={{ fontWeight: 700 }}>{creator.followerCnt}</span>
|
||||||
|
<span className='text-muted' style={{ fontWeight: 400, fontSize: '0.9rem' }}>Followers</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Card.Body>
|
</Card.Body>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import React, { useState, useEffect, useCallback } from 'react'
|
import React, { useState, useEffect, useCallback } from 'react'
|
||||||
import { Container, Spinner, Form } from 'react-bootstrap'
|
import { Container, Spinner, Dropdown } from 'react-bootstrap'
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
import { faFilter } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
// Local libraries
|
// Local libraries
|
||||||
@@ -12,6 +14,7 @@ const SERVER = config.dexServer
|
|||||||
function ContentCreators (props) {
|
function ContentCreators (props) {
|
||||||
const [creators, setCreators] = useState([])
|
const [creators, setCreators] = useState([])
|
||||||
const [loaded, setLoaded] = useState(false)
|
const [loaded, setLoaded] = useState(false)
|
||||||
|
const [selectedFilter, setSelectedFilter] = useState('Most Followers')
|
||||||
const { appData } = props
|
const { appData } = props
|
||||||
|
|
||||||
const [followList, setFollowList] = useState([])
|
const [followList, setFollowList] = useState([])
|
||||||
@@ -47,13 +50,57 @@ function ContentCreators (props) {
|
|||||||
setFollowList(list)
|
setFollowList(list)
|
||||||
}, [appData])
|
}, [appData])
|
||||||
|
|
||||||
|
const loadProfile = useCallback(async (pubKey) => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const psf = 'wss://nostr-relay.psfoundation.info'
|
||||||
|
|
||||||
|
const pool = RelayPool([psf])
|
||||||
|
pool.on('open', relay => {
|
||||||
|
relay.subscribe('subid', { limit: 5, kinds: [0], authors: [pubKey] })
|
||||||
|
})
|
||||||
|
|
||||||
|
pool.on('eose', relay => {
|
||||||
|
console.log('Closing Relay')
|
||||||
|
relay.close()
|
||||||
|
resolve(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
pool.on('event', (relay, subId, ev) => {
|
||||||
|
try {
|
||||||
|
const profile = JSON.parse(ev.content)
|
||||||
|
// console.log('profile', profile)
|
||||||
|
resolve(profile)
|
||||||
|
} catch (error) {
|
||||||
|
resolve(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadCreators = async () => {
|
const loadCreators = async () => {
|
||||||
try {
|
try {
|
||||||
const creators = await axios.get(`${SERVER}/sm/list/all/0`)
|
const creatorsRes = await axios.get(`${SERVER}/sm/list/all/0`)
|
||||||
console.log(creators.data)
|
const creators = creatorsRes.data
|
||||||
setCreators(creators.data)
|
// console.log('creators', creators)
|
||||||
|
setCreators(creators)
|
||||||
setLoaded(true)
|
setLoaded(true)
|
||||||
|
|
||||||
|
for (let i = 0; i < creators.length; i++) {
|
||||||
|
try {
|
||||||
|
const creator = creators[i]
|
||||||
|
const profile = await loadProfile(creator.pubkey)
|
||||||
|
|
||||||
|
// the folowing lines should re-render the ContentCard
|
||||||
|
setCreators(prevCreators => {
|
||||||
|
const updatedCreators = [...prevCreators]
|
||||||
|
updatedCreators[i] = { ...updatedCreators[i], profile }
|
||||||
|
return updatedCreators
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setLoaded(true)
|
setLoaded(true)
|
||||||
}
|
}
|
||||||
@@ -63,7 +110,21 @@ function ContentCreators (props) {
|
|||||||
loadCreators()
|
loadCreators()
|
||||||
getFollowList()
|
getFollowList()
|
||||||
}
|
}
|
||||||
}, [loaded, followList, getFollowList])
|
}, [loaded, followList, getFollowList, loadProfile])
|
||||||
|
|
||||||
|
const filteredCreators = useCallback(() => {
|
||||||
|
if (!creators || creators.length === 0) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
let filtered = [...creators]
|
||||||
|
|
||||||
|
if (selectedFilter === 'Most Followers') {
|
||||||
|
filtered = filtered.sort((a, b) => (b.followerCnt || 0) - (a.followerCnt || 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered
|
||||||
|
}, [creators, selectedFilter])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container className='mt-4 mb-5'>
|
<Container className='mt-4 mb-5'>
|
||||||
@@ -74,13 +135,25 @@ function ContentCreators (props) {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='mb-4'>
|
<div className='mb-4 d-flex justify-content-end'>
|
||||||
<h3>Filters</h3>
|
<Dropdown>
|
||||||
<Form.Select>
|
<Dropdown.Toggle variant='outline-secondary' className='d-flex align-items-center gap-2'>
|
||||||
<option>Most Followers</option>
|
<FontAwesomeIcon icon={faFilter} />
|
||||||
<option>Most Tokens</option>
|
<span>{selectedFilter}</span>
|
||||||
<option>Most Likes</option>
|
</Dropdown.Toggle>
|
||||||
</Form.Select>
|
|
||||||
|
<Dropdown.Menu>
|
||||||
|
<Dropdown.Item onClick={() => setSelectedFilter('Most Followers')}>
|
||||||
|
Most Followers
|
||||||
|
</Dropdown.Item>
|
||||||
|
<Dropdown.Item onClick={() => setSelectedFilter('Most Tokens')}>
|
||||||
|
Most Tokens
|
||||||
|
</Dropdown.Item>
|
||||||
|
<Dropdown.Item onClick={() => setSelectedFilter('Most Likes')}>
|
||||||
|
Most Likes
|
||||||
|
</Dropdown.Item>
|
||||||
|
</Dropdown.Menu>
|
||||||
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!loaded && (
|
{!loaded && (
|
||||||
@@ -92,7 +165,7 @@ function ContentCreators (props) {
|
|||||||
|
|
||||||
{loaded && (
|
{loaded && (
|
||||||
<div>
|
<div>
|
||||||
{creators.map((creator, i) => (
|
{filteredCreators().map((creator, i) => (
|
||||||
<ContentCard
|
<ContentCard
|
||||||
key={`creator-key${i}`}
|
key={`creator-key${i}`}
|
||||||
creator={creator}
|
creator={creator}
|
||||||
@@ -104,7 +177,7 @@ function ContentCreators (props) {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{loaded && creators.length === 0 && (
|
{loaded && filteredCreators().length === 0 && (
|
||||||
<div className='text-center text-muted py-5 bg-light rounded-4 shadow-sm'>
|
<div className='text-center text-muted py-5 bg-light rounded-4 shadow-sm'>
|
||||||
<i className='bi bi-people-fill fs-1 mb-3 d-block opacity-50' />
|
<i className='bi bi-people-fill fs-1 mb-3 d-block opacity-50' />
|
||||||
<div>No content creators found</div>
|
<div>No content creators found</div>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@ const config = {
|
|||||||
radicleUrl: 'https://app.radicle.network/seeds/maple.radicle.garden/rad:git:hnrkd5cjwwb5tzx37hq9uqm5ubon7ee468xcy/remotes/hyyycncbn9qzqmobnhjq9rry6t4mbjiadzjoyhaknzxjcz3cxkpfpc',
|
radicleUrl: 'https://app.radicle.network/seeds/maple.radicle.garden/rad:git:hnrkd5cjwwb5tzx37hq9uqm5ubon7ee468xcy/remotes/hyyycncbn9qzqmobnhjq9rry6t4mbjiadzjoyhaknzxjcz3cxkpfpc',
|
||||||
|
|
||||||
dexServer: 'https://dex-api.fullstack.cash',
|
dexServer: 'https://dex-api.fullstack.cash',
|
||||||
//dexServer: 'http://localhost:5700',
|
// dexServer: 'http://localhost:5700',
|
||||||
|
|
||||||
nostrTopic: 'bch-dex-test-topic-02',
|
nostrTopic: 'bch-dex-test-topic-02',
|
||||||
nostrRelay: 'wss://nostr-relay.psfoundation.info'
|
nostrRelay: 'wss://nostr-relay.psfoundation.info'
|
||||||
|
|||||||
Reference in New Issue
Block a user