mirror of
https://github.com/coracle-social/coracle.git
synced 2024-10-06 11:43:30 +00:00
Make scroller stoppable
This commit is contained in:
parent
7015ed136c
commit
ddcb5ac0a3
@ -7,7 +7,7 @@
|
||||
import {toHtml} from 'src/util/html'
|
||||
import UserBadge from 'src/partials/UserBadge.svelte'
|
||||
import {Listener, Cursor, epoch} from 'src/state/nostr'
|
||||
import {accounts, scroller, ensureAccounts} from 'src/state/app'
|
||||
import {accounts, createScroller, ensureAccounts} from 'src/state/app'
|
||||
import {dispatch} from 'src/state/dispatch'
|
||||
import {user} from 'src/state/user'
|
||||
import RoomList from "src/partials/chat/RoomList.svelte"
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
let cursor
|
||||
let listener
|
||||
let scroll
|
||||
let scroller
|
||||
let textarea
|
||||
let messages = []
|
||||
let annotatedMessages = []
|
||||
@ -63,7 +63,7 @@
|
||||
}
|
||||
|
||||
cursor = new Cursor({kinds: [42], '#e': [room]})
|
||||
scroll = scroller(
|
||||
scroller = createScroller(
|
||||
cursor,
|
||||
chunk => {
|
||||
stickToBottom('auto', async () => {
|
||||
@ -97,14 +97,14 @@
|
||||
}
|
||||
)
|
||||
|
||||
scroll()
|
||||
|
||||
scroller.start()
|
||||
listener.start()
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
cursor?.stop()
|
||||
listener?.stop()
|
||||
scroller?.stop()
|
||||
})
|
||||
|
||||
const edit = () => {
|
||||
@ -129,7 +129,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:scroll={scroll} />
|
||||
<svelte:window on:scroll={scroller?.start} />
|
||||
|
||||
<div class="flex gap-4 h-full">
|
||||
<div class="sm:ml-56 w-full">
|
||||
|
@ -8,12 +8,13 @@
|
||||
import Spinner from "src/partials/Spinner.svelte"
|
||||
import Note from "src/partials/Note.svelte"
|
||||
import {relays, Cursor} from "src/state/nostr"
|
||||
import {scroller, annotateNotes, notesListener, modal} from "src/state/app"
|
||||
import {createScroller, annotateNotes, notesListener, modal} from "src/state/app"
|
||||
|
||||
const notes = writable([])
|
||||
let cursor
|
||||
let listener
|
||||
let scroll
|
||||
let scroller
|
||||
let modalUnsub
|
||||
|
||||
const createNote = () => {
|
||||
navigate("/notes/new")
|
||||
@ -22,38 +23,35 @@
|
||||
onMount(async () => {
|
||||
cursor = new Cursor({kinds: [1]})
|
||||
listener = await notesListener(notes, {kinds: [1, 5, 7]})
|
||||
scroll = scroller(cursor, async chunk => {
|
||||
scroller = createScroller(cursor, async chunk => {
|
||||
const annotated = await annotateNotes(chunk, {showParents: true})
|
||||
|
||||
notes.update($notes => uniqBy(prop('id'), $notes.concat(annotated)))
|
||||
})
|
||||
|
||||
// Populate our initial empty space
|
||||
scroll()
|
||||
|
||||
// When a modal opens, suspend our subscriptions
|
||||
const modalUnsub = modal.subscribe(async $modal => {
|
||||
modalUnsub = modal.subscribe(async $modal => {
|
||||
if ($modal) {
|
||||
cursor.stop()
|
||||
listener.stop()
|
||||
scroller.stop()
|
||||
} else {
|
||||
cursor.start()
|
||||
listener.start()
|
||||
scroller.start()
|
||||
}
|
||||
})
|
||||
|
||||
return () => {
|
||||
modalUnsub()
|
||||
}
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
cursor?.stop()
|
||||
listener?.stop()
|
||||
scroller?.stop()
|
||||
modalUnsub?.()
|
||||
})
|
||||
</script>
|
||||
|
||||
<svelte:window on:scroll={scroll} />
|
||||
<svelte:window on:scroll={scroller?.start} />
|
||||
|
||||
<ul class="py-8 flex flex-col gap-2 max-w-xl m-auto">
|
||||
{#each (notes ? $notes : []) as n (n.id)}
|
||||
|
@ -7,7 +7,7 @@
|
||||
import Spinner from "src/partials/Spinner.svelte"
|
||||
import {Cursor, epoch} from 'src/state/nostr'
|
||||
import {user as currentUser} from 'src/state/user'
|
||||
import {accounts, scroller, notesListener, modal, annotateNotes} from "src/state/app"
|
||||
import {accounts, createScroller, notesListener, modal, annotateNotes} from "src/state/app"
|
||||
|
||||
export let pubkey
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
let user
|
||||
let cursor
|
||||
let listener
|
||||
let scroll
|
||||
let scroller
|
||||
let interval
|
||||
let loading = true
|
||||
let modalUnsub
|
||||
@ -25,14 +25,14 @@
|
||||
onMount(async () => {
|
||||
cursor = new Cursor({kinds: [1], authors: [pubkey]})
|
||||
listener = await notesListener(notes, [{kinds: [1], authors: [pubkey]}, {kinds: [5, 7]}])
|
||||
scroll = scroller(cursor, async chunk => {
|
||||
scroller = createScroller(cursor, async chunk => {
|
||||
const annotated = await annotateNotes(chunk, {showParents: true})
|
||||
|
||||
notes.update($notes => uniqBy(prop('id'), $notes.concat(annotated)))
|
||||
})
|
||||
|
||||
// Populate our initial empty space
|
||||
scroll()
|
||||
scroller.start()
|
||||
|
||||
// Track loading based on cursor cutoff date
|
||||
interval = setInterval(() => {
|
||||
@ -54,13 +54,14 @@
|
||||
onDestroy(() => {
|
||||
cursor?.stop()
|
||||
listener?.stop()
|
||||
modalUnsub()
|
||||
scroller?.stop()
|
||||
modalUnsub?.()
|
||||
clearInterval(interval)
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<svelte:window on:scroll={scroll} />
|
||||
<svelte:window on:scroll={scroller?.start} />
|
||||
|
||||
{#if user}
|
||||
<div class="max-w-2xl m-auto flex flex-col gap-4 py-8 px-4">
|
||||
|
@ -170,10 +170,22 @@ export const notesListener = (notes, filter) => {
|
||||
|
||||
// UI
|
||||
|
||||
export const scroller = (cursor, cb, {isInModal = false, since = epoch, reverse = false} = {}) => {
|
||||
export const createScroller = (
|
||||
cursor,
|
||||
onChunk,
|
||||
{isInModal = false, since = epoch, reverse = false} = {}
|
||||
) => {
|
||||
const startingDelta = cursor.delta
|
||||
|
||||
return debounce(1000, async () => {
|
||||
let active = false
|
||||
|
||||
const start = debounce(1000, async () => {
|
||||
if (active) {
|
||||
return
|
||||
}
|
||||
|
||||
active = true
|
||||
|
||||
/* eslint no-constant-condition: 0 */
|
||||
while (true) {
|
||||
// If a modal opened up, wait for them to close it. Otherwise, throttle a tad
|
||||
@ -206,7 +218,7 @@ export const scroller = (cursor, cb, {isInModal = false, since = epoch, reverse
|
||||
|
||||
// Notify the caller
|
||||
if (chunk.length > 0) {
|
||||
await cb(chunk)
|
||||
await onChunk(chunk)
|
||||
}
|
||||
|
||||
// If we have an empty chunk, increase our step size so we can get back to where
|
||||
@ -216,6 +228,18 @@ export const scroller = (cursor, cb, {isInModal = false, since = epoch, reverse
|
||||
} else {
|
||||
cursor.delta = startingDelta
|
||||
}
|
||||
|
||||
if (!active) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
active = false
|
||||
})
|
||||
|
||||
return {
|
||||
start,
|
||||
stop: () => { active = false },
|
||||
isActive: () => Boolean(cursor.sub),
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user