Clean up notifications a bit

This commit is contained in:
Jonathan Staab 2023-05-21 11:56:59 -07:00
parent 7062037eee
commit a05117a5a8
5 changed files with 70 additions and 45 deletions

View File

@ -4,6 +4,7 @@
- [x] Register url handler for web+nostr and use that for sharing
- [x] Combine search and scan pages
- [x] Clean up notifications page
# 0.2.28

View File

@ -1,4 +1,5 @@
<script>
import cx from "classnames"
import {Link} from "svelte-routing"
import {killEvent} from "src/util/html"
import {displayPerson} from "src/util/nostr"
@ -10,14 +11,14 @@
</script>
{#if inert}
<span class="relative z-10 flex items-center gap-2">
<span class={cx($$props.class, "relative z-10 flex items-center gap-2")}>
<PersonCircle {person} />
<span class="text-lg font-bold">{displayPerson(person)}</span>
</span>
{:else}
<Link
to={routes.person(person.pubkey)}
class="relative z-10 flex items-center gap-2"
class={cx($$props.class, "relative z-10 flex items-center gap-2")}
on:click={killEvent}>
<PersonCircle {person} />
<span class="text-lg font-bold">{displayPerson(person)}</span>

View File

@ -1,7 +1,7 @@
<script>
import {max, pipe, filter, map, when, identity, pluck, propEq, uniq} from "ramda"
import {pipe, filter, map, when, identity, pluck, propEq, uniq} from "ramda"
import {closure, quantify} from "hurdak/lib/hurdak"
import {formatTimestamp, tryJson} from "src/util/misc"
import {tryJson} from "src/util/misc"
import {Tags} from "src/util/nostr"
import PersonBadge from "src/app/shared/PersonBadge.svelte"
import Card from "src/partials/Card.svelte"
@ -23,7 +23,6 @@
const notifications = modifyZaps(event.notifications)
const note = event.ref || notifications[0]
const timestamp = pluck("created_at", notifications).reduce(max, 0)
const replies = notifications.filter(propEq("kind", 1))
const likes = notifications.filter(propEq("kind", 7))
const zaps = notifications.filter(propEq("kind", 9734))
@ -40,38 +39,41 @@
</script>
{#if note}
<Card
interactive
class="flex flex-col gap-2 text-left"
on:click={() => modal.push({type: "note/detail", note})}>
<div class="relative flex w-full items-center justify-between gap-2" on:click|stopPropagation>
{#if !event.ref}
<div class="flex items-center gap-2">
<PersonBadge person={author} /> mentioned you.
</div>
{:else}
<Popover>
<div slot="trigger">
{quantify(pubkeys.length, "person", "people")}
{actionText} your note.
<div class="flex flex-col items-end gap-1">
<Card
interactive
class="flex w-full flex-col gap-2 text-left"
on:click={() => modal.push({type: "note/detail", note})}>
<div on:click|stopPropagation>
{#if !event.ref}
<div>
<PersonBadge class="float-left" person={author} />
<span class="relative top-px pl-1">mentioned you.</span>
</div>
<div slot="tooltip" class="flex flex-col gap-4">
{#if zaps.length > 0}
<NotificationSection pubkeys={pluck("pubkey", zaps)}>Zapped by</NotificationSection>
{/if}
{#if likes.length > 0}
<NotificationSection pubkeys={pluck("pubkey", likes)}>Liked by</NotificationSection>
{/if}
{#if replies.length > 0}
<NotificationSection pubkeys={pluck("pubkey", replies)}>Replies</NotificationSection>
{/if}
</div>
</Popover>
{/if}
<p class="text-sm text-gray-1">{formatTimestamp(timestamp)}</p>
</div>
<div class="break-word ml-6 overflow-hidden text-gray-1">
<NoteContent maxLength={80} showMedia={false} {note} />
</div>
</Card>
{:else}
<Popover>
<div slot="trigger">
{quantify(pubkeys.length, "person", "people")}
{actionText} your note.
</div>
<div slot="tooltip" class="flex flex-col gap-4">
{#if zaps.length > 0}
<NotificationSection pubkeys={pluck("pubkey", zaps)}>Zapped by</NotificationSection>
{/if}
{#if likes.length > 0}
<NotificationSection pubkeys={pluck("pubkey", likes)}>Liked by</NotificationSection>
{/if}
{#if replies.length > 0}
<NotificationSection pubkeys={pluck("pubkey", replies)}
>Replies</NotificationSection>
{/if}
</div>
</Popover>
{/if}
</div>
<div class="break-word overflow-hidden text-gray-1">
<NoteContent maxLength={80} showMedia={false} {note} />
</div>
</Card>
</div>
{/if}

View File

@ -4,7 +4,7 @@
import {onMount} from "svelte"
import {fly} from "svelte/transition"
import {navigate} from "svelte-routing"
import {now, timedelta, createScroller} from "src/util/misc"
import {now, timedelta, formatTimestampAsDate, createScroller} from "src/util/misc"
import {findReplyId} from "src/util/nostr"
import Spinner from "src/partials/Spinner.svelte"
import Tabs from "src/partials/Tabs.svelte"
@ -62,6 +62,7 @@
ref,
key: e.id,
notifications: [e],
dateDisplay: formatTimestampAsDate(e.created_at),
showLine: e.created_at < prevChecked && prevTimestamp >= prevChecked,
})
}
@ -71,6 +72,15 @@
const setActiveTab = tab => navigate(`/notifications/${tab}`)
const getLineText = i => {
const event = events[i]
const prev = events[i - 1]
if (prev?.dateDisplay !== event.dateDisplay) {
return event.dateDisplay
}
}
onMount(() => {
document.title = "Notifications"
@ -83,16 +93,17 @@
{#if events}
<Content>
<Tabs {tabs} {activeTab} {setActiveTab} />
{#each events as event (event.key)}
<div in:fly={{y: 20}}>
<Notification {event} />
</div>
{#if event.showLine}
{#each events as event, i (event.key)}
{@const lineText = getLineText(i)}
{#if lineText}
<div class="flex items-center gap-4">
<small class="whitespace-nowrap text-gray-1">Older notifications</small>
<small class="whitespace-nowrap text-gray-1">{lineText}</small>
<div class="h-px w-full bg-gray-6" />
</div>
{/if}
<div in:fly={{y: 20}}>
<Notification {event} />
</div>
{:else}
<Content size="lg" class="text-center">No notifications found - check back later!</Content>
{/each}

View File

@ -76,6 +76,16 @@ export const formatTimestamp = ts => {
return formatter.format(new Date(ts * 1000))
}
export const formatTimestampAsDate = ts => {
const formatter = new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric",
})
return formatter.format(new Date(ts * 1000))
}
export const formatTimestampRelative = ts => {
let unit
let delta = now() - ts