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(() => {