diff --git a/src/pages/summary.tsx b/src/pages/summary.tsx index db13390..4e3f3e9 100644 --- a/src/pages/summary.tsx +++ b/src/pages/summary.tsx @@ -17,220 +17,220 @@ import { formatSats } from "number"; import { findTag, getEventFromLocationState } from "utils"; export function StreamSummaryPage() { - const location = useLocation(); - const evPreload = getEventFromLocationState(location.state); - const link = useStreamLink(); - if (link) { - return ; - } + const location = useLocation(); + const evPreload = getEventFromLocationState(location.state); + const link = useStreamLink(); + if (link) { + return ; + } } interface StatSlot { - time: number; - zaps: number; - messages: number; - reactions: number; + time: number; + zaps: number; + messages: number; + reactions: number; } export function StreamSummary({ link, preload }: { link: NostrLink; preload?: NostrEvent }) { - const ev = useCurrentStreamFeed(link, true, preload); - const thisLink = ev ? NostrLink.fromEvent(ev) : undefined; - const data = useLiveChatFeed(thisLink, undefined, 5_000); - const reactions = useEventReactions(thisLink ?? link, data.reactions); + const ev = useCurrentStreamFeed(link, true, preload); + const thisLink = ev ? NostrLink.fromEvent(ev) : undefined; + const data = useLiveChatFeed(thisLink, undefined, 5_000); + const reactions = useEventReactions(thisLink ?? link, data.reactions); - const chatSummary = useMemo(() => { - return Object.entries( - data.messages.reduce((acc, v) => { - acc[v.pubkey] ??= []; - acc[v.pubkey].push(v); - return acc; - }, {} as Record>) - ) - .map(([k, v]) => ({ - pubkey: k, - messages: v, - })) - .sort((a, b) => (a.messages.length > b.messages.length ? -1 : 1)); - }, [data.messages]); + const chatSummary = useMemo(() => { + return Object.entries( + data.messages.reduce((acc, v) => { + acc[v.pubkey] ??= []; + acc[v.pubkey].push(v); + return acc; + }, {} as Record>) + ) + .map(([k, v]) => ({ + pubkey: k, + messages: v, + })) + .sort((a, b) => (a.messages.length > b.messages.length ? -1 : 1)); + }, [data.messages]); - const zapsSummary = useMemo(() => { - return Object.entries( - reactions.zaps.reduce((acc, v) => { - if (!v.sender) return acc; - acc[v.sender] ??= []; - acc[v.sender].push(v); - return acc; - }, {} as Record>) - ) - .map(([k, v]) => ({ - pubkey: k, - zaps: v, - total: v.reduce((acc, vv) => acc + vv.amount, 0), - })) - .sort((a, b) => (a.total > b.total ? -1 : 1)); - }, [reactions.zaps]); + const zapsSummary = useMemo(() => { + return Object.entries( + reactions.zaps.reduce((acc, v) => { + if (!v.sender) return acc; + acc[v.sender] ??= []; + acc[v.sender].push(v); + return acc; + }, {} as Record>) + ) + .map(([k, v]) => ({ + pubkey: k, + zaps: v, + total: v.reduce((acc, vv) => acc + vv.amount, 0), + })) + .sort((a, b) => (a.total > b.total ? -1 : 1)); + }, [reactions.zaps]); - const title = findTag(ev, "title"); - const summary = findTag(ev, "summary"); - const status = findTag(ev, "status"); - const starts = findTag(ev, "starts"); + const title = findTag(ev, "title"); + const summary = findTag(ev, "summary"); + const status = findTag(ev, "status"); + const starts = findTag(ev, "starts"); - const Day = 60 * 60 * 24; - const startTime = starts ? Number(starts) : ev?.created_at ?? unixNow(); - const endTime = status === StreamState.Live ? unixNow() : ev?.created_at ?? unixNow(); + const Day = 60 * 60 * 24; + const startTime = starts ? Number(starts) : ev?.created_at ?? unixNow(); + const endTime = status === StreamState.Live ? unixNow() : ev?.created_at ?? unixNow(); - const streamLength = endTime - startTime; - const windowSize = streamLength > Day ? Day : 60 * 10; + const streamLength = endTime - startTime; + const windowSize = streamLength > Day ? Day : 60 * 10; - const stats = useMemo(() => { - let min = unixNow(); - let max = 0; - const ret = [...data.messages, ...data.reactions] - .sort((a, b) => (a.created_at > b.created_at ? -1 : 1)) - .reduce((acc, v) => { - const time = Math.floor(v.created_at - (v.created_at % windowSize)); - if (time < min) { - min = time; - } - if (time > max) { - max = time; - } - const key = time.toString(); - acc[key] ??= { - time, - zaps: 0, - messages: 0, - reactions: 0, - }; - - if (v.kind === LIVE_STREAM_CHAT) { - acc[key].messages++; - } else if (v.kind === EventKind.ZapReceipt) { - acc[key].zaps++; - } else if (v.kind === EventKind.Reaction) { - acc[key].reactions++; - } else { - console.debug("Uncounted stat", v); - } - return acc; - }, {} as Record); - - // fill empty time slots - for (let x = min; x < max; x += windowSize) { - ret[x.toString()] ??= { - time: x, - zaps: 0, - messages: 0, - reactions: 0, - }; + const stats = useMemo(() => { + let min = unixNow(); + let max = 0; + const ret = [...data.messages, ...data.reactions] + .sort((a, b) => (a.created_at > b.created_at ? -1 : 1)) + .reduce((acc, v) => { + const time = Math.floor(v.created_at - (v.created_at % windowSize)); + if (time < min) { + min = time; } - return ret; - }, [data]); + if (time > max) { + max = time; + } + const key = time.toString(); + acc[key] ??= { + time, + zaps: 0, + messages: 0, + reactions: 0, + }; - return ( -
-

{title}

-

{summary}

-
- - {streamLength > 0 && ( - , - }} - /> - )} -
-

- -

- - - - - - - - { - if (active && payload && payload.length) { - const data = payload[0].payload as StatSlot; - return ( -
-
- -
-
-
- -
-
{data.messages}
-
-
-
- -
-
{data.reactions}
-
-
-
- -
-
{data.zaps}
-
-
- ); - } - return null; - }} - /> -
-
+ if (v.kind === LIVE_STREAM_CHAT) { + acc[key].messages++; + } else if (v.kind === EventKind.ZapReceipt) { + acc[key].zaps++; + } else if (v.kind === EventKind.Reaction) { + acc[key].reactions++; + } else { + console.debug("Uncounted stat", v); + } + return acc; + }, {} as Record); -
-
-

- -

-
- {chatSummary.slice(0, 5).map(a => ( -
- -
- , - }} - /> -
-
- ))} + // fill empty time slots + for (let x = min; x < max; x += windowSize) { + ret[x.toString()] ??= { + time: x, + zaps: 0, + messages: 0, + reactions: 0, + }; + } + return ret; + }, [data]); + + return ( +
+

{title}

+

{summary}

+
+ + {streamLength > 0 && ( + , + }} + /> + )} +
+

+ +

+ + + + + + + + { + if (active && payload && payload.length) { + const data = payload[0].payload as StatSlot; + return ( +
+
+
-
-
-

- -

-
- {zapsSummary.slice(0, 5).map(a => ( -
- -
- -
-
- ))} +
+
+ +
+
{data.messages}
+
+
+ +
+
{data.reactions}
+
+
+
+ +
+
{data.zaps}
+
+
+ ); + } + return null; + }} + /> + + + +
+
+

+ +

+
+ {chatSummary.slice(0, 5).map(a => ( +
+ +
+ , + }} + />
-
+
+ ))} +
- ); +
+

+ +

+
+ {zapsSummary.slice(0, 5).map(a => ( +
+ +
+ +
+
+ ))} +
+
+
+
+ ); }