@ -15,8 +15,8 @@
|
|||||||
"@react-hook/resize-observer": "^1.2.6",
|
"@react-hook/resize-observer": "^1.2.6",
|
||||||
"@scure/base": "^1.1.1",
|
"@scure/base": "^1.1.1",
|
||||||
"@snort/shared": "^1.0.9",
|
"@snort/shared": "^1.0.9",
|
||||||
"@snort/system": "^1.1.1",
|
"@snort/system": "^1.1.4",
|
||||||
"@snort/system-react": "^1.1.1",
|
"@snort/system-react": "^1.1.4",
|
||||||
"@snort/system-web": "^1.0.2",
|
"@snort/system-web": "^1.0.2",
|
||||||
"@szhsin/react-menu": "^4.0.2",
|
"@szhsin/react-menu": "^4.0.2",
|
||||||
"@testing-library/jest-dom": "^5.14.1",
|
"@testing-library/jest-dom": "^5.14.1",
|
||||||
|
@ -55,7 +55,7 @@ export function ChatMessage({
|
|||||||
const profile = useUserProfile(inView?.isIntersecting ? ev.pubkey : undefined);
|
const profile = useUserProfile(inView?.isIntersecting ? ev.pubkey : undefined);
|
||||||
const shouldShowMuteButton = ev.pubkey !== streamer && ev.pubkey !== login?.pubkey;
|
const shouldShowMuteButton = ev.pubkey !== streamer && ev.pubkey !== login?.pubkey;
|
||||||
const zapTarget = profile?.lud16 ?? profile?.lud06;
|
const zapTarget = profile?.lud16 ?? profile?.lud06;
|
||||||
const { zaps, reactions } = useEventReactions(ev, related);
|
const { zaps, reactions } = useEventReactions(link, related);
|
||||||
const emojiNames = emojiPacks.map(p => p.emojis).flat();
|
const emojiNames = emojiPacks.map(p => p.emojis).flat();
|
||||||
|
|
||||||
const filteredReactions = useMemo(() => {
|
const filteredReactions = useMemo(() => {
|
||||||
@ -175,15 +175,15 @@ export function ChatMessage({
|
|||||||
style={
|
style={
|
||||||
isTablet
|
isTablet
|
||||||
? {
|
? {
|
||||||
display: showZapDialog || isHovering ? "flex" : "none",
|
display: showZapDialog || isHovering ? "flex" : "none",
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
position: "fixed",
|
position: "fixed",
|
||||||
top: topOffset ? topOffset - 12 : 0,
|
top: topOffset ? topOffset - 12 : 0,
|
||||||
left: leftOffset ? leftOffset - 32 : 0,
|
left: leftOffset ? leftOffset - 32 : 0,
|
||||||
opacity: showZapDialog || isHovering ? 1 : 0,
|
opacity: showZapDialog || isHovering ? 1 : 0,
|
||||||
pointerEvents: showZapDialog || isHovering ? "auto" : "none",
|
pointerEvents: showZapDialog || isHovering ? "auto" : "none",
|
||||||
}
|
}
|
||||||
}>
|
}>
|
||||||
{zapTarget && (
|
{zapTarget && (
|
||||||
<SendZapsDialog
|
<SendZapsDialog
|
||||||
|
@ -30,7 +30,7 @@ export function Goal({ ev }: { ev: NostrEvent }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const soFar = useMemo(() => {
|
const soFar = useMemo(() => {
|
||||||
return zaps.filter(z => z.receiver === ev.pubkey && z.event?.id === ev.id).reduce((acc, z) => acc + z.amount, 0);
|
return zaps.filter(z => z.receiver === ev.pubkey && z.targetEvents.some(a => a.matchesEvent(ev))).reduce((acc, z) => acc + z.amount, 0);
|
||||||
}, [zaps]);
|
}, [zaps]);
|
||||||
|
|
||||||
const progress = Math.max(0, Math.min(100, (soFar / goalAmount) * 100));
|
const progress = Math.max(0, Math.min(100, (soFar / goalAmount) * 100));
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import "./live-chat.css";
|
import "./live-chat.css";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
import { EventKind, NostrPrefix, NostrLink, ParsedZap, NostrEvent, parseZap, encodeTLV } from "@snort/system";
|
import { EventKind, NostrLink, ParsedZap, NostrEvent } from "@snort/system";
|
||||||
|
import { useEventReactions } from "@snort/system-react";
|
||||||
import { unixNow } from "@snort/shared";
|
import { unixNow } from "@snort/shared";
|
||||||
import { useContext, useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import uniqBy from "lodash.uniqby";
|
import uniqBy from "lodash.uniqby";
|
||||||
|
|
||||||
import { Icon } from "element/icon";
|
import { Icon } from "element/icon";
|
||||||
@ -23,7 +24,6 @@ import { formatSats } from "number";
|
|||||||
import { WEEK, LIVE_STREAM_CHAT } from "const";
|
import { WEEK, LIVE_STREAM_CHAT } from "const";
|
||||||
import { findTag, getTagValues, getHost } from "utils";
|
import { findTag, getTagValues, getHost } from "utils";
|
||||||
import { TopZappers } from "element/top-zappers";
|
import { TopZappers } from "element/top-zappers";
|
||||||
import { SnortContext } from "@snort/system-react";
|
|
||||||
|
|
||||||
export interface LiveChatOptions {
|
export interface LiveChatOptions {
|
||||||
canWrite?: boolean;
|
canWrite?: boolean;
|
||||||
@ -61,7 +61,6 @@ export function LiveChat({
|
|||||||
options?: LiveChatOptions;
|
options?: LiveChatOptions;
|
||||||
height?: number;
|
height?: number;
|
||||||
}) {
|
}) {
|
||||||
const system = useContext(SnortContext);
|
|
||||||
const host = getHost(ev);
|
const host = getHost(ev);
|
||||||
const feed = useLiveChatFeed(link, goal ? [goal.id] : undefined);
|
const feed = useLiveChatFeed(link, goal ? [goal.id] : undefined);
|
||||||
const login = useLogin();
|
const login = useLogin();
|
||||||
@ -80,15 +79,11 @@ export function LiveChat({
|
|||||||
return uniqBy(userEmojiPacks.concat(channelEmojiPacks), packId);
|
return uniqBy(userEmojiPacks.concat(channelEmojiPacks), packId);
|
||||||
}, [userEmojiPacks, channelEmojiPacks]);
|
}, [userEmojiPacks, channelEmojiPacks]);
|
||||||
|
|
||||||
const zaps = feed.zaps.map(ev => parseZap(ev, system.ProfileLoader.Cache)).filter(z => z && z.valid);
|
const reactions = useEventReactions(link, feed.reactions);
|
||||||
const events = useMemo(() => {
|
const events = useMemo(() => {
|
||||||
return [...feed.messages, ...feed.zaps, ...awards].sort((a, b) => b.created_at - a.created_at);
|
return [...feed.messages, ...feed.reactions, ...awards].sort((a, b) => b.created_at - a.created_at);
|
||||||
}, [feed.messages, feed.zaps, awards]);
|
}, [feed.messages, feed.reactions, awards]);
|
||||||
const naddr = useMemo(() => {
|
|
||||||
if (ev) {
|
|
||||||
return encodeTLV(NostrPrefix.Address, findTag(ev, "d") ?? "", undefined, ev.kind, ev.pubkey);
|
|
||||||
}
|
|
||||||
}, [ev]);
|
|
||||||
const filteredEvents = useMemo(() => {
|
const filteredEvents = useMemo(() => {
|
||||||
return events.filter(e => !mutedPubkeys.has(e.pubkey) && !hostMutedPubkeys.has(e.pubkey));
|
return events.filter(e => !mutedPubkeys.has(e.pubkey) && !hostMutedPubkeys.has(e.pubkey));
|
||||||
}, [events, mutedPubkeys, hostMutedPubkeys]);
|
}, [events, mutedPubkeys, hostMutedPubkeys]);
|
||||||
@ -104,17 +99,17 @@ export function LiveChat({
|
|||||||
name="link"
|
name="link"
|
||||||
className="secondary"
|
className="secondary"
|
||||||
size={32}
|
size={32}
|
||||||
onClick={() => window.open(`/chat/${naddr}?chat=true`, "_blank", "popup,width=400,height=800")}
|
onClick={() => window.open(`/chat/${link.encode()}?chat=true`, "_blank", "popup,width=400,height=800")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{zaps.length > 0 && (
|
{reactions.zaps.length > 0 && (
|
||||||
<div className="top-zappers">
|
<div className="top-zappers">
|
||||||
<h3>
|
<h3>
|
||||||
<FormattedMessage defaultMessage="Top zappers" />
|
<FormattedMessage defaultMessage="Top zappers" />
|
||||||
</h3>
|
</h3>
|
||||||
<div className="top-zappers-container">
|
<div className="top-zappers-container">
|
||||||
<TopZappers zaps={zaps} />
|
<TopZappers zaps={reactions.zaps} />
|
||||||
</div>
|
</div>
|
||||||
{goal && <Goal ev={goal} />}
|
{goal && <Goal ev={goal} />}
|
||||||
</div>
|
</div>
|
||||||
@ -138,7 +133,7 @@ export function LiveChat({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
case EventKind.ZapReceipt: {
|
case EventKind.ZapReceipt: {
|
||||||
const zap = zaps.find(b => b.id === a.id && b.receiver === host);
|
const zap = reactions.zaps.find(b => b.id === a.id && b.receiver === host);
|
||||||
if (zap) {
|
if (zap) {
|
||||||
return <ChatZap zap={zap} key={a.id} />;
|
return <ChatZap zap={zap} key={a.id} />;
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,18 @@
|
|||||||
import { NostrLink, RequestBuilder, EventKind, NoteCollection } from "@snort/system";
|
import { NostrLink, RequestBuilder, NoteCollection } from "@snort/system";
|
||||||
import { SnortContext, useRequestBuilder } from "@snort/system-react";
|
import { useReactions, useRequestBuilder } from "@snort/system-react";
|
||||||
import { unixNow, unwrap } from "@snort/shared";
|
import { unixNow } from "@snort/shared";
|
||||||
import { useContext, useEffect, useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { LIVE_STREAM_CHAT, WEEK } from "const";
|
import { LIVE_STREAM_CHAT, WEEK } from "const";
|
||||||
import { findTag } from "utils";
|
|
||||||
|
|
||||||
export function useLiveChatFeed(link: NostrLink, eZaps?: Array<string>) {
|
export function useLiveChatFeed(link: NostrLink, eZaps?: Array<string>) {
|
||||||
const system = useContext(SnortContext);
|
|
||||||
const since = useMemo(() => unixNow() - WEEK, [link.id]);
|
const since = useMemo(() => unixNow() - WEEK, [link.id]);
|
||||||
const sub = useMemo(() => {
|
const sub = useMemo(() => {
|
||||||
const rb = new RequestBuilder(`live:${link.id}:${link.author}`);
|
const rb = new RequestBuilder(`live:${link.id}:${link.author}`);
|
||||||
rb.withOptions({
|
rb.withOptions({
|
||||||
leaveOpen: true,
|
leaveOpen: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const aTag = `${link.kind}:${link.author}:${link.id}`;
|
const aTag = `${link.kind}:${link.author}:${link.id}`;
|
||||||
rb.withFilter().kinds([LIVE_STREAM_CHAT]).tag("a", [aTag]).limit(100);
|
rb.withFilter().kinds([LIVE_STREAM_CHAT]).tag("a", [aTag]).limit(100);
|
||||||
rb.withFilter().kinds([EventKind.ZapReceipt]).tag("a", [aTag]).since(since);
|
|
||||||
if (eZaps) {
|
|
||||||
rb.withFilter().kinds([EventKind.ZapReceipt]).tag("e", eZaps);
|
|
||||||
}
|
|
||||||
return rb;
|
return rb;
|
||||||
}, [link.id, since, eZaps]);
|
}, [link.id, since, eZaps]);
|
||||||
|
|
||||||
@ -28,33 +21,7 @@ export function useLiveChatFeed(link: NostrLink, eZaps?: Array<string>) {
|
|||||||
const messages = useMemo(() => {
|
const messages = useMemo(() => {
|
||||||
return (feed.data ?? []).filter(ev => ev.kind === LIVE_STREAM_CHAT);
|
return (feed.data ?? []).filter(ev => ev.kind === LIVE_STREAM_CHAT);
|
||||||
}, [feed.data]);
|
}, [feed.data]);
|
||||||
const zaps = useMemo(() => {
|
|
||||||
return (feed.data ?? []).filter(ev => ev.kind === EventKind.ZapReceipt);
|
|
||||||
}, [feed.data]);
|
|
||||||
|
|
||||||
const etags = useMemo(() => {
|
const reactions = useReactions(`live:${link.id}:${link.author}:reactions`, messages.map(a => NostrLink.fromEvent(a)).concat(link), undefined, true);
|
||||||
return messages.map(e => e.id);
|
return { messages, reactions: reactions.data ?? [] };
|
||||||
}, [messages]);
|
|
||||||
|
|
||||||
const esub = useMemo(() => {
|
|
||||||
if (etags.length === 0) return null;
|
|
||||||
const rb = new RequestBuilder(`reactions:${link.id}:${link.author}`);
|
|
||||||
rb.withOptions({
|
|
||||||
leaveOpen: true,
|
|
||||||
});
|
|
||||||
rb.withFilter().kinds([EventKind.Reaction, EventKind.ZapReceipt]).tag("e", etags);
|
|
||||||
return rb;
|
|
||||||
}, [etags]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const pubkeys = [...new Set(zaps.flatMap(a => [a.pubkey, unwrap(findTag(a, "p"))]))];
|
|
||||||
system.ProfileLoader.TrackMetadata(pubkeys);
|
|
||||||
return () => system.ProfileLoader.UntrackMetadata(pubkeys);
|
|
||||||
}, [zaps]);
|
|
||||||
|
|
||||||
const reactionsSub = useRequestBuilder(NoteCollection, esub);
|
|
||||||
|
|
||||||
const reactions = reactionsSub.data ?? [];
|
|
||||||
|
|
||||||
return { messages, zaps, reactions };
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { useContext, useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { RequestBuilder, NoteCollection, NostrLink, EventKind, parseZap } from "@snort/system";
|
import { RequestBuilder, NoteCollection, NostrLink } from "@snort/system";
|
||||||
import { SnortContext, useRequestBuilder } from "@snort/system-react";
|
import { useRequestBuilder } from "@snort/system-react";
|
||||||
import { LIVE_STREAM } from "const";
|
import { LIVE_STREAM } from "const";
|
||||||
import { findTag } from "utils";
|
import { useZaps } from "./zaps";
|
||||||
|
|
||||||
export function useProfile(link: NostrLink, leaveOpen = false) {
|
export function useProfile(link: NostrLink, leaveOpen = false) {
|
||||||
const system = useContext(SnortContext);
|
|
||||||
const sub = useMemo(() => {
|
const sub = useMemo(() => {
|
||||||
const b = new RequestBuilder(`profile:${link.id.slice(0, 12)}`);
|
const b = new RequestBuilder(`profile:${link.id.slice(0, 12)}`);
|
||||||
b.withOptions({
|
b.withOptions({
|
||||||
@ -20,35 +19,11 @@ export function useProfile(link: NostrLink, leaveOpen = false) {
|
|||||||
return b;
|
return b;
|
||||||
}, [link, leaveOpen]);
|
}, [link, leaveOpen]);
|
||||||
|
|
||||||
const { data: streamsData } = useRequestBuilder(NoteCollection, sub);
|
const streams = useRequestBuilder(NoteCollection, sub);
|
||||||
const streams = streamsData ?? [];
|
const zaps = useZaps(link);
|
||||||
|
|
||||||
const addresses = useMemo(() => {
|
|
||||||
if (streamsData) {
|
|
||||||
return streamsData.map(e => `${e.kind}:${e.pubkey}:${findTag(e, "d")}`);
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}, [streamsData]);
|
|
||||||
|
|
||||||
const zapsSub = useMemo(() => {
|
|
||||||
const b = new RequestBuilder(`profile-zaps:${link.id.slice(0, 12)}`);
|
|
||||||
b.withOptions({
|
|
||||||
leaveOpen,
|
|
||||||
})
|
|
||||||
.withFilter()
|
|
||||||
.kinds([EventKind.ZapReceipt])
|
|
||||||
.tag("a", addresses);
|
|
||||||
return b;
|
|
||||||
}, [link, addresses, leaveOpen]);
|
|
||||||
|
|
||||||
const { data: zapsData } = useRequestBuilder(NoteCollection, zapsSub);
|
|
||||||
const zaps = (zapsData ?? [])
|
|
||||||
.map(ev => parseZap(ev, system.ProfileLoader.Cache))
|
|
||||||
.filter(z => z && z.valid && z.receiver === link.id);
|
|
||||||
|
|
||||||
const sortedStreams = useMemo(() => {
|
const sortedStreams = useMemo(() => {
|
||||||
const sorted = [...streams];
|
const sorted = [...(streams.data ?? [])].sort((a, b) => b.created_at - a.created_at);
|
||||||
sorted.sort((a, b) => b.created_at - a.created_at);
|
|
||||||
return sorted;
|
return sorted;
|
||||||
}, [streams]);
|
}, [streams]);
|
||||||
|
|
||||||
|
@ -1,22 +1,13 @@
|
|||||||
import { useContext, useMemo, useEffect } from "react";
|
import { useMemo } from "react";
|
||||||
import { unwrap } from "@snort/shared";
|
import { NostrLink, RequestBuilder, EventKind, NoteCollection, parseZap } from "@snort/system";
|
||||||
import { NostrLink, RequestBuilder, NostrPrefix, EventKind, NoteCollection, parseZap } from "@snort/system";
|
import { useRequestBuilder } from "@snort/system-react";
|
||||||
import { SnortContext, useRequestBuilder } from "@snort/system-react";
|
|
||||||
import { findTag } from "utils";
|
|
||||||
|
|
||||||
export function useZaps(link?: NostrLink, leaveOpen = false) {
|
export function useZaps(link?: NostrLink, leaveOpen = false) {
|
||||||
const system = useContext(SnortContext);
|
|
||||||
const sub = useMemo(() => {
|
const sub = useMemo(() => {
|
||||||
if (link) {
|
if (link) {
|
||||||
const b = new RequestBuilder(`zaps:${link.id}`);
|
const b = new RequestBuilder(`zaps:${link.id}`);
|
||||||
b.withOptions({ leaveOpen });
|
b.withOptions({ leaveOpen });
|
||||||
if (link.type === NostrPrefix.Event || link.type === NostrPrefix.Note) {
|
b.withFilter().kinds([EventKind.ZapReceipt]).replyToLink([link]);
|
||||||
b.withFilter().kinds([EventKind.ZapReceipt]).tag("e", [link.id]);
|
|
||||||
} else if (link.type === NostrPrefix.Address) {
|
|
||||||
b.withFilter()
|
|
||||||
.kinds([EventKind.ZapReceipt])
|
|
||||||
.tag("a", [`${link.kind}:${link.author}:${link.id}`]);
|
|
||||||
}
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -24,16 +15,10 @@ export function useZaps(link?: NostrLink, leaveOpen = false) {
|
|||||||
|
|
||||||
const { data: zaps } = useRequestBuilder(NoteCollection, sub);
|
const { data: zaps } = useRequestBuilder(NoteCollection, sub);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const pubkeys = zaps ? [...new Set(zaps.flatMap(a => [a.pubkey, unwrap(findTag(a, "p"))]))] : [];
|
|
||||||
system.ProfileLoader.TrackMetadata(pubkeys);
|
|
||||||
return () => system.ProfileLoader.UntrackMetadata(pubkeys);
|
|
||||||
}, [zaps]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
[...(zaps ?? [])]
|
[...(zaps ?? [])]
|
||||||
.sort((a, b) => (b.created_at > a.created_at ? 1 : -1))
|
.sort((a, b) => (b.created_at > a.created_at ? 1 : -1))
|
||||||
.map(ev => parseZap(ev, system.ProfileLoader.Cache))
|
.map(ev => parseZap(ev))
|
||||||
.filter(z => z && z.valid) ?? []
|
.filter(z => z && z.valid) ?? []
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,13 @@ import { NostrPrefix, encodeTLV, parseNostrLink } from "@snort/system";
|
|||||||
import { unwrap } from "@snort/shared";
|
import { unwrap } from "@snort/shared";
|
||||||
import { useCurrentStreamFeed } from "hooks/current-stream-feed";
|
import { useCurrentStreamFeed } from "hooks/current-stream-feed";
|
||||||
import { findTag } from "utils";
|
import { findTag } from "utils";
|
||||||
|
import { useZapGoal } from "hooks/goals";
|
||||||
|
|
||||||
export function ChatPopout() {
|
export function ChatPopout() {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const link = parseNostrLink(unwrap(params.id));
|
const link = parseNostrLink(unwrap(params.id));
|
||||||
const ev = useCurrentStreamFeed(link, true);
|
const ev = useCurrentStreamFeed(link, true);
|
||||||
|
const goal = useZapGoal(findTag(ev, "goal"));
|
||||||
|
|
||||||
const lnk = parseNostrLink(encodeTLV(NostrPrefix.Address, findTag(ev, "d") ?? "", undefined, ev?.kind, ev?.pubkey));
|
const lnk = parseNostrLink(encodeTLV(NostrPrefix.Address, findTag(ev, "d") ?? "", undefined, ev?.kind, ev?.pubkey));
|
||||||
const chat = Boolean(new URL(window.location.href).searchParams.get("chat"));
|
const chat = Boolean(new URL(window.location.href).searchParams.get("chat"));
|
||||||
@ -22,6 +24,7 @@ export function ChatPopout() {
|
|||||||
canWrite: chat,
|
canWrite: chat,
|
||||||
showHeader: false,
|
showHeader: false,
|
||||||
}}
|
}}
|
||||||
|
goal={goal}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -77,6 +77,7 @@ function ZapAlertConfiguration({ npub, baseUrl }: ZapAlertConfigurationProps) {
|
|||||||
errors: [],
|
errors: [],
|
||||||
sender: login?.pubkey,
|
sender: login?.pubkey,
|
||||||
amount: 1_000_000,
|
amount: 1_000_000,
|
||||||
|
targetEvents: []
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div className="text-to-speech-settings">
|
<div className="text-to-speech-settings">
|
||||||
|
32
yarn.lock
32
yarn.lock
@ -2492,14 +2492,14 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@snort/system-react@npm:^1.1.1":
|
"@snort/system-react@npm:^1.1.4":
|
||||||
version: 1.1.1
|
version: 1.1.4
|
||||||
resolution: "@snort/system-react@npm:1.1.1"
|
resolution: "@snort/system-react@npm:1.1.4"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@snort/shared": ^1.0.9
|
"@snort/shared": ^1.0.9
|
||||||
"@snort/system": ^1.1.1
|
"@snort/system": ^1.1.4
|
||||||
react: ^18.2.0
|
react: ^18.2.0
|
||||||
checksum: fab77abfc738a5e415c2369aa509200b484faa09ff9dbf328872d0c527e315811a1adfcd991956837a3699e23a61d379b2eb536c9cf8dd45d013f8122c4824d5
|
checksum: 22a9a4f5bdc0ad1428d0c051a5d13c7168591ee0d1e30921acc5a6cc3aee98172f76439b777b9cfb03d689098ee052ed0276c77bbcd79af0944750dd90975de0
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -2532,6 +2532,24 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@snort/system@npm:^1.1.4":
|
||||||
|
version: 1.1.4
|
||||||
|
resolution: "@snort/system@npm:1.1.4"
|
||||||
|
dependencies:
|
||||||
|
"@noble/curves": ^1.2.0
|
||||||
|
"@noble/hashes": ^1.3.2
|
||||||
|
"@scure/base": ^1.1.2
|
||||||
|
"@snort/shared": ^1.0.9
|
||||||
|
"@stablelib/xchacha20": ^1.0.1
|
||||||
|
debug: ^4.3.4
|
||||||
|
eventemitter3: ^5.0.1
|
||||||
|
isomorphic-ws: ^5.0.0
|
||||||
|
uuid: ^9.0.0
|
||||||
|
ws: ^8.14.0
|
||||||
|
checksum: f0c7d920e7ea6aa1d8ca3b24a69841dbb33dec0e560d5b2f665c4ab93ccf1604bb01ec9733422daf3d275706e1c5b518fec80d2440a3c9136ba8d4e91d42ba2b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@stablelib/binary@npm:^1.0.1":
|
"@stablelib/binary@npm:^1.0.1":
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
resolution: "@stablelib/binary@npm:1.0.1"
|
resolution: "@stablelib/binary@npm:1.0.1"
|
||||||
@ -9482,8 +9500,8 @@ __metadata:
|
|||||||
"@react-hook/resize-observer": ^1.2.6
|
"@react-hook/resize-observer": ^1.2.6
|
||||||
"@scure/base": ^1.1.1
|
"@scure/base": ^1.1.1
|
||||||
"@snort/shared": ^1.0.9
|
"@snort/shared": ^1.0.9
|
||||||
"@snort/system": ^1.1.1
|
"@snort/system": ^1.1.4
|
||||||
"@snort/system-react": ^1.1.1
|
"@snort/system-react": ^1.1.4
|
||||||
"@snort/system-web": ^1.0.2
|
"@snort/system-web": ^1.0.2
|
||||||
"@szhsin/react-menu": ^4.0.2
|
"@szhsin/react-menu": ^4.0.2
|
||||||
"@testing-library/dom": ^9.3.1
|
"@testing-library/dom": ^9.3.1
|
||||||
|
Reference in New Issue
Block a user