mirror of
https://github.com/coracle-social/coracle.git
synced 2024-10-06 11:43:30 +00:00
Add some loading icons
This commit is contained in:
parent
e5a4f86474
commit
7015ed136c
BIN
package-lock.json
generated
BIN
package-lock.json
generated
Binary file not shown.
@ -30,6 +30,7 @@
|
||||
"hurdak": "github:ConsignCloud/hurdak",
|
||||
"nostr-tools": "github:fiatjaf/nostr-tools#1b798b2",
|
||||
"ramda": "^0.28.0",
|
||||
"svelte-loading-spinners": "^0.3.4",
|
||||
"svelte-routing": "^1.6.0",
|
||||
"throttle-debounce": "^5.0.0",
|
||||
"vite-plugin-node-polyfills": "^0.5.0"
|
||||
|
@ -50,10 +50,14 @@
|
||||
modal.subscribe($modal => {
|
||||
// Keep scroll position on body, but don't allow scrolling
|
||||
if ($modal) {
|
||||
|
||||
// This is not idempotent, so don't duplicate it
|
||||
if (document.body.style.position !== 'fixed') {
|
||||
scrollY = window.scrollY
|
||||
|
||||
document.body.style.top = `-${scrollY}px`
|
||||
document.body.style.position = `fixed`
|
||||
}
|
||||
} else {
|
||||
document.body.style = ''
|
||||
window.scrollTo(0, scrollY)
|
||||
@ -77,11 +81,15 @@
|
||||
<Route path="/chat/new" component={ChatEdit} />
|
||||
<Route path="/chat/:room" let:params>
|
||||
{#key params.room}
|
||||
<ChatRoom room={params.room} />
|
||||
<ChatRoom {...params} />
|
||||
{/key}
|
||||
</Route>
|
||||
<Route path="/chat/:room/edit" component={ChatEdit} />
|
||||
<Route path="/users/:pubkey" component={UserDetail} />
|
||||
<Route path="/users/:pubkey" let:params>
|
||||
{#key params.pubkey}
|
||||
<UserDetail {...params} />
|
||||
{/key}
|
||||
</Route>
|
||||
<Route path="/settings/keys" component={Keys} />
|
||||
<Route path="/settings/relays" component={RelayList} />
|
||||
<Route path="/settings/profile" component={Profile} />
|
||||
|
@ -37,11 +37,8 @@
|
||||
}
|
||||
|
||||
const showParent = async () => {
|
||||
const notes = await annotateNotes(
|
||||
await channels.getter.all({kinds: [1, 5, 7], ids: [parentId]})
|
||||
)
|
||||
|
||||
modal.set({note: notes[0]})
|
||||
modal.set({note: {id: parentId}})
|
||||
}
|
||||
|
||||
const react = content => {
|
||||
|
@ -1,20 +1,28 @@
|
||||
<script>
|
||||
import {onMount} from 'svelte'
|
||||
import {writable} from 'svelte/store'
|
||||
import {fly} from 'svelte/transition'
|
||||
import {find, propEq} from 'ramda'
|
||||
import {Cursor} from "src/state/nostr"
|
||||
import {notesListener, modal} from "src/state/app"
|
||||
import Spinner from 'src/partials/Spinner.svelte'
|
||||
import {Cursor, channels} from "src/state/nostr"
|
||||
import {notesListener, annotateNotes, modal} from "src/state/app"
|
||||
import {user} from "src/state/user"
|
||||
import Note from 'src/partials/Note.svelte'
|
||||
|
||||
export let note
|
||||
|
||||
const notes = writable([note])
|
||||
const notes = writable([])
|
||||
let cursor
|
||||
let listener
|
||||
|
||||
onMount(() => {
|
||||
cursor = new Cursor({ids: [note.id]}, note.created_at)
|
||||
channels.getter
|
||||
.all({kinds: [1, 5, 7], ids: [note.id]})
|
||||
.then(annotateNotes)
|
||||
.then($notes => {
|
||||
notes.set($notes)
|
||||
})
|
||||
|
||||
listener = notesListener(notes, [
|
||||
{kinds: [1, 5, 7], '#e': [note.id]},
|
||||
// We can't target reaction deletes by e tag, so get them
|
||||
@ -25,10 +33,6 @@
|
||||
// Populate our initial empty space
|
||||
listener.start()
|
||||
|
||||
const unsubNotes = notes.subscribe($notes => {
|
||||
note = find(propEq('id', note.id), $notes)
|
||||
})
|
||||
|
||||
// Unsubscribe when modal closes so that others can re-subscribe sooner
|
||||
const unsubModal = modal.subscribe($modal => {
|
||||
cursor?.stop()
|
||||
@ -36,13 +40,13 @@
|
||||
})
|
||||
|
||||
return () => {
|
||||
unsubNotes()
|
||||
unsubModal()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if note.pubkey}
|
||||
{#each $notes as note (note.id)}
|
||||
<div n:fly={{y: 20}}>
|
||||
<Note showEntire note={note} />
|
||||
{#each note.replies as r (r.id)}
|
||||
<div class="ml-4 border-l border-solid border-medium">
|
||||
@ -59,4 +63,7 @@
|
||||
{/each}
|
||||
</div>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<Spinner />
|
||||
{/each}
|
||||
|
@ -134,7 +134,7 @@
|
||||
<div class="flex gap-4 h-full">
|
||||
<div class="sm:ml-56 w-full">
|
||||
<div class="relative">
|
||||
<div class="flex flex-col pt-20 pb-32">
|
||||
<div class="flex flex-col py-32">
|
||||
<ul class="p-4 max-h-full flex-grow flex flex-col-reverse" name="messages">
|
||||
{#each annotatedMessages as m (m.id)}
|
||||
<li in:fly={{y: 20}} class="py-1">
|
||||
|
@ -5,6 +5,7 @@
|
||||
import {navigate} from "svelte-routing"
|
||||
import {uniqBy, prop} from 'ramda'
|
||||
import Anchor from "src/partials/Anchor.svelte"
|
||||
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"
|
||||
@ -31,7 +32,7 @@
|
||||
scroll()
|
||||
|
||||
// When a modal opens, suspend our subscriptions
|
||||
modal.subscribe(async $modal => {
|
||||
const modalUnsub = modal.subscribe(async $modal => {
|
||||
if ($modal) {
|
||||
cursor.stop()
|
||||
listener.stop()
|
||||
@ -40,6 +41,10 @@
|
||||
listener.start()
|
||||
}
|
||||
})
|
||||
|
||||
return () => {
|
||||
modalUnsub()
|
||||
}
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
@ -61,11 +66,10 @@
|
||||
{/each}
|
||||
</li>
|
||||
{/each}
|
||||
<li class="flex justify-center py-12" in:fly={{y: 20}}>
|
||||
<p>Loading notes...</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- This will always be sitting at the bottom in case infinite scrolling can't keep up -->
|
||||
<Spinner />
|
||||
|
||||
{#if $relays.length > 0}
|
||||
<div class="fixed bottom-0 right-0 p-8">
|
||||
|
@ -4,7 +4,8 @@
|
||||
import {uniqBy, prop} from 'ramda'
|
||||
import {fly} from 'svelte/transition'
|
||||
import Note from "src/partials/Note.svelte"
|
||||
import {Cursor} from 'src/state/nostr'
|
||||
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"
|
||||
|
||||
@ -15,12 +16,15 @@
|
||||
let cursor
|
||||
let listener
|
||||
let scroll
|
||||
let interval
|
||||
let loading = true
|
||||
let modalUnsub
|
||||
|
||||
$: user = $accounts[pubkey]
|
||||
|
||||
onMount(async () => {
|
||||
cursor = new Cursor({kinds: [1], authors: [pubkey]})
|
||||
listener = await notesListener(notes, {kinds: [1, 5, 7], authors: [pubkey]})
|
||||
listener = await notesListener(notes, [{kinds: [1], authors: [pubkey]}, {kinds: [5, 7]}])
|
||||
scroll = scroller(cursor, async chunk => {
|
||||
const annotated = await annotateNotes(chunk, {showParents: true})
|
||||
|
||||
@ -30,8 +34,13 @@
|
||||
// Populate our initial empty space
|
||||
scroll()
|
||||
|
||||
// Track loading based on cursor cutoff date
|
||||
interval = setInterval(() => {
|
||||
loading = cursor.since > epoch
|
||||
}, 1000)
|
||||
|
||||
// When a modal opens, suspend our subscriptions
|
||||
modal.subscribe(async $modal => {
|
||||
modalUnsub = modal.subscribe(async $modal => {
|
||||
if ($modal) {
|
||||
cursor.stop()
|
||||
listener.stop()
|
||||
@ -45,7 +54,10 @@
|
||||
onDestroy(() => {
|
||||
cursor?.stop()
|
||||
listener?.stop()
|
||||
modalUnsub()
|
||||
clearInterval(interval)
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<svelte:window on:scroll={scroll} />
|
||||
@ -81,6 +93,12 @@
|
||||
</div>
|
||||
{/each}
|
||||
</li>
|
||||
{:else}
|
||||
{#if loading}
|
||||
<li><Spinner /></li>
|
||||
{:else}
|
||||
<li class="p-20 text-center" in:fly={{y: 20}}>No notes found.</li>
|
||||
{/if}
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user