Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: drops max count #10713

Merged
merged 27 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b6529de
fix: drops max count
preschian Aug 1, 2024
c25e266
refactor(tests): simplify image loading wait logic in explore.spec.ts
preschian Aug 1, 2024
5f4bf39
feat(tests): ensure images load during scroll in e2e explore
preschian Aug 1, 2024
5e481d8
refactor(tests): update collection spec to new data and optimize wait…
preschian Aug 1, 2024
c0cbc89
chore(workflow): increase shard count in Playwright configuration
preschian Aug 1, 2024
ac63e8b
chore(tests): add network idle state wait in gallery item interaction…
preschian Aug 1, 2024
9836743
feat(playwright): increase timeout and ensure server start command
preschian Aug 1, 2024
44c96a0
feat(playwright): increase timeout settings and add expect timeout
preschian Aug 1, 2024
318da3f
revert: flaky e2e test
preschian Aug 2, 2024
22f6985
Merge branch 'main' of github.com:kodadot/nft-gallery into fix--drops…
preschian Aug 2, 2024
515f22d
Merge branch 'main' of github.com:kodadot/nft-gallery into fix--drops…
preschian Aug 5, 2024
6cdf1a8
feat(drop): integrate EVM and Substrate collection data handling
preschian Aug 5, 2024
841d325
refactor(mint-button): add null check for maxCount comparison
preschian Aug 5, 2024
bb09b10
Merge branch 'main' of github.com:kodadot/nft-gallery into fix--drops…
preschian Aug 5, 2024
fa8b050
Update composables/drop/useGenerativeDropMint.ts
preschian Aug 5, 2024
90b9695
refactor(onchain): change API endpoint and adjust result parsing
preschian Aug 5, 2024
ff2ec26
feat(ogi): add service to fetch EVM collection data
preschian Aug 7, 2024
916e98c
refactor(drop): replace collection entity references with drop
preschian Aug 8, 2024
ae281ab
refactor(drop): replace useDrop with storeToRefs to streamline state
preschian Aug 8, 2024
ca3ac44
Merge branch 'main' of github.com:kodadot/nft-gallery into fix--drops…
preschian Aug 8, 2024
631991e
refactor(generative-drop): correct typos in function names and fix me…
preschian Aug 8, 2024
643fb86
Update components/drops/useDrops.ts
preschian Aug 8, 2024
942547e
fix(drops): prevent execution if collection is undefined in useDrop
preschian Aug 8, 2024
7dc049e
Merge branch 'main' of github.com:kodadot/nft-gallery into fix--drops…
preschian Aug 8, 2024
7c46b44
Merge branch 'main' of github.com:kodadot/nft-gallery into fix--drops…
preschian Aug 15, 2024
25292da
refactor(onchain): remove unused wagmi config definitions
preschian Aug 15, 2024
74c9bd5
chore(config): remove use-wagmi from dependencies
preschian Aug 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ jobs:
strategy:
fail-fast: false
matrix:
shardIndex: [1, 2, 3, 4, 5, 6]
shardTotal: [6]
shardIndex: [1, 2, 3, 4, 5, 6, 7, 8]
shardTotal: [8]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
Expand Down
22 changes: 14 additions & 8 deletions components/collection/drop/GenerativePreview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,22 @@
<div class="mr-4 text-neutral-7">
{{ mintedPercent }}% ~
</div>
<div class="font-bold">
{{ dropStore.mintsCount }}/{{ maxCount }}
<div
v-if="nftCount >= 0 && maxCount"
class="font-bold"
>
{{ nftCount }}/{{ maxCount }}
{{ $t('statsOverview.minted') }}
</div>
<div v-else>
<NeoSkeleton width="100" />
</div>
</div>
</div>

<CollectionUnlockableSlider
class="text-neutral-5 dark:text-neutral-9"
:value="dropStore.mintsCount / maxCount"
:value="nftCount / maxCount"
/>

<div class="flex mt-6 gap-4 max-md:flex-col">
Expand All @@ -88,18 +94,18 @@
</template>

<script setup lang="ts">
import { NeoButton, NeoIcon } from '@kodadot1/brick'
import { NeoButton, NeoIcon, NeoSkeleton } from '@kodadot1/brick'
import { sanitizeIpfsUrl } from '@/utils/ipfs'
import useGenerativeIframeData from '@/composables/drop/useGenerativeIframeData'
import { useDrop } from '@/components/drops/useDrops'
import useGenerativeDropMint from '@/composables/drop/useGenerativeDropMint'
import { useCollectionEntity } from '@/composables/drop/useGenerativeDropMint'

const { accountId } = useAuth()
const { chainSymbol, decimals } = useChain()
const { drop } = useDrop()
const dropStore = useDropStore()
const { userMintsCount, mintsCount } = storeToRefs(dropStore)
const { maxCount } = useGenerativeDropMint()
const { userMintsCount } = storeToRefs(dropStore)
const { maxCount, nftCount } = useCollectionEntity()
const { imageDataPayload, imageDataLoaded } = useGenerativeIframeData()
const { formatted: formattedPrice } = useAmount(
computed(() => drop.value.price),
Expand All @@ -124,7 +130,7 @@ const mintedPercent = computed(() => {
if (!maxCount.value) {
return 0
}
return Math.round((mintsCount.value / maxCount.value) * 100)
return Math.round((nftCount.value / maxCount.value) * 100)
})

const displayUrl = computed(() => generativeImageUrl.value || drop.value?.image)
Expand Down
7 changes: 4 additions & 3 deletions components/collection/drop/MintButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

<script setup lang="ts">
import { NeoButton } from '@kodadot1/brick'
import useGenerativeDropMint from '@/composables/drop/useGenerativeDropMint'
import useGenerativeDropMint, { useCollectionEntity } from '@/composables/drop/useGenerativeDropMint'
import { useDropStore } from '@/stores/drop'
import { useDrop, useDropMinimumFunds } from '@/components/drops/useDrops'
import {
Expand All @@ -41,6 +41,7 @@ const { hasCurrentChainBalance } = useMultipleBalance()
const { drop } = useDrop()
const now = useNow()
const { mintCountAvailable, maxCount } = useGenerativeDropMint()
const { nftCount } = useCollectionEntity()
const { amountToMint, previewItem, userMintsCount } = storeToRefs(dropStore)

const { hasMinimumFunds } = useDropMinimumFunds()
Expand All @@ -51,7 +52,7 @@ const priceUsd = ref()
const isHolderAndEligible = computed(
() =>
holderOfCollection.value.isHolder
&& maxCount.value > dropStore.mintsCount
&& maxCount.value > nftCount.value
&& hasMinimumFunds.value
&& holderOfCollection.value.hasAvailable,
)
Expand All @@ -74,7 +75,7 @@ const mintForLabel = computed(() =>
)

const label = computed(() => {
if (!mintCountAvailable.value) {
if (maxCount.value === nftCount.value) {
return $i18n.t('mint.unlockable.seeListings')
}
if (!isLogIn.value) {
Expand Down
13 changes: 1 addition & 12 deletions components/collection/drop/MintStepper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,5 @@ const min = computed(() =>
isHolder.value ? Math.min(1, availableNftsAmount.value) : 1,
)

const max = computed(() => {
// tmp remove when uploading to IPFS step can be skipped @see https://github.com/kodadot/nft-gallery/issues/10001#issuecomment-2041533819
const dropMax = DROP_MASSMINT_LIMIT[drop.value.alias] ?? undefined

if (isHolder.value) {
return dropMax
? Math.min(dropMax, availableNftsAmount.value)
: availableNftsAmount.value
}

return dropMax
})
const max = computed(() => isHolder.value ? availableNftsAmount.value : undefined)
</script>
79 changes: 30 additions & 49 deletions composables/drop/useGenerativeDropMint.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { useQuery } from '@tanstack/vue-query'
import { type MintedNFT } from '@/components/collection/drop/types'
import type { DoResult } from '@/services/fxart'
import { setMetadataUrl } from '@/services/fxart'
import { useDrop } from '@/components/drops/useDrops'
import unlockableCollectionById from '@/queries/subsquid/general/unlockableCollectionById.graphql'
import { FALLBACK_DROP_COLLECTION_MAX } from '@/utils/drop'
import type {
MassMintNFT,
Expand All @@ -28,47 +26,38 @@ export type DropCollectionById = {
}
}

function useCollectionData(collectionId, client) {
const { accountId } = useAuth()
const { vueApp } = useNuxtApp()
return vueApp.runWithContext(() =>
useQuery<DropCollectionById | null>({
queryKey: ['collection-drop-data', client, collectionId, accountId],
queryFn: () =>
collectionId.value
? useAsyncQuery<DropCollectionById | null>({
clientId: client.value,
query: unlockableCollectionById,
variables: {
id: collectionId.value,
search: { issuer_eq: accountId.value },
},
}).then(res => res.data.value)
: null,
}),
)
}

export function useCollectionEntity() {
const { drop } = useDrop()
const { client } = usePrefix()
const { data: collectionData } = useCollectionData(
computed(() => drop.value?.collection),
client,
)
const maxCount = computed(() => collectionData.value?.collectionEntity?.max)
const description = computed(
() => collectionData.value?.collectionEntity?.meta?.description ?? '',
)
const collectionName = computed(
() => collectionData.value?.collectionEntity?.name ?? '',
)
const nftCount = computed(
() => collectionData.value?.collectionEntity?.nftCount ?? 0,
)
const maxSupply = ref()
const nftCount = ref()
const description = ref()
const collectionName = ref()

watchEffect(async () => {
if (drop.value.collection) {
const api = await useApi().apiInstance.value
const [queryCollectionConfig, queryCollection, queryCollectionMetadata] = await Promise.all([
api.query.nfts.collectionConfigOf(drop.value.collection),
api.query.nfts.collection(drop.value.collection),
api.query.nfts.collectionMetadataOf(drop.value.collection),
])
const collectionConfig = queryCollectionConfig.toJSON() as unknown as { maxSupply?: number }
Jarsen136 marked this conversation as resolved.
Show resolved Hide resolved
const collection = queryCollection.toJSON() as unknown as { items?: number }

maxSupply.value = collectionConfig.maxSupply ?? 0
nftCount.value = collection.items ?? 0

const collectionMetadata = queryCollectionMetadata.toHuman() as unknown as { data?: string }
if (collectionMetadata.data) {
const metadata = await $fetch<{ description?: string, name?: string }>(sanitizeIpfsUrl(collectionMetadata.data))
description.value = metadata.description
collectionName.value = metadata.name
}
}
})

return {
maxCount,
maxCount: maxSupply,
description,
collectionName,
nftCount,
Expand Down Expand Up @@ -172,24 +161,16 @@ export const useUpdateMetadata = async () => {
export default () => {
const dropStore = useDropStore()
const { mintedNFTs } = storeToRefs(dropStore)
const { drop } = useDrop()
const { maxCount: collectionMaxCount } = useCollectionEntity()
const { maxCount, nftCount } = useCollectionEntity()
const { listNftByNftWithMetadata } = useListingCartModal()

const claimedNft = computed({
get: () => dropStore.claimedNFT,
set: value => dropStore.setClaimedNFT(value),
})

const maxCount = computed(
() =>
collectionMaxCount.value
?? drop.value?.max
?? FALLBACK_DROP_COLLECTION_MAX,
)

const mintCountAvailable = computed(
() => dropStore.mintsCount < maxCount.value,
() => nftCount.value < maxCount.value,
)

const canListMintedNft = computed(() => Boolean(mintedNFTs.value.length))
Expand Down
8 changes: 8 additions & 0 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ export default defineNuxtConfig({
'unzipit',
'vue-chartjs',
'wavesurfer.js',
'@kodadot1/minimark/utils',
'lodash',
'jdenticon',
'gql.tada',
'viem/chains',
'@web3modal/wagmi/vue',
'@wagmi/core',
'use-wagmi',
],
}
: undefined,
Expand Down
7 changes: 5 additions & 2 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ export default defineConfig({
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
timeout: 1 * 60 * 1000,
timeout: 4 * 60 * 1000,
expect: {
timeout: 4 * 60 * 1000,
},
use: {
// headless: true,
/* Base URL to use in actions like `await page.goto('/')`. */
Expand Down Expand Up @@ -73,7 +76,7 @@ export default defineConfig({

/* Run your local dev server before starting the tests */
webServer: {
command: process.env.CI ? 'pnpm start:node' : 'pnpm run dev',
command: 'pnpm start:node', // on local make sure run pnpm generate first
url: 'http://localhost:9090',
reuseExistingServer: !process.env.CI,
timeout: 2 * 60 * 1000,
Expand Down
14 changes: 6 additions & 8 deletions tests/e2e/collection.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { expect, test } from './fixtures'

const COLLECTION_ADDRESS_PATH = '/ahp/collection/38/'
const COLLECTION_NAME = 'Pare1d0scope'
const COLLECTION_ADDRESS_PATH = '/ahp/collection/158/'
const COLLECTION_NAME = 'Under the Microscope'
const COLLECTION_OWNER = '15CoYMEnJhhWHvdEPXDuTBnZKXwrJzMQdcMwcHGsVx5kXYvW'

test('Collection interactions', async ({ page, Commands }) => {
await page.goto(COLLECTION_ADDRESS_PATH)
await Commands.scrollDownAndStop()
await page.waitForLoadState('networkidle')
await test.step('Check collection name and description', async () => {
await expect(page.getByTestId('collection-banner-name')).toContainText(
COLLECTION_NAME,
Expand All @@ -15,7 +16,7 @@ test('Collection interactions', async ({ page, Commands }) => {
await page.getByTestId('description-show-less-more-button').click()
// collection description
await expect(page.getByTestId('collection-description')).toContainText(
'Geometry',
'Artist: Gorilla Sun',
)
})

Expand Down Expand Up @@ -72,10 +73,11 @@ test('Collection interactions', async ({ page, Commands }) => {
.fill('34')
await page.keyboard.press('Enter')
await Commands.scrollDownSlow()
await page.waitForLoadState('networkidle')
await expect(
page.locator('[class="infinite-scroll-item"]').first(),
).toBeVisible()
await expect(page.getByTestId('nft-name')).toHaveText('Pare1d0scope #34')
await expect(page.getByTestId('nft-name')).toHaveText('Under the Microscope #34')
})

// art view
Expand Down Expand Up @@ -115,17 +117,13 @@ test('Collection interactions', async ({ page, Commands }) => {
// event filters
await test.step('Event Filters(sale,list,mint,transfer)', async () => {
const eventTable = page.getByTestId('nfts-event-table')
const saleFilter = page.getByTestId('event-checkbox-filter-sale').nth(1)
const listingFilter = page
.getByTestId('event-checkbox-filter-listing')
.nth(1)
const mintFilter = page.getByTestId('event-checkbox-filter-mint').nth(1)
const transferFilter = page
.getByTestId('event-checkbox-filter-transfer')
.nth(1)
await saleFilter.check()
await expect(eventTable).toContainText('Sale')
await saleFilter.uncheck()
await listingFilter.check()
await expect(eventTable).toContainText('List')
await listingFilter.uncheck()
Expand Down
2 changes: 2 additions & 0 deletions tests/e2e/drops.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const collections = TEST_DROPS.map(drop => drop.collection)

test('make sure drops page with type holder not broken', async ({ page }) => {
await page.goto(addresses[2])
await page.waitForLoadState('networkidle')
await expect(page.locator('div.content-markdown')).toHaveText(
`
Artist: Nicolas Lebrun
Expand All @@ -41,6 +42,7 @@ test('make sure drops page with type holder not broken', async ({ page }) => {
// CONVERGENTE
test('Drop page verification', async ({ page, Commands }) => {
await page.goto(addresses[0])
await page.waitForLoadState('networkidle')

await test.step('Created By', async () => {
await expect(page.getByTestId('drop-created-by-container')).toBeVisible({
Expand Down
26 changes: 20 additions & 6 deletions tests/e2e/explore.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { expect, test } from './fixtures'
const EXPLORE_COLLECTIONS_PATH = '/ahk/explore/collectibles'
const EXPLORE_ITEMS_PATH = '/ahk/explore/items?page=1'

test('Explore collections', async ({ page, Commands }) => {
test('Explore collections', async ({ page }) => {
await page.goto(EXPLORE_COLLECTIONS_PATH)

// Tabs
Expand All @@ -22,12 +22,26 @@ test('Explore collections', async ({ page, Commands }) => {
})

// Lazy loading mitigation
const imageRequests = new Set()
await page.route('https://image-beta.w.kodadot.xyz/**', async (route) => {
const request = route.request()
const url = request.url()

// Check if it's an image request
if (request.resourceType() === 'image') {
imageRequests.add(url)
}

// Continue the request and get the response
const response = await route.fetch()

await route.fulfill({ response })
})

await test.step('Scroll down and wait for images to load', async () => {
await Commands.scrollDownAndStop()
await page.waitForFunction(() => {
const images = Array.from(document.querySelectorAll('img'))
return images.every(img => img.complete)
})
// await Commands.scrollDownAndStop()
await page.waitForLoadState('networkidle')
expect(imageRequests.size).toBeGreaterThan(0)
})

// Results
Expand Down
1 change: 1 addition & 0 deletions tests/e2e/galleryitem.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const ITEM_ROYALTY_RECIPIENT = '1L2xst...ucgnNZ'

test('Gallery item Interactions', async ({ page }) => {
await page.goto(ITEM_ADDRESS_PATH)
await page.waitForLoadState('networkidle')

// Activity tab
await test.step('Verifies if activity tab has content', async () => {
Expand Down
Loading
Loading