upend/ui/src/components/Address.vue

101 lines
2.2 KiB
Vue

<template>
<div :class="['address', { identified: Boolean(inferredIds) }]" 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 } }">
{{ inferredIds.join(" | ") || address }}
</router-link>
<template v-else>
{{ inferredIds.join(" | ") || address }}
</template>
</template>
</div>
</template>
<script lang="ts">
import { identify, useEntity } from "@/lib/entity";
import { IEntry } from "@/types/base";
import {
computed,
ComputedRef,
defineComponent,
onMounted,
reactive,
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) {
// Enable IntersectionObserver for performance reasons
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);
}
});
// Identification
const { attributes } = useEntity(props.address, () => visible.value);
const inferredEntries = identify(attributes);
const inferredIds: ComputedRef<string[]> = computed(() => {
return inferredEntries.value.map((eid) => eid.value);
});
return {
root: rootEl,
inferredIds,
};
},
});
</script>
<style scoped>
.address {
font-family: var(--monospace-font);
display: flex;
align-items: center;
}
.address {
line-break: anywhere;
}
.address.identified {
font-family: var(--default-font);
font-size: 0.95em;
line-break: auto;
}
.hash-badge {
margin-right: 0.5em;
}
</style>