diff --git a/src/app/commands.ts b/src/app/commands.ts index 1e4ffde5..ce4bef9c 100644 --- a/src/app/commands.ts +++ b/src/app/commands.ts @@ -19,12 +19,12 @@ import { } from "@welshman/util" import type {TrustedEvent, EventTemplate} from "@welshman/util" import type {SubscribeRequestWithHandlers} from "@welshman/net" +import {PublishStatus, AuthStatus, ConnectionStatus} from "@welshman/net" import {Nip59, stamp} from "@welshman/signer" import { pubkey, signer, repository, - makeThunk, publishThunk, loadProfile, loadInboxRelaySelections, @@ -40,6 +40,7 @@ import { userRelaySelections, userInboxRelaySelections, nip44EncryptToSelf, + loadRelay, } from "@welshman/app" import {tagRoom, userMembership, MEMBERSHIPS, INDEXER_RELAYS, loadMembership} from "@app/state" @@ -112,7 +113,7 @@ export const broadcastUserData = async (relays: string[]) => { for (const event of events) { if (isSignedEvent(event)) { - await publishThunk(makeThunk({event, relays})) + await publishThunk({event, relays}) } } } @@ -186,18 +187,46 @@ export const setInboxRelayPolicy = (url: string, enabled: boolean) => { } } -export const joinRelay = async (url: string, claim?: string) => { - if (claim) { - await publishThunk( - makeThunk({ - event: createEvent(28934, {tags: [["claim", claim]]}), - relays: [url], - }), - ) +// Relay access + +export const requestRelayAccess = (url: string, claim = "") => + publishThunk({ + event: createEvent(28934, {tags: [["claim", claim]]}), + relays: [url], + }) + +export const attemptRelayAccess = async (url: string, claim = "") => { + const relay = await loadRelay(url) + + // Make sure the relay has a profile + if (!relay?.profile) { + return "Sorry, we weren't able to find that relay." } - await setRelayPolicy(url, true, true) - await broadcastUserData([url]) + const connection = ctx.net.pool.get(url) + + // Check connection status + await connection.ensureConnected() + + if (![ConnectionStatus.Ok, ConnectionStatus.Slow].includes(connection.meta.getStatus())) { + return `Failed to connect: "${connection.meta.getDescription()}"` + } + + // Attempt to publish a join request + const result = await requestRelayAccess(url, claim) + + if (result[url].status !== PublishStatus.Success) { + const message = result[url].message?.replace(/^.*: /, '') || "join request rejected" + + return `Failed to join relay: ${message}` + } + + // Check auth status + await connection.ensureAuth() + + if (![AuthStatus.Ok, AuthStatus.Pending].includes(connection.meta.authStatus)) { + return `Failed to authenticate: "${connection.meta.authStatus}"` + } } // Actions @@ -213,12 +242,10 @@ export const sendWrapped = async ({ await Promise.all( uniq(pubkeys).map(async recipient => { - return publishThunk( - makeThunk({ - event: await nip59.wrap(recipient, stamp(template)), - relays: ctx.app.router.PublishMessage(recipient).getUrls(), - }), - ) + return publishThunk({ + event: await nip59.wrap(recipient, stamp(template)), + relays: ctx.app.router.PublishMessage(recipient).getUrls(), + }) }), ) } @@ -247,10 +274,10 @@ export const publishReaction = ({ event: TrustedEvent content: string tags?: string[][] -}) => publishThunk(makeThunk({event: makeReaction({event, content, tags}), relays})) +}) => publishThunk({event: makeReaction({event, content, tags}), relays}) export const makeDelete = ({event}: {event: TrustedEvent}) => createEvent(DELETE, {tags: [["k", String(event.kind)], ...tagEvent(event)]}) export const publishDelete = ({relays, event}: {relays: string[]; event: TrustedEvent}) => - publishThunk(makeThunk({event: makeDelete({event}), relays})) + publishThunk({event: makeDelete({event}), relays}) diff --git a/src/app/components/ChannelThread.svelte b/src/app/components/ChannelThread.svelte index a38860b4..110cc318 100644 --- a/src/app/components/ChannelThread.svelte +++ b/src/app/components/ChannelThread.svelte @@ -2,7 +2,7 @@ import {sortBy, append} from "@welshman/lib" import {createEvent} from "@welshman/util" import type {EventContent, TrustedEvent} from "@welshman/util" - import {repository, makeThunk, publishThunk} from "@welshman/app" + import {repository, publishThunk} from "@welshman/app" import {deriveEvents} from "@welshman/store" import ChannelMessage from "@app/components/ChannelMessage.svelte" import ChannelCompose from "@app/components/ChannelCompose.svelte" @@ -39,7 +39,7 @@ const reply = createEvent(REPLY, {content, tags: append(tagRoom(room, url), tags)}) - publishThunk(makeThunk({event: reply, relays: [url]})) + publishThunk({event: reply, relays: [url]}) } diff --git a/src/app/components/ChatMessageEmojiButton.svelte b/src/app/components/ChatMessageEmojiButton.svelte index 065522f1..d2c62a7b 100644 --- a/src/app/components/ChatMessageEmojiButton.svelte +++ b/src/app/components/ChatMessageEmojiButton.svelte @@ -4,7 +4,7 @@ import {ctx, uniq, between} from "@welshman/lib" import {Nip59} from "@welshman/signer" import type {TrustedEvent} from "@welshman/util" - import {makeThunk, signer, publishThunk} from "@welshman/app" + import {signer, publishThunk} from "@welshman/app" import Icon from "@lib/components/Icon.svelte" import Button from "@lib/components/Button.svelte" import Tippy from "@lib/components/Tippy.svelte" @@ -23,12 +23,10 @@ for (const recipient of uniq(pubkeys)) { const rumor = await nip59.wrap(recipient, template) - publishThunk( - makeThunk({ - event: rumor.wrap, - relays: ctx.app.router.PublishMessage(recipient).getUrls(), - }), - ) + publishThunk({ + event: rumor.wrap, + relays: ctx.app.router.PublishMessage(recipient).getUrls(), + }) } popover.hide() diff --git a/src/app/components/ChatStart.svelte b/src/app/components/ChatStart.svelte index 952f165f..80246cef 100644 --- a/src/app/components/ChatStart.svelte +++ b/src/app/components/ChatStart.svelte @@ -3,6 +3,8 @@ import Field from "@lib/components/Field.svelte" import Button from "@lib/components/Button.svelte" import Icon from "@lib/components/Icon.svelte" + import ModalHeader from "@lib/components/ModalHeader.svelte" + import ModalFooter from "@lib/components/ModalFooter.svelte" import ProfileMultiSelect from "@app/components/ProfileMultiSelect.svelte" import {makeChatPath} from "@app/routes" @@ -16,15 +18,17 @@
diff --git a/src/app/components/EventCreate.svelte b/src/app/components/EventCreate.svelte index 2e28c5fd..37f32ee8 100644 --- a/src/app/components/EventCreate.svelte +++ b/src/app/components/EventCreate.svelte @@ -5,10 +5,12 @@ import {createEditor, type Editor, EditorContent} from "svelte-tiptap" import {randomId} from "@welshman/lib" import {createEvent, EVENT_DATE, EVENT_TIME} from "@welshman/util" - import {publishThunk, makeThunk, dateToSeconds} from "@welshman/app" + import {publishThunk, dateToSeconds} from "@welshman/app" import Icon from "@lib/components/Icon.svelte" import Field from "@lib/components/Field.svelte" import Button from "@lib/components/Button.svelte" + import ModalHeader from "@lib/components/ModalHeader.svelte" + import ModalFooter from "@lib/components/ModalFooter.svelte" import DateTimeInput from "@lib/components/DateTimeInput.svelte" import {getPubkeyHints} from "@app/commands" import {getEditorOptions, addFile, uploadFiles, getEditorTags} from "@lib/editor" @@ -51,7 +53,7 @@ ], }) - publishThunk(makeThunk({event, relays: [url]})) + publishThunk({event, relays: [url]}) clearModal() } @@ -68,10 +70,10 @@ diff --git a/src/app/components/LogOut.svelte b/src/app/components/LogOut.svelte index 484142be..a766be48 100644 --- a/src/app/components/LogOut.svelte +++ b/src/app/components/LogOut.svelte @@ -3,6 +3,8 @@ import Icon from "@lib/components/Icon.svelte" import Button from "@lib/components/Button.svelte" import Spinner from "@lib/components/Spinner.svelte" + import ModalHeader from "@lib/components/ModalHeader.svelte" + import ModalFooter from "@lib/components/ModalFooter.svelte" const back = () => history.back() @@ -23,8 +25,10 @@ diff --git a/src/app/components/RoomCreate.svelte b/src/app/components/RoomCreate.svelte index 1446c038..241e76e5 100644 --- a/src/app/components/RoomCreate.svelte +++ b/src/app/components/RoomCreate.svelte @@ -6,6 +6,7 @@ import Button from "@lib/components/Button.svelte" import Icon from "@lib/components/Icon.svelte" import ModalHeader from "@lib/components/ModalHeader.svelte" + import ModalFooter from '@lib/components/ModalFooter.svelte' import {addRoomMembership} from "@app/commands" import {makeSpacePath} from "@app/routes" @@ -46,7 +47,7 @@ -Once you've created a relay of your own, come back here to link Flotilla with your new relay.
-