Show notification badges on thread items

This commit is contained in:
Jon Staab 2026-08-17 08:55:54 -07:00
parent 922a0996e5
commit da64b46494
2 changed files with 18 additions and 9 deletions

View file

@ -3,9 +3,12 @@
import {formatTimestamp, max} from "@welshman/lib" import {formatTimestamp, max} from "@welshman/lib"
import type {TrustedEvent} from "@welshman/util" import type {TrustedEvent} from "@welshman/util"
import {COMMENT, tagSpec, tagValue} from "@welshman/util" import {COMMENT, tagSpec, tagValue} from "@welshman/util"
import {fade} from "@lib/transition"
import Link from '@lib/components/Link.svelte'
import ProfileCircle from "@app/components/ProfileCircle.svelte" import ProfileCircle from "@app/components/ProfileCircle.svelte"
import ProfileName from "@app/components/ProfileName.svelte" import ProfileName from "@app/components/ProfileName.svelte"
import {deriveEventsForUrl} from "@app/repository" import {deriveEventsForUrl} from "@app/repository"
import {notifications} from "@app/notifications"
import {makeThreadPath} from "@app/routes" import {makeThreadPath} from "@app/routes"
type Props = { type Props = {
@ -22,15 +25,15 @@
const lastActive = $derived(max([...$replies, event].map(e => e.created_at))) const lastActive = $derived(max([...$replies, event].map(e => e.created_at)))
const title = tagValue(tagSpec("title"), event.tags) const title = tagValue(tagSpec("title"), event.tags)
const path = makeThreadPath(url, event.id) const path = makeThreadPath(url, event.id)
const onClick = () => goto(path)
// notification={$notifications.has(path)}
const goToThread = () => goto(path)
</script> </script>
{#if mobile} {#if mobile}
<button <Link
type="button" 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" 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">
onclick={goToThread}>
<p class="truncate font-medium">{title || "Untitled thread"}</p> <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"> <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"> <span class="flex min-w-0 items-center gap-1.5">
@ -42,12 +45,15 @@
<span>{replyCount} {replyCount === 1 ? "reply" : "replies"}</span> <span>{replyCount} {replyCount === 1 ? "reply" : "replies"}</span>
<span>{formatTimestamp(lastActive)}</span> <span>{formatTimestamp(lastActive)}</span>
</div> </div>
</button> </Link>
{:else} {:else}
<tr <tr
class="hover:bg-surface-less cursor-pointer border-b border-solid border-line text-sm transition-colors" onclick={onClick}
onclick={goToThread}> class="hover:bg-surface-less cursor-pointer border-b border-solid border-line text-sm transition-colors">
<td class="max-w-0 truncate px-4 py-3 align-top"> <td class="max-w-0 truncate px-4 py-3 align-top">
{#if $notifications.has(path)}
<div class="h-2 w-2 rounded-full bg-primary inline-block mr-1" transition:fade></div>
{/if}
{title || "Untitled thread"} {title || "Untitled thread"}
</td> </td>
<td class="w-32 px-4 py-3 align-middle"> <td class="w-32 px-4 py-3 align-middle">

View file

@ -304,7 +304,10 @@ export const allNotifications = derived(
for (const [path, {listPath, latestEvent}] of latestEventByContentPath(url, events)) { for (const [path, {listPath, latestEvent}] of latestEventByContentPath(url, events)) {
if (hasNotification(path, latestEvent)) { if (hasNotification(path, latestEvent)) {
paths.add(path) paths.add(path)
paths.add(listPath)
if (hasNotification(listPath, latestEvent)) {
paths.add(listPath)
}
if (hasNotification(spacePath, latestEvent)) { if (hasNotification(spacePath, latestEvent)) {
paths.add(spacePath) paths.add(spacePath)