Skip to content

Commit

Permalink
feat: add nft details
Browse files Browse the repository at this point in the history
Signed-off-by: Tim Schmidt <tim@launchbadge.com>

fix: reformat

Signed-off-by: Tim Schmidt <tim@launchbadge.com>

fix: nftdetails page organization, fix filter, probably broke pause/play

Signed-off-by: Tim Schmidt <tim@launchbadge.com>

fix: fix the play/pause button

Signed-off-by: Tim Schmidt <tim@launchbadge.com>

feat: fix filter options, don't display none values, make ipfs metadata a link

Signed-off-by: Tim Schmidt <tim@launchbadge.com>

feat: add decoded url links, fix test

Signed-off-by: Tim Schmidt <tim@launchbadge.com>

feat: add nft list and links from balances

Signed-off-by: Tim Schmidt <tim@launchbadge.com>
  • Loading branch information
Sheng-Long committed Oct 16, 2023
1 parent 3530b2c commit feae6a6
Show file tree
Hide file tree
Showing 16 changed files with 1,219 additions and 1,386 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>
30 changes: 20 additions & 10 deletions src/components/token/NftHolderTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,13 @@
v-model:current-page="currentPage"
:per-page="perPage"
@page-change="onPageChange"
@cell-click="handleClick"

@cell-click="handleClick"
:hoverable="true"
:narrowed="true"
:striped="true"
:mobile-breakpoint="ORUGA_MOBILE_BREAKPOINT"

style="cursor: pointer"

aria-current-label="Current page"
aria-next-label="Next page"
aria-page-label="Page"
Expand All @@ -56,7 +54,7 @@
</o-table-column>

<o-table-column v-slot="props" field="account_id" label="Account ID">
<AccountLink v-bind:account-id="props.row.account_id"/>
<AccountLink v-bind:account-id="props.row.account_id" no-anchor/>
</o-table-column>

<o-table-column v-slot="props" field="deleted" label="Deleted">
Expand Down Expand Up @@ -93,7 +91,7 @@ import BlobValue from "@/components/values/BlobValue.vue";
import {ORUGA_MOBILE_BREAKPOINT} from '@/App.vue';
import EmptyTable from "@/components/EmptyTable.vue";
import {NftHolderTableController} from "@/components/token/NftHolderTableController";
import {routeManager} from "@/router";
import { routeManager } from "@/router";
export default defineComponent({
name: 'NftHolderTable',
Expand All @@ -111,11 +109,21 @@ export default defineComponent({
const isTouchDevice = inject('isTouchDevice', false)
const isMediumScreen = inject('isMediumScreen', true)
const handleClick = (n: Nft, c: unknown, i: number, ci: number, event: MouseEvent) => {
const handleClick = (
n: Nft,
c: unknown,
i: number,
ci: number,
event: MouseEvent,
) => {
if (n.token_id && n.serial_number) {
routeManager.routeToSerial(n.token_id, n.serial_number, event.ctrlKey || event.metaKey)
routeManager.routeToSerial(
n.token_id,
n.serial_number,
event.ctrlKey || event.metaKey,
);
}
}
};
return {
isTouchDevice,
Expand All @@ -127,13 +135,15 @@ export default defineComponent({
onPageChange: props.controller.onPageChange,
perPage: props.controller.pageSize as Ref<number>,
ORUGA_MOBILE_BREAKPOINT,
handleClick
handleClick,
}
}
});
</script>

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

<style/>
64 changes: 32 additions & 32 deletions src/components/transaction/NftTransactionAnalyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,78 +18,78 @@
*
*/

import { computed, ComputedRef, ref, Ref, watch, WatchStopHandle } from "vue";
import {computed, ComputedRef, ref, Ref, watch, WatchStopHandle} from "vue"
import {
NftTransactionTransfer,
TokenRelationship,
TransactionType,
} from "@/schemas/HederaSchemas";
import { EntityDescriptor } from "@/utils/EntityDescriptor";
import { normalizeTransactionId } from "@/utils/TransactionID";
import { TokenRelationshipCache } from "@/utils/cache/TokenRelationshipCache";
} from "@/schemas/HederaSchemas"
import {EntityDescriptor} from "@/utils/EntityDescriptor"
import {normalizeTransactionId} from "@/utils/TransactionID"
import {TokenRelationshipCache} from "@/utils/cache/TokenRelationshipCache"

export class NftTransactionAnalyzer {
public readonly transaction: Ref<NftTransactionTransfer | null>;
public readonly transaction: Ref<NftTransactionTransfer | null>
public readonly entityDescriptor = ref(
EntityDescriptor.DEFAULT_ENTITY_DESCRIPTOR,
);
public readonly tokenRelationships: Ref<TokenRelationship[]> = ref([]);
private readonly watchHandles: WatchStopHandle[] = [];
)
public readonly tokenRelationships: Ref<TokenRelationship[]> = ref([])
private readonly watchHandles: WatchStopHandle[] = []

//
// Public
//

public constructor(transaction: Ref<NftTransactionTransfer | null>) {
this.transaction = transaction;
this.transaction = transaction
}

public mount(): void {
this.watchHandles.push(
watch(this.transaction, this.transactionDidChange, {
immediate: true,
}),
);
)
}

public unmount(): void {
this.watchHandles.map((wh) => wh());
this.watchHandles.splice(0);
this.watchHandles.map((wh) => wh())
this.watchHandles.splice(0)
}

public readonly consensusTimestamp = computed(
() => this.transaction.value?.consensus_timestamp ?? null,
);
)

public readonly transactionType = computed(
() => this.transaction.value?.type ?? null,
);
)

public readonly entityId = computed(
() => this.transaction.value?.sender_account_id ?? null,
);
)

public readonly formattedTransactionId: ComputedRef<string | null> =
computed(() => {
const transaction_id = this.transaction.value?.transaction_id;
const transaction_id = this.transaction.value?.transaction_id
return transaction_id
? normalizeTransactionId(transaction_id, true)
: null;
});
: null
})

public readonly isTokenAssociation = computed(
() => this.transactionType.value === TransactionType.TOKENASSOCIATE,
);
)

public readonly tokens = computed(() => {
const result: string[] = [];
const result: string[] = []
for (const r of this.tokenRelationships.value) {
if (r.token_id) {
result.push(r.token_id);
result.push(r.token_id)
}
}
return result;
});
return result
})

//
// Private
Expand All @@ -104,29 +104,29 @@ export class NftTransactionAnalyzer {
) {
const r = await TokenRelationshipCache.instance.lookup(
this.entityId.value,
);
)
this.tokenRelationships.value = this.filterTokenRelationships(
r ?? [],
this.consensusTimestamp.value,
);
)
} else {
this.tokenRelationships.value = [];
this.tokenRelationships.value = []
}
} else {
this.tokenRelationships.value = [];
this.tokenRelationships.value = []
}
};
}

private filterTokenRelationships(
relationships: TokenRelationship[],
createdTimestamp: string,
): TokenRelationship[] {
const result: TokenRelationship[] = [];
const result: TokenRelationship[] = []
for (const r of relationships) {
if (r.created_timestamp === createdTimestamp && r.token_id) {
result.push(r);
result.push(r)
}
}
return result;
return result
}
}
Loading

0 comments on commit feae6a6

Please sign in to comment.