From 90a7d2ca7ea2524396d7d93e618138bf0035313f Mon Sep 17 00:00:00 2001 From: Kieran Date: Tue, 1 Aug 2023 16:54:06 +0100 Subject: [PATCH] feat: pubkey stream loading chore: faster stream navigation --- src/element/new-stream.tsx | 4 ++- src/element/video-tile.tsx | 1 + src/hooks/current-stream-feed.ts | 12 +++++++- src/index.tsx | 5 ++++ src/pages/catch-all.tsx | 6 ++++ src/pages/stream-page.tsx | 12 ++++---- src/utils.ts | 50 +++++++++++++++++++++++++------- 7 files changed, 72 insertions(+), 18 deletions(-) create mode 100644 src/pages/catch-all.tsx diff --git a/src/element/new-stream.tsx b/src/element/new-stream.tsx index b32226c..d387943 100644 --- a/src/element/new-stream.tsx +++ b/src/element/new-stream.tsx @@ -31,7 +31,9 @@ function NewStream({ ev, onFinish }: StreamEditorProps) { onFinish={(ex) => { currentProvider.updateStreamInfo(ex); if (!ev) { - navigate(eventLink(ex)); + navigate(`/${eventLink(ex)}`, { + state: ev + }); } else { onFinish?.(ev); } diff --git a/src/element/video-tile.tsx b/src/element/video-tile.tsx index 4c53e10..313cbcd 100644 --- a/src/element/video-tile.tsx +++ b/src/element/video-tile.tsx @@ -43,6 +43,7 @@ export function VideoTile({ to={`/${link}`} className={`video-tile${contentWarning ? " nsfw" : ""}`} ref={ref} + state={ev} >
{ @@ -38,6 +44,10 @@ export function useCurrentStreamFeed(link: NostrLink, leaveOpen = false) { const q = useRequestBuilder(System, NoteCollection, sub); + if (evPreload) { + q.add(evPreload as TaggedRawEvent); + } + return useMemo(() => { const hosting = q.data?.filter( (a) => diff --git a/src/index.tsx b/src/index.tsx index 97b4621..bf3bb62 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -15,6 +15,7 @@ import { ChatPopout } from "pages/chat-popout"; import { LoginStore } from "login"; import { StreamProvidersPage } from "pages/providers"; import { defaultRelays } from "const"; +import { CatchAllRoutePage } from "pages/catch-all"; export enum StreamState { Live = "live", @@ -58,6 +59,10 @@ const router = createBrowserRouter([ path: "/providers/:id?", element: , }, + { + path: "*", + element: + } ], }, { diff --git a/src/pages/catch-all.tsx b/src/pages/catch-all.tsx new file mode 100644 index 0000000..c77c796 --- /dev/null +++ b/src/pages/catch-all.tsx @@ -0,0 +1,6 @@ + +export function CatchAllRoutePage() { + //const { ["*"]: param } = useParams(); + + return Not found :( +} \ No newline at end of file diff --git a/src/pages/stream-page.tsx b/src/pages/stream-page.tsx index df2c905..0609420 100644 --- a/src/pages/stream-page.tsx +++ b/src/pages/stream-page.tsx @@ -1,14 +1,13 @@ import "./stream-page.css"; import { parseNostrLink, TaggedRawEvent } from "@snort/system"; -import { useNavigate, useParams } from "react-router-dom"; +import { useLocation, useNavigate, useParams } from "react-router-dom"; import { Helmet } from "react-helmet"; import { LiveVideoPlayer } from "element/live-video-player"; -import { findTag, getHost } from "utils"; +import { createNostrLink, findTag, getEventFromLocationState, getHost } from "utils"; import { Profile, getName } from "element/profile"; import { LiveChat } from "element/live-chat"; import AsyncButton from "element/async-button"; -import useEventFeed from "hooks/event-feed"; import { useLogin } from "hooks/login"; import { useZapGoal } from "hooks/goals"; import { StreamState, System } from "index"; @@ -26,6 +25,7 @@ import { ContentWarningOverlay, isContentWarningAccepted, } from "element/content-warning"; +import { useCurrentStreamFeed } from "hooks/current-stream-feed"; function ProfileInfo({ ev, goal }: { ev?: NostrEvent; goal?: TaggedRawEvent }) { const login = useLogin(); @@ -107,8 +107,10 @@ function ProfileInfo({ ev, goal }: { ev?: NostrEvent; goal?: TaggedRawEvent }) { export function StreamPage() { const params = useParams(); + const location = useLocation(); + const evPreload = getEventFromLocationState(location.state); const link = parseNostrLink(params.id!); - const { data: ev } = useEventFeed(link, true); + const ev = useCurrentStreamFeed(link, true, evPreload); const host = getHost(ev); const goal = useZapGoal(host, link, true); @@ -151,7 +153,7 @@ export function StreamPage() {
- + ); } diff --git a/src/utils.ts b/src/utils.ts index 609d9d8..331980c 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,14 @@ -import { NostrEvent, NostrPrefix, encodeTLV } from "@snort/system"; +import { + NostrEvent, + NostrPrefix, + TaggedRawEvent, + encodeTLV, + parseNostrLink, +} from "@snort/system"; import * as utils from "@noble/curves/abstract/utils"; import { bech32 } from "@scure/base"; import type { Tag, Tags } from "types"; +import { LIVE_STREAM } from "const"; export function toAddress(e: NostrEvent): string { if (e.kind && e.kind >= 30000 && e.kind <= 40000) { @@ -70,16 +77,28 @@ export function splitByUrl(str: string) { return str.split(urlRegex); } -export function eventLink(ev: NostrEvent) { - const d = findTag(ev, "d") ?? ""; - const naddr = encodeTLV( - NostrPrefix.Address, - d, - undefined, - ev.kind, - ev.pubkey - ); - return `/${naddr}`; +export function eventLink(ev: NostrEvent | TaggedRawEvent) { + if (ev.kind && ev.kind >= 30000 && ev.kind <= 40000) { + const d = findTag(ev, "d") ?? ""; + return encodeTLV( + NostrPrefix.Address, + d, + "relays" in ev ? ev.relays : undefined, + ev.kind, + ev.pubkey + ); + } else { + return encodeTLV( + NostrPrefix.Event, + ev.id, + "relays" in ev ? ev.relays : undefined + ); + } +} + +export function createNostrLink(ev?: NostrEvent) { + if (!ev) return; + return parseNostrLink(eventLink(ev)); } export function getHost(ev?: NostrEvent) { @@ -113,3 +132,12 @@ export function getTagValues(tags: Tags, tag: string): Array { .filter((t) => t) .map((t) => t as string); } + +export function getEventFromLocationState(state: unknown | undefined | null) { + return state && + typeof state === "object" && + "kind" in state && + state.kind === LIVE_STREAM + ? (state as NostrEvent) + : undefined; +}