From 057fa8f68e9361ae62efedbda8e1d7a22015d80f Mon Sep 17 00:00:00 2001 From: Zouheir Layine <58786497+zlayine@users.noreply.github.com> Date: Tue, 11 Jun 2024 04:25:13 +0300 Subject: [PATCH] [PLA-1648] add token collection name (#121) --- resources/js/api/index.ts | 11 +++- resources/js/components/pages/Collections.vue | 52 ++++++++++++++++++- resources/js/components/pages/Tokens.vue | 52 ++++++++++++++++++- resources/js/store/index.ts | 2 +- 4 files changed, 113 insertions(+), 4 deletions(-) diff --git a/resources/js/api/index.ts b/resources/js/api/index.ts index 495da3f..e2a27fe 100644 --- a/resources/js/api/index.ts +++ b/resources/js/api/index.ts @@ -131,7 +131,7 @@ export class ApiService { }); } - static async fetchURL(url: URL) { + static async fetchPlatformURL(url: URL) { return ApiService.request({ url: `${url}.well-known/enjin-platform.json`, method: HttpMethods.GET, @@ -149,6 +149,15 @@ export class ApiService { }); } + static async fetchUrl(url: string) { + return ApiService.request({ + url: url, + method: HttpMethods.GET, + credentials: undefined, + mode: undefined, + }); + } + static async freeze(freezeData: Record) { const data = { query: mutations.Freeze, diff --git a/resources/js/components/pages/Collections.vue b/resources/js/components/pages/Collections.vue index 9c21df2..48eee70 100644 --- a/resources/js/components/pages/Collections.vue +++ b/resources/js/components/pages/Collections.vue @@ -38,7 +38,13 @@ scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-light-content-strong dark:text-dark-content-strong sm:pl-3" > - CollectionId + Name + + + ID + + {{ collectionNames[collection.collectionId] }} + @@ -146,6 +157,7 @@ import { snackbarErrors } from '~/util'; import Btn from '~/components/Btn.vue'; import { TransactionState } from '~/types/types.enums'; import { useRoute, useRouter } from 'vue-router'; +import { ApiService } from '~/api'; const isLoading = ref(true); const isPaginationLoading = ref(false); @@ -168,6 +180,7 @@ const paginatorRef = ref(); const modalSlide = ref(false); const slideComponent = ref(); const searchInput = ref(''); +const collectionNames = ref<{ [key: string]: string }[]>([]); const route = useRoute(); const router = useRouter(); @@ -260,6 +273,7 @@ const getCollections = async () => { try { const res = await CollectionApi.getCollections(); collections.value = DTOFactory.forCollections(res); + setCollectionNames(); } catch (e) { collections.value.items = []; if (snackbarErrors(e)) return; @@ -272,6 +286,41 @@ const getCollections = async () => { } }; +const getCollectionName = async (collection) => { + const uri = collection.attributes.find((attr) => attr.key === 'uri')?.value; + if (uri) { + return await fetchUri(uri); + } + + return collection.attributes.find((attr) => attr.key === 'name')?.value || '-'; +}; + +const setCollectionNames = async () => { + collections.value.items.map(async (item) => { + if (collectionNames.value[`${item.collectionId}`]) { + return item; + } + const name = await getCollectionName(item); + collectionNames.value = { ...collectionNames.value, [`${item.collectionId}`]: name }; + + return item; + }); +}; + +const fetchUri = async (uri) => { + try { + const res = await ApiService.fetchUrl(uri); + const json = JSON.parse(res); + if (json.name) { + return json.name; + } + + return '-'; + } catch (e) { + return '-'; + } +}; + const loadMoreCollectionsWithObserver = () => { const observer = new IntersectionObserver( async (entries) => { @@ -283,6 +332,7 @@ const loadMoreCollectionsWithObserver = () => { const res = await CollectionApi.getCollections(collections.value.cursor); const data = DTOFactory.forCollections(res); collections.value = { items: [...collections.value.items, ...data.items], cursor: data.cursor }; + setCollectionNames(); isPaginationLoading.value = false; } catch (error) { isPaginationLoading.value = false; diff --git a/resources/js/components/pages/Tokens.vue b/resources/js/components/pages/Tokens.vue index 7619c66..b287033 100644 --- a/resources/js/components/pages/Tokens.vue +++ b/resources/js/components/pages/Tokens.vue @@ -52,7 +52,13 @@ scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-light-content-strong dark:text-dark-content-strong sm:pl-3" > - Token ID + Name + + + ID + + {{ tokenNames[`${token.collection.collectionId}-${token.tokenId}`] }} + @@ -159,6 +170,7 @@ import snackbar, { events } from '~/util/snackbar'; import FormInput from '~/components/FormInput.vue'; import NoItems from '~/components/NoItems.vue'; import Btn from '~/components/Btn.vue'; +import { ApiService } from '~/api'; const isLoading = ref(false); const isPaginationLoading = ref(false); @@ -186,6 +198,7 @@ const searchTokensInput = ref({ tokenId: '', tokenType: TokenIdSelectType.Integer, }); +const tokenNames = ref<{ [key: string]: string }[]>([]); const enablePagination = computed(() => searchTokensInput.value.tokenId === ''); @@ -271,11 +284,24 @@ const searchTokensChange = (e) => { } }; +const setTokenNames = async () => { + tokens.value.items.map(async (item) => { + if (tokenNames.value[`${item.collection.collectionId}-${item.tokenId}`]) { + return item; + } + const name = await getTokenName(item); + tokenNames.value = { ...tokenNames.value, [`${item.collection.collectionId}-${item.tokenId}`]: name }; + + return item; + }); +}; + const getTokens = async () => { try { isLoading.value = true; const res = await TokenApi.getTokens(searchCollectionInput.value, formatTokens([searchTokensInput.value])); tokens.value = DTOFactory.forTokens(res); + setTokenNames(); } catch (e) { tokens.value.items = []; if (snackbarErrors(e)) return; @@ -303,6 +329,7 @@ const loadMoreTokensWithObserver = () => { ); const data = DTOFactory.forTokens(res); tokens.value = { items: [...tokens.value.items, ...data.items], cursor: data.cursor }; + setTokenNames(); isPaginationLoading.value = false; } catch (error) { isPaginationLoading.value = false; @@ -340,6 +367,29 @@ const openTransactionSlide = async (transactionId: string) => { }, 600); }; +const getTokenName = async (token): Promise => { + const uri = token.attributes.find((attr) => attr.key === 'uri')?.value; + if (uri) { + return await fetchUri(uri); + } + + return token.attributes.find((attr) => attr.key === 'name')?.value || '-'; +}; + +const fetchUri = async (uri) => { + try { + const res = await ApiService.fetchUrl(uri); + const json = JSON.parse(res); + if (json.name) { + return json.name; + } + + return '-'; + } catch (e) { + return '-'; + } +}; + onMounted(async () => { getTokens(); loadMoreTokensWithObserver(); diff --git a/resources/js/store/index.ts b/resources/js/store/index.ts index 8c61cfd..e9965cb 100644 --- a/resources/js/store/index.ts +++ b/resources/js/store/index.ts @@ -160,7 +160,7 @@ export const useAppStore = defineStore('app', { async checkURL(url: URL) { try { if (url) { - const urlConfig = await ApiService.fetchURL(url); + const urlConfig = await ApiService.fetchPlatformURL(url); if (urlConfig) return urlConfig; throw 'The URL is not valid';