Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove legacy message #471

Merged
merged 5 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 45 additions & 33 deletions src/app/views/ChannelsDetail.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,15 @@
import {onMount, onDestroy} from "svelte"
import {deriveEvents} from "@welshman/store"
import {DIRECT_MESSAGE} from "@welshman/util"
import {session} from "@welshman/app"
import {inboxRelaySelectionsByPubkey, session} from "@welshman/app"
import {repository, displayProfileByPubkey, loadInboxRelaySelections} from "@welshman/app"
import Channel from "src/partials/Channel.svelte"
import Anchor from "src/partials/Anchor.svelte"
import PersonCircles from "src/app/shared/PersonCircles.svelte"
import PersonAbout from "src/app/shared/PersonAbout.svelte"
import {router} from "src/app/util/router"
import {
hasNip44,
sendMessage,
sendLegacyMessage,
markChannelRead,
getChannelIdFromEvent,
listenForMessages,
} from "src/engine"
import {sendMessage, markChannelRead, getChannelIdFromEvent, listenForMessages} from "src/engine"
import Popover from "src/partials/Popover.svelte"

export let pubkeys
export let channelId
Expand All @@ -28,16 +22,15 @@
$events => $events.filter(e => getChannelIdFromEvent(e) === channelId),
)

const pubkeysWithoutInbox = derived(inboxRelaySelectionsByPubkey, $inboxRelayPoliciesByPubkey =>
pubkeys.filter(pubkey => !$inboxRelayPoliciesByPubkey.has(pubkey)),
)

let isAccepted

const showPerson = pubkey => router.at("people").of(pubkey).open()

const send = async (content, useNip17) => {
// If we don't have nip44 support, just send a legacy message
if (!$hasNip44 || !useNip17) {
return sendLegacyMessage(channelId, content)
}

const send = async content => {
await sendMessage(channelId, content)
}

Expand All @@ -60,25 +53,44 @@
</script>

<Channel {pubkeys} messages={$messages} sendMessage={send} {initialMessage}>
<div slot="header" class="flex h-16 items-start gap-4 overflow-hidden p-1 px-4">
<div class="flex items-center gap-4 pt-1">
<Anchor
class="fa fa-arrow-left cursor-pointer text-2xl"
href={"/channels" + (isAccepted ? "" : "/requests")} />
<PersonCircles {pubkeys} />
</div>
<div class="flex h-12 w-full flex-col overflow-hidden pt-1">
<div class="w-full">
{#each pubkeys as pubkey, i (pubkey)}
{#if i > 0}&bullet;{/if}
<Anchor class="hover:underline" on:click={() => showPerson(pubkey)}>
{displayProfileByPubkey(pubkey)}
</Anchor>
{/each}
<div slot="header" class="flex h-16 justify-between px-4">
<div class="flex items-center gap-4">
<div class="flex items-center gap-4 pt-1">
<Anchor
class="fa fa-arrow-left cursor-pointer text-2xl"
href={"/channels" + (isAccepted ? "" : "/requests")} />
<PersonCircles {pubkeys} />
</div>
<div class="flex flex-col items-start overflow-hidden pt-2">
<div>
{#each pubkeys as pubkey, i (pubkey)}
{#if i > 0}&bullet;{/if}
<Anchor class="hover:underline" on:click={() => showPerson(pubkey)}>
{displayProfileByPubkey(pubkey)}
</Anchor>
{/each}
</div>
{#if pubkeys.length === 1}
<PersonAbout truncate pubkey={pubkeys[0]} />
{/if}
</div>
{#if pubkeys.length === 1}
<PersonAbout truncate pubkey={pubkeys[0]} />
{/if}
</div>
{#if $pubkeysWithoutInbox.length > 0}
<div class="flex items-center">
<Popover triggerType="mouseenter" placement="left">
<div
slot="trigger"
class="flex cursor-pointer items-center gap-1 rounded-full bg-danger px-2">
<i class="fa fa-exclamation-triangle" />
<span>
{$pubkeysWithoutInbox.length}
</span>
</div>
<div slot="tooltip">
{$pubkeysWithoutInbox.length} inbox is not configured
</div>
</Popover>
</div>
{/if}
</div>
</Channel>
21 changes: 1 addition & 20 deletions src/engine/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ import {
} from "@welshman/util"
import crypto from "crypto"
import {Fetch, seconds, sleep, tryFunc} from "hurdak"
import {assoc, flatten, identity, omit, prop, reject, uniq, without} from "ramda"
import {assoc, flatten, identity, omit, prop, reject, uniq} from "ramda"
import {
addClientTags,
anonymous,
Expand Down Expand Up @@ -409,25 +409,6 @@ export const markAsSeen = async (kind: number, eventsByKey: Record<string, Trust

// Messages

export const sendLegacyMessage = async (channelId: string, content: string) => {
const $pubkey = pubkey.get()
const recipients = without([$pubkey], channelId.split(","))

if (recipients.length > 1) {
throw new Error("Attempted to send legacy message to more than 1 recipient")
}

const recipient = recipients[0] || $pubkey

return createAndPublish({
kind: 4,
tags: [tagPubkey(recipient), ...getClientTags()],
content: await signer.get().nip04.encrypt(recipient, content),
relays: ctx.app.router.PubkeyInbox(recipient).getUrls(),
forcePlatform: false,
})
}

export const sendMessage = async (channelId: string, content: string) => {
const recipients = channelId.split(",")
const template = {
Expand Down
60 changes: 7 additions & 53 deletions src/partials/Channel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import {onMount} from "svelte"
import {pluralize} from "hurdak"
import {derived} from "svelte/store"
import {sleep, remove} from "@welshman/lib"
import {sleep} from "@welshman/lib"
import type {TrustedEvent} from "@welshman/util"
import {Nip46Signer} from "@welshman/signer"
import {
Expand All @@ -18,7 +18,6 @@
import Spinner from "src/partials/Spinner.svelte"
import Anchor from "src/partials/Anchor.svelte"
import Popover from "src/partials/Popover.svelte"
import Toggle from "src/partials/Toggle.svelte"
import FlexColumn from "src/partials/FlexColumn.svelte"
import Modal from "src/partials/Modal.svelte"
import Subheading from "src/partials/Subheading.svelte"
Expand All @@ -30,14 +29,13 @@
import Compose from "src/app/shared/Compose.svelte"

export let pubkeys
export let sendMessage
export let sendMessage: (content: string) => Promise<void>
export let initialMessage = ""
export let messages: TrustedEvent[]

let editor: Editor

const loading = sleep(5_000)
const toggleScale = 0.7

const startScroller = () => {
scroller?.stop()
Expand Down Expand Up @@ -65,14 +63,10 @@
let showNewMessages = false
let groupedMessages = []

const isGroupMessage = pubkeys.length > 2
const recipients = remove($session?.pubkey, pubkeys)
const pubkeysWithoutInbox = derived(inboxRelaySelectionsByPubkey, $inboxRelayPoliciesByPubkey =>
pubkeys.filter(pubkey => !$inboxRelayPoliciesByPubkey.has(pubkey)),
)

let useNip17 = isGroupMessage || ($hasNip44 && $pubkeysWithoutInbox.length === 0)

onMount(() => {
editor = new Editor(
getEditorOptions({
Expand Down Expand Up @@ -119,7 +113,7 @@
}

const sendOrConfirm = () => {
if (isGroupMessage && $pubkeysWithoutInbox.length > 0) {
if ($pubkeysWithoutInbox.length > 0) {
openConfirm()
} else {
send()
Expand All @@ -132,7 +126,7 @@
if (content) {
sending = true

await sendMessage(content, useNip17)
await sendMessage(content)

sending = false
stickToBottom()
Expand All @@ -141,7 +135,6 @@
}

$: userHasInbox = !$pubkeysWithoutInbox.includes($session?.pubkey)
$: hasSingleRecipientWithInbox = !isGroupMessage && !$pubkeysWithoutInbox.includes(recipients[0])

// Group messages so we're only showing the person once per chunk
$: {
Expand Down Expand Up @@ -247,12 +240,12 @@
<div in:fly={{y: 20}} class="py-20 text-center">End of message history</div>
{/await}
</div>
{#if $hasNip44 || !isGroupMessage}
{#if $hasNip44}
<div class="flex border-t border-solid border-tinted-700 bg-neutral-900 dark:bg-neutral-600">
<Compose
bind:element={textarea}
{editor}
class="mb-8 h-20 w-full resize-none bg-transparent p-2 text-neutral-100 outline-0 placeholder:text-neutral-100" />
class="w-full resize-none bg-transparent p-2 text-neutral-100 outline-0 placeholder:text-neutral-100" />
<div>
<button
on:click={() => editor.commands.selectFiles()}
Expand All @@ -267,44 +260,6 @@
<i class="fa-solid fa-paper-plane fa-lg" />
</button>
</div>
{#if $hasNip44 && hasSingleRecipientWithInbox}
<div class="fixed bottom-0 right-12 flex items-center justify-end gap-2 p-2">
{#if userHasInbox}
<Toggle scale={toggleScale} bind:value={useNip17} />
{:else}
<Popover triggerType="mouseenter">
<div slot="trigger">
<Toggle disabled scale={toggleScale} value={false} />
</div>
<Anchor modal slot="tooltip" class="flex items-center gap-1" href="/settings/relays">
<i class="fa fa-info-circle" />
You must have at least one inbox relay to send messages using nip-17. Click here to set
up your inbox relays.
</Anchor>
</Popover>
{/if}
<small>
Send messages using
<Popover class="inline">
<span slot="trigger" class="cursor-pointer underline">NIP 17</span>
<div slot="tooltip" class="flex flex-col gap-2">
<p>
When enabled, Coracle will use nostr's new group chat specification, which solves
several problems with legacy DMs. Read more <Anchor
underline
modal
href="/help/nip-17-dms">here</Anchor
>.
</p>
<p>
Note that these messages are not yet universally supported. Make sure the person
you're chatting with is using a compatible nostr client.
</p>
</div>
</Popover>
</small>
</div>
{/if}
</div>
{:else}
<FlexColumn class="bg-neutral-900 px-4 py-2">
Expand Down Expand Up @@ -332,8 +287,7 @@
<p>
{displayList($pubkeysWithoutInbox.map(displayProfileByPubkey))}
{pluralize($pubkeysWithoutInbox.length, "does not have", "do not have")}
inbox relays, which means they likely either don't want to receive DMs, or are using a client
that does not support nostr group chats.
inbox relays, which means they likely don't want to receive DMs.
</p>
{:else if !userHasInbox}
<p>
Expand Down