Set outfit

This commit is contained in:
Mentor Palokaj 2021-11-27 15:53:38 +01:00
parent 1f1aeadf46
commit c0d5e193ad
3 changed files with 75 additions and 17 deletions

View File

@ -2,24 +2,74 @@ import { Container, Loading } from './generic'
import '../App.css'
import { useState, useEffect } from 'react'
import { useRocketeers } from '../modules/api'
import { useRocketeers, callApi } from '../modules/api'
import { useChainId, useAddress, sign } from '../modules/web3'
import { log } from '../modules/helpers'
import { useAddress } from '../modules/web3'
import { useParams, useNavigate } from 'react-router'
export default function Verifier() {
const { rocketeerId } = useParams()
const navigate = useNavigate()
// ///////////////////////////////
// State management
// ///////////////////////////////
const address = useAddress()
const metamaskAddress = useAddress()
const [ validatorAddress, setValidatorAddress ] = useState( )
const rocketeers = useRocketeers()
const [ selectedId, setSelectedId ] = useState( )
const rocketeers = useRocketeers( rocketeerId )
const chainId = useChainId()
const [ rocketeer, setRocketeer ] = useState( )
const [ loading, setLoading ] = useState( )
/* ///////////////////////////////
// Functions
// /////////////////////////////*/
async function setPrimaryOutfit( outfitId ) {
try {
log( `Setting outfit ${ outfitId } for Rocketeer #${ rocketeerId }` )
setLoading( `Setting outfit ${ outfitId } for Rocketeer #${ rocketeerId }` )
alert( 'You will be prompted to sign a message, this is NOT a transaction' )
const signature = await sign( JSON.stringify( {
signer: address.toLowerCase(),
outfitId: outfitId,
chainId,
} ), address )
log( 'Making request with ', signature )
setLoading( 'Updating profile' )
const { error, success } = await callApi( `/rocketeer/${ rocketeerId }/outfits`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify( signature )
} )
if( error ) throw new Error( error )
alert( `Success! Outfit changed, please click "refresh metadata" on Opensea to update it there.\nForwarding you to the tools homepage.` )
navigate( `/` )
} catch( e ) {
log( e )
alert( e.message )
} finally {
setLoading( false )
}
}
// ///////////////////////////////
// Lifecycle
// ///////////////////////////////
@ -29,8 +79,10 @@ export default function Verifier() {
useEffect( f => {
const selected = rocketeers.find( ( { id } ) => id === selectedId )
// Find the data for the clicked Rocketeer
const selected = rocketeers.find( ( { id } ) => id === rocketeerId )
// If the selected rocketeer is available, compute it's available outfits to an easy to access property
if( selected ) {
const { value: outfits } = selected.attributes.find( ( { trait_type } ) => trait_type === 'available outfits' ) || 0
selected.outfits = outfits
@ -38,15 +90,16 @@ export default function Verifier() {
log( "Selecting rocketeer ", selected )
// Set the selected rocketeer to state
if( selected ) setRocketeer( selected )
}, [ selectedId, rocketeers ] )
}, [ rocketeerId, rocketeers ] )
// ///////////////////////////////
// Rendering
// ///////////////////////////////
if( !rocketeers.length ) return <Loading message="Loading Rocketeers, please make sure you selected the right wallet" />
if( !rocketeers.length || loading ) return <Loading message={ loading || "Loading Rocketeers, please make sure you selected the right wallet" } />
// Rocketeer selector
if(!rocketeer ) return <Container id="avatar" className={ rocketeers.length > 1 ? 'wide' : '' }>
@ -57,7 +110,7 @@ export default function Verifier() {
{ rocketeers.map( ( { id, image } ) => {
return <img id={ `rocketeer=${ id }` } onClick={ f => setSelectedId( id ) } key={ id } className='rocketeer' src={ image } alt={ `Rocketeer number ${ id }` } />
return <img id={ `rocketeer-${ id }` } onClick={ f => navigate( `/outfits/${ id }` ) } key={ id } className='rocketeer' src={ image } alt={ `Rocketeer number ${ id }` } />
} ) }
@ -69,16 +122,18 @@ export default function Verifier() {
</Container>
// Changing room
if( rocketeer ) return <Container id="avatar" className={ rocketeers.length > 1 ? 'wide' : '' }>
if( rocketeer ) return <Container id="avatar" className={ rocketeer.outfits > 0 ? 'wide' : '' }>
<h1>Changing room for Rocketeer { selectedId }</h1>
<img onClick={ f => window.location.href =`https://viewer.rocketeer.fans/?rocketeer=${ rocketeer.id }` } key={ rocketeer.id } className='rocketeer' src={ rocketeer.image } alt={ `Rocketeer number ${ rocketeer.id }` } />
<p>This Rocketeer has { rocketeer.outfits } alternative outfits. { rocketeer.outfits > 0 && 'Click any outfit to select it as primary.' }</p>
<h1>Changing room for Rocketeer { rocketeerId }</h1>
<img key={ rocketeer.id } className='rocketeer' src={ rocketeer.image } alt={ `Rocketeer number ${ rocketeer.id }` } />
<p>This Rocketeer has { 1 + rocketeer.outfits } outfits. { rocketeer.outfits > 0 && 'Click any outfit to select it as primary.' }</p>
<div className="row">
<img key={ rocketeer.id + 0 } onClick={ f => setPrimaryOutfit( 0 ) } className='rocketeer' src={ rocketeer.image } alt={ `Rocketeer number ${ rocketeer.id }` } />
{ Array.from( Array( rocketeer.outfits ) ).map( ( val, i ) => {
return <img onClick={ f => f } key={ rocketeer.id } className='rocketeer' src={ rocketeer.image.replace( '.jpg', `-${ i + 1 }.jpg` ) } alt={ `Rocketeer number ${ rocketeer.id }` } />
return <img onClick={ f => setPrimaryOutfit( i ) } key={ rocketeer.id + i } className='rocketeer' src={ rocketeer.image.replace( '.jpg', `-${ i + 1 }.jpg` ) } alt={ `Rocketeer number ${ rocketeer.id }` } />
} ) }
</div>

View File

@ -53,7 +53,9 @@ function Router() {
</Route>
<Route exact path='/avatar' element={ <Avatar /> } />
<Route exact path='/portfolio' element={ <Portfolio /> } />
<Route exact path='/outfits' element={ <Outfits /> } />
<Route path='/outfits/' element={ <Outfits /> }>
<Route path='/outfits/:rocketeerId' element={ <Outfits /> } />
</Route>
</Routes>

View File

@ -36,9 +36,10 @@ export function getImage( id, ext='jpg', network ) {
}
export function useRocketeers() {
export function useRocketeers( onlyGrabThisId ) {
const ids = useTokenIds()
const tokenIds = useTokenIds()
const ids = onlyGrabThisId ? [ onlyGrabThisId ] : tokenIds
const [ rocketeers, setRocketeers ] = useState( [] )
useEffect( f => {
@ -54,7 +55,7 @@ export function useRocketeers() {
} )( )
}, [ ids ] )
}, [ tokenIds, onlyGrabThisId ] )
return rocketeers