upend/ui/src/components/Address.vue

108 lines
2.7 KiB
Vue

<template>
<div :class="['address', { identified: Boolean(inferredId) }]" ref="root">
<hash-badge :address="address" class="hash-badge" />
<router-link v-if="isFile" :to="{ name: 'file', params: { address } }">
{{ address }}
</router-link>
<template v-else>
<router-link v-if="link" :to="{ name: 'inspect', params: { address } }">
{{ inferredId || address }}
</router-link>
<template v-else>{{ inferredId || address }}</template>
</template>
</div>
</template>
<script lang="ts">
import { ListingResult } from "@/types/base";
import { fetcher } from "@/utils";
import useSWRV from "swrv";
import { computed, defineComponent, onMounted, ref } from "vue";
import HashBadge from "./HashBadge.vue";
export default defineComponent({
components: { HashBadge },
name: "Address",
props: {
address: {
type: String,
required: true,
},
link: {
type: Boolean,
default: false,
},
isFile: {
type: Boolean,
default: false,
},
resolve: {
type: Boolean,
default: true,
},
},
setup(props) {
const rootEl = ref<HTMLElement | undefined>();
const visible = ref(false);
const observer = new IntersectionObserver((entries) => {
visible.value = entries.some((entry) => entry.isIntersecting);
});
onMounted(() => {
if (rootEl.value) {
observer.observe(rootEl.value);
}
});
const { data: addressEntries } = useSWRV<ListingResult, unknown>(
() => (visible.value && `/api/obj/${props.address}`) || null,
fetcher
);
const { data: typeId } = useSWRV<ListingResult, unknown>(() => {
if (!props.isFile && props.resolve) {
const entries = Object.values(addressEntries?.value || {});
const isEntry = entries.find(
(entry) => entry.entity === props.address && entry.attribute === "IS"
);
if (isEntry) {
return `/api/obj?query=(matches "${isEntry.value.c}" "TYPE_ID" ?)`;
}
}
return null;
}, fetcher);
const inferredId = computed(() => {
const typeIdValue = Object.values(typeId?.value || {})[0];
if (typeIdValue) {
return Object.values(addressEntries?.value || []).find(
(entry) =>
entry.entity === props.address &&
entry.attribute === typeIdValue.value.c
)?.value.c;
}
});
return {
root: rootEl,
inferredId,
};
},
});
</script>
<style scoped>
.address {
font-family: var(--monospace-font);
display: flex;
}
.address.identified {
font-family: var(--default-font);
font-size: 0.95em;
}
.hash-badge {
margin-right: 0.5em;
}
</style>