Skip to content

Commit

Permalink
⚡️ [Portfolio] Lazy-load metadata (#781)
Browse files Browse the repository at this point in the history
  • Loading branch information
nwingt authored Nov 17, 2022
1 parent e5fc13b commit 7309ca5
Show file tree
Hide file tree
Showing 8 changed files with 267 additions and 53 deletions.
10 changes: 0 additions & 10 deletions src/components/NFTPortfolio/Item.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,6 @@ export default {
return { name: 'nft-class-classId', params: { classId: this.classId } };
},
},
async mounted() {
await this.updateNFTClassMetadata();
this.$emit('load');
this.updateNFTOwners();
// wait for metadata to determine if it is writing NFT
if (this.isWritingNFT) {
await this.updateNFTPurchaseInfo();
this.$emit('load');
}
},
methods: {
async handleClickCollect() {
logTrackerEvent(this, 'NFT', 'NFTCollect(Portfolio)', this.classId, 1);
Expand Down
1 change: 1 addition & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
"nft_portfolio_page_label_collected": "Collected",
"nft_portfolio_page_label_created": "Created",
"nft_portfolio_page_label_loading": "Loading",
"nft_portfolio_page_label_loading_more": "Loading more",
"nft_supply_section_title": "Item Supply",
"footer_nav_about_liker_land": "About Liker Land",
"footer_nav_about_likecoin": "About LikeCoin",
Expand Down
1 change: 1 addition & 0 deletions src/locales/zh-Hant.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
"nft_portfolio_page_label_collected": "Collected",
"nft_portfolio_page_label_created": "Created",
"nft_portfolio_page_label_loading": "Loading",
"nft_portfolio_page_label_loading_more": "Loading more",
"nft_supply_section_title": "Item Supply",
"footer_nav_about_liker_land": "About Liker Land",
"footer_nav_about_likecoin": "About LikeCoin",
Expand Down
121 changes: 114 additions & 7 deletions src/mixins/portfolio.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { mapActions, mapGetters } from 'vuex';
import MagicGrid from 'magic-grid';
import throat from 'throat';

import {
ORDER_CREATED_CLASS_ID_BY,
Expand All @@ -15,6 +16,12 @@ const tabOptions = {
created: 'created',
};

const ITEMS_PER_PAGE = 10;

const NFT_INFO_FETCH_CONCURRENT_REQUEST_MAX = 10;

const throttleNFTInfoFetch = throat(NFT_INFO_FETCH_CONCURRENT_REQUEST_MAX);

export default {
tabOptions,
mixins: [clipboardMixin, userInfoMixin],
Expand All @@ -23,8 +30,10 @@ export default {
isLoading: false,
collectedOrderBy: ORDER_COLLECTED_CLASS_ID_BY.LAST_COLLECTED_NFT,
collectedOrder: ORDER.DESC,
collectedLimit: ITEMS_PER_PAGE,
createdOrderBy: ORDER_CREATED_CLASS_ID_BY.ISCN_TIMESTAMP,
createdOrder: ORDER.DESC,
createdLimit: ITEMS_PER_PAGE,
};
},
computed: {
Expand All @@ -37,6 +46,11 @@ export default {
return this.$route.query.tab || tabOptions.collected;
},

hasMoreNFTs() {
return this.currentTab === tabOptions.collected
? this.collectedLimit < this.collectedNFTs?.length
: this.createdLimit < this.createdClassIds?.length;
},
nftList() {
return this.getNFTListByAddress(this.wallet);
},
Expand All @@ -59,14 +73,14 @@ export default {
nftOwner: this.wallet,
orderBy: this.collectedOrderBy,
order: this.collectedOrder,
});
}).slice(0, this.collectedLimit);
},
sortedCreatedClassIds() {
return this.getCreatedClassIdSorter({
classIds: this.createdClassIds,
orderBy: this.createdOrderBy,
order: this.createdOrder,
});
}).slice(0, this.createdLimit);
},
currentOrderBy() {
return this.currentTab === tabOptions.collected
Expand Down Expand Up @@ -160,15 +174,48 @@ export default {
currentTab() {
this.$nextTick(this.setupNFTGrid);
},
sortedCollectedNFTs() {
this.$nextTick(this.updateNFTGrid);
sortedCollectedNFTs(list, prevList) {
this.$nextTick(
list?.length !== prevList?.length
? this.setupNFTGrid
: this.updateNFTGrid
);
},
sortedCreatedClassIds() {
this.$nextTick(this.updateNFTGrid);
sortedCreatedClassIds(list, prevList) {
this.$nextTick(
list?.length !== prevList?.length
? this.setupNFTGrid
: this.updateNFTGrid
);
},
collectedNFTs(nfts) {
nfts.map(({ classId }) =>
throttleNFTInfoFetch(() => this.fetchNFTInfo(classId))
);
},
createdClassIds(classIds) {
classIds.map(classId =>
throttleNFTInfoFetch(() => this.fetchNFTInfo(classId))
);
},
hasMoreNFTs(hasMoreNFTs) {
if (hasMoreNFTs) {
this.addInfiniteScrollListener();
} else {
this.removeInfiniteScrollListener();
}
},
},
beforeDestroy() {
this.removeInfiniteScrollListener();
},
methods: {
...mapActions(['fetchNFTListByAddress']),
...mapActions([
'fetchNFTListByAddress',
'fetchNFTMetadata',
'fetchNFTPurchaseInfo',
'fetchNFTOwners',
]),
syncRouteForTab(tab = tabOptions.collected) {
const { query } = this.$route;
if (!query.tab || !tabOptions[query.tab] || this.currentTab !== tab) {
Expand All @@ -178,6 +225,35 @@ export default {
});
}
},
addInfiniteScrollListener() {
window.addEventListener('scroll', this.handleInfiniteScroll);
},
removeInfiniteScrollListener() {
window.removeEventListener('scroll', this.handleInfiniteScroll);
},
handleInfiniteScroll() {
if (!this.hasMoreNFTs) return;

const { loadingMore: trigger } = this.$refs;
if (
!trigger ||
window.innerHeight + window.pageYOffset < trigger.offsetTop
) {
return;
}

if (this.currentTab === tabOptions.collected) {
this.collectedLimit = Math.min(
this.collectedLimit + ITEMS_PER_PAGE,
this.collectedNFTs.length
);
} else {
this.createdLimit = Math.min(
this.createdLimit + ITEMS_PER_PAGE,
this.createdClassIds.length
);
}
},
async loadNFTListByAddress(address) {
const fetchPromise = this.fetchNFTListByAddress(address);
if (!this.getNFTListByAddress(address)) {
Expand All @@ -186,6 +262,37 @@ export default {
this.isLoading = false;
}
},
async fetchNFTInfo(classId) {
try {
await this.fetchNFTMetadata(classId);
} catch (error) {
if (error.response?.status !== 404) {
// eslint-disable-next-line no-console
console.error(JSON.stringify(error));
}
}
this.$nextTick(this.updateNFTGrid);

this.fetchNFTOwners(classId).catch(error => {
if (error.response?.status !== 404) {
// eslint-disable-next-line no-console
console.error(JSON.stringify(error));
}
});

// wait for metadata to determine if it is writing NFT
if (this.isWritingNFT) {
try {
await this.fetchNFTPurchaseInfo(classId);
} catch (error) {
if (error.response?.status !== 404) {
// eslint-disable-next-line no-console
console.error(JSON.stringify(error));
}
}
this.$nextTick(this.updateNFTGrid);
}
},
changeTab(tab) {
this.syncRouteForTab(tab);
},
Expand Down
Loading

0 comments on commit 7309ca5

Please sign in to comment.