mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-30 00:41:12 +00:00
Get everything working again
This commit is contained in:
parent
46062a721e
commit
ee04e2987a
@ -1,7 +1,6 @@
|
||||
Bugs
|
||||
|
||||
- [ ] Make sure to stop loading chunks on component unmount
|
||||
- [ ] Don't lose scroll position when opening modals
|
||||
- [ ] Load/publish user preferred relays
|
||||
- [ ] Optimistically load events the user publishes (e.g. to reduce reflow for reactions/replies). Essentially, we can pretend to be our own in-memory relay.
|
||||
|
||||
Features
|
||||
|
@ -111,6 +111,12 @@
|
||||
Reply to <Anchor on:click={showParent}>{parentId.slice(0, 8)}</Anchor>
|
||||
</small>
|
||||
{/if}
|
||||
{#if flag}
|
||||
<p class="text-light border-l-2 border-solid border-medium pl-4">
|
||||
You have flagged this content as offensive.
|
||||
<Anchor on:click={() => deleteReaction(flag)}>Unflag</Anchor>
|
||||
</p>
|
||||
{:else}
|
||||
<p>
|
||||
{#if note.content.length > 240 && !showEntire}
|
||||
{ellipsize(note.content, 240)}
|
||||
@ -131,13 +137,12 @@
|
||||
on:click={() => like ? deleteReaction(like) : react("+")} />
|
||||
{uniqBy(prop('pubkey'), note.reactions.filter(whereEq({content: '+'}))).length}
|
||||
</div>
|
||||
<div class={cx({'text-accent': flag})}>
|
||||
<i
|
||||
class="fa-solid fa-flag cursor-pointer"
|
||||
on:click={() => flag ? deleteReaction(flag) : react("-")} />
|
||||
<div>
|
||||
<i class="fa-solid fa-flag cursor-pointer" on:click={() => react("-")} />
|
||||
{uniqBy(prop('pubkey'), note.reactions.filter(whereEq({content: '-'}))).length}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import {onMount, onDestroy} from 'svelte'
|
||||
import {onMount} from 'svelte'
|
||||
import {writable} from 'svelte/store'
|
||||
import {find, propEq} from 'ramda'
|
||||
import {notesLoader, notesListener, modal} from "src/state/app"
|
||||
|
@ -11,8 +11,12 @@
|
||||
let q = ""
|
||||
let rooms = {}
|
||||
let search
|
||||
let nOtherRooms
|
||||
|
||||
$: search = fuzzy(Object.values(rooms), {keys: ["name", "about"]})
|
||||
$: {
|
||||
search = fuzzy(Object.values(rooms), {keys: ["name", "about"]})
|
||||
nOtherRooms = Math.floor(0, Object.keys(rooms).length - 8)
|
||||
}
|
||||
|
||||
const createRoom = () => navigate(`/chat/new`)
|
||||
|
||||
@ -60,9 +64,11 @@
|
||||
{/if}
|
||||
</li>
|
||||
{/each}
|
||||
{#if nOtherRooms > 1}
|
||||
<li class="px-3">
|
||||
<small>{Math.floor(0, Object.keys(rooms).length - 8)} more rooms found</small>
|
||||
<small>Enter a search term to discover {nOtherRooms} more rooms.</small>
|
||||
</li>
|
||||
{/if}
|
||||
<li class="bg-medium m-3 h-px" />
|
||||
<li class="cursor-pointer font-bold hover:bg-accent transition-all px-3 py-2" on:click={createRoom}>
|
||||
<i class="fa-solid fa-plus" /> Create Room
|
||||
|
@ -87,6 +87,8 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="hidden sm:block">
|
||||
<RoomList />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import {onMount} from 'svelte'
|
||||
import {onMount, onDestroy} from 'svelte'
|
||||
import {fly} from 'svelte/transition'
|
||||
import {navigate} from 'svelte-routing'
|
||||
import {prop, uniqBy, sortBy, last} from 'ramda'
|
||||
@ -7,7 +7,7 @@
|
||||
import {formatTimestamp} from 'src/util/misc'
|
||||
import {toHtml} from 'src/util/html'
|
||||
import UserBadge from 'src/partials/UserBadge.svelte'
|
||||
import {channels} from 'src/state/nostr'
|
||||
import {Listener, epoch} from 'src/state/nostr'
|
||||
import {accounts, ensureAccounts} from 'src/state/app'
|
||||
import {dispatch} from 'src/state/dispatch'
|
||||
import {user} from 'src/state/user'
|
||||
@ -15,6 +15,7 @@
|
||||
|
||||
export let room
|
||||
|
||||
let listener
|
||||
let textarea
|
||||
let messages = []
|
||||
let annotatedMessages = []
|
||||
@ -46,27 +47,20 @@
|
||||
return navigate('/login')
|
||||
}
|
||||
|
||||
const events = await channels.getter.all({kinds: [40, 41], ids: [room]})
|
||||
|
||||
events.forEach(({pubkey, content}) => {
|
||||
roomData = {pubkey, ...roomData, ...JSON.parse(content)}
|
||||
})
|
||||
|
||||
const isVisible = $el => {
|
||||
const bodyRect = document.body.getBoundingClientRect()
|
||||
const {top, height} = $el.getBoundingClientRect()
|
||||
|
||||
return top + height < bodyRect.height
|
||||
}
|
||||
|
||||
return await channels.listener.sub(
|
||||
{limit: 100, kinds: [42, 43, 44], '#e': [room]},
|
||||
listener = new Listener(
|
||||
[{kinds: [40, 41], ids: [room], since: epoch},
|
||||
{kinds: [42, 43, 44], '#e': [room], since: epoch}],
|
||||
e => {
|
||||
switcherFn(e.kind, {
|
||||
const {pubkey, kind, content} = e
|
||||
|
||||
if ([40, 41].includes(kind)) {
|
||||
roomData = {pubkey, ...roomData, ...JSON.parse(content)}
|
||||
} else {
|
||||
switcherFn(kind, {
|
||||
42: () => {
|
||||
messages = messages.concat(e)
|
||||
|
||||
ensureAccounts([e.pubkey])
|
||||
ensureAccounts([pubkey])
|
||||
|
||||
const $prevListItem = last(document.querySelectorAll('.chat-message'))
|
||||
|
||||
@ -81,10 +75,24 @@
|
||||
43: () => null,
|
||||
44: () => null,
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
listener.start()
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
listener?.stop()
|
||||
})
|
||||
|
||||
const isVisible = $el => {
|
||||
const bodyRect = document.body.getBoundingClientRect()
|
||||
const {top, height} = $el.getBoundingClientRect()
|
||||
|
||||
return top + height < bodyRect.height
|
||||
}
|
||||
|
||||
const edit = () => {
|
||||
navigate(`/chat/${room}/edit`)
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
<div class="flex flex-col gap-8 w-full">
|
||||
<div class="flex flex-col gap-1">
|
||||
<strong>Public Key</strong>
|
||||
<Input disabled value={$user.pubkey}>
|
||||
<Input disabled value={$user?.pubkey}>
|
||||
<i slot="after" class="fa-solid fa-copy cursor-pointer" on:click={() => copyKey('public')} />
|
||||
</Input>
|
||||
<p class="text-sm text-light">
|
||||
@ -47,7 +47,7 @@
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<strong>Private Key</strong>
|
||||
<Input disabled type="password" value={$user.privkey}>
|
||||
<Input disabled type="password" value={$user?.privkey}>
|
||||
<i slot="after" class="fa-solid fa-copy cursor-pointer" on:click={() => copyKey('private')} />
|
||||
</Input>
|
||||
<p class="text-sm text-light">
|
||||
|
@ -5,7 +5,7 @@ import {navigate} from "svelte-routing"
|
||||
import {switcherFn, ensurePlural} from 'hurdak/lib/hurdak'
|
||||
import {getLocalJson, setLocalJson, now, timedelta, sleep} from "src/util/misc"
|
||||
import {user} from 'src/state/user'
|
||||
import {filterMatches, Listener, Cursor, channels, relays, findReplyTo} from 'src/state/nostr'
|
||||
import {epoch, filterMatches, Listener, Cursor, channels, relays, findReplyTo} from 'src/state/nostr'
|
||||
|
||||
export const modal = writable(null)
|
||||
|
||||
@ -123,7 +123,7 @@ export const notesLoader = async (
|
||||
showParents = false,
|
||||
delta = timedelta(1, 'hours'),
|
||||
isInModal = false,
|
||||
since = 1633046400, // nostr epoch
|
||||
since = epoch,
|
||||
} = {}
|
||||
) => {
|
||||
const cursor = new Cursor(filter, delta)
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {writable} from 'svelte/store'
|
||||
import {writable, get} from 'svelte/store'
|
||||
import {relayPool, getPublicKey} from 'nostr-tools'
|
||||
import {last, intersection, uniqBy, prop} from 'ramda'
|
||||
import {first, noop, ensurePlural} from 'hurdak/lib/hurdak'
|
||||
@ -6,6 +6,8 @@ import {getLocalJson, setLocalJson, now, timedelta} from "src/util/misc"
|
||||
|
||||
export const nostr = relayPool()
|
||||
|
||||
export const epoch = 1633046400
|
||||
|
||||
export const filterTags = (where, events) =>
|
||||
ensurePlural(events)
|
||||
.flatMap(
|
||||
@ -55,6 +57,15 @@ export class Channel {
|
||||
// before they can get a new one.
|
||||
await this.p
|
||||
|
||||
// If we don't have any relays, we'll wait forever for an eose, but
|
||||
// we already know we're done. Use a timeout since callers are
|
||||
// expecting this to be async and we run into errors otherwise.
|
||||
if (get(relays).length === 0) {
|
||||
setTimeout(onEose)
|
||||
|
||||
return {unsub: noop}
|
||||
}
|
||||
|
||||
let resolve
|
||||
const sub = nostr.sub({filter, cb}, this.name, onEose)
|
||||
|
||||
@ -160,10 +171,15 @@ export class Listener {
|
||||
this.p = Promise.resolve()
|
||||
}
|
||||
async start() {
|
||||
const {filter, since} = this
|
||||
|
||||
if (!this.sub) {
|
||||
this.sub = await channels.listener.sub(
|
||||
this.filter.map(f => ({...f, since: this.since})),
|
||||
e => this.onEvent(e)
|
||||
filter.map(f => ({since, ...f})),
|
||||
e => {
|
||||
this.since = e.created_at
|
||||
this.onEvent(e)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -171,7 +187,6 @@ export class Listener {
|
||||
if (this.sub) {
|
||||
this.sub.unsub()
|
||||
this.sub = null
|
||||
this.since = now()
|
||||
}
|
||||
}
|
||||
restart() {
|
||||
|
@ -14,6 +14,7 @@ module.exports = {
|
||||
light: "#CCC5B9",
|
||||
medium: "#403D39",
|
||||
dark: "#252422",
|
||||
danger: "#ff0000",
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
|
Loading…
Reference in New Issue
Block a user