mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-30 00:41:12 +00:00
Spiff up channels
This commit is contained in:
parent
ef3b7f2d3d
commit
07564ef29e
15
README.md
15
README.md
@ -17,7 +17,8 @@ If you like Coracle and want to support its development, you can donate sats via
|
|||||||
- [x] Mentions
|
- [x] Mentions
|
||||||
- [x] Persist and load relay list
|
- [x] Persist and load relay list
|
||||||
- [x] NIP 05
|
- [x] NIP 05
|
||||||
- [ ] Direct messages using NIP 04
|
- [x] Direct messages using NIP 04
|
||||||
|
- [ ] Add petnames for channels
|
||||||
- [ ] Deploy coracle relay, set better defaults
|
- [ ] Deploy coracle relay, set better defaults
|
||||||
- [ ] Image uploads
|
- [ ] Image uploads
|
||||||
- Use dufflepud. Default will charge via lightning and have a tos, others can self-host and skip that.
|
- Use dufflepud. Default will charge via lightning and have a tos, others can self-host and skip that.
|
||||||
@ -53,19 +54,9 @@ If you like Coracle and want to support its development, you can donate sats via
|
|||||||
|
|
||||||
- [ ] Figure out migrations from previous version
|
- [ ] Figure out migrations from previous version
|
||||||
- [ ] Fix notes search
|
- [ ] Fix notes search
|
||||||
- [ ] Chat
|
|
||||||
- [ ] Figure out which relays to use
|
|
||||||
- [ ] Add petnames for channels
|
|
||||||
- [ ] Add back button
|
|
||||||
- [ ] Create Room -> open modal, choose dm or public room
|
|
||||||
- [x] Add DM button to profile pages
|
|
||||||
- [ ] Linkify bech32 entities
|
- [ ] Linkify bech32 entities
|
||||||
- [ ] linkify dm page header
|
|
||||||
- [ ] Add lock/unlock icon to channel header
|
|
||||||
- [ ] Add notification for dms
|
- [ ] Add notification for dms
|
||||||
- [ ] Default to network/following
|
- [ ] Default to network/following
|
||||||
- [ ] Add analytics
|
|
||||||
- [ ] Allow disabling error reporting/analytics
|
|
||||||
|
|
||||||
## 0.2.7
|
## 0.2.7
|
||||||
|
|
||||||
@ -97,6 +88,8 @@ If you like Coracle and want to support its development, you can donate sats via
|
|||||||
- [x] Added error tracking with bugsnag
|
- [x] Added error tracking with bugsnag
|
||||||
- [x] Upgraded nostr-tools
|
- [x] Upgraded nostr-tools
|
||||||
- [x] Added support for NIP-05 verfication
|
- [x] Added support for NIP-05 verfication
|
||||||
|
- [x] Added analytics and error reporting (opt out supported)
|
||||||
|
- [x] Added direct messages and group chat
|
||||||
|
|
||||||
## 0.2.6
|
## 0.2.6
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Bugsnag from "@bugsnag/js"
|
import Bugsnag from "@bugsnag/js"
|
||||||
import {prop, nthArg} from "ramda"
|
import {prop} from "ramda"
|
||||||
import {uuid} from "hurdak/lib/hurdak"
|
import {uuid} from "hurdak/lib/hurdak"
|
||||||
import {navigate} from "svelte-routing"
|
import {navigate} from "svelte-routing"
|
||||||
import {nip19} from 'nostr-tools'
|
import {nip19} from 'nostr-tools'
|
||||||
|
@ -6,11 +6,13 @@
|
|||||||
import {prop, path as getPath, reverse, uniqBy, sortBy, last} from 'ramda'
|
import {prop, path as getPath, reverse, uniqBy, sortBy, last} from 'ramda'
|
||||||
import {formatTimestamp, sleep, createScroller, Cursor} from 'src/util/misc'
|
import {formatTimestamp, sleep, createScroller, Cursor} from 'src/util/misc'
|
||||||
import Badge from 'src/partials/Badge.svelte'
|
import Badge from 'src/partials/Badge.svelte'
|
||||||
|
import Anchor from 'src/partials/Anchor.svelte'
|
||||||
import Spinner from 'src/partials/Spinner.svelte'
|
import Spinner from 'src/partials/Spinner.svelte'
|
||||||
import {user, getPerson} from 'src/agent'
|
import {user, getPerson} from 'src/agent'
|
||||||
import {render} from 'src/app'
|
import {render} from 'src/app'
|
||||||
|
|
||||||
export let name
|
export let name
|
||||||
|
export let link
|
||||||
export let about
|
export let about
|
||||||
export let picture
|
export let picture
|
||||||
export let loadMessages
|
export let loadMessages
|
||||||
@ -18,11 +20,10 @@
|
|||||||
export let sendMessage
|
export let sendMessage
|
||||||
export let editRoom = null
|
export let editRoom = null
|
||||||
export let type
|
export let type
|
||||||
console.log(editRoom)
|
|
||||||
|
|
||||||
let textarea
|
let textarea
|
||||||
let messages = []
|
let messages = []
|
||||||
let loading = sleep(10_000)
|
let loading = sleep(30_000)
|
||||||
let annotatedMessages = []
|
let annotatedMessages = []
|
||||||
let showNewMessages = false
|
let showNewMessages = false
|
||||||
let cursor = new Cursor()
|
let cursor = new Cursor()
|
||||||
@ -64,14 +65,14 @@
|
|||||||
return navigate('/login')
|
return navigate('/login')
|
||||||
}
|
}
|
||||||
|
|
||||||
const sub = listenForMessages(
|
const sub = await listenForMessages(
|
||||||
newMessages => stickToBottom('smooth', () => {
|
newMessages => stickToBottom('smooth', () => {
|
||||||
loading = sleep(10_000)
|
loading = sleep(30_000)
|
||||||
messages = messages.concat(newMessages)
|
messages = messages.concat(newMessages)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
const scroller = createScroller(
|
const scroller = await createScroller(
|
||||||
async () => {
|
async () => {
|
||||||
const events = await loadMessages(cursor)
|
const events = await loadMessages(cursor)
|
||||||
|
|
||||||
@ -79,7 +80,7 @@
|
|||||||
cursor.onChunk(events)
|
cursor.onChunk(events)
|
||||||
|
|
||||||
stickToBottom('auto', () => {
|
stickToBottom('auto', () => {
|
||||||
loading = sleep(10_000)
|
loading = sleep(30_000)
|
||||||
messages = events.concat(messages)
|
messages = events.concat(messages)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -121,8 +122,8 @@
|
|||||||
|
|
||||||
<div class="flex gap-4 h-full">
|
<div class="flex gap-4 h-full">
|
||||||
<div class="relative w-full">
|
<div class="relative w-full">
|
||||||
<div class="flex flex-col py-32 h-full">
|
<div class="flex flex-col pt-20 pb-28 h-full">
|
||||||
<ul class="p-4 h-full flex-grow flex flex-col-reverse justify-start" name="messages">
|
<ul class="pb-6 p-4 overflow-auto flex-grow flex flex-col-reverse justify-start" name="messages">
|
||||||
{#each annotatedMessages as m (m.id)}
|
{#each annotatedMessages as m (m.id)}
|
||||||
<li in:fly={{y: 20}} class="py-1 flex flex-col gap-2">
|
<li in:fly={{y: 20}} class="py-1 flex flex-col gap-2">
|
||||||
{#if type === 'chat' && m.showPerson}
|
{#if type === 'chat' && m.showPerson}
|
||||||
@ -143,22 +144,42 @@
|
|||||||
{/each}
|
{/each}
|
||||||
{#await loading}
|
{#await loading}
|
||||||
<Spinner>Looking for messages...</Spinner>
|
<Spinner>Looking for messages...</Spinner>
|
||||||
|
{:then}
|
||||||
|
<div in:fly={{y: 20}} class="text-center py-20">End of message history</div>
|
||||||
{/await}
|
{/await}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="fixed z-10 top-16 w-full lg:-ml-56 lg:pl-56 border-b border-solid border-medium bg-dark">
|
<div class="fixed z-10 top-16 w-full lg:-ml-56 lg:pl-56 border-b border-solid border-medium bg-dark">
|
||||||
<div class="p-4 flex gap-4">
|
<div class="p-4 flex gap-4">
|
||||||
<div
|
<div class="flex items-center gap-4">
|
||||||
class="overflow-hidden w-12 h-12 rounded-full bg-cover bg-center shrink-0 border border-solid border-white"
|
<i class="fa fa-arrow-left text-2xl cursor-pointer" on:click={() => navigate("/chat")} />
|
||||||
style="background-image: url({picture})" />
|
<div
|
||||||
<div class="w-full">
|
class="overflow-hidden w-12 h-12 rounded-full bg-cover bg-center shrink-0 border border-solid border-white"
|
||||||
|
style="background-image: url({picture})" />
|
||||||
|
</div>
|
||||||
|
<div class="w-full flex flex-col gap-2">
|
||||||
<div class="flex items-center justify-between w-full">
|
<div class="flex items-center justify-between w-full">
|
||||||
<div class="text-lg font-bold">{name || ''}</div>
|
<div class="flex items-center gap-4">
|
||||||
{#if editRoom}
|
{#if link}
|
||||||
<small class="cursor-pointer" on:click={editRoom}>
|
<Anchor type="unstyled" href={link} class="text-lg font-bold">{name || ''}</Anchor>
|
||||||
<i class="fa-solid fa-edit" /> Edit
|
{:else}
|
||||||
</small>
|
<div class="text-lg font-bold">{name || ''}</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if editRoom}
|
||||||
|
<small class="cursor-pointer" on:click={editRoom}>
|
||||||
|
<i class="fa-solid fa-edit" /> Edit
|
||||||
|
</small>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
{#if type === 'dm'}
|
||||||
|
<i class="fa fa-lock text-light" />
|
||||||
|
<span class="text-light">Encrypted</span>
|
||||||
|
{:else}
|
||||||
|
<i class="fa fa-lock-open text-light" />
|
||||||
|
<span class="text-light">Public</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>{about || ''}</div>
|
<div>{about || ''}</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
import {nip19} from 'nostr-tools'
|
import {nip19} from 'nostr-tools'
|
||||||
import {now, batch} from 'src/util/misc'
|
import {now, batch} from 'src/util/misc'
|
||||||
import Channel from 'src/partials/Channel.svelte'
|
import Channel from 'src/partials/Channel.svelte'
|
||||||
import {getRelays, db, listen, load} from 'src/agent'
|
import {getRelays, user, db, listen, load} from 'src/agent'
|
||||||
import {modal} from 'src/app'
|
import {modal} from 'src/app'
|
||||||
import loaders from 'src/app/loaders'
|
import loaders from 'src/app/loaders'
|
||||||
import cmd from 'src/app/cmd'
|
import cmd from 'src/app/cmd'
|
||||||
@ -14,25 +14,42 @@
|
|||||||
let {data: roomId} = nip19.decode(entity)
|
let {data: roomId} = nip19.decode(entity)
|
||||||
let room = liveQuery(() => db.rooms.where('id').equals(roomId).first())
|
let room = liveQuery(() => db.rooms.where('id').equals(roomId).first())
|
||||||
|
|
||||||
const listenForMessages = cb => listen(
|
const getRoomRelays = $room => {
|
||||||
getRelays(),
|
let relays = getRelays()
|
||||||
// Listen for updates to the room in case we didn't get them before
|
|
||||||
[{kinds: [40, 41], ids: [roomId]},
|
|
||||||
{kinds: [42], '#e': [roomId], since: now()}],
|
|
||||||
batch(300, events => {
|
|
||||||
const newMessages = events.filter(e => e.kind === 42)
|
|
||||||
|
|
||||||
loaders.loadPeople(getRelays(), pluck('pubkey', events))
|
if ($room) {
|
||||||
|
relays = relays.concat(getRelays($room.pubkey))
|
||||||
|
}
|
||||||
|
|
||||||
cb(newMessages)
|
return relays
|
||||||
})
|
}
|
||||||
)
|
|
||||||
|
const listenForMessages = async cb => {
|
||||||
|
// Make sure we have our room so we can calculate relays
|
||||||
|
const $room = await db.rooms.where('id').equals(roomId).first()
|
||||||
|
const relays = getRoomRelays($room)
|
||||||
|
|
||||||
|
return listen(
|
||||||
|
relays,
|
||||||
|
// Listen for updates to the room in case we didn't get them before
|
||||||
|
[{kinds: [40, 41], ids: [roomId]},
|
||||||
|
{kinds: [42], '#e': [roomId], since: now()}],
|
||||||
|
batch(300, events => {
|
||||||
|
const newMessages = events.filter(e => e.kind === 42)
|
||||||
|
|
||||||
|
loaders.loadPeople(relays, pluck('pubkey', events))
|
||||||
|
|
||||||
|
cb(newMessages)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const loadMessages = async ({until, limit}) => {
|
const loadMessages = async ({until, limit}) => {
|
||||||
const events = await load(getRelays(), {kinds: [42], '#e': [roomId], until, limit})
|
const relays = getRoomRelays($room)
|
||||||
|
const events = await load(relays, {kinds: [42], '#e': [roomId], until, limit})
|
||||||
|
|
||||||
if (events.length) {
|
if (events.length) {
|
||||||
await loaders.loadPeople(getRelays(), pluck('pubkey', events))
|
await loaders.loadPeople(relays, pluck('pubkey', events))
|
||||||
}
|
}
|
||||||
|
|
||||||
return events
|
return events
|
||||||
@ -51,8 +68,8 @@
|
|||||||
name={$room?.name}
|
name={$room?.name}
|
||||||
about={$room?.about}
|
about={$room?.about}
|
||||||
picture={$room?.picture}
|
picture={$room?.picture}
|
||||||
|
editRoom={$room?.pubkey === $user.pubkey && editRoom}
|
||||||
{loadMessages}
|
{loadMessages}
|
||||||
{listenForMessages}
|
{listenForMessages}
|
||||||
{sendMessage}
|
{sendMessage}
|
||||||
{editRoom}
|
|
||||||
/>
|
/>
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
import {batch} from 'src/util/misc'
|
import {batch} from 'src/util/misc'
|
||||||
import Channel from 'src/partials/Channel.svelte'
|
import Channel from 'src/partials/Channel.svelte'
|
||||||
import {getRelays, user, db, listen, keys} from 'src/agent'
|
import {getRelays, user, db, listen, keys} from 'src/agent'
|
||||||
|
import {routes} from 'src/app/ui'
|
||||||
import cmd from 'src/app/cmd'
|
import cmd from 'src/app/cmd'
|
||||||
|
|
||||||
export let entity
|
export let entity
|
||||||
@ -26,7 +27,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const listenForMessages = cb => listen(
|
const listenForMessages = cb => listen(
|
||||||
getRelays(),
|
getRelays().concat(getRelays(pubkey)),
|
||||||
[{kinds: personKinds, authors: [pubkey]},
|
[{kinds: personKinds, authors: [pubkey]},
|
||||||
{kinds: [4], authors: [$user.pubkey], '#p': [pubkey]},
|
{kinds: [4], authors: [$user.pubkey], '#p': [pubkey]},
|
||||||
{kinds: [4], authors: [pubkey], '#p': [$user.pubkey]}],
|
{kinds: [4], authors: [pubkey], '#p': [$user.pubkey]}],
|
||||||
@ -62,6 +63,7 @@
|
|||||||
name={$person?.name}
|
name={$person?.name}
|
||||||
about={$person?.about}
|
about={$person?.about}
|
||||||
picture={$person?.picture}
|
picture={$person?.picture}
|
||||||
|
link={$person ? routes.person($person.pubkey) : null}
|
||||||
{loadMessages}
|
{loadMessages}
|
||||||
{listenForMessages}
|
{listenForMessages}
|
||||||
{sendMessage}
|
{sendMessage}
|
||||||
|
Loading…
Reference in New Issue
Block a user