Skip to content

Commit

Permalink
Merge branch 'main' into fix/seo/bsx
Browse files Browse the repository at this point in the history
  • Loading branch information
roiLeo committed Jul 7, 2022
2 parents 2edb73d + d09d325 commit 1af2f2f
Show file tree
Hide file tree
Showing 37 changed files with 797 additions and 74 deletions.
11 changes: 10 additions & 1 deletion components/Navbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@
<LazyHistoryBrowser
class="custom-navbar-item navbar-link-background is-hidden-touch"
id="NavHistoryBrowser" />
<b-navbar-dropdown arrowless collapsible id="NavCreate">
<b-navbar-dropdown
arrowless
collapsible
id="NavCreate"
v-show="isCreateVisible">
<template #label>
<span>{{ $t('create') }}</span>
</template>
Expand Down Expand Up @@ -134,6 +138,7 @@ import PrefixMixin from '~/utils/mixins/prefixMixin'
import Identity from '@/components/shared/format/Identity.vue'
import Search from '@/components/rmrk/Gallery/Search/SearchBar.vue'
import BasicImage from '@/components/shared/view/BasicImage.vue'
import { createVisible } from '@/utils/config/permision.config'
import { identityStore } from '@/utils/idbStore'
import { get } from 'idb-keyval'
Expand Down Expand Up @@ -173,6 +178,10 @@ export default class NavbarMenu extends mixins(PrefixMixin) {
return this.$route.name === 'rmrk-u-id'
}
get isCreateVisible(): boolean {
return createVisible(this.urlPrefix)
}
get isTargetPage(): boolean {
return (
this.inCollectionPage ||
Expand Down
2 changes: 1 addition & 1 deletion components/bsx/Create/CreateCollection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import ChainMixin from '@/utils/mixins/chainMixin'
import MetaTransactionMixin from '@/utils/mixins/metaMixin'
import PrefixMixin from '@/utils/mixins/prefixMixin'
import { notificationTypes, showNotification } from '@/utils/notification'
import { pinJson, PinningKey } from '@/utils/pinning'
import { pinJson, PinningKey } from '@/utils/nftStorage'
import resolveQueryPath from '@/utils/queryPathResolver'
import { getImageTypeSafe, pinImageSafe } from '@/utils/safePin'
import { estimate } from '@/utils/transactionExecutor'
Expand Down
20 changes: 15 additions & 5 deletions components/bsx/Create/CreateToken.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ import {
} from '@/components/rmrk/Create/mintUtils'
import ChainMixin from '@/utils/mixins/chainMixin'
import { notificationTypes, showNotification } from '@/utils/notification'
import { pinFileToIPFS, pinJson, PinningKey } from '@/utils/pinning'
import { pinFileToIPFS, pinJson, PinningKey } from '@/utils/nftStorage'
import shouldUpdate from '@/utils/shouldUpdate'
import {
Attribute,
Expand All @@ -80,14 +80,20 @@ import {
} from '@/components/unique/apiConstants'
import { createTokenId } from '@/components/unique/utils'
import onApiConnect from '@/utils/api/general'
import { IPFS_KODADOT_IMAGE_PLACEHOLDER } from '@/utils/constants'
import {
DETAIL_TIMEOUT,
IPFS_KODADOT_IMAGE_PLACEHOLDER,
} from '@/utils/constants'
import AuthMixin from '@/utils/mixins/authMixin'
import MetaTransactionMixin from '@/utils/mixins/metaMixin'
import PrefixMixin from '@/utils/mixins/prefixMixin'
import resolveQueryPath from '@/utils/queryPathResolver'
import { unwrapSafe } from '@/utils/uniquery'
import { isRoyaltyValid, Royalty } from '@/utils/royalty'
import { fetchCollectionMetadata } from '~/components/rmrk/utils'
import {
fetchCollectionMetadata,
preheatFileFromIPFS,
} from '~/components/rmrk/utils'
import { getMany, update } from 'idb-keyval'
type MintedCollection = BaseMintedCollection & {
Expand Down Expand Up @@ -337,18 +343,22 @@ export default class CreateToken extends mixins(
file.type
)
preheatFileFromIPFS(fileHash)
// uploadDirect(file, this.accountId).catch(this.$consola.warn)
const metaHash = await pinJson(meta, imageHash)
return unSanitizeIpfsUrl(metaHash)
}
protected navigateToDetail(collection: string, id: string): void {
showNotification('You will go to the detail in 2 seconds')
showNotification(
`You will go to the detail in ${DETAIL_TIMEOUT / 1000} seconds`
)
const go = () =>
this.$router.push({
path: `/${this.urlPrefix}/gallery/${createTokenId(collection, id)}`,
query: { message: 'congrats' },
})
setTimeout(go, 2000)
setTimeout(go, DETAIL_TIMEOUT)
}
}
</script>
2 changes: 1 addition & 1 deletion components/bsx/Offer/OfferTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
:label="$t('offer.price')"
v-slot="props"
sortable>
<Money :value="props.row.price" inline hideUnit />
<Money :value="props.row.price" inline />
</b-table-column>
<b-table-column
v-if="!isBsxStats"
Expand Down
278 changes: 278 additions & 0 deletions components/moonsama/Gallery/Item/GalleryItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
<template>
<BaseGalleryItem
v-if="nft"
:image="meta.image"
:animationUrl="meta.animation_url"
:mimeType="mimeType"
:description="meta.description"
:imageVisible="imageVisible"
:isLoading="isLoading">
<template v-slot:top v-if="message">
<b-message class="message-box" type="is-primary">
<div class="columns">
<div class="column is-four-fifths">
<p class="title is-3 has-text-black">{{ $t('mint.success') }} 🎉</p>
<p class="subtitle is-size-5 subtitle-text">
{{ $t('mint.shareWithFriends', [nft.name]) }} △
</p>
</div>
<div class="column">
<Sharing onlyCopyLink />
</div>
</div>
</b-message>
</template>
<template v-slot:main>
<div class="columns">
<div class="column is-6">
<div class="nft-title">
<Name :nft="nft" :isLoading="isLoading" />
</div>

<div v-if="meta.description" class="block">
<p class="label">{{ $t('legend') }}</p>
<VueMarkdown
v-if="!isLoading"
class="is-size-5"
:source="meta.description.replaceAll('\n', ' \n')" />
<b-skeleton
:count="3"
size="is-large"
:active="isLoading"></b-skeleton>
</div>

<div class="block" v-if="meta.attributes && meta.attributes.length">
<Properties :attributes="meta.attributes" fieldKey="trait_type" />
</div>
</div>

<div class="column is-6" v-if="detailVisible">
<b-skeleton
:count="2"
size="is-large"
:active="isLoading"></b-skeleton>

<div class="columns">
<div class="column">
<div class="nft-title">
<Detail :nft="nft" :isLoading="isLoading" />
</div>
</div>
<div
class="column is-flex is-flex-direction-column is-justify-content-space-between">
<template v-if="detailVisible && !nft.burned">
<div class="card bordered mb-4" aria-id="contentIdForA11y3">
<div class="card-content">
<template v-if="hasPrice">
<div class="label">
{{ $t('price') }}
</div>
<div class="price-block__container">
<div class="price-block__original">
<Money :value="nft.price" inline />
</div>
</div>
</template>
<div class="content pt-4">
<p class="subtitle">
<Auth class="mt-4" evm />
</p>
</div>
<Sharing class="mb-4" />
</div>
</div>
</template>
</div>
</div>
<b-skeleton
:count="2"
size="is-large"
:active="isLoading"></b-skeleton>
</div>
</div>
</template>
</BaseGalleryItem>
</template>

<script lang="ts">
import { Emote, NFT, NFTMetadata } from '@/components/rmrk/service/scheme'
import {
fetchNFTMetadata,
getSanitizer,
sanitizeIpfsUrl,
} from '@/components/rmrk/utils'
import { createTokenId, tokenIdToRoute } from '@/components/unique/utils'
import Orientation from '@/utils/directives/DeviceOrientation'
import { emptyObject } from '@/utils/empty'
import isShareMode from '@/utils/isShareMode'
import SubscribeMixin from '@/utils/mixins/subscribeMixin'
import { notificationTypes, showNotification } from '@/utils/notification'
import { get, set } from 'idb-keyval'
import { Component, mixins, Vue } from 'nuxt-property-decorator'
import { processMedia } from '@/utils/gallery/media'
import AuthMixin from '~/utils/mixins/authMixin'
import PrefixMixin from '~/utils/mixins/prefixMixin'
import resolveQueryPath from '~/utils/queryPathResolver'
import { isEmpty } from '@kodadot1/minimark'
import { royaltyOf } from '@/utils/royalty'
@Component<GalleryItem>({
components: {
Auth: () => import('@/components/shared/Auth.vue'),
Name: () => import('@/components/rmrk/Gallery/Item/Name.vue'),
Sharing: () => import('@/components/rmrk/Gallery/Item/Sharing.vue'),
IndexerGuard: () => import('@/components/shared/wrapper/IndexerGuard.vue'),
VueMarkdown: () => import('vue-markdown-render'),
Detail: () => import('@/components/unique/Gallery/Item/Detail.vue'),
DangerModal: () =>
import('@/components/unique/Gallery/Item/DangerModal.vue'),
Properties: () => import('@/components/unique/Gallery/Item/Properties.vue'),
BaseGalleryItem: () =>
import('@/components/shared/gallery/BaseGalleryItem.vue'),
Money: () => import('@/components/shared/format/Money.vue'),
OfferList: () => import('@/components/bsx/Offer/OfferList.vue'),
},
directives: {
orientation: Orientation,
},
})
export default class GalleryItem extends mixins(
SubscribeMixin,
PrefixMixin,
AuthMixin
) {
private id = ''
private collectionId = ''
private nft: NFT = emptyObject<NFT>()
private imageVisible = true
public isLoading = false
public mimeType = ''
public meta: NFTMetadata = emptyObject<NFTMetadata>()
public emotes: Emote[] = []
public message = ''
public created() {
this.checkId()
this.fetchNftData()
}
get tokenId(): [string, string] {
return [this.collectionId, this.id]
}
private async fetchNftData() {
const query = await resolveQueryPath(this.urlPrefix, 'nftById')
const nft = await this.$apollo.query({
query: query.default,
client: this.urlPrefix,
variables: {
id: createTokenId(this.collectionId, this.id),
},
})
const {
data: { nftEntity },
} = nft
if (!nftEntity) {
this.$consola.warn(`No NFT with ID ${this.id}`)
// showNotification(`No NFT with ID ${this.id}`, notificationTypes.warn)
return
}
this.nft = {
...this.nft,
...nftEntity,
}
if (nftEntity.meta) {
this.meta = {
...this.meta,
...nftEntity.meta,
image: sanitizeIpfsUrl(nftEntity.meta.image || ''),
}
}
this.fetchMetadata()
}
onImageError(e: any) {
this.$consola.warn('Image error', e)
}
public async fetchMetadata() {
if (this.nft['metadata']) {
const cachedMeta = await get(this.nft.metadata)
const meta = !isEmpty(cachedMeta)
? cachedMeta
: await fetchNFTMetadata(
this.nft,
getSanitizer(this.nft.metadata, 'cloudflare', 'permafrost')
)
const imageSanitizer = getSanitizer(meta.image, 'cloudflare')
this.meta = {
...meta,
image: imageSanitizer(meta.image),
animation_url: sanitizeIpfsUrl(
meta.animation_url || meta.image,
'pinata'
),
}
if (!this.nft.name && meta.name) {
Vue.set(this.nft, 'name', meta.name)
}
if (this.meta.animation_url && !this.mimeType) {
const { mimeType, imageVisible } = await processMedia(
this.meta.animation_url
)
this.mimeType = mimeType
this.imageVisible = imageVisible
}
if (!cachedMeta && !isEmpty(meta)) {
set(this.nft.metadata, meta)
}
}
}
public checkId() {
if (this.$route.params.id) {
const { id, item } = tokenIdToRoute(this.$route.params.id)
this.id = item
this.collectionId = id
}
}
public toast(message: string): void {
this.$buefy.toast.open(message)
}
get hasPrice(): boolean {
return Number(this.nft.price) > 0
}
get nftRoyalties(): string {
return this.nft.price && this.nft.royalty
? royaltyOf(this.nft.price, this.nft.royalty)
: ''
}
get nftId() {
const { id } = this.nft
return id
}
get detailVisible() {
return !isShareMode
}
protected handleAction(deleted: boolean) {
if (deleted) {
showNotification('INSTANCE REMOVED', notificationTypes.warn)
}
}
}
</script>
Loading

0 comments on commit 1af2f2f

Please sign in to comment.