Skip to content

Commit

Permalink
Merge pull request kodadot#10670 from hassnian/issue-10648
Browse files Browse the repository at this point in the history
feat: Support minting (free) drops on EVM
  • Loading branch information
preschian authored Aug 4, 2024
2 parents da176ea + 1cac180 commit b16fcbf
Show file tree
Hide file tree
Showing 69 changed files with 2,112 additions and 346 deletions.
17 changes: 11 additions & 6 deletions components/Navbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
<!-- NAV END -->
<div class="navbar-end">
<nuxt-link
to="/ahp/drops"
:to="dropsPath"
rel="nofollow"
>
<div
Expand Down Expand Up @@ -250,7 +250,7 @@
import { NeoButton, NeoIcon } from '@kodadot1/brick'
import { nextTick } from 'vue'
import ShoppingCartButton from './navbar/ShoppingCartButton.vue'
import { ConnectWalletModalConfig } from '@/components/common/ConnectWallet/useConnectWallet'
import { openConnectWalletModal } from '@/components/common/ConnectWallet/useConnectWallet'
import ChainSelectDropdown from '@/components/navbar/ChainSelectDropdown.vue'
import CreateDropdown from '@/components/navbar/CreateDropdown.vue'
import MobileExpandableSection from '@/components/navbar/MobileExpandableSection.vue'
Expand Down Expand Up @@ -287,6 +287,14 @@ const logoSrc = computed(() => {
return `/${variant}${color}.svg`
})
const dropsPath = computed(() => {
const prefix = pickByVm({
SUB: 'ahp',
EVM: 'base',
})
return `/${prefix}/drops`
})
const handleMobileChainSelect = () => {
showMobileNavbar()
}
Expand All @@ -295,10 +303,7 @@ const closeAllModals = () => neoModal.closeAll()
const openWalletConnectModal = (): void => {
closeAllModals()
neoModal.open({
...ConnectWalletModalConfig,
...(isMobile ? { animation: 'none' } : {}),
})
openConnectWalletModal()
}
const showMobileNavbar = () => {
Expand Down
2 changes: 2 additions & 0 deletions components/balance/MultipleBalances.vue
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
v-if="isBalanceLoading"
data-testid="skeleton-multiple-balances"
animated
no-margin
/>
</div>

Expand Down Expand Up @@ -107,6 +108,7 @@ const displayChainOrder: ChainType[] = [
'kusamaHub',
]
const identityStore = useIdentityStore()

const rampActive = ref(false)

const { multiBalances } = useMultipleBalance(true)
Expand Down
30 changes: 26 additions & 4 deletions components/carousel/CarouselTypeDrops.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
:items="drops"
:config="config"
>
<DropsDropCard :drop="item" />
<DropsDropCard
:drop="item"
emit-on-click
@click="onDropClick"
/>
</CarouselModuleCarouselAgnostic>
<CarouselModuleCarouselAgnostic
v-else
Expand All @@ -22,23 +26,30 @@
</template>

<script lang="ts" setup>
import type { Drop } from '@/components/drops/useDrops'
import { useDrops } from '@/components/drops/useDrops'
let queries = {
limit: 12,
active: [true],
chain: ['ahp'],
chain: ['ahp', 'base'],
}
if (!isProduction) {
const { urlPrefix } = usePrefix()
if (!isProduction && urlPrefix.value === 'ahk') {
queries = {
...queries,
chain: ['ahp', 'ahk'],
chain: ['ahk'],
}
}
const container = ref()
const { accountId } = useAuth()
const { vmOf, vm } = useChain()
const router = useRouter()
const { doAfterReconnect } = useDoAfterReconnect()
const { cols, isReady: isDynamicGridReady } = useDynamicGrid({
container,
itemMintWidth: computed(() => DROP_CARD_MIN_WIDTH),
Expand All @@ -54,4 +65,15 @@ const skeletonCount = computed(() =>
const { drops, loaded: isReady } = useDrops(queries)
const dropsAlias = computed(() => drops.value.map(drop => drop.alias))
const onDropClick = ({ path, drop }: { path: string, drop: Drop }) => {
if (vm.value === vmOf(drop.chain) || !accountId.value) {
router.push(path)
return
}
doAfterReconnect({
onSuccess: () => router.push(path),
})
}
</script>
7 changes: 4 additions & 3 deletions components/collection/drop/HolderOfGenerative.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@ const { $i18n, $consola } = useNuxtApp()
const { urlPrefix } = usePrefix()
const { toast } = useToast()
const { isLogIn } = useAuth()
const instance = getCurrentInstance()
const { doAfterLogin } = useDoAfterlogin(instance)
const { doAfterLogin } = useDoAfterlogin()
const {
transaction,
isLoading: isTransactionLoading,
status,
isError: isTransactionError,
txHash,
blockNumber,
} = useTransaction({
disableSuccessNotification: true,
})
Expand Down Expand Up @@ -130,6 +130,7 @@ const mintNft = async () => {
collectionId: drop.value?.collection,
availableSerialNumbers: availableNfts.serialNumbers,
price: drop.value?.price || null,
prefix: urlPrefix.value,
})
}
catch (e) {
Expand Down Expand Up @@ -178,7 +179,7 @@ const mint = async () => {
const submitMints = async () => {
try {
await useUpdateMetadata()
await useUpdateMetadata({ blockNumber })
loading.value = false
isSuccessModalActive.value = true
Expand Down
3 changes: 2 additions & 1 deletion components/collection/drop/MintStepper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import useHolderOfCollection from '@/composables/drop/useHolderOfCollection'
const { availableNfts } = useHolderOfCollection()
const { amountToMint, drop } = storeToRefs(useDropStore())
const { isEvm } = useIsChain(usePrefix().urlPrefix)
const show = computed(() => drop.value.type !== 'free')
const show = computed(() => drop.value.type !== 'free' && !isEvm.value)
const isHolder = computed(() => drop.value.type === 'holder')
const availableNftsAmount = computed(() => availableNfts.serialNumbers.length)
Expand Down
8 changes: 5 additions & 3 deletions components/collection/drop/PaidGenerative.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import { NFTs } from '@/composables/transaction/types'
const { drop } = useDrop()
const { subscribeDropStatus } = useDropStatus(drop)
const instance = getCurrentInstance()
const { doAfterLogin } = useDoAfterlogin(instance)
const { urlPrefix } = usePrefix()
const { doAfterLogin } = useDoAfterlogin()
const { $i18n, $consola } = useNuxtApp()
const { toast } = useToast()
const { isLogIn } = useAuth()
Expand All @@ -46,6 +46,7 @@ const {
status,
isError,
txHash,
blockNumber,
} = useTransaction({
disableSuccessNotification: true,
})
Expand Down Expand Up @@ -74,6 +75,7 @@ const mintNft = async () => {
interaction: NFTs.MINT_DROP,
collectionId: drop.value?.collection,
price: drop.value?.price || null,
prefix: urlPrefix.value,
})
}
catch (e) {
Expand Down Expand Up @@ -117,7 +119,7 @@ const closeMintModal = () => {
const submitMints = async () => {
try {
await useUpdateMetadata()
await useUpdateMetadata({ blockNumber })
loading.value = false
}
Expand Down
29 changes: 19 additions & 10 deletions components/collection/drop/modal/shared/SuccessfulDrop.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type { MintedNFT, MintingSession } from '../../types'
import type { ItemMedia } from '@/components/common/successfulModal/SuccessfulItemsMedia.vue'
import type { ShareProp } from '@/components/common/successfulModal/SuccessfulModalBody.vue'
import type { TransactionStatus } from '@/composables/useTransactionStatus'
import { listVisible } from '@/utils/config/permission.config'
const emit = defineEmits(['list'])
const props = defineProps<{
Expand Down Expand Up @@ -84,18 +85,26 @@ const share = computed<ShareProp>(() => ({
},
}))
const actionButtons = computed(() => ({
secondary: {
label: $i18n.t('viewNft', props.mintingSession.items.length),
onClick: handleViewNft,
},
primary: {
label: $i18n.t('listNft', props.mintingSession.items.length),
onClick: listNft,
disabled: cantList.value,
},
const viewButton = computed(() => ({
label: $i18n.t('viewNft', props.mintingSession.items.length),
onClick: handleViewNft,
}))
const listButton = computed(() => ({
label: $i18n.t('listNft', props.mintingSession.items.length),
onClick: listNft,
disabled: cantList.value,
}))
const actionButtons = computed(() =>
listVisible(urlPrefix.value)
? {
secondary: viewButton.value,
primary: listButton.value,
}
: { primary: viewButton.value },
)
const handleViewNft = () => {
window.open(
singleMint.value ? nftPath.value : userProfilePath.value,
Expand Down
9 changes: 7 additions & 2 deletions components/common/ConnectWallet/ConnectWalletModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@
</div>

<template v-else>
<WalletTabs v-model="selectedTab" />
<WalletTabs
v-if="!preselected"
v-model="selectedTab"
/>

<ConnectSubstrate
v-if="selectedTab === 'SUB'"
Expand All @@ -36,6 +39,7 @@
<ConnectEvm
v-else
class="!px-7"
:preselected="preselected"
@select="setAccount"
/>
</template>
Expand All @@ -52,14 +56,15 @@ import WalletAsset from '@/components/common/ConnectWallet/WalletAsset.vue'
import { ModalCloseType } from '@/components/navbar/types'
const emit = defineEmits(['close', 'connect'])
const props = defineProps<{ preselected?: ChainVM }>()
const { urlPrefix, setUrlPrefix } = usePrefix()
const { redirectAfterChainChange } = useChainRedirect()
const walletStore = useWalletStore()
const { selected: account, disconnecting } = storeToRefs(walletStore)
const identityStore = useIdentityStore()
const selectedTab = ref<ChainVM>('SUB')
const selectedTab = ref<ChainVM>(props.preselected ?? 'SUB')
const showAccount = computed(() => Boolean(account.value))
Expand Down
105 changes: 105 additions & 0 deletions components/common/ConnectWallet/ReconnectWalletModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<template>
<ModalBody
class="border border-border-color"
:title="$t('reconnect.required')"
:scrollable="false"
>
<div>
<div class="flex gap-5 items-center justify-center !py-5 ">
<div>
<BasicImage
:src="vmDetails.current.icon"
:alt="vmDetails.current.name"
class="image is-48x48"
/>
</div>

<img
:src="'/right-arrow.svg'"
alt="right arrow"
>

<div>
<BasicImage
:src="vmDetails.target.icon"
:alt="vmDetails.target.name"
class="image is-48x48"
/>
</div>
</div>

<div class="flex flex-col gap-2 items-center capitalize !mt-3">
<p class="font-bold text-xl">
{{ $t("reconnect.title") }}
</p>
<p
v-dompurify-html="$t('reconnect.toProceed', [vmDetails.target.name, vmDetails.target.shortName ? `(${vmDetails.target.shortName})` : undefined])"
class="max-w-60 text-center"
/>
</div>

<div class="flex justify-between !pt-8">
<NeoButton
:label="$t('reconnect.switch')"
variant="primary"
no-shadow
:loading="loading"
:disabled="loading"
class="flex flex-grow !h-[3.5rem]"
@click="switchWallet"
/>
</div>
</div>
</ModalBody>
</template>

<script setup lang="ts">
import { NeoButton } from '@kodadot1/brick'
import { type ChainVM } from '@kodadot1/static'
import ModalBody from '@/components/shared/modals/ModalBody.vue'
const VM_SWITCH_MAP: Record<ChainVM, ChainVM> = {
EVM: 'SUB',
SUB: 'EVM',
}
const VM_DETAILS: Record<ChainVM, { icon: string, name: string, shortName?: string }> = {
SUB: {
name: 'Polkadot',
icon: '/token/dot_branded.svg',
},
EVM: {
name: 'Ethereum',
shortName: 'EVM',
icon: '/token/base_branded.svg',
},
}
const emit = defineEmits(['close', 'connect'])
const { logout } = useWallet()
const { vm } = useChain()
const { doAfterLogin } = useDoAfterlogin()
const loading = ref(false)
const targetVm = computed(() => VM_SWITCH_MAP[vm.value]) // make prop
const vmDetails = computed(() => ({
current: VM_DETAILS[vm.value],
target: VM_DETAILS[targetVm.value],
}))
const switchWallet = async () => {
loading.value = true
await logout()
doAfterLogin({
onLoginSuccess: () => emit('connect'),
onCancel: () => {
loading.value = false
},
preselected: targetVm.value,
})
}
</script>
Loading

0 comments on commit b16fcbf

Please sign in to comment.