diff --git a/src/element/new-stream.tsx b/src/element/new-stream.tsx index f6b1a87..fbceec7 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 48de82d..1fa21b0 100644 --- a/src/pages/layout.tsx +++ b/src/pages/layout.tsx @@ -1,6 +1,11 @@ import { Icon } from "element/icon"; import "./layout.css"; -import { EventPublisher } from "@snort/system"; +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"; @@ -58,6 +63,19 @@ export function LayoutPage() { ); } + function goToStream(ev: NostrEvent) { + 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); + } + return ( <>
@@ -74,7 +92,7 @@ export function LayoutPage() { {newStream && ( setNewStream(false)}> - navigate("/")} /> + )} 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(() => {