upend/ui/src/components/Address.svelte

95 lines
2.1 KiB
Svelte

<script lang="ts">
import { createEventDispatcher } from "svelte";
import { BLOB_TYPE_ADDR } from "upend/constants";
import { identify, useEntity } from "../lib/entity";
import HashBadge from "./HashBadge.svelte";
import Marquee from "./Marquee.svelte";
import UpLink from "./UpLink.svelte";
const dispatch = createEventDispatcher();
export let address: string;
export let link = false;
export let resolve = true;
export let banner = false;
let resolving = resolve;
const { attributes, backlinks } = useEntity(address, () => resolve);
// isFile
$: isFile = $attributes.some(
([_, attr]) => attr.attribute === "IS" && attr.value.c === BLOB_TYPE_ADDR
);
// Identification
let inferredIds: string[] = [];
$: {
if (resolve) {
resolving = true;
identify($attributes, $backlinks).then((inferredEntries) => {
inferredIds = inferredEntries.map((eid) => eid.value);
resolving = false;
});
}
}
$: label = inferredIds.join(" | ") || address;
$: dispatch("resolved", inferredIds);
</script>
<div class="address" class:identified={Boolean(inferredIds)} class:banner>
<HashBadge {address} />
<div class="separator" />
<Marquee>
<div class="label" class:resolving title={label}>
{#if banner && isFile}
<a href="/api/raw/{address}" target="_blank">
{label}
</a>
{:else if link}
<UpLink to={{ entity: address }}>
{label}
</UpLink>
{:else}
{label}
{/if}
</div>
</Marquee>
</div>
<style scoped lang="scss">
.address {
display: flex;
align-items: center;
padding: 0.1em;
font-family: var(--monospace-font);
line-break: anywhere;
background: var(--background-emph);
border: 0.1em solid var(--foreground-lighter);
border-radius: 0.2em;
&.banner {
border: 0.12em solid var(--foreground);
padding: 0.5em 0.25em;
}
&.identified {
font-family: var(--default-font);
font-size: 0.95em;
line-break: auto;
}
}
.separator {
width: 0.5em;
}
.resolving {
opacity: 0.7;
}
</style>