From 31b854963234da1271132e9041689730df5ab95f Mon Sep 17 00:00:00 2001 From: Kieran Date: Thu, 7 Dec 2023 22:50:15 +0000 Subject: [PATCH] feat: stream forwards --- package.json | 4 +- src/element/login-signup.tsx | 4 +- src/element/new-stream.tsx | 5 +- src/element/nostr-provider-dialog.tsx | 122 +++++++++++++++++++------- src/pages/providers/nostr.tsx | 6 +- src/pages/settings-page.tsx | 4 +- src/providers/index.ts | 9 +- src/providers/zsz.ts | 22 ++++- yarn.lock | 40 +++------ 9 files changed, 141 insertions(+), 75 deletions(-) diff --git a/package.json b/package.json index 447a414..1860610 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,8 @@ "@react-hook/resize-observer": "^1.2.6", "@scure/base": "^1.1.3", "@snort/shared": "^1.0.10", - "@snort/system": "^1.1.7", - "@snort/system-react": "^1.1.7", + "@snort/system": "^1.1.8", + "@snort/system-react": "^1.1.8", "@snort/system-wasm": "^1.0.1", "@snort/system-web": "^1.0.2", "@szhsin/react-menu": "^4.0.2", diff --git a/src/element/login-signup.tsx b/src/element/login-signup.tsx index effb7d8..d28a327 100644 --- a/src/element/login-signup.tsx +++ b/src/element/login-signup.tsx @@ -26,7 +26,7 @@ import Copy from "./copy"; import { openFile } from "@/utils"; import { LoginType } from "@/login"; import { DefaultProvider, StreamProviderInfo } from "@/providers"; -import { Nip103StreamProvider } from "@/providers/zsz"; +import { NostrStreamProvider } from "@/providers/zsz"; enum Stage { Login = 0, @@ -109,7 +109,7 @@ export function LoginSignup({ close }: { close: () => void }) { } async function setupProfile() { - const px = new Nip103StreamProvider(DefaultProvider.name, DefaultProvider.url, EventPublisher.privateKey(key)); + const px = new NostrStreamProvider(DefaultProvider.name, DefaultProvider.url, EventPublisher.privateKey(key)); const info = await px.info(); setProviderInfo(info); diff --git a/src/element/new-stream.tsx b/src/element/new-stream.tsx index dd74585..05cb8c4 100644 --- a/src/element/new-stream.tsx +++ b/src/element/new-stream.tsx @@ -8,7 +8,7 @@ import { SnortContext } from "@snort/system-react"; import { Icon } from "./icon"; import { useStreamProvider } from "@/hooks/stream-provider"; -import { StreamProvider, StreamProviders } from "@/providers"; +import { NostrStreamProvider, StreamProvider, StreamProviders } from "@/providers"; import { StreamEditor, StreamEditorProps } from "./stream-editor"; import { eventLink, findTag } from "@/utils"; import { NostrProviderDialog } from "./nostr-provider-dialog"; @@ -65,11 +65,12 @@ function NewStream({ ev, onFinish }: Omit & { onF ); diff --git a/src/element/nostr-provider-dialog.tsx b/src/element/nostr-provider-dialog.tsx index 88a9c72..afc9924 100644 --- a/src/element/nostr-provider-dialog.tsx +++ b/src/element/nostr-provider-dialog.tsx @@ -1,9 +1,9 @@ import { NostrEvent } from "@snort/system"; import { useContext, useEffect, useState } from "react"; -import { FormattedMessage } from "react-intl"; +import { FormattedMessage, useIntl } from "react-intl"; import { SnortContext } from "@snort/system-react"; -import { StreamProvider, StreamProviderEndpoint, StreamProviderInfo } from "@/providers"; +import { NostrStreamProvider, StreamProviderEndpoint, StreamProviderInfo } from "@/providers"; import { SendZaps } from "./send-zap"; import { StreamEditor, StreamEditorProps } from "./stream-editor"; import Spinner from "./spinner"; @@ -13,8 +13,9 @@ export function NostrProviderDialog({ provider, showEndpoints, showEditor, + showForwards, ...others -}: { provider: StreamProvider; showEndpoints: boolean; showEditor: boolean } & StreamEditorProps) { +}: { provider: NostrStreamProvider; showEndpoints: boolean; showEditor: boolean, showForwards: boolean } & StreamEditorProps) { const system = useContext(SnortContext); const [topup, setTopup] = useState(false); const [info, setInfo] = useState(); @@ -133,7 +134,7 @@ export function NostrProviderDialog({

{sortEndpoints(info.endpoints).map(a => ( - setEndpoint(a)}> + setEndpoint(a)}> {a.name} ))} @@ -187,42 +188,101 @@ export function NostrProviderDialog({

{ep?.capabilities?.map(a => ( - {parseCapability(a)} + {parseCapability(a)} ))}
); } + + function streamEditor() { + if (!info || !showEditor) return; + if (info.tosAccepted === false) { + return tosInput(); + } + + return { + provider.updateStreamInfo(system, ex); + others.onFinish?.(ex); + }} + ev={ + { + tags: [ + ["title", info.streamInfo?.title ?? ""], + ["summary", info.streamInfo?.summary ?? ""], + ["image", info.streamInfo?.image ?? ""], + ...(info.streamInfo?.goal ? [["goal", info.streamInfo.goal]] : []), + ...(info.streamInfo?.content_warning ? [["content-warning", info.streamInfo?.content_warning]] : []), + ...(info.streamInfo?.tags?.map(a => ["t", a]) ?? []), + ], + } as NostrEvent + } + options={{ + canSetStream: false, + canSetStatus: false, + }} + />; + } + + function forwardInputs() { + if (!info || !showForwards) return; + + return
+

+ +

+ +
+ {info.forwards?.map(a => <> +
{a.name}
+ { + await provider.removeForward(a.id); + }}> + + +
+ )} + { }} /> +
+
+ } + return ( <> {showEndpoints && streamEndpoints()} - {info.tosAccepted === false ? ( - tosInput() - ) : showEditor ? ( - { - provider.updateStreamInfo(system, ex); - others.onFinish?.(ex); - }} - ev={ - { - tags: [ - ["title", info.streamInfo?.title ?? ""], - ["summary", info.streamInfo?.summary ?? ""], - ["image", info.streamInfo?.image ?? ""], - ...(info.streamInfo?.goal ? [["goal", info.streamInfo.goal]] : []), - ...(info.streamInfo?.content_warning ? [["content-warning", info.streamInfo?.content_warning]] : []), - ...(info.streamInfo?.tags?.map(a => ["t", a]) ?? []), - ], - } as NostrEvent - } - options={{ - canSetStream: false, - canSetStatus: false, - }} - /> - ) : null} + {streamEditor()} + {forwardInputs()} ); } + +function AddForwardInputs({ provider, onAdd }: { provider: NostrStreamProvider, onAdd: (name: string, target: string) => void }) { + const [name, setName] = useState(""); + const [target, setTarget] = useState(""); + const { formatMessage } = useIntl(); + + async function doAdd() { + await provider.addForward(name, target); + setName(""); + setTarget(""); + onAdd(name, target); + } + + return <> +
+ setName(e.target.value)} /> +
+
+ setTarget(e.target.value)} /> +
+ + + + +} \ No newline at end of file diff --git a/src/pages/providers/nostr.tsx b/src/pages/providers/nostr.tsx index a18eafe..2ba88a0 100644 --- a/src/pages/providers/nostr.tsx +++ b/src/pages/providers/nostr.tsx @@ -6,7 +6,7 @@ import AsyncButton from "@/element/async-button"; import { StatePill } from "@/element/state-pill"; import { StreamState } from "@/index"; import { StreamProviderInfo, StreamProviderStore } from "@/providers"; -import { Nip103StreamProvider } from "@/providers/zsz"; +import { NostrStreamProvider } from "@/providers/zsz"; export function ConfigureNostrType() { const [url, setUrl] = useState(""); @@ -15,7 +15,7 @@ export function ConfigureNostrType() { async function tryConnect() { try { - const api = new Nip103StreamProvider(new URL(url).host, url); + const api = new NostrStreamProvider(new URL(url).host, url); const inf = await api.info(); setInfo(inf); } catch (e) { @@ -58,7 +58,7 @@ export function ConfigureNostrType() {