89 lines
2.3 KiB
Svelte
89 lines
2.3 KiB
Svelte
<script lang="ts">
|
|
import {onMount} from "svelte"
|
|
import {sortBy} from "@welshman/lib"
|
|
import {getListTags, getEventTagValues} from "@welshman/util"
|
|
import type {TrustedEvent} from "@welshman/util"
|
|
import {derivePinList, repository} from "@welshman/app"
|
|
import {Router} from "@welshman/router"
|
|
import {load} from "@welshman/net"
|
|
import {fly} from "@lib/transition"
|
|
import Spinner from "@lib/components/Spinner.svelte"
|
|
import NoteItem from "@app/components/NoteItem.svelte"
|
|
|
|
type Props = {
|
|
pubkey: string
|
|
limit?: number
|
|
onViewAll?: () => void
|
|
editable?: boolean
|
|
}
|
|
|
|
const {pubkey, limit, onViewAll, editable = false}: Props = $props()
|
|
|
|
const pinList = derivePinList(pubkey)
|
|
const pinnedIds = $derived(getEventTagValues(getListTags($pinList)))
|
|
const displayIds = $derived(limit ? pinnedIds.slice(0, limit) : pinnedIds)
|
|
|
|
const pinnedEvents = $derived.by(() => {
|
|
return sortBy(
|
|
e => -pinnedIds.indexOf(e.id),
|
|
displayIds
|
|
.map(id => repository.getEvent(id))
|
|
.filter((event): event is TrustedEvent => Boolean(event)),
|
|
)
|
|
})
|
|
|
|
let loading = $state(pinnedIds.length > 0)
|
|
|
|
onMount(() => {
|
|
if (pinnedIds.length === 0) {
|
|
loading = false
|
|
|
|
return
|
|
}
|
|
|
|
const missing = pinnedIds.filter(id => !repository.getEvent(id))
|
|
|
|
if (missing.length === 0) {
|
|
loading = false
|
|
|
|
return
|
|
}
|
|
|
|
load({
|
|
relays: Router.get().FromPubkeys([pubkey]).getUrls(),
|
|
filters: [{ids: missing}],
|
|
onEvent: () => {
|
|
loading = !pinnedIds.every(id => repository.getEvent(id))
|
|
},
|
|
onClose: () => {
|
|
loading = false
|
|
},
|
|
})
|
|
})
|
|
</script>
|
|
|
|
{#if pinnedIds.length > 0}
|
|
<div class="col-4 border-t border-base-300 pt-4">
|
|
<strong>Pinned notes</strong>
|
|
{#if loading && pinnedEvents.length === 0}
|
|
<p class="center flex py-8">
|
|
<Spinner loading />
|
|
</p>
|
|
{:else}
|
|
<div class="col-2">
|
|
{#each pinnedEvents as event (event.id)}
|
|
<div in:fly>
|
|
<NoteItem {event} {editable} />
|
|
</div>
|
|
{/each}
|
|
</div>
|
|
{#if onViewAll && pinnedIds.length > (limit || pinnedIds.length)}
|
|
<button class="link link-primary row-2 text-sm" onclick={onViewAll}>
|
|
View all pinned notes
|
|
<span aria-hidden="true">→</span>
|
|
</button>
|
|
{/if}
|
|
{/if}
|
|
</div>
|
|
{/if}
|