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

feat: confirmation modal for mint #7241

Merged
merged 50 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
75796f6
modal layout
xiiiAtCn Sep 11, 2023
42d13b1
tmp: add question icon
xiiiAtCn Sep 11, 2023
ff3ebfe
tmp: check data source
xiiiAtCn Sep 11, 2023
7593536
tmp: add i18n
xiiiAtCn Sep 12, 2023
aa21f9c
Merge branch 'main' into feat_mint-confirm-modal
xiiiAtCn Sep 12, 2023
1d364f8
tmp: remove unused import
xiiiAtCn Sep 12, 2023
e9d404f
tmp: calculate deposit fee
xiiiAtCn Sep 13, 2023
da49ccf
Merge branch 'main' into feat_mint-confirm-modal
xiiiAtCn Sep 13, 2023
bde8973
feat: add fee in collection create modal
xiiiAtCn Sep 14, 2023
b91bfa6
fix: wrong token unit
xiiiAtCn Sep 14, 2023
85b38db
create collection modal
xiiiAtCn Sep 15, 2023
4b31560
nft mint modal in ksm
xiiiAtCn Sep 15, 2023
f73b2fa
fix: remove unused code
xiiiAtCn Sep 15, 2023
d14718b
Merge branch 'main' into feat_mint-confirm-modal
xiiiAtCn Sep 15, 2023
7844f14
fix: submit btn text
xiiiAtCn Sep 15, 2023
1864da4
fix: correct deposit
xiiiAtCn Sep 15, 2023
43a145a
Merge branch 'main' into feat_mint-confirm-modal
xiiiAtCn Sep 18, 2023
0e293c5
format tooltip
xiiiAtCn Sep 18, 2023
0a5420f
feat: add mint confirm modal
xiiiAtCn Sep 18, 2023
10f7da0
feat: add custom class for submit button
xiiiAtCn Sep 18, 2023
36a163e
use global css
xiiiAtCn Sep 18, 2023
443ac5e
fix: rename existential deposit to Collection/NFT existential deposit
xiiiAtCn Sep 20, 2023
2b674fc
Merge branch 'main' into feat_mint-confirm-modal
xiiiAtCn Sep 20, 2023
4fb849d
fix: abnormal modal responsive
xiiiAtCn Sep 26, 2023
f1159e2
Merge branch 'main' into feat_mint-confirm-modal
xiiiAtCn Sep 26, 2023
b35146b
fix: code style
xiiiAtCn Sep 26, 2023
f6fc301
fix: class conflict resolve
xiiiAtCn Sep 26, 2023
5c9d8cf
fix: avoid k-grey
xiiiAtCn Sep 26, 2023
c7c8f56
fix: keep class align with Bulma
xiiiAtCn Sep 26, 2023
4f8e026
fix: change class name
xiiiAtCn Sep 26, 2023
062c7d2
chore: props check and remove console
xiiiAtCn Sep 26, 2023
8f45838
Merge branch 'main' into feat_mint-confirm-modal
xiiiAtCn Sep 27, 2023
74b7915
fix modal header color
xiiiAtCn Sep 27, 2023
0d8eed0
fix modal head background
xiiiAtCn Sep 28, 2023
4699b57
Merge branch 'main' into feat_mint-confirm-modal
xiiiAtCn Sep 28, 2023
3ea53dc
support new nft create page
xiiiAtCn Sep 28, 2023
faacbfc
Update components/create/ConfirmMintItem.vue
yangwao Oct 9, 2023
4d4a9e0
Update components/create/ConfirmMintItem.vue
yangwao Oct 9, 2023
d1a9fd5
* chore: remove unused CreateToken.vue components
preschian Oct 9, 2023
de85192
* chore(CreateNft.vue): fix NeoField component props in CreateNft.vue
preschian Oct 9, 2023
2819674
* chore(CreateCollection.vue): rearrange code to move Loader componen…
preschian Oct 9, 2023
d265ad5
Merge branch 'main' of github.com:kodadot/nft-gallery into pr/xiiiAtC…
preschian Oct 9, 2023
db072e1
* refactor(TokenMoney.vue): Remove unused props and computed properties
preschian Oct 9, 2023
fceef9c
* refactor(Money.vue): refactor computed properties for tokenDecimals…
preschian Oct 9, 2023
aa62e8a
* refactor(confirm): move ConfirmMintItem.vue, MintConfirmModal.vue, …
preschian Oct 9, 2023
d9395aa
Merge branch 'nuxt' of github.com:kodadot/nft-gallery into pr/xiiiAtC…
preschian Oct 10, 2023
547f45f
Merge branch 'nuxt' of github.com:kodadot/nft-gallery into pr/xiiiAtC…
preschian Oct 10, 2023
2fec668
fix: Fix import path in ConfirmMintItem and MintConfirmModal components
preschian Oct 10, 2023
906b3ab
* chore(en.json): remove unnecessary line break
preschian Oct 10, 2023
5531657
Merge branch 'nuxt' of github.com:kodadot/nft-gallery into pr/xiiiAtC…
preschian Oct 10, 2023
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
2 changes: 2 additions & 0 deletions components/base/SubmitButton.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<NeoField>
<NeoButton
:class="customClass"
:size="size"
:type="type"
:icon-left="icon"
Expand Down Expand Up @@ -28,6 +29,7 @@ export interface Props {
loading?: boolean
type?: string
size?: 'small' | 'medium' | 'large'
customClass: string
}

withDefaults(defineProps<Props>(), {
Expand Down
67 changes: 35 additions & 32 deletions components/bsx/Create/CreateToken.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<template>
<div>
<MintConfirmModal
v-model="modalShowStatus"
:nft-information="nftInformation"
@confirm="submit" />
<Loader
v-model="isTransactionLoading"
:status="transactionStatus"
Expand Down Expand Up @@ -62,16 +66,13 @@
<NeoField key="token">
<MultiPaymentFeeButton :account-id="accountId" :prefix="urlPrefix" />
</NeoField>
<NeoField
<SubmitButton
key="submit"
variant="danger"
:message="balanceNotEnoughMessage">
<SubmitButton
expanded
label="mint.submit"
:loading="isTransactionLoading"
@click="submit()" />
</NeoField>
expanded
custom-class="is-size-6"
label="mint.submit"
:loading="isTransactionLoading"
@click="showConfirm" />
</template>
</BaseTokenForm>
</div>
Expand All @@ -95,13 +96,14 @@ import { unwrapSafe } from '@/utils/uniquery'
import { Royalty } from '@/utils/royalty'
import { fetchCollectionMetadata } from '@/utils/ipfs'
import { CollectionMetadata } from '@/components/rmrk/types'
import { Token, getBalance, getDeposit, getFeesToken } from './utils'
import { MintedCollection } from '@/composables/transaction/types'
import { NeoField } from '@kodadot1/brick'
import type TokenBalanceInputComponent from '@/components/bsx/input/TokenBalanceInput.vue'
import type BaseTokenFormComponent from '@/components/base/BaseTokenForm.vue'
import MintConfirmModal from '@/components/create/MintConfirmModal.vue'
import { CreateComponent } from '@/composables/useCreate'

const { $i18n, $apollo, $consola, $router } = useNuxtApp()
const { $apollo, $consola, $router } = useNuxtApp()

const CustomAttributeInput = () =>
import('@/components/rmrk/Create/CustomAttributeInput.vue')
Expand Down Expand Up @@ -130,6 +132,7 @@ withDefaults(
const { apiUrl } = useApi()
const { urlPrefix, tokenId } = usePrefix()
const { accountId } = useAuth()
const { chain } = useDeposit(urlPrefix)
const {
status: transactionStatus,
isLoading: isTransactionLoading,
Expand Down Expand Up @@ -158,32 +161,28 @@ const nsfw = ref(false)
const price = ref('0')
const listed = ref(false)
const hasRoyalty = ref(true)
const feesToken = ref<Token>('BSX')
const royalty = ref<Royalty>({
amount: 0.15,
address: accountId.value,
})
const balanceNotEnough = ref(false)
const modalShowStatus = ref(false)

const balanceInput = ref<typeof TokenBalanceInputComponent | null>(null)
const baseTokenForm = ref<typeof BaseTokenFormComponent | null>(null)

const nftInformation = computed(() => ({
...base.value,
price: price.value.toString(),
listForSale: listed.value,
paidToken: chain.value,
mintType: CreateComponent.NFT,
}))

watch(price, (value) => {
price.value = value
balanceInput.value?.checkValidity()
})

const balanceOfToken = computed(() => getBalance(feesToken.value))
const depositOfToken = computed(() =>
getDeposit(feesToken.value, parseFloat(deposit.value))
)
const balanceNotEnoughMessage = computed(() => {
if (balanceNotEnough.value) {
return $i18n.t('tooltip.notEnoughBalance')
}
return ''
})

const loadCollectionMeta = async () => {
const metadata = collections.value.map(({ metadata }) => metadata)

Expand Down Expand Up @@ -251,20 +250,25 @@ const navigateToDetail = (collection: string, id: string): void => {
setTimeout(go, DETAIL_TIMEOUT)
}

const submit = async (retryCount = 0): Promise<void> => {
const showConfirm = () => {
if (preCheck()) {
modalShowStatus.value = true
}
}

const preCheck = () => {
if (!base.value.selectedCollection) {
throw ReferenceError('[MINT] Unable to mint without collection')
}
// check fields
if (!checkValidity()) {
return
}
// check balance
if (!!deposit.value && balanceOfToken.value < depositOfToken.value) {
balanceNotEnough.value = true
return
return false
}
return true
}

const submit = async (retryCount = 0): Promise<void> => {
modalShowStatus.value = false
isTransactionLoading.value = true
transactionStatus.value = 'loader.ipfs'
const {
Expand Down Expand Up @@ -322,7 +326,6 @@ watch(
async (value, oldVal) => {
if (shouldUpdate(value, oldVal)) {
await fetchCollections()
feesToken.value = await getFeesToken()
}
},
{ immediate: true }
Expand Down
93 changes: 93 additions & 0 deletions components/create/ConfirmMintItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<template>
<div>
<div class="is-flex is-justify-content-space-between">
<div class="is-flex pr-2">
<div>
<BasicImage
:src="avatar"
:alt="nft.name"
class="border image is-48x48" />
</div>
<div
class="is-flex is-flex-direction-column is-justify-content-space-between ml-4 limit-width">
<div class="has-text-color line-height-1 no-wrap is-clipped ellipsis">
{{ nft.name }}
</div>
<div class="line-height-1 no-wrap has-text-grey is-clipped ellipsis">
{{ label }}:
</div>
</div>
</div>
<div
class="is-flex is-align-items-end no-wrap has-text-grey line-height-1">
<template v-if="isNFT">
<template v-if="showPrice">
<CommonTokenMoney :value="price" />
</template>
<template v-else> Not Listed </template>
</template>
<template v-else>
{{ blockchain.text }}
</template>
</div>
</div>
<div v-if="isNFT" class="is-flex mt-4 is-align-items-center">
<div class="has-text-grey mr-2">
{{ $t('mint.nft.modal.intoCollection') }}
</div>
<NeoIcon pack="fa-sharp" icon="arrow-right-long" class="k-grey mr-4" />
<div>{{ nft.selectedCollection.name }}</div>
yangwao marked this conversation as resolved.
Show resolved Hide resolved
</div>
</div>
</template>

<script setup lang="ts">
import BasicImage from '@/components/shared/view/BasicImage.vue'
import { ExtendedInformation } from './MintConfirmModal.vue'
import { NeoIcon } from '@kodadot1/brick'
import { CreateComponent } from '@/composables/useCreate'
import CommonTokenMoney from '@/components/shared/CommonTokenMoney.vue'

const { $i18n } = useNuxtApp()

const props = defineProps<{ nft: ExtendedInformation }>()
const avatar = ref<string>()

const isNFT = computed(() => props.nft.mintType === CreateComponent.NFT)
const label = computed(() =>
isNFT.value
? $i18n.t('mint.nft.modal.price')
: $i18n.t('mint.nft.modal.network')
)
const price = computed(() => props.nft.price)
const showPrice = computed(() => props.nft.listForSale)
const blockchain = computed(() => props.nft.blockchain)
watch(
() => props.nft.file,
() => {
const file = props.nft.file
const reader = new FileReader()
avatar.value = URL.createObjectURL(file)
reader.readAsText(file)
},
{
immediate: true,
}
)
yangwao marked this conversation as resolved.
Show resolved Hide resolved
</script>

<style scoped lang="scss">
@import '@/styles/abstracts/variables';

.limit-width {
max-width: 170px;
}

.ellipsis {
text-overflow: ellipsis;
}

.line-height-1 {
line-height: 1;
}
</style>
81 changes: 48 additions & 33 deletions components/create/CreateCollection.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
<template>
<div class="is-centered" :class="{ columns: classColumn }">
<MintConfirmModal
v-model="modalShowStatus"
:nft-information="collectionInformation"
@confirm="createCollection" />
<Loader v-model="isLoading" :status="status" />
<form
class="is-half"
:class="{ column: classColumn }"
@submit.prevent="createCollection">
@submit.prevent="showConfirm">
<h1 class="title is-size-3">
{{ $t('mint.collection.create') }}
</h1>
Expand Down Expand Up @@ -123,37 +127,32 @@
<hr class="my-6" />

<!-- create collection button -->
<NeoField>
<div>
<NeoButton
expanded
:label="`${canDeposit ? 'Create Collection' : 'Not Enough Funds'}`"
type="submit"
size="medium"
data-testid="collection-create"
:loading="isLoading"
:disabled="!canDeposit" />

<div class="p-4 is-flex">
<NeoIcon icon="circle-info" size="medium" class="mr-4" />
<p class="is-size-7">
<span
v-dompurify-html="
$t('mint.requiredDeposit', [
`${totalCollectionDeposit} ${chainSymbol}`,
])
" />
<a
href="https://hello.kodadot.xyz/multi-chain/fees"
target="_blank"
class="has-text-link"
rel="nofollow noopener noreferrer">
{{ $t('helper.learnMore') }}
</a>
</p>
</div>
</div>
</NeoField>
<NeoButton
class="is-size-6"
expanded
:label="$t('mint.collection.submit')"
type="submit"
size="medium"
data-testid="collection-create"
:loading="isLoading" />
<div class="p-4 is-flex">
<NeoIcon icon="circle-info" size="medium" class="mr-4" />
<p class="is-size-7">
<span
v-dompurify-html="
$t('mint.requiredDeposit', [
`${totalCollectionDeposit} ${chainSymbol}`,
])
" />
<a
href="https://hello.kodadot.xyz/multi-chain/fees"
target="_blank"
class="has-text-link"
rel="nofollow noopener noreferrer">
{{ $t('helper.learnMore') }}
</a>
</p>
</div>
</form>
</div>
</template>
Expand All @@ -180,6 +179,7 @@ import { availablePrefixes } from '@/utils/chain'
import { Interaction } from '@kodadot1/minimark/v1'
import { notificationTypes, showNotification } from '@/utils/notification'
import { makeSymbol } from '@kodadot1/minimark/shared'
import MintConfirmModal from './MintConfirmModal.vue'

// props
withDefaults(
Expand All @@ -204,6 +204,8 @@ const unlimited = ref(true)
const max = ref(1)
const symbol = ref('')

const modalShowStatus = ref(false)

const menus = availablePrefixes().filter(
(menu) => menu.value !== 'movr' && menu.value !== 'glmr'
)
Expand All @@ -215,16 +217,28 @@ const currentChain = computed(() => {
})

const { isAssetHub, isBasilisk, isRemark } = useIsChain(currentChain)
const { balance, totalCollectionDeposit, chainSymbol } =
const { balance, totalCollectionDeposit, chainSymbol, chain } =
useDeposit(currentChain)

// balance state
const canDeposit = computed(() => {
return parseFloat(balance.value) >= parseFloat(totalCollectionDeposit.value)
})

const collectionInformation = computed(() => ({
file: logo.value,
name: name.value,
paidToken: chain.value,
mintType: CreateComponent.Collection,
}))

watchEffect(() => setUrlPrefix(currentChain.value as Prefix))

const showConfirm = () => {
console.log('show confirm')
modalShowStatus.value = true
}

const createCollection = async () => {
let collection: BaseCollectionType = {
file: logo.value,
Expand Down Expand Up @@ -255,6 +269,7 @@ const createCollection = async () => {
notificationTypes.info
)
isLoading.value = true
modalShowStatus.value = false

await transaction(
{
Expand Down
Loading