Merge branch 'main' into emotes

This commit is contained in:
Alejandro Gomez
2023-06-24 14:50:57 +02:00
3 changed files with 130 additions and 87 deletions

View File

@ -6,7 +6,13 @@ import AsyncButton from "./async-button";
import { System } from "index"; import { System } from "index";
import { findTag } from "utils"; import { findTag } from "utils";
export function NewStream({ ev, onFinish }: { ev?: NostrEvent, onFinish: () => void }) { export function NewStream({
ev,
onFinish,
}: {
ev?: NostrEvent;
onFinish: (ev: NostrEvent) => void;
}) {
const [title, setTitle] = useState(findTag(ev, "title") ?? ""); const [title, setTitle] = useState(findTag(ev, "title") ?? "");
const [summary, setSummary] = useState(findTag(ev, "summary") ?? ""); const [summary, setSummary] = useState(findTag(ev, "summary") ?? "");
const [image, setImage] = useState(findTag(ev, "image") ?? ""); const [image, setImage] = useState(findTag(ev, "image") ?? "");
@ -33,66 +39,82 @@ export function NewStream({ ev, onFinish }: { ev?: NostrEvent, onFinish: () => v
async function publishStream() { async function publishStream() {
const pub = await EventPublisher.nip7(); const pub = await EventPublisher.nip7();
if (pub) { if (pub) {
const evNew = await pub.generic(eb => { const evNew = await pub.generic((eb) => {
const now = unixNow(); const now = unixNow();
const dTag = findTag(ev, "d") ?? now.toString(); const dTag = findTag(ev, "d") ?? now.toString();
return eb.kind(30_311) return eb
.kind(30_311)
.tag(["d", dTag]) .tag(["d", dTag])
.tag(["title", title]) .tag(["title", title])
.tag(["summary", summary]) .tag(["summary", summary])
.tag(["image", image]) .tag(["image", image])
.tag(["streaming", stream]) .tag(["streaming", stream])
.tag(["status", "live"]) .tag(["status", "live"]);
}); });
console.debug(evNew); console.debug(evNew);
System.BroadcastEvent(evNew); System.BroadcastEvent(evNew);
onFinish(); onFinish(evNew);
} }
} }
return <div className="new-stream"> return (
<h3> <div className="new-stream">
{ev ? "Edit Stream" : "New Stream"} <h3>{ev ? "Edit Stream" : "New Stream"}</h3>
</h3>
<div> <div>
<p> <p>Title</p>
Title
</p>
<div className="input"> <div className="input">
<input type="text" placeholder="What are we steaming today?" value={title} onChange={e => setTitle(e.target.value)} /> <input
type="text"
placeholder="What are we steaming today?"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
</div> </div>
</div> </div>
<div> <div>
<p> <p>Summary</p>
Summary
</p>
<div className="input"> <div className="input">
<input type="text" placeholder="A short description of the content" value={summary} onChange={e => setSummary(e.target.value)} /> <input
type="text"
placeholder="A short description of the content"
value={summary}
onChange={(e) => setSummary(e.target.value)}
/>
</div> </div>
</div> </div>
<div> <div>
<p> <p>Cover image</p>
Cover image
</p>
<div className="input"> <div className="input">
<input type="text" placeholder="https://" value={image} onChange={e => setImage(e.target.value)} /> <input
type="text"
placeholder="https://"
value={image}
onChange={(e) => setImage(e.target.value)}
/>
</div> </div>
</div> </div>
<div> <div>
<p> <p>Stream Url</p>
Stream Url
</p>
<div className="input"> <div className="input">
<input type="text" placeholder="https://" value={stream} onChange={e => setStream(e.target.value)} /> <input
type="text"
placeholder="https://"
value={stream}
onChange={(e) => setStream(e.target.value)}
/>
</div> </div>
<small> <small>Stream type should be HLS</small>
Stream type should be HLS
</small>
</div> </div>
<div> <div>
<AsyncButton type="button" className="btn btn-primary" disabled={!isValid} onClick={publishStream}> <AsyncButton
type="button"
className="btn btn-primary"
disabled={!isValid}
onClick={publishStream}
>
{ev ? "Save" : "Start Stream"} {ev ? "Save" : "Start Stream"}
</AsyncButton> </AsyncButton>
</div> </div>
</div> </div>
);
} }

View File

@ -1,6 +1,11 @@
import { Icon } from "element/icon"; import { Icon } from "element/icon";
import "./layout.css"; import "./layout.css";
import { EventPublisher } from "@snort/system"; import {
EventPublisher,
NostrEvent,
encodeTLV,
NostrPrefix,
} from "@snort/system";
import { Outlet, useNavigate } from "react-router-dom"; import { Outlet, useNavigate } from "react-router-dom";
import AsyncButton from "element/async-button"; import AsyncButton from "element/async-button";
import { Login } from "index"; 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 ( return (
<> <>
<header> <header>
@ -74,7 +92,7 @@ export function LayoutPage() {
<Outlet /> <Outlet />
{newStream && ( {newStream && (
<Modal onClose={() => setNewStream(false)}> <Modal onClose={() => setNewStream(false)}>
<NewStream onFinish={() => navigate("/")} /> <NewStream onFinish={goToStream} />
</Modal> </Modal>
)} )}
</> </>

View File

@ -9,10 +9,13 @@ import { VideoTile } from "../element/video-tile";
import { findTag } from "utils"; import { findTag } from "utils";
export function RootPage() { export function RootPage() {
const rb = useMemo(() => {
const rb = new RequestBuilder("root"); const rb = new RequestBuilder("root");
rb.withFilter() rb.withFilter()
.kinds([30_311 as EventKind]) .kinds([30_311 as EventKind])
.since(unixNow() - 86400); .since(unixNow() - 86400);
return rb;
}, []);
const feed = useRequestBuilder<ParameterizedReplaceableNoteStore>(System, ParameterizedReplaceableNoteStore, rb); const feed = useRequestBuilder<ParameterizedReplaceableNoteStore>(System, ParameterizedReplaceableNoteStore, rb);
const feedSorted = useMemo(() => { const feedSorted = useMemo(() => {