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 | |
|---|---|---|---|
|
|
907bb7e468 | ||
|
|
7eb5ff7821 | ||
|
|
8a982d2ef2 | ||
|
|
24bb18c77c |
@@ -50,7 +50,7 @@ function AppBody (props) {
|
||||
<Route path='/nostr-post' element={<NostrPost appData={appData} />} />
|
||||
<Route path='/nostr-read' element={<NostrRead appData={appData} />} />
|
||||
<Route path='/global-feed' element={<GlobalFeed appData={appData} />} />
|
||||
<Route path='/user-data/:cid' element={<UserDataReview appData={appData} />} />
|
||||
<Route path='/user-data/:tokenId' element={<UserDataReview appData={appData} />} />
|
||||
<Route path='/offers' element={<Offers appData={appData} />} />
|
||||
</Routes>
|
||||
{/** Show in all paths except the servers view */}
|
||||
|
||||
@@ -102,7 +102,7 @@ function InfoButton (props) {
|
||||
<Col xs={4}><b>User Data</b>:</Col>
|
||||
<Col xs={8}>
|
||||
<a
|
||||
href={`/user-data/${mutableDataCid}`}
|
||||
href={`/user-data/${props.token.tokenId}`}
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
className='btn btn-link p-0'
|
||||
|
||||
@@ -47,11 +47,14 @@ function PublicPost (props) {
|
||||
// Relay list
|
||||
const psf = 'wss://nostr-relay.psfoundation.info'
|
||||
|
||||
// BCH address of the user.
|
||||
const bchAddr = bchWalletState.address
|
||||
|
||||
// Generate a post.
|
||||
const eventTemplate = {
|
||||
kind: 1,
|
||||
created_at: Math.floor(Date.now() / 1000),
|
||||
tags: [['t', 'slpdex-socialmedia']],
|
||||
tags: [['t', 'slpdex-socialmedia'], ['u', bchAddr]],
|
||||
content: formData.content
|
||||
}
|
||||
console.log(`eventTemplate: ${JSON.stringify(eventTemplate, null, 2)}`)
|
||||
|
||||
@@ -5,25 +5,34 @@
|
||||
// Global npm libraries
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { Container, Row, Col, Tabs, Tab, Spinner, Carousel } from 'react-bootstrap'
|
||||
import { Container, Row, Col, Spinner, Carousel } from 'react-bootstrap'
|
||||
import ReactMarkdown from 'react-markdown'
|
||||
|
||||
function UserDataReview (props) {
|
||||
const appData = props.appData
|
||||
const [media, setMedia] = useState([])
|
||||
const [markdown, setMarkdown] = useState('')
|
||||
const [activeTab, setActiveTab] = useState('media')
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [error, setError] = useState(null)
|
||||
const [tokenData, setTokenData] = useState(null)
|
||||
// Get the id parameter from the URL
|
||||
const { cid } = useParams()
|
||||
const { tokenId } = useParams()
|
||||
|
||||
useEffect(() => {
|
||||
const loadMedia = async () => {
|
||||
setLoading(true)
|
||||
const loadData = async () => {
|
||||
try {
|
||||
const tokenData = await appData.wallet.getTokenData(tokenId)
|
||||
|
||||
setTokenData(tokenData)
|
||||
setLoading(true)
|
||||
|
||||
if (!tokenData.mutableData) throw new Error('Mutable data not found')
|
||||
|
||||
const cid = parseCid(tokenData.mutableData)
|
||||
|
||||
const { json } = await appData.wallet.cid2json({ cid })
|
||||
const userDataString = json.userData
|
||||
|
||||
if (userDataString) {
|
||||
const userData = JSON.parse(userDataString)
|
||||
setMedia(userData.media)
|
||||
@@ -34,74 +43,80 @@ function UserDataReview (props) {
|
||||
}
|
||||
setLoading(false)
|
||||
}
|
||||
loadMedia()
|
||||
}, [cid, appData.wallet])
|
||||
loadData()
|
||||
}, [tokenId, appData.wallet])
|
||||
|
||||
// Get Cid from url
|
||||
const parseCid = (url) => {
|
||||
// get the cid from the url format 'ipfs://bafybeicem27xbzs65uvbcgykcmscsgln3lmhbfrcoec3gdttkdgtxv5acq
|
||||
if (url && url.includes('ipfs://')) {
|
||||
const cid = url.split('ipfs://')[1]
|
||||
return cid
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Row>
|
||||
<Col>
|
||||
{/** Error message */}
|
||||
{error && <p className='text-danger'>{error}</p>}
|
||||
{loading
|
||||
? (
|
||||
|
||||
{/** Loading spinner */}
|
||||
{loading &&
|
||||
(
|
||||
<div className='text-center my-5'>
|
||||
<Spinner animation='border' role='status' variant='primary'>
|
||||
<span className='visually-hidden'>Loading...</span>
|
||||
</Spinner>
|
||||
</div>
|
||||
)
|
||||
: (
|
||||
<Tabs
|
||||
activeKey={activeTab}
|
||||
onSelect={(k) => setActiveTab(k)}
|
||||
className='mb-4'
|
||||
>
|
||||
<Tab eventKey='media' title='Media'>
|
||||
{media && media.length > 0
|
||||
? (
|
||||
<div className='mt-3 mb-5'>
|
||||
<Carousel>
|
||||
{media.map((item, index) => (
|
||||
<Carousel.Item key={index}>
|
||||
<img
|
||||
className='d-block w-100'
|
||||
src={item.url}
|
||||
alt={`Review media ${index + 1}`}
|
||||
style={{ height: '400px', objectFit: 'contain' }}
|
||||
/>
|
||||
<Carousel.Caption>
|
||||
<p>Image {index + 1} of {media.length}</p>
|
||||
</Carousel.Caption>
|
||||
</Carousel.Item>
|
||||
))}
|
||||
</Carousel>
|
||||
<style>{`
|
||||
.carousel-control-next,
|
||||
.carousel-control-prev,
|
||||
.carousel-indicators {
|
||||
filter: invert(100%);
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
</div>
|
||||
)
|
||||
: (
|
||||
<p className='mt-3'>No media content available</p>
|
||||
)}
|
||||
</Tab>
|
||||
<Tab eventKey='markdown' title='Content'>
|
||||
{markdown
|
||||
? (
|
||||
<div className='markdown-content mt-3'>
|
||||
<ReactMarkdown>{markdown}</ReactMarkdown>
|
||||
</div>
|
||||
)
|
||||
: (
|
||||
<p className='mt-3'>No content available</p>
|
||||
)}
|
||||
</Tab>
|
||||
</Tabs>
|
||||
)}
|
||||
)}
|
||||
{/** User data */}
|
||||
{!loading && !error && (
|
||||
<div className='text-center'>
|
||||
{/** Name */}
|
||||
<h1>{tokenData.genesisData.name}</h1>
|
||||
|
||||
{/** Media Content Carousel */}
|
||||
{media && media.length > 0
|
||||
? (
|
||||
<div className='my-5 '>
|
||||
<Carousel>
|
||||
{media.map((item, index) => (
|
||||
<Carousel.Item key={index}>
|
||||
<img
|
||||
className='d-block w-100'
|
||||
src={item.url}
|
||||
alt={`Review media ${index + 1}`}
|
||||
style={{ height: '400px', objectFit: 'contain' }}
|
||||
/>
|
||||
<Carousel.Caption>
|
||||
<p>Image {index + 1} of {media.length}</p>
|
||||
</Carousel.Caption>
|
||||
</Carousel.Item>
|
||||
))}
|
||||
</Carousel>
|
||||
<style>{'.carousel-control-next,.carousel-control-prev, .carousel-indicators {filter: invert(100%); } '}
|
||||
</style>
|
||||
</div>
|
||||
)
|
||||
: (
|
||||
<p className='mt-3'>No media content available</p>
|
||||
)}
|
||||
|
||||
{/** Markdown Content */}
|
||||
{markdown
|
||||
? (
|
||||
<div className='markdown-content my-5 text-center'>
|
||||
<ReactMarkdown>{markdown}</ReactMarkdown>
|
||||
</div>
|
||||
)
|
||||
: (
|
||||
<p className='mt-3'>No content available</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
|
||||
Reference in New Issue
Block a user