Fix reactivity of notes in feeds by using livequery

This commit is contained in:
Jonathan Staab 2022-12-26 14:46:22 -08:00
parent 2748fad2cc
commit 20bd89a90a
8 changed files with 80 additions and 60 deletions

View File

@ -36,6 +36,10 @@ If you like Coracle and want to support its development, you can donate sats via
# Changelog
## 0.2.4
- [x] Fix reactions - livequery is required in order to listen for changes
## 0.2.3
- [x] Fix reactions - we'll show new reactions optimistically to avoid complexity in listeners

View File

@ -1,5 +1,6 @@
<script>
import {fly} from 'svelte/transition'
import {uniqBy, prop} from 'ramda'
import {ellipsize, quantify} from 'hurdak/src/core'
import Badge from "src/partials/Badge.svelte"
import {formatTimestamp} from 'src/util/misc'
@ -38,7 +39,7 @@
transition:fly={{y: 20}}
class="absolute top-0 mt-8 py-2 px-4 rounded border border-solid border-medium
bg-dark grid grid-cols-3 gap-y-2 gap-x-4 z-20">
{#each note.people as person (person.pubkey)}
{#each uniqBy(prop('pubkey'), note.people) as person (person.pubkey)}
<Badge {person} />
{/each}
</div>

View File

@ -1,37 +1,36 @@
<script>
import {sortBy, uniqBy, reject, prop} from 'ramda'
import {onDestroy} from 'svelte'
import {sortBy, reject} from 'ramda'
import {onMount} from 'svelte'
import {slide} from 'svelte/transition'
import {quantify} from 'hurdak/lib/hurdak'
import {createScroller} from 'src/util/misc'
import {createScroller, now} from 'src/util/misc'
import {findReply} from 'src/util/nostr'
import Spinner from 'src/partials/Spinner.svelte'
import Note from "src/partials/Note.svelte"
import relay from 'src/relay'
export let loadNotes
export const addNewNotes = xs => {
newNotes = newNotes.concat(xs)
}
export let queryNotes
let notes = []
const notes = relay.lq(async () => {
const notes = await queryNotes()
const annotated = await relay.annotateChunk(notes)
return sortBy(e => -e.created_at, annotated)
})
let until = now()
let newNotes = []
let newNotesLength = 0
$: newNotes = ($notes || []).filter(e => e.created_at > until)
$: newNotesLength = reject(findReply, newNotes).length
$: visibleNotes = ($notes || []).filter(e => e.created_at < until)
const scroller = createScroller(async () => {
addNotes(await loadNotes())
})
onMount(() => {
const scroller = createScroller(loadNotes)
const addNotes = async xs => {
const chunk = await relay.annotateChunk(xs)
notes = sortBy(e => -e.created_at, uniqBy(prop('id'), notes.concat(chunk)))
}
onDestroy(() => {
scroller.stop()
return scroller.stop
})
</script>
@ -40,11 +39,11 @@
<div
transition:slide
class="mb-2 cursor-pointer text-center underline text-light"
on:click={() => { addNotes(newNotes); newNotes = [] }}>
on:click={() => { until = now() }}>
Load {quantify(newNotesLength, 'new note')}
</div>
{/if}
{#each notes as n (n.id)}
{#each visibleNotes as n (n.id)}
<li><Note note={n} depth={2} /></li>
{/each}
</ul>

View File

@ -6,17 +6,13 @@
import {getTagValues} from 'src/util/nostr'
import relay, {user} from 'src/relay'
let notes, sub
let sub
onMount(async () => {
sub = await relay.pool.listenForEvents(
'views/notes/Global',
[{kinds: [1, 5, 7], since: cursor.since}],
when(propEq('kind', 1), async e => {
await relay.loadNoteContext(e)
notes.addNewNotes([e])
})
when(propEq('kind', 1), relay.loadNoteContext)
)
})
@ -28,21 +24,22 @@
const cursor = new Cursor(timedelta(1, 'minutes'))
const loadNotes = async () => {
const loadNotes = () => {
const [since, until] = cursor.step()
await relay.pool.loadEvents(
return relay.pool.loadEvents(
[{kinds: [1, 5, 7], since, until}],
when(propEq('kind', 1), relay.loadNoteContext)
)
}
const queryNotes = () => {
return relay.filterEvents({
since,
until,
kinds: [1],
since: cursor.since,
muffle: getTagValues($user?.muffle || []),
})
}
</script>
<Notes bind:this={notes} shouldMuffle {loadNotes} />
<Notes shouldMuffle {loadNotes} {queryNotes} />

View File

@ -6,7 +6,7 @@
import {getTagValues} from 'src/util/nostr'
import relay, {user, network} from 'src/relay'
let notes, sub, networkUnsub
let sub, networkUnsub
onMount(() => {
// We need to re-create the sub when network changes, since this is where
@ -16,11 +16,7 @@
sub = await relay.pool.listenForEvents(
'views/notes/Network',
[{kinds: [1, 5, 7], authors: $network, since: cursor.since}],
when(propEq('kind', 1), async e => {
await relay.loadNoteContext(e)
notes.addNewNotes([e])
})
when(propEq('kind', 1), relay.loadNoteContext)
)
})
})
@ -35,23 +31,24 @@
const cursor = new Cursor(timedelta(10, 'minutes'))
const loadNotes = async () => {
const loadNotes = () => {
const [since, until] = cursor.step()
await relay.pool.loadEvents(
return relay.pool.loadEvents(
[{kinds: [1, 5, 7], authors: $network, since, until}],
when(propEq('kind', 1), relay.loadNoteContext)
)
}
const queryNotes = () => {
return relay.filterEvents({
since,
until,
kinds: [1],
since: cursor.since,
authors: $network.concat($user.pubkey),
muffle: getTagValues($user?.muffle || []),
})
}
</script>
<Notes bind:this={notes} shouldMuffle {loadNotes} />
<Notes shouldMuffle {loadNotes} {queryNotes} />

View File

@ -8,16 +8,21 @@
const cursor = new Cursor(timedelta(1, 'days'))
const loadNotes = async () => {
const loadNotes = () => {
const [since, until] = cursor.step()
const filter = {kinds: [7], authors: [pubkey], since, until}
const muffle = getTagValues($user?.muffle || [])
await relay.pool.loadEvents(filter)
return relay.pool.loadEvents({kinds: [7], authors: [pubkey], since, until})
}
return relay.filterEvents({...filter, muffle})
const queryNotes = () => {
return relay.filterEvents({
kinds: [7],
since: cursor.since,
authors: [pubkey],
muffle: getTagValues($user?.muffle || []),
})
}
</script>
<Notes shouldMuffle {loadNotes} />
<Notes shouldMuffle {loadNotes} {queryNotes} />

View File

@ -10,15 +10,24 @@
const loadNotes = async () => {
const [since, until] = cursor.step()
const authors = getTagValues(person.petnames)
const filter = {kinds: [1], authors, since, until}
const muffle = getTagValues($user?.muffle || [])
await relay.pool.loadEvents(filter)
return relay.pool.loadEvents({
since,
until,
kinds: [1],
authors: getTagValues(person.petnames),
})
}
return relay.filterEvents({...filter, muffle})
const queryNotes = () => {
return relay.filterEvents({
kinds: [1],
since: cursor.since,
authors: getTagValues(person.petnames),
muffle: getTagValues($user?.muffle || []),
})
}
</script>
<Notes shouldMuffle {loadNotes} />
<Notes shouldMuffle {loadNotes} {queryNotes} />

View File

@ -7,15 +7,23 @@
const cursor = new Cursor(timedelta(1, 'days'))
const loadNotes = async () => {
const loadNotes = () => {
const [since, until] = cursor.step()
const filter = {kinds: [1], authors: [pubkey], since, until}
await relay.pool.loadEvents(filter, relay.loadNoteContext)
return relay.pool.loadEvents(
[{kinds: [1], authors: [pubkey], since, until}],
relay.loadNoteContext
)
}
return relay.filterEvents(filter)
const queryNotes = () => {
return relay.filterEvents({
kinds: [1],
since: cursor.since,
authors: [pubkey],
})
}
</script>
<Notes shouldMuffle {loadNotes} />
<Notes shouldMuffle {loadNotes} {queryNotes} />