Keep a profile pinned note out of the feed store so it renders once (#499)
This commit is contained in:
parent
ad480ad4a0
commit
5520b851de
2 changed files with 16 additions and 5 deletions
|
|
@ -465,9 +465,11 @@ test("US-079 read a person's notes", async ({seed, as}) => {
|
||||||
makeEvent(NOTE, {content: "Anyone seen the tide charts?", created_at: at(4, HOUR)}),
|
makeEvent(NOTE, {content: "Anyone seen the tide charts?", created_at: at(4, HOUR)}),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Older than the feed's first window, so the pin is fetched by id while the feed only
|
||||||
|
// reaches it by paging — the order in which one note arrives down both routes.
|
||||||
pinned = space.event(
|
pinned = space.event(
|
||||||
user.alice,
|
user.alice,
|
||||||
makeEvent(NOTE, {content: "PINNED how to read a tide chart", created_at: at(3, HOUR)}),
|
makeEvent(NOTE, {content: "PINNED how to read a tide chart", created_at: at(2, MONTH)}),
|
||||||
)
|
)
|
||||||
|
|
||||||
space.event(
|
space.event(
|
||||||
|
|
@ -521,6 +523,7 @@ test("US-079 read a person's notes", async ({seed, as}) => {
|
||||||
|
|
||||||
// The pin outranks the newer notes; the rest are newest first.
|
// The pin outranks the newer notes; the rest are newest first.
|
||||||
await expect(list.first()).toContainText("PINNED")
|
await expect(list.first()).toContainText("PINNED")
|
||||||
|
await expect(list.filter({hasText: "PINNED"})).toHaveCount(1)
|
||||||
await expect(list.nth(1)).toContainText("NEWEST")
|
await expect(list.nth(1)).toContainText("NEWEST")
|
||||||
await expect(list.nth(2)).toContainText("MIDDLE")
|
await expect(list.nth(2)).toContainText("MIDDLE")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {onDestroy, onMount} from "svelte"
|
import {onDestroy, onMount} from "svelte"
|
||||||
import {derived, writable} from "svelte/store"
|
import {derived, writable} from "svelte/store"
|
||||||
import type {Writable} from "svelte/store"
|
import type {Readable} from "svelte/store"
|
||||||
import {sortBy, uniqBy, now} from "@welshman/lib"
|
import {sortBy, uniqBy, now} from "@welshman/lib"
|
||||||
import type {Maybe} from "@welshman/lib"
|
import type {Maybe} from "@welshman/lib"
|
||||||
import {NOTE, outbox} from "@welshman/util"
|
import {NOTE, outbox} from "@welshman/util"
|
||||||
|
|
@ -27,6 +27,11 @@
|
||||||
|
|
||||||
const pinnedIds = derived($app.use(PinLists).one(pubkey), $pinList => $pinList?.ids() ?? [])
|
const pinnedIds = derived($app.use(PinLists).one(pubkey), $pinList => $pinList?.ids() ?? [])
|
||||||
|
|
||||||
|
// Pinned notes are asked for by id instead of by the feed's filters, so they get a store of
|
||||||
|
// their own. A feed dedupes and sorts what it holds as it loads it, and writing to its store
|
||||||
|
// from out here bypasses both.
|
||||||
|
const pinnedEvents = writable<TrustedEvent[]>([])
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if ($pinnedIds.length > 0) {
|
if ($pinnedIds.length > 0) {
|
||||||
const controller = new AbortController()
|
const controller = new AbortController()
|
||||||
|
|
@ -36,7 +41,8 @@
|
||||||
relays: $relays,
|
relays: $relays,
|
||||||
filters: [{ids: $pinnedIds}],
|
filters: [{ids: $pinnedIds}],
|
||||||
signal: controller.signal,
|
signal: controller.signal,
|
||||||
onEvent: e => events.update($events => uniqBy(e => e.id, $events.concat(e))),
|
onEvent: event =>
|
||||||
|
pinnedEvents.update($pinned => uniqBy(e => e.id, $pinned.concat(event))),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -49,12 +55,14 @@
|
||||||
|
|
||||||
const exhausted = $derived($older?.status === "exhausted")
|
const exhausted = $derived($older?.status === "exhausted")
|
||||||
const loading = $derived(isFeedLoading($older))
|
const loading = $derived(isFeedLoading($older))
|
||||||
let events: Writable<TrustedEvent[]> = $state(writable([]))
|
let events: Readable<TrustedEvent[]> = $state(writable([]))
|
||||||
|
|
||||||
const feedEvents = $derived(
|
const feedEvents = $derived(
|
||||||
sortBy(
|
sortBy(
|
||||||
e => ($pinnedIds.includes(e.id) ? -(now() + e.created_at) : -e.created_at),
|
e => ($pinnedIds.includes(e.id) ? -(now() + e.created_at) : -e.created_at),
|
||||||
$events.filter(e => getReplyTags(e.tags).replies.length === 0),
|
uniqBy(e => e.id, [...$pinnedEvents, ...$events]).filter(
|
||||||
|
e => getReplyTags(e.tags).replies.length === 0,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue