2026-06-17 16:08:58 +00:00
|
|
|
<script lang="ts">
|
2026-07-28 16:16:26 +00:00
|
|
|
import {goto} from "$app/navigation"
|
2026-08-29 16:48:04 +00:00
|
|
|
import {derived} from "svelte/store"
|
|
|
|
|
import {filter, formatTimestamp, max, spec} from "@welshman/lib"
|
2026-06-17 16:08:58 +00:00
|
|
|
import type {TrustedEvent} from "@welshman/util"
|
2026-08-29 16:48:04 +00:00
|
|
|
import {COMMENT, tagSpec, tagValue} from "@welshman/util"
|
2026-08-17 15:55:54 +00:00
|
|
|
import {fade} from "@lib/transition"
|
2026-08-17 16:21:30 +00:00
|
|
|
import Link from "@lib/components/Link.svelte"
|
2026-06-17 16:08:58 +00:00
|
|
|
import ProfileCircle from "@app/components/ProfileCircle.svelte"
|
|
|
|
|
import ProfileName from "@app/components/ProfileName.svelte"
|
2026-08-29 16:48:04 +00:00
|
|
|
import type {FeedContext} from "@app/feeds"
|
2026-08-17 15:55:54 +00:00
|
|
|
import {notifications} from "@app/notifications"
|
2026-06-17 16:08:58 +00:00
|
|
|
import {makeThreadPath} from "@app/routes"
|
|
|
|
|
|
|
|
|
|
type Props = {
|
|
|
|
|
url: string
|
|
|
|
|
event: TrustedEvent
|
2026-08-29 16:48:04 +00:00
|
|
|
context: FeedContext
|
2026-07-15 21:23:43 +00:00
|
|
|
mobile?: boolean
|
2026-06-17 16:08:58 +00:00
|
|
|
}
|
|
|
|
|
|
2026-08-29 16:48:04 +00:00
|
|
|
const {url, event, context, mobile = false}: Props = $props()
|
2026-06-17 16:08:58 +00:00
|
|
|
|
2026-08-29 16:48:04 +00:00
|
|
|
const related = context.related(event)
|
|
|
|
|
const replies = derived(related, $related => filter(spec({kind: COMMENT}), $related))
|
2026-06-17 16:08:58 +00:00
|
|
|
const replyCount = $derived($replies.length)
|
|
|
|
|
const lastActive = $derived(max([...$replies, event].map(e => e.created_at)))
|
2026-07-28 16:16:26 +00:00
|
|
|
const title = tagValue(tagSpec("title"), event.tags)
|
2026-06-24 18:19:13 +00:00
|
|
|
const path = makeThreadPath(url, event.id)
|
2026-08-17 15:55:54 +00:00
|
|
|
const onClick = () => goto(path)
|
|
|
|
|
// notification={$notifications.has(path)}
|
2026-06-17 16:08:58 +00:00
|
|
|
</script>
|
|
|
|
|
|
2026-07-15 21:23:43 +00:00
|
|
|
{#if mobile}
|
2026-08-17 15:55:54 +00:00
|
|
|
<Link
|
|
|
|
|
href={path}
|
|
|
|
|
class="hover:bg-surface-less flex w-full flex-col gap-2 border-b border-solid border-line px-4 py-3 text-left text-sm transition-colors">
|
2026-07-15 21:23:43 +00:00
|
|
|
<p class="truncate font-medium">{title || "Untitled thread"}</p>
|
|
|
|
|
<div class="text-content-muted flex flex-wrap items-center gap-x-3 gap-y-1 text-xs">
|
|
|
|
|
<span class="flex min-w-0 items-center gap-1.5">
|
|
|
|
|
<ProfileCircle pubkey={event.pubkey} {url} size={4} />
|
|
|
|
|
<span class="truncate">
|
|
|
|
|
<ProfileName pubkey={event.pubkey} {url} />
|
|
|
|
|
</span>
|
|
|
|
|
</span>
|
|
|
|
|
<span>{replyCount} {replyCount === 1 ? "reply" : "replies"}</span>
|
|
|
|
|
<span>{formatTimestamp(lastActive)}</span>
|
|
|
|
|
</div>
|
2026-08-17 15:55:54 +00:00
|
|
|
</Link>
|
2026-07-15 21:23:43 +00:00
|
|
|
{:else}
|
|
|
|
|
<tr
|
2026-08-17 15:55:54 +00:00
|
|
|
onclick={onClick}
|
|
|
|
|
class="hover:bg-surface-less cursor-pointer border-b border-solid border-line text-sm transition-colors">
|
2026-07-15 21:23:43 +00:00
|
|
|
<td class="max-w-0 truncate px-4 py-3 align-top">
|
2026-08-17 15:55:54 +00:00
|
|
|
{#if $notifications.has(path)}
|
|
|
|
|
<div class="h-2 w-2 rounded-full bg-primary inline-block mr-1" transition:fade></div>
|
|
|
|
|
{/if}
|
2026-07-15 21:23:43 +00:00
|
|
|
{title || "Untitled thread"}
|
|
|
|
|
</td>
|
|
|
|
|
<td class="w-32 px-4 py-3 align-middle">
|
|
|
|
|
<div class="flex min-w-0 items-center gap-2">
|
|
|
|
|
<ProfileCircle pubkey={event.pubkey} {url} size={5} />
|
|
|
|
|
<span class="min-w-0 truncate">
|
|
|
|
|
<ProfileName pubkey={event.pubkey} {url} />
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</td>
|
|
|
|
|
<td class="w-20 px-4 py-3 text-center align-middle">
|
|
|
|
|
{replyCount}
|
|
|
|
|
</td>
|
|
|
|
|
<td class="w-32 whitespace-nowrap px-4 py-3 text-right align-middle">
|
|
|
|
|
{formatTimestamp(lastActive)}
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
{/if}
|