diff --git a/src/element/stream/live-video-player.tsx b/src/element/stream/live-video-player.tsx index eb49133..4ff844c 100644 --- a/src/element/stream/live-video-player.tsx +++ b/src/element/stream/live-video-player.tsx @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ -import { CSSProperties, HTMLProps } from "react"; +import { CSSProperties, HTMLProps, Suspense, lazy } from "react"; import classNames from "classnames"; import { MediaControlBar, @@ -20,8 +20,8 @@ import { } from "media-chrome/react"; import "hls-video-element"; import { StreamState } from "@/const"; -import Nip94Player from "./n94-player"; import { NostrLink } from "@snort/system"; +const Nip94Player = lazy(() => import("./n94-player")); type VideoPlayerProps = { title?: string; @@ -35,12 +35,15 @@ type VideoPlayerProps = { export default function LiveVideoPlayer({ title, stream, status, poster, link, ...props }: VideoPlayerProps) { function innerPlayer() { if (stream === "nip94") { - return ; - } - { + return ( + + + + ); + } else { /* @ts-ignore Web Componenet */ + return ; } - return ; } return ( import("@/element/summary-chart")); -export function DashboardForLink({ link }: { link: NostrLink }) { +export default function DashboardForLink({ link }: { link: NostrLink }) { + const navigate = useNavigate(); const streamEvent = useCurrentStreamFeed(link, true); const location = useLocation(); const login = useLogin(); const streamLink = streamEvent ? NostrLink.fromEvent(streamEvent) : undefined; const { stream, status, image, participants, service } = extractStreamInfo(streamEvent); const [info, setInfo] = useState(); + const [tos, setTos] = useState(info?.tosAccepted ?? false); const isMyManual = streamEvent?.pubkey === login?.pubkey; const system = useContext(SnortContext); const [recording, setRecording] = useState(Boolean(localStorage.getItem("default-recording") ?? "true")); @@ -126,7 +130,14 @@ export function DashboardForLink({ link }: { link: NostrLink }) { {streamLink && status === StreamState.Live && !isMyManual && ( <> - +
} @@ -170,7 +181,14 @@ export function DashboardForLink({ link }: { link: NostrLink }) { )} {streamLink && isMyManual && (status === StreamState.Live || status === StreamState.Planned) && ( <> - +
} /> @@ -283,6 +301,29 @@ export function DashboardForLink({ link }: { link: NostrLink }) { )} {streamLink && status === StreamState.Planned && } + {info && !info.tosAccepted && ( + +
+

Please accept TOS before continuing

+ +
+ { + if (tos) { + await provider.acceptTos(); + provider.info().then(setInfo); + } + }}> + + + navigate("/")}> + + +
+
+
+ )}
); } diff --git a/src/pages/dashboard/index.tsx b/src/pages/dashboard/index.tsx index 5c0c827..2c878ef 100644 --- a/src/pages/dashboard/index.tsx +++ b/src/pages/dashboard/index.tsx @@ -1,13 +1,19 @@ import { useLogin } from "@/hooks/login"; import { NostrLink, NostrPrefix, parseNostrLink } from "@snort/system"; -import { DashboardForLink } from "./dashboard"; +import { Suspense, lazy } from "react"; import { useParams } from "react-router-dom"; +const DashboardForLink = lazy(() => import("./dashboard")); + export default function DashboardPage() { const login = useLogin(); const { id } = useParams(); if (!login) return; const link = id ? parseNostrLink(id) : new NostrLink(NostrPrefix.PublicKey, login.pubkey); - return ; + return ( + + + + ); } diff --git a/src/pages/dashboard/intro/index.tsx b/src/pages/dashboard/intro/index.tsx index b3d918d..19e4bbf 100644 --- a/src/pages/dashboard/intro/index.tsx +++ b/src/pages/dashboard/intro/index.tsx @@ -7,6 +7,7 @@ import { useEffect, useMemo, useState } from "react"; import { FormattedMessage, FormattedNumber } from "react-intl"; import { useNavigate } from "react-router-dom"; import ZapGlow from "../zap-glow"; +import { AcceptTos } from "../tos"; export default function DashboardIntro() { const navigate = useNavigate(); @@ -16,7 +17,7 @@ export default function DashboardIntro() { const exampleHours = 4; const defaultEndpoint = useMemo(() => { - return info?.endpoints.find(a => a.name == "Best") ?? info?.endpoints[0]; + return info?.endpoints?.find(a => a.name == "Best") ?? info?.endpoints?.at(0); }, [info]); const rate = useRates("BTCUSD"); const exampleCost = rate.ask * (exampleHours * (defaultEndpoint?.rate ?? 0) * 60) * 1e-8; @@ -69,31 +70,7 @@ export default function DashboardIntro() { }} />

- {!info?.tosAccepted && ( -
-
setTos(v => !v)}> - setTos(e.target.checked)} /> -

- { - e.stopPropagation(); - window.open(info?.tosLink, "popup", "width=400,height=800"); - }}> - - - ), - }} - /> -

-
-
- )} + {!info?.tosAccepted && } { diff --git a/src/pages/dashboard/tos.tsx b/src/pages/dashboard/tos.tsx new file mode 100644 index 0000000..5e0a4ab --- /dev/null +++ b/src/pages/dashboard/tos.tsx @@ -0,0 +1,39 @@ +import { FormattedMessage } from "react-intl"; + +export function AcceptTos({ + provider, + tosLink, + tos, + setTos, +}: { + provider?: string; + tosLink?: string; + tos: boolean; + setTos: (f: (r: boolean) => boolean) => void; +}) { + return ( +
+
setTos(v => !v)}> + setTos(() => e.target.checked)} /> +

+ { + e.stopPropagation(); + window.open(tosLink, "popup", "width=400,height=800"); + }}> + + + ), + }} + /> +

+
+
+ ); +} diff --git a/src/translations/en.json b/src/translations/en.json index ffc48d1..a4c1584 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -240,6 +240,7 @@ "gQxxlw": "Goal Name", "gt65Gg": "Stream goals encourage viewers to support streamers via donations.", "gzsn7k": "{n} messages", + "h6NRY6": "No Thanks!", "h9mX2/": "If you use our in-house zap.stream hosting (cheapest and easiest), copy your stream URL and Stream Key to your OBS settings and you should be good to go.", "hMzcSq": "Messages", "heyxZL": "Enable text to speech",