fix: stabilize list loading and show correct list count
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
<script lang="ts">
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import {displayPubkey} from "@welshman/util"
|
||||
import {formatTimestamp} from "@welshman/lib"
|
||||
import {displayProfileByPubkey} from "@welshman/app"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import ProfileCircle from "@app/components/ProfileCircle.svelte"
|
||||
import NoteContentMinimal from "@app/components/NoteContentMinimal.svelte"
|
||||
import ContentLinkBlockImage from "@app/components/ContentLinkBlockImage.svelte"
|
||||
import MenuDots from "@assets/icons/menu-dots.svg?dataurl"
|
||||
|
||||
type BookmarkItem = {
|
||||
key: string
|
||||
event: TrustedEvent
|
||||
href: string
|
||||
external: boolean
|
||||
image: string | undefined
|
||||
video: string | undefined
|
||||
contentType: "image" | "video" | "text"
|
||||
preview: string
|
||||
pollOptions: string[]
|
||||
searchable: string
|
||||
}
|
||||
|
||||
type Props = {
|
||||
item: BookmarkItem
|
||||
showAddToSaved: boolean
|
||||
onOpen: (item: BookmarkItem) => Promise<void> | void
|
||||
onCopyLink: (item: BookmarkItem) => Promise<void> | void
|
||||
onAddToSaved: (item: BookmarkItem) => Promise<void> | void
|
||||
onRemove: (item: BookmarkItem) => Promise<void> | void
|
||||
}
|
||||
|
||||
const {item, showAddToSaved, onOpen, onCopyLink, onAddToSaved, onRemove}: Props = $props()
|
||||
|
||||
let openMenu = $state(false)
|
||||
|
||||
const closeMenu = () => {
|
||||
openMenu = false
|
||||
}
|
||||
|
||||
const toggleMenu = (event: Event) => {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
openMenu = !openMenu
|
||||
}
|
||||
|
||||
const openItem = async (event: Event) => {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
closeMenu()
|
||||
await onOpen(item)
|
||||
}
|
||||
|
||||
const copyLink = async (event: Event) => {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
closeMenu()
|
||||
await onCopyLink(item)
|
||||
}
|
||||
|
||||
const addToSaved = async (event: Event) => {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
closeMenu()
|
||||
await onAddToSaved(item)
|
||||
}
|
||||
|
||||
const removeFromList = async (event: Event) => {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
closeMenu()
|
||||
await onRemove(item)
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window onclick={closeMenu} />
|
||||
|
||||
<Link
|
||||
href={item.href}
|
||||
external={item.external}
|
||||
class="card2 bg-alt col-2 w-full gap-3 p-3 transition-colors hover:bg-base-100 md:w-[calc(50%-0.375rem)] xl:w-[calc(33.333%-0.5rem)]">
|
||||
<div class="flex items-start justify-between gap-2">
|
||||
<div class="flex min-w-0 items-center gap-2">
|
||||
<ProfileCircle pubkey={item.event.pubkey} size={5} />
|
||||
<div class="min-w-0">
|
||||
<p class="truncate text-sm font-semibold text-primary">
|
||||
{displayProfileByPubkey(item.event.pubkey)}
|
||||
</p>
|
||||
<p class="truncate text-[11px] opacity-60">
|
||||
{displayPubkey(item.event.pubkey)} · {formatTimestamp(item.event.created_at)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative" role="presentation">
|
||||
<Button class="btn btn-ghost btn-xs btn-square" onclick={toggleMenu}>
|
||||
<Icon size={4} icon={MenuDots} />
|
||||
</Button>
|
||||
|
||||
{#if openMenu}
|
||||
<ul
|
||||
class="menu absolute right-0 top-7 z-popover w-44 rounded-box bg-base-100 p-2 shadow-xl"
|
||||
role="menu">
|
||||
<li>
|
||||
<Button class="justify-start" onclick={openItem}>Open bookmark</Button>
|
||||
</li>
|
||||
<li>
|
||||
<Button class="justify-start" onclick={copyLink}>Copy link</Button>
|
||||
</li>
|
||||
{#if showAddToSaved}
|
||||
<li>
|
||||
<Button class="justify-start" onclick={addToSaved}>Add to Saved Items</Button>
|
||||
</li>
|
||||
{/if}
|
||||
<li>
|
||||
<Button class="justify-start text-error" onclick={removeFromList}
|
||||
>Remove from this list</Button>
|
||||
</li>
|
||||
</ul>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if item.image}
|
||||
<ContentLinkBlockImage
|
||||
value={{url: item.image}}
|
||||
event={item.event}
|
||||
class="max-h-[28rem] w-full rounded-lg object-contain" />
|
||||
{:else if item.video}
|
||||
<video
|
||||
src={item.video}
|
||||
class="max-h-[28rem] w-full rounded-lg object-contain"
|
||||
muted
|
||||
playsinline
|
||||
preload="metadata"></video>
|
||||
{/if}
|
||||
|
||||
<NoteContentMinimal event={item.event} />
|
||||
</Link>
|
||||
Reference in New Issue
Block a user