Merge pull request #75 from public-awesome/ui-improvements

Base Minter related UI improvements
This commit is contained in:
Serkan Reis 2022-12-15 15:10:00 +03:00 committed by GitHub
commit 03ad2f816e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 126 additions and 46 deletions

View File

@ -25,7 +25,11 @@ export const AssetsPreview = ({ assetFilesArray, updateMetadataFileIndex, minter
tempArray.push( tempArray.push(
<video <video
key={assetFile.name} key={assetFile.name}
className="absolute px-1 my-1 max-h-24 thumbnail" className={clsx(
'absolute px-1 my-1 thumbnail',
{ 'max-h-24': minterType === 'vending' },
{ 'max-h-72': minterType === 'base' },
)}
id="video" id="video"
muted muted
onMouseEnter={(e) => { onMouseEnter={(e) => {
@ -54,7 +58,11 @@ export const AssetsPreview = ({ assetFilesArray, updateMetadataFileIndex, minter
return assetFilesArray.slice((page - 1) * ITEM_NUMBER, page * ITEM_NUMBER).map((assetSource, index) => ( return assetFilesArray.slice((page - 1) * ITEM_NUMBER, page * ITEM_NUMBER).map((assetSource, index) => (
<button <button
key={assetSource.name} key={assetSource.name}
className="relative p-0 w-[100px] h-[100px] bg-transparent hover:bg-transparent border-0 btn modal-button" className={clsx(
'relative p-0 bg-transparent hover:bg-transparent border-0 btn modal-button',
{ 'w-[100px] h-[100px]': minterType === 'vending' },
{ 'mt-14 ml-20 w-[288px] h-[288px]': minterType === 'base' },
)}
onClick={() => { onClick={() => {
updateMetadataFileIndex((page - 1) * ITEM_NUMBER + index) updateMetadataFileIndex((page - 1) * ITEM_NUMBER + index)
}} }}
@ -64,18 +72,29 @@ export const AssetsPreview = ({ assetFilesArray, updateMetadataFileIndex, minter
className="relative p-0 w-full h-full bg-transparent hover:bg-transparent border-0 btn modal-button" className="relative p-0 w-full h-full bg-transparent hover:bg-transparent border-0 btn modal-button"
htmlFor="my-modal-4" htmlFor="my-modal-4"
> >
<div <Conditional test={minterType === 'vending'}>
className={clsx( <div
'flex absolute right-20 bottom-20 justify-center items-center', className={clsx(
'text-sm text-white bg-stargaze rounded-full', 'flex absolute right-20 bottom-20 justify-center items-center',
getOverlaySize(), 'text-sm text-white bg-stargaze rounded-full',
)} getOverlaySize(),
> )}
{(page - 1) * 12 + (index + 1)} >
</div> {(page - 1) * 12 + (index + 1)}
</div>
</Conditional>
{getAssetType(assetSource.name) === 'audio' && ( {getAssetType(assetSource.name) === 'audio' && (
<div className="flex absolute flex-col items-center mt-4 ml-2"> <div className="flex absolute flex-col items-center mt-4 ml-2">
<img key={`audio-${index}`} alt="audio_icon" className="mb-2 ml-1 w-6 h-6 thumbnail" src="/audio.png" /> <img
key={`audio-${index}`}
alt="audio_icon"
className={clsx(
'mb-2 ml-1 thumbnail',
{ 'w-6 h-6': minterType === 'vending' },
{ 'w-24 h-24': minterType === 'base' },
)}
src="/audio.png"
/>
<span className="flex self-center ">{assetSource.name}</span> <span className="flex self-center ">{assetSource.name}</span>
</div> </div>
)} )}
@ -87,7 +106,11 @@ export const AssetsPreview = ({ assetFilesArray, updateMetadataFileIndex, minter
<img <img
key={`image-${index}`} key={`image-${index}`}
alt="asset" alt="asset"
className="px-1 my-1 max-h-24 thumbnail" className={clsx(
'px-1 my-1 thumbnail',
{ 'max-h-24': minterType === 'vending' },
{ 'max-h-72': minterType === 'base' },
)}
src={URL.createObjectURL(assetSource)} src={URL.createObjectURL(assetSource)}
/> />
</div> </div>

View File

@ -92,16 +92,18 @@ export const UploadDetails = ({ onChange, minterType, minterAcquisitionMethod }:
setAssetFilesArray([]) setAssetFilesArray([])
setMetadataFilesArray([]) setMetadataFilesArray([])
if (event.target.files === null) return if (event.target.files === null) return
//sort the files if (minterType === 'vending') {
const sortedFiles = Array.from(event.target.files).sort((a, b) => naturalCompare(a.name, b.name)) //sort the files
//check if the sorted file names are in numerical order const sortedFiles = Array.from(event.target.files).sort((a, b) => naturalCompare(a.name, b.name))
const sortedFileNames = sortedFiles.map((file) => file.name.split('.')[0]) //check if the sorted file names are in numerical order
for (let i = 0; i < sortedFileNames.length; i++) { const sortedFileNames = sortedFiles.map((file) => file.name.split('.')[0])
if (isNaN(Number(sortedFileNames[i])) || parseInt(sortedFileNames[i]) !== i + 1) { for (let i = 0; i < sortedFileNames.length; i++) {
toast.error('The file names should be in numerical order starting from 1.') if (isNaN(Number(sortedFileNames[i])) || parseInt(sortedFileNames[i]) !== i + 1) {
//clear the input toast.error('The file names should be in numerical order starting from 1.')
event.target.value = '' //clear the input
return event.target.value = ''
return
}
} }
} }
let loadedFileCount = 0 let loadedFileCount = 0
@ -133,16 +135,18 @@ export const UploadDetails = ({ onChange, minterType, minterAcquisitionMethod }:
event.target.value = '' event.target.value = ''
return toast.error('The number of metadata files should be equal to the number of asset files.') return toast.error('The number of metadata files should be equal to the number of asset files.')
} }
//sort the files if (minterType === 'vending') {
const sortedFiles = Array.from(event.target.files).sort((a, b) => naturalCompare(a.name, b.name)) //sort the files
//check if the sorted file names are in numerical order const sortedFiles = Array.from(event.target.files).sort((a, b) => naturalCompare(a.name, b.name))
const sortedFileNames = sortedFiles.map((file) => file.name.split('.')[0]) //check if the sorted file names are in numerical order
for (let i = 0; i < sortedFileNames.length; i++) { const sortedFileNames = sortedFiles.map((file) => file.name.split('.')[0])
if (isNaN(Number(sortedFileNames[i])) || parseInt(sortedFileNames[i]) !== i + 1) { for (let i = 0; i < sortedFileNames.length; i++) {
toast.error('The file names should be in numerical order starting from 1.') if (isNaN(Number(sortedFileNames[i])) || parseInt(sortedFileNames[i]) !== i + 1) {
//clear the input toast.error('The file names should be in numerical order starting from 1.')
event.target.value = '' //clear the input
return event.target.value = ''
return
}
} }
} }
let loadedFileCount = 0 let loadedFileCount = 0

View File

@ -50,7 +50,7 @@ export const CollectionQueries = ({
const address = addressState.value const address = addressState.value
const showTokenIdField = type === 'token_info' const showTokenIdField = type === 'token_info'
const showAddressField = type === 'tokens_minted_to_user' const showAddressField = type === 'tokens_minted_to_user' || type === 'tokens'
const { data: response } = useQuery( const { data: response } = useQuery(
[sg721Messages, baseMinterMessages, vendingMinterMessages, type, tokenId, address] as const, [sg721Messages, baseMinterMessages, vendingMinterMessages, type, tokenId, address] as const,

View File

@ -9,6 +9,7 @@ export const QUERY_TYPES = [
'mint_price', 'mint_price',
'num_tokens', 'num_tokens',
'tokens_minted_to_user', 'tokens_minted_to_user',
'tokens',
// 'token_owners', // 'token_owners',
'token_info', 'token_info',
'config', 'config',
@ -70,7 +71,7 @@ export const BASE_QUERY_LIST: QueryListItem[] = [
description: `Get information about the collection.`, description: `Get information about the collection.`,
}, },
{ {
id: 'tokens_minted_to_user', id: 'tokens',
name: 'Tokens Minted to User', name: 'Tokens Minted to User',
description: `Get the number of tokens minted in the collection to a user.`, description: `Get the number of tokens minted in the collection to a user.`,
}, },
@ -108,6 +109,7 @@ export type DispatchQueryArgs = {
| { type: Select<'mint_price'> } | { type: Select<'mint_price'> }
| { type: Select<'num_tokens'> } | { type: Select<'num_tokens'> }
| { type: Select<'tokens_minted_to_user'>; address: string } | { type: Select<'tokens_minted_to_user'>; address: string }
| { type: Select<'tokens'>; address: string }
// | { type: Select<'token_owners'> } // | { type: Select<'token_owners'> }
| { type: Select<'token_info'>; tokenId: string } | { type: Select<'token_info'>; tokenId: string }
| { type: Select<'config'> } | { type: Select<'config'> }
@ -132,6 +134,9 @@ export const dispatchQuery = async (args: DispatchQueryArgs) => {
case 'tokens_minted_to_user': { case 'tokens_minted_to_user': {
return vendingMinterMessages.getMintCount(args.address) return vendingMinterMessages.getMintCount(args.address)
} }
case 'tokens': {
return sg721Messages.tokens(args.address)
}
// case 'token_owners': { // case 'token_owners': {
// return vendingMinterMessages.updateStartTime(txSigner, args.startTime) // return vendingMinterMessages.updateStartTime(txSigner, args.startTime)
// } // }

View File

@ -1,6 +1,6 @@
{ {
"name": "stargaze-studio", "name": "stargaze-studio",
"version": "0.3.0", "version": "0.3.1",
"workspaces": [ "workspaces": [
"packages/*" "packages/*"
], ],

View File

@ -241,7 +241,10 @@ const CollectionCreationPage: NextPage = () => {
setBaseTokenUri(baseUri) setBaseTokenUri(baseUri)
setCoverImageUrl(coverImageUri) setCoverImageUrl(coverImageUri)
await instantiateBaseMinter(baseUri, coverImageUri) await instantiateBaseMinter(
`ipfs://${baseUri}/${uploadDetails.metadataFiles[0].name.split('.')[0]}`,
coverImageUri,
)
} else { } else {
setBaseTokenUri(uploadDetails?.baseTokenURI as string) setBaseTokenUri(uploadDetails?.baseTokenURI as string)
setCoverImageUrl(uploadDetails?.imageUrl as string) setCoverImageUrl(uploadDetails?.imageUrl as string)
@ -276,7 +279,8 @@ const CollectionCreationPage: NextPage = () => {
setBaseTokenUri(baseUri) setBaseTokenUri(baseUri)
const result = await baseMinterContract const result = await baseMinterContract
.use(minterDetails?.existingMinter as string) .use(minterDetails?.existingMinter as string)
?.mint(wallet.address, `ipfs://${baseUri}`) // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
?.mint(wallet.address, `ipfs://${baseUri}/${uploadDetails?.metadataFiles[0].name.split('.')[0]}`)
console.log(result) console.log(result)
return result return result
}) })
@ -397,6 +401,7 @@ const CollectionCreationPage: NextPage = () => {
const instantiateBaseMinter = async (baseUri: string, coverImageUri: string) => { const instantiateBaseMinter = async (baseUri: string, coverImageUri: string) => {
if (!wallet.initialized) throw new Error('Wallet not connected') if (!wallet.initialized) throw new Error('Wallet not connected')
if (!baseFactoryContract) throw new Error('Contract not found') if (!baseFactoryContract) throw new Error('Contract not found')
if (!baseMinterContract) throw new Error('Contract not found')
let royaltyInfo = null let royaltyInfo = null
if (royaltyDetails?.royaltyType === 'new') { if (royaltyDetails?.royaltyType === 'new') {
@ -437,10 +442,37 @@ const CollectionCreationPage: NextPage = () => {
msg, msg,
funds: [coin('1000000000', 'ustars')], funds: [coin('1000000000', 'ustars')],
} }
const data = await baseFactoryDispatchExecute(payload) await baseFactoryDispatchExecute(payload)
setTransactionHash(data.transactionHash) .then(async (data) => {
setVendingMinterContractAddress(data.baseMinterAddress) setTransactionHash(data.transactionHash)
setSg721ContractAddress(data.sg721Address) setVendingMinterContractAddress(data.baseMinterAddress)
setSg721ContractAddress(data.sg721Address)
await toast
.promise(
baseMinterContract
.use(data.baseMinterAddress)
?.mint(wallet.address, baseUri) as Promise<string>,
{
loading: 'Minting token...',
success: (result) => `Token minted successfully! Tx Hash: ${result}`,
error: (error) => `Failed to mint token: ${error.message}`,
},
{ style: { maxWidth: 'none' } },
)
.catch((error) => {
toast.error(error.message, { style: { maxWidth: 'none' } })
setUploading(false)
setCreatingCollection(false)
})
setUploading(false)
setCreatingCollection(false)
})
.catch((error) => {
toast.error(error.message, { style: { maxWidth: 'none' } })
setUploading(false)
setCreatingCollection(false)
})
} }
const uploadFiles = async (): Promise<string> => { const uploadFiles = async (): Promise<string> => {
@ -521,7 +553,8 @@ const CollectionCreationPage: NextPage = () => {
if (uploadDetails.uploadMethod === 'new' && uploadDetails.metadataFiles.length === 0) { if (uploadDetails.uploadMethod === 'new' && uploadDetails.metadataFiles.length === 0) {
throw new Error('Please select the metadata files') throw new Error('Please select the metadata files')
} }
if (uploadDetails.uploadMethod === 'new') compareFileArrays(uploadDetails.assetFiles, uploadDetails.metadataFiles) if (uploadDetails.uploadMethod === 'new' && minterType === 'vending')
compareFileArrays(uploadDetails.assetFiles, uploadDetails.metadataFiles)
if (uploadDetails.uploadMethod === 'new') { if (uploadDetails.uploadMethod === 'new') {
if (uploadDetails.uploadService === 'nft-storage') { if (uploadDetails.uploadService === 'nft-storage') {
if (uploadDetails.nftStorageApiKey === '') { if (uploadDetails.nftStorageApiKey === '') {
@ -688,7 +721,11 @@ const CollectionCreationPage: NextPage = () => {
<Anchor <Anchor
className="text-stargaze hover:underline" className="text-stargaze hover:underline"
external external
href={`/contracts/vendingMinter/query/?contractAddress=${vendingMinterContractAddress as string}`} href={
minterType === 'vending'
? `/contracts/vendingMinter/query/?contractAddress=${vendingMinterContractAddress as string}`
: `/contracts/baseMinter/query/?contractAddress=${vendingMinterContractAddress as string}`
}
> >
{vendingMinterContractAddress} {vendingMinterContractAddress}
</Anchor> </Anchor>

View File

@ -20,8 +20,19 @@ const HomePage: NextPage = () => {
<br /> <br />
<div className="grid gap-8 md:grid-cols-2"> <div className="grid gap-8 md:grid-cols-2">
<HomeCard className="p-4 -m-4 hover:bg-gray-500/10 rounded" link="/contracts/minter" title="Minter contract"> <HomeCard
Execute messages and run queries on Stargaze&apos;s minter contract. className="p-4 -m-4 hover:bg-gray-500/10 rounded"
link="/contracts/baseMinter"
title="Base Minter contract"
>
Execute messages and run queries on Stargaze&apos;s Base Minter contract.
</HomeCard>
<HomeCard
className="p-4 -m-4 hover:bg-gray-500/10 rounded"
link="/contracts/vendingMinter"
title="Vending Minter contract"
>
Execute messages and run queries on Stargaze&apos;s Vending Minter contract.
</HomeCard> </HomeCard>
<HomeCard className="p-4 -m-4 hover:bg-gray-500/10 rounded" link="/contracts/sg721" title="Sg721 Contract"> <HomeCard className="p-4 -m-4 hover:bg-gray-500/10 rounded" link="/contracts/sg721" title="Sg721 Contract">
Execute messages and run queries on Stargaze&apos;s sg721 contract. Execute messages and run queries on Stargaze&apos;s sg721 contract.