Skip to content

Commit

Permalink
feat: add nft list and links from balances
Browse files Browse the repository at this point in the history
Signed-off-by: Tim Schmidt <tim@launchbadge.com>
  • Loading branch information
Sheng-Long committed Oct 16, 2023
1 parent 74ecdbe commit e058663
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 2 deletions.
123 changes: 123 additions & 0 deletions src/components/account/NftsTable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<!--
-
- Hedera Mirror Node Explorer
-
- Copyright (C) 2021 - 2023 Hedera Hashgraph, LLC
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-->

<!-- --------------------------------------------------------------------------------------------------------------- -->
<!-- TEMPLATE -->
<!-- --------------------------------------------------------------------------------------------------------------- -->

<template>

<o-table
:data="nfts"
:hoverable="true"
:paginated="!isTouchDevice"
:per-page="isMediumScreen ? pageSize : 5"
:striped="true"
:v-model:current-page="currentPage"
:mobile-breakpoint="ORUGA_MOBILE_BREAKPOINT"
aria-current-label="Current page"
aria-next-label="Next page"
aria-page-label="Page"
aria-previous-label="Previous page"
@cell-click="handleClick"
>
<o-table-column v-slot="props" field="token_id" label="Token">
<TokenLink
v-bind:show-extra="true"
v-bind:token-id="props.row.token_id"
v-bind:no-anchor="true"
/>
</o-table-column>

<o-table-column v-slot="props" field="serial" label="Serial Number" position="right">
{{props.row.serial_number}}
</o-table-column>

</o-table>

<EmptyTable v-if="!nfts.length"/>

</template>

<!-- --------------------------------------------------------------------------------------------------------------- -->
<!-- SCRIPT -->
<!-- --------------------------------------------------------------------------------------------------------------- -->

<script lang="ts">
import {defineComponent, inject, PropType, ref} from 'vue';
import { Nft, TokenBalance } from "@/schemas/HederaSchemas";
import TokenLink from "@/components/values/TokenLink.vue";
import TokenAmount from "@/components/values/TokenAmount.vue";
import {ORUGA_MOBILE_BREAKPOINT} from '@/App.vue';
import EmptyTable from "@/components/EmptyTable.vue";
import {routeManager} from "@/router";
export default defineComponent({
name: 'NftsTable',
components: {
EmptyTable,
TokenLink,
// TokenAmount
},
props: {
nfts: {
type: Array as PropType<Array<Nft>>,
default: () => []
},
nbItems: Number,
},
setup(props) {
const isTouchDevice = inject('isTouchDevice', false)
const isMediumScreen = inject('isMediumScreen', true)
const DEFAULT_PAGE_SIZE = 15
const pageSize = props.nbItems ?? DEFAULT_PAGE_SIZE
const handleClick = (nft: Nft, c: unknown, i: number, ci: number, event: MouseEvent) => {
if (nft.token_id && nft.serial_number) {
routeManager.routeToSerial(nft.token_id, nft.serial_number, event.ctrlKey || event.metaKey)
}
}
let currentPage = ref(1)
return {
isTouchDevice,
isMediumScreen,
pageSize,
handleClick,
currentPage,
ORUGA_MOBILE_BREAKPOINT
}
}
});
</script>

<!-- --------------------------------------------------------------------------------------------------------------- -->
<!-- STYLE -->
<!-- --------------------------------------------------------------------------------------------------------------- -->

<style scoped>
</style>
32 changes: 30 additions & 2 deletions src/pages/AccountBalances.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@
</template>
</DashboardCard>

<DashboardCard>
<template v-slot:title>
<span class="h-is-primary-title">NFTs owned by </span>
<span class="h-is-secondary-text">{{ accountId }}</span>
</template>
<template v-slot:content>
<NftsTable v-bind:nfts="nfts"/>
</template>
</DashboardCard>

</section>

<Footer/>
Expand All @@ -53,12 +63,15 @@ import BalanceTable from "@/components/account/BalanceTable.vue";
import DashboardCard from "@/components/DashboardCard.vue";
import Footer from "@/components/Footer.vue";
import {BalanceCache} from "@/utils/cache/BalanceCache";
import { NftByAccountCache } from "@/utils/cache/NftByAccountCache";
import NftsTable from "@/components/account/NftsTable.vue";
export default defineComponent({
name: 'AccountBalances',
components: {
NftsTable,
Footer,
DashboardCard,
BalanceTable
Expand All @@ -77,18 +90,33 @@ export default defineComponent({
// balanceLookup
//
const balanceLookup = BalanceCache.instance.makeLookup(computed(() => props.accountId ?? null))
onMounted(() => balanceLookup.mount())
onBeforeUnmount(() => balanceLookup.unmount())
const nftsLookup = NftByAccountCache.instance.makeLookup(computed(() => props.accountId ?? null))
onMounted(() => {
balanceLookup.mount()
nftsLookup.mount()
})
onBeforeUnmount(() => {
balanceLookup.unmount()
nftsLookup.mount()
})
const tokenBalances = computed(() => {
const allBalances = balanceLookup.entity.value?.balances
return allBalances && allBalances.length >= 1 ? allBalances[0].tokens : []
})
const nfts = computed(() => {
const allNfts = nftsLookup.entity.value?.nfts
return allNfts
})
console.log(nfts)
return {
isSmallScreen,
isTouchDevice,
tokenBalances,
nfts
}
}
});
Expand Down
50 changes: 50 additions & 0 deletions src/utils/cache/NftByAccountCache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*-
*
* Hedera Mirror Node Explorer
*
* Copyright (C) 2021 - 2022 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

import { Nft, Nfts } from "@/schemas/HederaSchemas";
import axios from "axios"
import {SerialCache} from "./base/SerialCache"
import {Ref, ref} from "vue"
import {Lookup} from "./base/EntityCache"

export class NftByAccountCache extends SerialCache<string, Nfts | null> {
public static readonly instance = new NftByAccountCache()

//
// Cache
//

protected async load(accountId: string): Promise<Nfts | null> {
let result: Promise<Nfts | null>
try {
const response = await axios.get<Nfts>(
`api/v1/accounts/${accountId}/nfts`,
)
result = Promise.resolve(response.data)
} catch (error) {
if (axios.isAxiosError(error) && error.response?.status == 404) {
result = Promise.resolve(null)
} else {
throw error
}
}
return result
}
}

0 comments on commit e058663

Please sign in to comment.