2022-02-02 19:17:30 +01:00
|
|
|
<script lang="ts">
|
2022-08-01 21:08:34 +02:00
|
|
|
import { readable, type Readable } from "svelte/store";
|
2022-09-04 23:29:41 +02:00
|
|
|
import type { UpListing } from "upend";
|
|
|
|
import type { Address } from "upend/types";
|
2022-02-15 22:05:51 +01:00
|
|
|
import { query } from "../../lib/entity";
|
2022-03-18 21:27:24 +01:00
|
|
|
import BlobPreview from "../display/BlobPreview.svelte";
|
|
|
|
import UpLink from "../display/UpLink.svelte";
|
|
|
|
import UpObject from "../display/UpObject.svelte";
|
2022-02-02 19:17:30 +01:00
|
|
|
|
2022-09-04 23:29:41 +02:00
|
|
|
export let entities: Address[];
|
|
|
|
export let thumbnails = true;
|
|
|
|
export let sort = true;
|
|
|
|
|
2022-09-05 00:04:44 +02:00
|
|
|
const deduplicatedEntities = Array.from(new Set(entities));
|
|
|
|
|
2022-09-04 23:29:41 +02:00
|
|
|
let style: "list" | "grid" | "flex" = "grid";
|
|
|
|
|
|
|
|
let clientWidth: number;
|
2022-09-05 00:04:44 +02:00
|
|
|
$: style = !thumbnails || clientWidth < 600 ? "list" : "grid";
|
2022-02-02 19:17:30 +01:00
|
|
|
|
|
|
|
// Sorting
|
2022-12-18 14:08:27 +01:00
|
|
|
let sortedEntities = [];
|
2022-12-17 19:07:31 +01:00
|
|
|
let resort = false;
|
2022-02-02 19:17:30 +01:00
|
|
|
|
|
|
|
let sortKeys: { [key: string]: string[] } = {};
|
2022-12-17 19:07:31 +01:00
|
|
|
function addSortKeys(key: string, vals: string[]) {
|
2022-02-02 19:17:30 +01:00
|
|
|
if (!sortKeys[key]) {
|
|
|
|
sortKeys[key] = [];
|
|
|
|
}
|
|
|
|
let changed = false;
|
|
|
|
vals.forEach((val) => {
|
|
|
|
if (!sortKeys[key].includes(val)) {
|
|
|
|
changed = true;
|
|
|
|
sortKeys[key].push(val);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2022-12-22 13:15:20 +01:00
|
|
|
if (resort && changed) sortEntities();
|
2022-02-02 19:17:30 +01:00
|
|
|
}
|
|
|
|
|
2022-02-09 20:40:59 +01:00
|
|
|
// Labelling
|
|
|
|
let labelListing: Readable<UpListing> = readable(undefined);
|
|
|
|
$: {
|
|
|
|
const addresses = [];
|
2022-09-05 00:04:44 +02:00
|
|
|
deduplicatedEntities.forEach((addr) => {
|
2022-09-04 23:29:41 +02:00
|
|
|
if (!addresses.includes(addr)) {
|
|
|
|
addresses.push(addr);
|
|
|
|
}
|
|
|
|
});
|
2022-02-09 20:40:59 +01:00
|
|
|
|
2022-03-30 10:20:27 +02:00
|
|
|
const addressesString = addresses.map((addr) => `@${addr}`).join(" ");
|
2022-02-09 20:40:59 +01:00
|
|
|
|
|
|
|
labelListing = query(`(matches (in ${addressesString}) "LBL" ? )`).result;
|
|
|
|
}
|
|
|
|
|
2022-12-22 13:15:20 +01:00
|
|
|
function sortEntities() {
|
2022-09-04 23:29:41 +02:00
|
|
|
if (!sort) return;
|
|
|
|
|
2022-09-05 00:04:44 +02:00
|
|
|
sortedEntities = deduplicatedEntities.concat();
|
2022-09-04 23:29:41 +02:00
|
|
|
|
|
|
|
sortedEntities.sort((a, b) => {
|
|
|
|
if (!sortKeys[a]?.length || !sortKeys[b]?.length) {
|
|
|
|
if (Boolean(sortKeys[a]?.length) && !sortKeys[b]?.length) {
|
|
|
|
return -1;
|
|
|
|
} else if (!sortKeys[a]?.length && Boolean(sortKeys[b]?.length)) {
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return a.localeCompare(b);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return sortKeys[a][0].localeCompare(sortKeys[b][0], undefined, {
|
|
|
|
numeric: true,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2022-02-02 19:17:30 +01:00
|
|
|
}
|
|
|
|
|
2022-02-09 20:40:59 +01:00
|
|
|
$: {
|
|
|
|
if ($labelListing) {
|
2022-09-05 00:04:44 +02:00
|
|
|
deduplicatedEntities.forEach((address) => {
|
2022-09-04 23:29:41 +02:00
|
|
|
addSortKeys(address, $labelListing.getObject(address).identify());
|
2022-02-09 20:40:59 +01:00
|
|
|
});
|
2022-12-22 13:15:20 +01:00
|
|
|
sortEntities();
|
2022-12-17 19:07:31 +01:00
|
|
|
resort = true;
|
2022-02-09 20:40:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-18 14:08:27 +01:00
|
|
|
if (!sort) {
|
2022-12-22 13:15:20 +01:00
|
|
|
sortedEntities = entities;
|
2022-12-18 14:08:27 +01:00
|
|
|
}
|
2022-02-02 19:17:30 +01:00
|
|
|
</script>
|
|
|
|
|
2022-09-04 23:29:41 +02:00
|
|
|
<div
|
|
|
|
class="gallery style-{style}"
|
|
|
|
class:has-thumbnails={thumbnails}
|
|
|
|
bind:clientWidth
|
|
|
|
>
|
|
|
|
<div class="header" />
|
|
|
|
<div class="items">
|
|
|
|
{#each sortedEntities as entity (entity)}
|
|
|
|
{#if thumbnails}
|
|
|
|
<div class="thumbnail">
|
2022-10-21 17:59:57 +02:00
|
|
|
<UpLink to={{ entity }} passthrough>
|
2022-09-04 23:29:41 +02:00
|
|
|
<BlobPreview address={entity} />
|
|
|
|
<div class="label">
|
|
|
|
<UpObject
|
|
|
|
address={entity}
|
2022-12-31 11:15:52 +01:00
|
|
|
labels={sortKeys[entity]}
|
2022-09-04 23:29:41 +02:00
|
|
|
on:resolved={(event) => {
|
|
|
|
addSortKeys(entity, event.detail);
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</UpLink>
|
2022-03-18 21:27:24 +01:00
|
|
|
</div>
|
2022-09-04 23:29:41 +02:00
|
|
|
{:else}
|
2022-12-31 11:15:52 +01:00
|
|
|
<UpObject link address={entity} labels={sortKeys[entity]} />
|
2022-09-04 23:29:41 +02:00
|
|
|
{/if}
|
|
|
|
{/each}
|
|
|
|
</div>
|
2022-02-02 19:17:30 +01:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<style lang="scss">
|
2022-03-18 21:27:24 +01:00
|
|
|
.thumbnail {
|
2022-09-04 23:29:41 +02:00
|
|
|
border: 1px solid var(--foreground-lighter);
|
2022-03-18 21:27:24 +01:00
|
|
|
border-radius: 4px;
|
2022-03-22 20:38:14 +01:00
|
|
|
padding: 0.25em;
|
2022-10-21 17:59:57 +02:00
|
|
|
max-height: 420px;
|
2022-10-21 18:49:08 +02:00
|
|
|
overflow: hidden;
|
2022-03-18 21:27:24 +01:00
|
|
|
}
|
|
|
|
|
2022-09-04 23:29:41 +02:00
|
|
|
.items {
|
|
|
|
gap: 4px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.gallery.has-thumbnails .items {
|
2022-02-02 19:17:30 +01:00
|
|
|
gap: 1rem;
|
2022-09-04 23:29:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
:global(.gallery.style-grid .items) {
|
|
|
|
display: grid;
|
|
|
|
grid-template-columns: repeat(4, 1fr);
|
2022-10-21 17:59:57 +02:00
|
|
|
|
|
|
|
.thumbnail {
|
|
|
|
height: 256px;
|
|
|
|
}
|
2022-09-04 23:29:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
:global(.gallery.style-flex .items) {
|
|
|
|
display: flex;
|
2022-02-02 19:17:30 +01:00
|
|
|
flex-wrap: wrap;
|
2022-03-22 20:38:14 +01:00
|
|
|
align-items: flex-end;
|
2022-02-02 19:17:30 +01:00
|
|
|
}
|
|
|
|
|
2022-09-04 23:29:41 +02:00
|
|
|
:global(.gallery.style-list .items) {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
align-items: stretch;
|
|
|
|
}
|
|
|
|
|
2022-02-02 19:17:30 +01:00
|
|
|
.thumbnail {
|
2022-09-04 23:29:41 +02:00
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
justify-content: flex-end;
|
2022-02-02 19:17:30 +01:00
|
|
|
}
|
|
|
|
</style>
|