From 28e8b5fffa27080556818dd310b4b84a4a59ffbf Mon Sep 17 00:00:00 2001 From: Alejandro Gomez Date: Sat, 24 Jun 2023 13:12:18 +0200 Subject: [PATCH 1/3] fix: redirect to stream after starting it --- package.json | 1 + src/element/new-stream.tsx | 184 +++++++++++++++++++++---------------- src/pages/layout.tsx | 125 +++++++++++++++---------- yarn.lock | 44 ++++++++- 4 files changed, 221 insertions(+), 133 deletions(-) diff --git a/package.json b/package.json index 9b34a33..c83fcf1 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "@testing-library/react": "^13.0.0", "@testing-library/user-event": "^13.2.1", "hls.js": "^1.4.6", + "nostr-tools": "^1.12.0", "qr-code-styling": "^1.6.0-rc.1", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/src/element/new-stream.tsx b/src/element/new-stream.tsx index f6b1a87..ee5530d 100644 --- a/src/element/new-stream.tsx +++ b/src/element/new-stream.tsx @@ -6,93 +6,115 @@ import AsyncButton from "./async-button"; import { System } from "index"; import { findTag } from "utils"; -export function NewStream({ ev, onFinish }: { ev?: NostrEvent, onFinish: () => void }) { - const [title, setTitle] = useState(findTag(ev, "title") ?? ""); - const [summary, setSummary] = useState(findTag(ev, "summary") ?? ""); - const [image, setImage] = useState(findTag(ev, "image") ?? ""); - const [stream, setStream] = useState(findTag(ev, "streaming") ?? ""); - const [isValid, setIsValid] = useState(false); +export function NewStream({ + ev, + onFinish, +}: { + ev?: NostrEvent; + onFinish: (ev: NostrEvent) => void; +}) { + const [title, setTitle] = useState(findTag(ev, "title") ?? ""); + const [summary, setSummary] = useState(findTag(ev, "summary") ?? ""); + const [image, setImage] = useState(findTag(ev, "image") ?? ""); + const [stream, setStream] = useState(findTag(ev, "streaming") ?? ""); + const [isValid, setIsValid] = useState(false); - function validate() { - if (title.length < 2) { - return false; - } - if (stream.length < 5 || !stream.match(/^https?:\/\/.*\.m3u8?$/i)) { - return false; - } - if (image.length > 0 && !image.match(/^https?:\/\//i)) { - return false; - } - return true; + function validate() { + if (title.length < 2) { + return false; } - - useEffect(() => { - setIsValid(validate()); - }, [title, summary, image, stream]); - - async function publishStream() { - const pub = await EventPublisher.nip7(); - if (pub) { - const evNew = await pub.generic(eb => { - const now = unixNow(); - const dTag = findTag(ev, "d") ?? now.toString(); - return eb.kind(30_311) - .tag(["d", dTag]) - .tag(["title", title]) - .tag(["summary", summary]) - .tag(["image", image]) - .tag(["streaming", stream]) - .tag(["status", "live"]) - }); - console.debug(evNew); - System.BroadcastEvent(evNew); - onFinish(); - } + if (stream.length < 5 || !stream.match(/^https?:\/\/.*\.m3u8?$/i)) { + return false; } + if (image.length > 0 && !image.match(/^https?:\/\//i)) { + return false; + } + return true; + } - return
-

- {ev ? "Edit Stream" : "New Stream"} -

-
-

- Title -

-
- setTitle(e.target.value)} /> -
+ useEffect(() => { + setIsValid(validate()); + }, [title, summary, image, stream]); + + async function publishStream() { + const pub = await EventPublisher.nip7(); + if (pub) { + const evNew = await pub.generic((eb) => { + const now = unixNow(); + const dTag = findTag(ev, "d") ?? now.toString(); + return eb + .kind(30_311) + .tag(["d", dTag]) + .tag(["title", title]) + .tag(["summary", summary]) + .tag(["image", image]) + .tag(["streaming", stream]) + .tag(["status", "live"]); + }); + console.debug(evNew); + //System.BroadcastEvent(evNew); + onFinish(evNew); + } + } + + return ( +
+

{ev ? "Edit Stream" : "New Stream"}

+
+

Title

+
+ setTitle(e.target.value)} + />
-
-

- Summary -

-
- setSummary(e.target.value)} /> -
+
+
+

Summary

+
+ setSummary(e.target.value)} + />
-
-

- Cover image -

-
- setImage(e.target.value)} /> -
+
+
+

Cover image

+
+ setImage(e.target.value)} + />
-
-

- Stream Url -

-
- setStream(e.target.value)} /> -
- - Stream type should be HLS - -
-
- - {ev ? "Save" : "Start Stream"} - +
+
+

Stream Url

+
+ setStream(e.target.value)} + />
+ Stream type should be HLS +
+
+ + {ev ? "Save" : "Start Stream"} + +
-} \ No newline at end of file + ); +} diff --git a/src/pages/layout.tsx b/src/pages/layout.tsx index b5c479c..25c9c3d 100644 --- a/src/pages/layout.tsx +++ b/src/pages/layout.tsx @@ -1,6 +1,7 @@ import { Icon } from "element/icon"; import "./layout.css"; -import { EventPublisher } from "@snort/system"; +import { EventPublisher, NostrEvent } from "@snort/system"; +import { nip19 } from "nostr-tools"; import { Outlet, useNavigate } from "react-router-dom"; import AsyncButton from "element/async-button"; import { Login } from "index"; @@ -11,59 +12,83 @@ import { NewStream } from "element/new-stream"; import { useState } from "react"; export function LayoutPage() { - const navigate = useNavigate(); - const login = useLogin(); - const [newStream, setNewStream] = useState(false); + const navigate = useNavigate(); + const login = useLogin(); + const [newStream, setNewStream] = useState(false); - async function doLogin() { - const pub = await EventPublisher.nip7(); - if (pub) { - Login.loginWithPubkey(pub.pubKey); - } + async function doLogin() { + const pub = await EventPublisher.nip7(); + if (pub) { + Login.loginWithPubkey(pub.pubKey); } + } - function loggedIn() { - if (!login) return; + function loggedIn() { + if (!login) return; - return <> - - - + return ( + <> + + + + ); + } + + function loggedOut() { + if (login) return; + + return ( + <> + + Login + + + + ); + } + + function goToStream(ev: NostrEvent) { + const addr = { + pubkey: ev.pubkey, + kind: ev.kind, + identifier: ev.tags.find(t => t.at(0) === "d")?.at(1) || "", } + const naddr = nip19.naddrEncode(addr) + navigate(`/live/${naddr}`); + setNewStream(false) + } - function loggedOut() { - if (login) return; - - return <> - - Login - - - - } - - return <> -
-
navigate("/")}> - S -
-
- - -
-
- {loggedIn()} - {loggedOut()} -
-
- - {newStream && setNewStream(false)} > - navigate("/")} /> - } + return ( + <> +
+
navigate("/")}>S
+
+ + +
+
+ {loggedIn()} + {loggedOut()} +
+
+ + {newStream && ( + setNewStream(false)}> + + + )} -} \ No newline at end of file + ); +} diff --git a/yarn.lock b/yarn.lock index 86b54f5..7066560 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1646,6 +1646,13 @@ dependencies: eslint-scope "5.1.1" +"@noble/curves@1.0.0", "@noble/curves@~1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.0.0.tgz#e40be8c7daf088aaf291887cbc73f43464a92932" + integrity sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw== + dependencies: + "@noble/hashes" "1.3.0" + "@noble/curves@^1.0.0", "@noble/curves@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" @@ -1653,7 +1660,12 @@ dependencies: "@noble/hashes" "1.3.1" -"@noble/hashes@1.3.1", "@noble/hashes@^1.3.1": +"@noble/hashes@1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1" + integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg== + +"@noble/hashes@1.3.1", "@noble/hashes@^1.3.1", "@noble/hashes@~1.3.0": version "1.3.1" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== @@ -1741,11 +1753,28 @@ resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.3.2.tgz#31b9c510d8cada9683549e1dbb4284cca5001faf" integrity sha512-V+MvGwaHH03hYhY+k6Ef/xKd6RYlc4q8WBx+2ANmipHJcKuktNcI/NgEsJgdSUF6Lw32njT6OnrRsKYCdgHjYw== -"@scure/base@1.1.1", "@scure/base@^1.1.1": +"@scure/base@1.1.1", "@scure/base@^1.1.1", "@scure/base@~1.1.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== +"@scure/bip32@1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.0.tgz#6c8d980ef3f290987736acd0ee2e0f0d50068d87" + integrity sha512-bcKpo1oj54hGholplGLpqPHRbIsnbixFtc06nwuNM5/dwSXOq/AAYoIBRsBmnZJSdfeNW5rnff7NTAz3ZCqR9Q== + dependencies: + "@noble/curves" "~1.0.0" + "@noble/hashes" "~1.3.0" + "@scure/base" "~1.1.0" + +"@scure/bip39@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.0.tgz#a207e2ef96de354de7d0002292ba1503538fc77b" + integrity sha512-SX/uKq52cuxm4YFXWFaVByaSHJh2w3BnokVSeUJVCv6K7WulT9u2BuNRBhuFl8vAuYnzx9bEu9WgpcNYTrYieg== + dependencies: + "@noble/hashes" "~1.3.0" + "@scure/base" "~1.1.0" + "@sinclair/typebox@^0.24.1": version "0.24.51" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" @@ -6644,6 +6673,17 @@ normalize-url@^6.0.1: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== +nostr-tools@^1.12.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/nostr-tools/-/nostr-tools-1.12.0.tgz#ec3618fc2298e029941b7db3bbe95187777c488f" + integrity sha512-fsIXaNJPKaSrO9MxsCEWbhI4tG4pToQK4D4sgLRD0fRDfZ6ocCg8CLlh9lcNx0o8pVErCMLVASxbJ+w4WNK0MA== + dependencies: + "@noble/curves" "1.0.0" + "@noble/hashes" "1.3.0" + "@scure/base" "1.1.1" + "@scure/bip32" "1.3.0" + "@scure/bip39" "1.2.0" + npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" From d3b18850ad9ecf1a7d35745a172b12c6a9902c2f Mon Sep 17 00:00:00 2001 From: Alejandro Gomez Date: Sat, 24 Jun 2023 13:19:11 +0200 Subject: [PATCH 2/3] fix: use encodeTLV --- package.json | 1 - src/element/new-stream.tsx | 2 +- src/pages/layout.tsx | 11 +++------- yarn.lock | 44 ++------------------------------------ 4 files changed, 6 insertions(+), 52 deletions(-) diff --git a/package.json b/package.json index c83fcf1..9b34a33 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ "@testing-library/react": "^13.0.0", "@testing-library/user-event": "^13.2.1", "hls.js": "^1.4.6", - "nostr-tools": "^1.12.0", "qr-code-styling": "^1.6.0-rc.1", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/src/element/new-stream.tsx b/src/element/new-stream.tsx index ee5530d..fbceec7 100644 --- a/src/element/new-stream.tsx +++ b/src/element/new-stream.tsx @@ -52,7 +52,7 @@ export function NewStream({ .tag(["status", "live"]); }); console.debug(evNew); - //System.BroadcastEvent(evNew); + System.BroadcastEvent(evNew); onFinish(evNew); } } diff --git a/src/pages/layout.tsx b/src/pages/layout.tsx index 25c9c3d..ca6c08c 100644 --- a/src/pages/layout.tsx +++ b/src/pages/layout.tsx @@ -1,7 +1,6 @@ import { Icon } from "element/icon"; import "./layout.css"; -import { EventPublisher, NostrEvent } from "@snort/system"; -import { nip19 } from "nostr-tools"; +import { EventPublisher, NostrEvent, encodeTLV, NostrPrefix } from "@snort/system"; import { Outlet, useNavigate } from "react-router-dom"; import AsyncButton from "element/async-button"; import { Login } from "index"; @@ -60,12 +59,8 @@ export function LayoutPage() { } function goToStream(ev: NostrEvent) { - const addr = { - pubkey: ev.pubkey, - kind: ev.kind, - identifier: ev.tags.find(t => t.at(0) === "d")?.at(1) || "", - } - const naddr = nip19.naddrEncode(addr) + const d = ev.tags.find(t => t.at(0) === "d")?.at(1) || "" + const naddr = encodeTLV(NostrPrefix.Address, d, undefined, ev.kind, ev.pubkey) navigate(`/live/${naddr}`); setNewStream(false) } diff --git a/yarn.lock b/yarn.lock index 7066560..86b54f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1646,13 +1646,6 @@ dependencies: eslint-scope "5.1.1" -"@noble/curves@1.0.0", "@noble/curves@~1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.0.0.tgz#e40be8c7daf088aaf291887cbc73f43464a92932" - integrity sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw== - dependencies: - "@noble/hashes" "1.3.0" - "@noble/curves@^1.0.0", "@noble/curves@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" @@ -1660,12 +1653,7 @@ dependencies: "@noble/hashes" "1.3.1" -"@noble/hashes@1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1" - integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg== - -"@noble/hashes@1.3.1", "@noble/hashes@^1.3.1", "@noble/hashes@~1.3.0": +"@noble/hashes@1.3.1", "@noble/hashes@^1.3.1": version "1.3.1" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== @@ -1753,28 +1741,11 @@ resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.3.2.tgz#31b9c510d8cada9683549e1dbb4284cca5001faf" integrity sha512-V+MvGwaHH03hYhY+k6Ef/xKd6RYlc4q8WBx+2ANmipHJcKuktNcI/NgEsJgdSUF6Lw32njT6OnrRsKYCdgHjYw== -"@scure/base@1.1.1", "@scure/base@^1.1.1", "@scure/base@~1.1.0": +"@scure/base@1.1.1", "@scure/base@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== -"@scure/bip32@1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.0.tgz#6c8d980ef3f290987736acd0ee2e0f0d50068d87" - integrity sha512-bcKpo1oj54hGholplGLpqPHRbIsnbixFtc06nwuNM5/dwSXOq/AAYoIBRsBmnZJSdfeNW5rnff7NTAz3ZCqR9Q== - dependencies: - "@noble/curves" "~1.0.0" - "@noble/hashes" "~1.3.0" - "@scure/base" "~1.1.0" - -"@scure/bip39@1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.0.tgz#a207e2ef96de354de7d0002292ba1503538fc77b" - integrity sha512-SX/uKq52cuxm4YFXWFaVByaSHJh2w3BnokVSeUJVCv6K7WulT9u2BuNRBhuFl8vAuYnzx9bEu9WgpcNYTrYieg== - dependencies: - "@noble/hashes" "~1.3.0" - "@scure/base" "~1.1.0" - "@sinclair/typebox@^0.24.1": version "0.24.51" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" @@ -6673,17 +6644,6 @@ normalize-url@^6.0.1: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== -nostr-tools@^1.12.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/nostr-tools/-/nostr-tools-1.12.0.tgz#ec3618fc2298e029941b7db3bbe95187777c488f" - integrity sha512-fsIXaNJPKaSrO9MxsCEWbhI4tG4pToQK4D4sgLRD0fRDfZ6ocCg8CLlh9lcNx0o8pVErCMLVASxbJ+w4WNK0MA== - dependencies: - "@noble/curves" "1.0.0" - "@noble/hashes" "1.3.0" - "@scure/base" "1.1.1" - "@scure/bip32" "1.3.0" - "@scure/bip39" "1.2.0" - npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" From 31adf40f7111844fd02098e959421e77fd246561 Mon Sep 17 00:00:00 2001 From: Kieran Date: Thu, 22 Jun 2023 22:27:27 +0100 Subject: [PATCH 3/3] Stop home page re-sub --- src/pages/root.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/pages/root.tsx b/src/pages/root.tsx index 53624ef..a4b9dad 100644 --- a/src/pages/root.tsx +++ b/src/pages/root.tsx @@ -9,10 +9,13 @@ import { VideoTile } from "../element/video-tile"; import { findTag } from "utils"; export function RootPage() { - const rb = new RequestBuilder("root"); - rb.withFilter() - .kinds([30_311 as EventKind]) - .since(unixNow() - 86400); + const rb = useMemo(() => { + const rb = new RequestBuilder("root"); + rb.withFilter() + .kinds([30_311 as EventKind]) + .since(unixNow() - 86400); + return rb; + }, []); const feed = useRequestBuilder(System, ParameterizedReplaceableNoteStore, rb); const feedSorted = useMemo(() => {