11<template >
22 <div class =" section" >
3- <div class =" pack-item-wrapper container" >
3+ <div class =" container" >
44 <div class =" columns is-centered" >
55 <div class =" column is-half has-text-centered" >
66 <div class =" container image is-128x128 mb-2" >
7- <b-image
8- v-if =" !isLoading"
7+ <BasicImage
98 :src =" image"
109 :alt =" name"
11- ratio =" 1by1"
1210 rounded
13- ></b-image >
11+ customClass =" collection__image"
12+ />
1413 </div >
1514 <h1 class =" title is-2" >
16- {{ name }}
15+ <template v-if =" ! isLoading " >
16+ {{ name }}
17+ </template >
18+ <b-skeleton :active =" isLoading" size =" is-medium" ></b-skeleton >
1719 </h1 >
1820 </div >
1921 </div >
2022
2123 <div class =" columns is-align-items-center" >
2224 <div class =" column" >
23- <div class =" label" >
24- {{ $t('creator') }}
25- </div >
26- <div class =" subtitle is-size-6" >
27- <ProfileLink :address =" issuer" :inline =" true" :showTwitter =" true" />
28- </div >
29- </div >
30- <div class =" column" v-if =" owner" >
31- <div class =" label" >
32- {{ $t('owner') }}
33- </div >
34- <div class =" subtitle is-size-6" >
35- <ProfileLink :address =" owner" :inline =" true" :showTwitter =" true" />
25+ <div v-if =" !isLoading" >
26+ <div class =" label" >
27+ {{ $t('creator') }}
28+ </div >
29+ <div v-if =" issuer" class =" subtitle is-size-6" >
30+ <ProfileLink :address =" issuer" inline showTwitter />
31+ </div >
3632 </div >
33+ <b-skeleton :active =" isLoading" width =" 40%" size =" is-small" ></b-skeleton >
34+ <b-skeleton :active =" isLoading" width =" 60%" size =" is-small" ></b-skeleton >
3735 </div >
36+
3837 <div class =" column is-6-tablet is-7-desktop is-8-widescreen" >
3938 <CollectionActivity :nfts =" stats" />
4039 </div >
40+
4141 <div class =" column has-text-right" >
4242 <Sharing v-if =" sharingVisible"
4343 class =" mb-2"
4848 </div >
4949 </div >
5050
51- <b-tabs v-model =" activeTab" >
52- <b-tab-item label =" Collection" >
51+ <b-tabs position = " is-centered " v-model =" activeTab" >
52+ <b-tab-item label =" Collection" value = " collection " >
5353 <div class =" columns is-centered" >
5454 <div class =" column is-8 has-text-centered" >
5555 <CollapseWrapper
6868 </b-field >
6969 </Search >
7070
71- <GalleryCardList :items =" collection.nfts" : horizontalLayout= " true " />
71+ <GalleryCardList :items =" collection.nfts" horizontalLayout />
7272
7373 <Pagination
7474 class =" py-5"
7979 :per-page =" first"
8080 />
8181 </b-tab-item >
82- <b-tab-item label =" Activity" >
83- <CollectionPriceChart v-if = " activeTab === 1 " :priceData =" priceData" />
82+ <b-tab-item label =" Activity" value = " activity " >
83+ <CollectionPriceChart :priceData =" priceData" />
8484 </b-tab-item >
8585 </b-tabs >
8686 </div >
8989
9090<script lang="ts" >
9191import { emptyObject } from ' @/utils/empty'
92- import { Component , Mixins } from ' vue-property-decorator'
92+ import { Component , Mixins , Watch } from ' vue-property-decorator'
9393import { CollectionWithMeta , Interaction } from ' ../service/scheme'
9494import {
9595 sanitizeIpfsUrl , fetchCollectionMetadata , sortByTimeStamp , onlyEvents , onlyPriceEvents ,
9696 eventTimestamp , soldNFTPrice , collectionFloorPriceList , PriceDataType , onlyBuyEvents
9797} from ' ../utils'
9898import isShareMode from ' @/utils/isShareMode'
99+ import shouldUpdate from ' @/utils/shouldUpdate'
99100import collectionById from ' @/queries/collectionById.graphql'
100101import nftListByCollection from ' @/queries/nftListByCollection.graphql'
101102import { CollectionMetadata } from ' ../types'
102103import { NFT } from ' @/components/rmrk/service/scheme'
104+ import { exist } from ' @/components/rmrk/Gallery/Search/exist'
103105import { SearchQuery } from ' ./Search/types'
104106import ChainMixin from ' @/utils/mixins/chainMixin'
105107
@@ -114,6 +116,7 @@ const components = {
114116 DonationButton : () => import (' @/components/transfer/DonationButton.vue' ),
115117 Layout : () => import (' @/components/rmrk/Gallery/Layout.vue' ),
116118 CollectionPriceChart : () => import (' @/components/rmrk/Gallery/CollectionPriceChart.vue' ),
119+ BasicImage : () => import (' @/components/shared/view/BasicImage.vue' ),
117120 CollapseWrapper : () => import (' @/components/shared/collapse/CollapseWrapper.vue' ),
118121}
119122@Component <CollectionItem >({
@@ -140,27 +143,30 @@ export default class CollectionItem extends Mixins(
140143) {
141144 private id = ' ' ;
142145 private collection: CollectionWithMeta = emptyObject <CollectionWithMeta >();
143- private isLoading = false ;
144146 public meta: CollectionMetadata = emptyObject <CollectionMetadata >();
145147 private searchQuery: SearchQuery = {
146148 search: ' ' ,
147149 type: ' ' ,
148150 sortBy: ' BLOCK_NUMBER_DESC' ,
149151 listed: false ,
150152 };
151- private activeTab = 0 ;
153+ public activeTab = ' collection ' ;
152154 private currentValue = 1 ;
153155 private first = 15 ;
154- private total = 0 ;
156+ protected total = 0 ;
155157 protected stats: NFT [] = [];
156158 protected priceData: any = [];
157159
160+ get isLoading(): boolean {
161+ return this .$apollo .queries .collection .loading
162+ }
163+
158164 get offset(): number {
159165 return this .currentValue * this .first - this .first
160166 }
161167
162- get image(): string {
163- return this .meta .image || ' '
168+ get image(): string | undefined {
169+ return this .meta .image
164170 }
165171
166172 get description(): string {
@@ -179,10 +185,6 @@ export default class CollectionItem extends Mixins(
179185 return this .collection .issuer || ' '
180186 }
181187
182- get owner(): string {
183- return this .collection .issuer === (this .collection as any ).currentOwner ? ' ' : (this .collection as any ).currentOwner
184- }
185-
186188 get sharingVisible(): boolean {
187189 return ! isShareMode
188190 }
@@ -206,10 +208,12 @@ export default class CollectionItem extends Mixins(
206208 }
207209
208210 public created(): void {
209- this .isLoading = true
210211 this .checkId ()
212+ this .checkActiveTab ()
213+ this .loadStats ()
211214 this .$apollo .addSmartQuery (' collection' , {
212215 query: collectionById ,
216+ loadingKey: ' isLoading' ,
213217 variables : () => {
214218 return {
215219 id: this .id ,
@@ -226,11 +230,9 @@ export default class CollectionItem extends Mixins(
226230 result: this .handleResult ,
227231 })
228232
229- this .loadStats ()
230- this .isLoading = false
231233 }
232234
233- public async loadStats(): Promise < void > {
235+ public loadStats(): void {
234236 const nftStatsP = this .$apollo .query ({
235237 query: nftListByCollection ,
236238 variables: {
@@ -245,29 +247,27 @@ export default class CollectionItem extends Mixins(
245247 }
246248
247249 public loadPriceData(): void {
248-
249250 this .priceData = []
250251
251- const events : Interaction [][] = this .stats ?.map (onlyEvents ) || []
252- const priceEvents : Interaction [][] = events .map (this .priceEvents ) || []
252+ const events: Interaction [][] = this .stats ?.map (onlyEvents ) || []
253+ const priceEvents: Interaction [][] = events .map (this .priceEvents ) || []
253254
254- const overTime : string [] = priceEvents .flat ().sort (sortByTimeStamp ).map (eventTimestamp )
255+ const overTime: string [] = priceEvents .flat ().sort (sortByTimeStamp ).map (eventTimestamp )
255256
256- const floorPriceData : PriceDataType [] = overTime .map (collectionFloorPriceList (priceEvents , this .decimals ))
257+ const floorPriceData: PriceDataType [] = overTime .map (collectionFloorPriceList (priceEvents , this .decimals ))
257258
258259 const buyEvents = events .map (onlyBuyEvents )?.flat ().sort (sortByTimeStamp )
259- const soldPriceData : PriceDataType [] = buyEvents ?.map (soldNFTPrice (this .decimals ))
260+ const soldPriceData: PriceDataType [] = buyEvents ?.map (soldNFTPrice (this .decimals ))
260261
261262 this .priceData = [floorPriceData , soldPriceData ]
262263 }
263264
264265 public async handleResult({data }: any ): Promise <void > {
265266 this .total = data .collectionEntity .nfts .totalCount
266- this .fetchMetadata ()
267+ await this .fetchMetadata ()
267268 }
268269
269270 public async fetchMetadata(): Promise <void > {
270- console .log (this .collection [' metadata' ], ! this .meta [' image' ])
271271 if (this .collection [' metadata' ] && ! this .meta [' image' ]) {
272272 const meta = await fetchCollectionMetadata (this .collection )
273273 this .meta = {
@@ -283,12 +283,34 @@ export default class CollectionItem extends Mixins(
283283 }
284284 }
285285
286+ public checkActiveTab(): void {
287+ exist (this .$route .query .tab , (val ) => {
288+ this .activeTab = val
289+ })
290+ }
291+
292+ @Watch (' activeTab' )
293+ protected onTabChange(val : string , oldVal : string ): void {
294+ if (shouldUpdate (val , oldVal )) {
295+ this .$router .replace ({
296+ name: String (this .$route .name ),
297+ query: { tab: val },
298+ })
299+ }
300+ }
301+
286302 get iframeSettings(): Record <string , unknown > {
287303 return { width: ' 100%' , height: ' 100vh' }
288304 }
289305
290- protected priceEvents(nftEvents : Interaction []) : Interaction [] {
306+ protected priceEvents(nftEvents : Interaction []): Interaction [] {
291307 return nftEvents .filter (onlyPriceEvents )
292308 }
293309}
294310 </script >
311+
312+ <style >
313+ .collection__image img {
314+ color : transparent ;
315+ }
316+ </style >
0 commit comments