feat: raids
This commit is contained in:
parent
4336513184
commit
43bf7f2d00
@ -14,8 +14,8 @@
|
|||||||
"@react-hook/resize-observer": "^1.2.6",
|
"@react-hook/resize-observer": "^1.2.6",
|
||||||
"@scure/base": "^1.1.3",
|
"@scure/base": "^1.1.3",
|
||||||
"@snort/shared": "^1.0.10",
|
"@snort/shared": "^1.0.10",
|
||||||
"@snort/system": "^1.1.6",
|
"@snort/system": "^1.1.7",
|
||||||
"@snort/system-react": "^1.1.6",
|
"@snort/system-react": "^1.1.7",
|
||||||
"@snort/system-wasm": "^1.0.1",
|
"@snort/system-wasm": "^1.0.1",
|
||||||
"@snort/system-web": "^1.0.2",
|
"@snort/system-web": "^1.0.2",
|
||||||
"@szhsin/react-menu": "^4.0.2",
|
"@szhsin/react-menu": "^4.0.2",
|
||||||
|
@ -2,6 +2,7 @@ import { EventKind } from "@snort/system";
|
|||||||
|
|
||||||
export const LIVE_STREAM = 30_311 as EventKind;
|
export const LIVE_STREAM = 30_311 as EventKind;
|
||||||
export const LIVE_STREAM_CHAT = 1_311 as EventKind;
|
export const LIVE_STREAM_CHAT = 1_311 as EventKind;
|
||||||
|
export const LIVE_STREAM_RAID = 1_312 as EventKind;
|
||||||
export const EMOJI_PACK = 30_030 as EventKind;
|
export const EMOJI_PACK = 30_030 as EventKind;
|
||||||
export const USER_EMOJIS = 10_030 as EventKind;
|
export const USER_EMOJIS = 10_030 as EventKind;
|
||||||
export const GOAL = 9041 as EventKind;
|
export const GOAL = 9041 as EventKind;
|
||||||
|
@ -5,7 +5,7 @@ import classNames from "classnames";
|
|||||||
|
|
||||||
interface AsyncButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
interface AsyncButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
onClick(e: React.MouseEvent): Promise<void> | void;
|
onClick?: (e: React.MouseEvent) => Promise<void> | void;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import "./live-chat.css";
|
import "./live-chat.css";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
import { EventKind, NostrEvent, NostrLink, ParsedZap, TaggedNostrEvent } from "@snort/system";
|
import { EventKind, NostrEvent, NostrLink, ParsedZap, TaggedNostrEvent, parseNostrLink } from "@snort/system";
|
||||||
import { useEventReactions } from "@snort/system-react";
|
import { useEventReactions, useUserProfile } from "@snort/system-react";
|
||||||
import { unixNow } from "@snort/shared";
|
import { unixNow, unwrap } from "@snort/shared";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
|
|
||||||
import { Icon } from "./icon";
|
import { Icon } from "./icon";
|
||||||
@ -18,11 +18,13 @@ import { useLiveChatFeed } from "@/hooks/live-chat";
|
|||||||
import { useMutedPubkeys } from "@/hooks/lists";
|
import { useMutedPubkeys } from "@/hooks/lists";
|
||||||
import { useBadges } from "@/hooks/badges";
|
import { useBadges } from "@/hooks/badges";
|
||||||
import { useLogin } from "@/hooks/login";
|
import { useLogin } from "@/hooks/login";
|
||||||
import { useAddress } from "@/hooks/event";
|
import { useAddress, useEvent } from "@/hooks/event";
|
||||||
import { formatSats } from "@/number";
|
import { formatSats } from "@/number";
|
||||||
import { LIVE_STREAM_CHAT, WEEK } from "@/const";
|
import { LIVE_STREAM_CHAT, LIVE_STREAM_RAID, WEEK } from "@/const";
|
||||||
import { findTag, getHost, getTagValues, uniqBy } from "@/utils";
|
import { findTag, getHost, getTagValues, uniqBy } from "@/utils";
|
||||||
import { TopZappers } from "./top-zappers";
|
import { TopZappers } from "./top-zappers";
|
||||||
|
import { Mention } from "./mention";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
export interface LiveChatOptions {
|
export interface LiveChatOptions {
|
||||||
canWrite?: boolean;
|
canWrite?: boolean;
|
||||||
@ -148,6 +150,9 @@ export function LiveChat({
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
case LIVE_STREAM_RAID: {
|
||||||
|
return <ChatRaid ev={a} link={link} />;
|
||||||
|
}
|
||||||
case EventKind.ZapReceipt: {
|
case EventKind.ZapReceipt: {
|
||||||
const zap = reactions.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) {
|
||||||
@ -207,3 +212,25 @@ export function ChatZap({ zap }: { zap: ParsedZap }) {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function ChatRaid({ link, ev }: { link: NostrLink, ev: TaggedNostrEvent }) {
|
||||||
|
const from = ev.tags.find(a => a[0] === "a" && a[3] === "root");
|
||||||
|
const to = ev.tags.find(a => a[0] === "a" && a[3] === "mention");
|
||||||
|
const isRaiding = link.toEventTag()?.at(1) === from?.at(1);
|
||||||
|
const otherLink = NostrLink.fromTag(unwrap(isRaiding ? to : from));
|
||||||
|
const otherEvent = useEvent(otherLink);
|
||||||
|
const otherProfile = useUserProfile(getHost(otherEvent));
|
||||||
|
|
||||||
|
if (isRaiding) {
|
||||||
|
return <Link to={`/${otherLink.encode()}`} className="px-3 py-2 text-center rounded-xl bg-primary uppercase pointer font-bold">
|
||||||
|
<FormattedMessage defaultMessage="Raiding {name}" id="j/jueq" values={{
|
||||||
|
name: otherProfile?.name
|
||||||
|
}} />
|
||||||
|
</Link>;
|
||||||
|
}
|
||||||
|
return <div className="px-3 py-2 text-center rounded-xl bg-primary uppercase pointer font-bold">
|
||||||
|
<FormattedMessage defaultMessage="Raid from {name}" id="69hmpj" values={{
|
||||||
|
name: otherProfile?.name
|
||||||
|
}} />
|
||||||
|
</div>;
|
||||||
|
}
|
76
src/element/raid-menu.tsx
Normal file
76
src/element/raid-menu.tsx
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import { useStreamsFeed } from "@/hooks/live-streams";
|
||||||
|
import { getHost, getTagValues } from "@/utils";
|
||||||
|
import { dedupe, unwrap } from "@snort/shared";
|
||||||
|
import { FormattedMessage } from "react-intl";
|
||||||
|
import { Profile } from "./profile";
|
||||||
|
import { useLogin } from "@/hooks/login";
|
||||||
|
import { useContext, useState } from "react";
|
||||||
|
import { NostrLink, parseNostrLink } from "@snort/system";
|
||||||
|
import AsyncButton from "./async-button";
|
||||||
|
import { SnortContext } from "@snort/system-react";
|
||||||
|
import { LIVE_STREAM_RAID } from "@/const";
|
||||||
|
|
||||||
|
export function DashboardRaidMenu({ link, onClose }: { link: NostrLink, onClose: () => void }) {
|
||||||
|
const system = useContext(SnortContext);
|
||||||
|
const login = useLogin();
|
||||||
|
const { live } = useStreamsFeed();
|
||||||
|
const [raiding, setRaiding] = useState("");
|
||||||
|
const [msg, setMsg] = useState("");
|
||||||
|
|
||||||
|
const mutedHosts = new Set(getTagValues(login?.muted.tags ?? [], "p"));
|
||||||
|
const livePubkeys = dedupe(live.map(a => getHost(a))).filter(a => !mutedHosts.has(a));
|
||||||
|
|
||||||
|
async function raid() {
|
||||||
|
if (login) {
|
||||||
|
const ev = await login.publisher().generic(eb => {
|
||||||
|
return eb.kind(LIVE_STREAM_RAID)
|
||||||
|
.tag(unwrap(link.toEventTag("root")))
|
||||||
|
.tag(unwrap(parseNostrLink(raiding).toEventTag("mention")))
|
||||||
|
.content(msg);
|
||||||
|
});
|
||||||
|
|
||||||
|
await system.BroadcastEvent(ev);
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div className="flex flex-col gap-4 p-6">
|
||||||
|
<h2>
|
||||||
|
<FormattedMessage defaultMessage="Start Raid" id="MTHO1W" />
|
||||||
|
</h2>
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<p className="text-gray-3 uppercase font-semibold text-sm">
|
||||||
|
<FormattedMessage defaultMessage="Live now" id="+sdKx8" />
|
||||||
|
</p>
|
||||||
|
<div className="flex gap-2 flex-wrap">
|
||||||
|
{livePubkeys.map(a => <div className="border border-gray-1 rounded-full px-4 py-2 bg-gray-2 pointer" onClick={() => {
|
||||||
|
const liveEvent = live.find(b => getHost(b) === a);
|
||||||
|
if (liveEvent) {
|
||||||
|
setRaiding(NostrLink.fromEvent(liveEvent).encode());
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
<Profile pubkey={a} options={{ showAvatar: false }} linkToProfile={false} />
|
||||||
|
</div>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<p className="text-gray-3 uppercase font-semibold text-sm">
|
||||||
|
<FormattedMessage defaultMessage="Raid target" id="Zse7yG" />
|
||||||
|
</p>
|
||||||
|
<div className="paper">
|
||||||
|
<input type="text" placeholder="naddr.." value={raiding} onChange={e => setRaiding(e.target.value)} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<p className="text-gray-3 uppercase font-semibold text-sm">
|
||||||
|
<FormattedMessage defaultMessage="Raid Message" id="RS6smY" />
|
||||||
|
</p>
|
||||||
|
<div className="paper">
|
||||||
|
<input type="text" value={msg} onChange={e => setMsg(e.target.value)} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<AsyncButton className="btn btn-primary" onClick={raid}>
|
||||||
|
<FormattedMessage defaultMessage="Raid!" id="aqjZxs" />
|
||||||
|
</AsyncButton>
|
||||||
|
</div>
|
||||||
|
}
|
@ -2,7 +2,7 @@ import { NostrLink, NoteCollection, RequestBuilder } from "@snort/system";
|
|||||||
import { useReactions, useRequestBuilder } from "@snort/system-react";
|
import { useReactions, useRequestBuilder } from "@snort/system-react";
|
||||||
import { unixNow } from "@snort/shared";
|
import { unixNow } from "@snort/shared";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { LIVE_STREAM_CHAT, WEEK } from "@/const";
|
import { LIVE_STREAM_CHAT, LIVE_STREAM_RAID, WEEK } from "@/const";
|
||||||
|
|
||||||
export function useLiveChatFeed(link?: NostrLink, eZaps?: Array<string>, limit = 100) {
|
export function useLiveChatFeed(link?: NostrLink, eZaps?: Array<string>, limit = 100) {
|
||||||
const since = useMemo(() => unixNow() - WEEK, [link?.id]);
|
const since = useMemo(() => unixNow() - WEEK, [link?.id]);
|
||||||
@ -13,14 +13,14 @@ export function useLiveChatFeed(link?: NostrLink, eZaps?: Array<string>, limit =
|
|||||||
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(limit);
|
rb.withFilter().kinds([LIVE_STREAM_CHAT, LIVE_STREAM_RAID]).tag("a", [aTag]).limit(limit);
|
||||||
return rb;
|
return rb;
|
||||||
}, [link?.id, since, eZaps]);
|
}, [link?.id, since, eZaps]);
|
||||||
|
|
||||||
const feed = useRequestBuilder(NoteCollection, sub);
|
const feed = useRequestBuilder(NoteCollection, sub);
|
||||||
|
|
||||||
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 || ev.kind === LIVE_STREAM_RAID);
|
||||||
}, [feed.data]);
|
}, [feed.data]);
|
||||||
|
|
||||||
const reactions = useReactions(
|
const reactions = useReactions(
|
||||||
|
@ -249,14 +249,16 @@ div.paper {
|
|||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
width: 90vw;
|
width: 90vw;
|
||||||
max-width: 450px;
|
max-width: 550px;
|
||||||
max-height: 85vh;
|
max-height: 85vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-content .header-image {
|
.dialog-content .header-image {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-content .content-inner {
|
.dialog-content .content-inner {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -369,4 +371,4 @@ div.paper {
|
|||||||
|
|
||||||
.h-inhreit {
|
.h-inhreit {
|
||||||
height: inherit;
|
height: inherit;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
"+AcVD+": {
|
"+AcVD+": {
|
||||||
"defaultMessage": "No emails, just awesomeness!"
|
"defaultMessage": "No emails, just awesomeness!"
|
||||||
},
|
},
|
||||||
|
"+sdKx8": {
|
||||||
|
"defaultMessage": "Live now"
|
||||||
|
},
|
||||||
"+vVZ/G": {
|
"+vVZ/G": {
|
||||||
"defaultMessage": "Connect"
|
"defaultMessage": "Connect"
|
||||||
},
|
},
|
||||||
@ -53,6 +56,9 @@
|
|||||||
"47FYwb": {
|
"47FYwb": {
|
||||||
"defaultMessage": "Cancel"
|
"defaultMessage": "Cancel"
|
||||||
},
|
},
|
||||||
|
"4iBdw1": {
|
||||||
|
"defaultMessage": "Raid"
|
||||||
|
},
|
||||||
"4l69eO": {
|
"4l69eO": {
|
||||||
"defaultMessage": "Hmm, your lightning address looks wrong"
|
"defaultMessage": "Hmm, your lightning address looks wrong"
|
||||||
},
|
},
|
||||||
@ -74,6 +80,9 @@
|
|||||||
"5tM0VD": {
|
"5tM0VD": {
|
||||||
"defaultMessage": "Stream Started"
|
"defaultMessage": "Stream Started"
|
||||||
},
|
},
|
||||||
|
"69hmpj": {
|
||||||
|
"defaultMessage": "Raid from {name}"
|
||||||
|
},
|
||||||
"6Z2pvJ": {
|
"6Z2pvJ": {
|
||||||
"defaultMessage": "Stream Providers"
|
"defaultMessage": "Stream Providers"
|
||||||
},
|
},
|
||||||
@ -191,6 +200,9 @@
|
|||||||
"LknBsU": {
|
"LknBsU": {
|
||||||
"defaultMessage": "Stream Key"
|
"defaultMessage": "Stream Key"
|
||||||
},
|
},
|
||||||
|
"MTHO1W": {
|
||||||
|
"defaultMessage": "Start Raid"
|
||||||
|
},
|
||||||
"My6HwN": {
|
"My6HwN": {
|
||||||
"defaultMessage": "Ok, it's safe"
|
"defaultMessage": "Ok, it's safe"
|
||||||
},
|
},
|
||||||
@ -233,6 +245,9 @@
|
|||||||
"RJOmzk": {
|
"RJOmzk": {
|
||||||
"defaultMessage": "I have read and agree with {provider}''s {terms}."
|
"defaultMessage": "I have read and agree with {provider}''s {terms}."
|
||||||
},
|
},
|
||||||
|
"RS6smY": {
|
||||||
|
"defaultMessage": "Raid Message"
|
||||||
|
},
|
||||||
"RXQdxR": {
|
"RXQdxR": {
|
||||||
"defaultMessage": "Please login to write messages!"
|
"defaultMessage": "Please login to write messages!"
|
||||||
},
|
},
|
||||||
@ -282,9 +297,15 @@
|
|||||||
"ZmqxZs": {
|
"ZmqxZs": {
|
||||||
"defaultMessage": "You can change this later"
|
"defaultMessage": "You can change this later"
|
||||||
},
|
},
|
||||||
|
"Zse7yG": {
|
||||||
|
"defaultMessage": "Raid target"
|
||||||
|
},
|
||||||
"acrOoz": {
|
"acrOoz": {
|
||||||
"defaultMessage": "Continue"
|
"defaultMessage": "Continue"
|
||||||
},
|
},
|
||||||
|
"aqjZxs": {
|
||||||
|
"defaultMessage": "Raid!"
|
||||||
|
},
|
||||||
"bfvyfs": {
|
"bfvyfs": {
|
||||||
"defaultMessage": "Anon"
|
"defaultMessage": "Anon"
|
||||||
},
|
},
|
||||||
@ -342,6 +363,9 @@
|
|||||||
"izWS4J": {
|
"izWS4J": {
|
||||||
"defaultMessage": "Unfollow"
|
"defaultMessage": "Unfollow"
|
||||||
},
|
},
|
||||||
|
"j/jueq": {
|
||||||
|
"defaultMessage": "Raiding {name}"
|
||||||
|
},
|
||||||
"jctiUc": {
|
"jctiUc": {
|
||||||
"defaultMessage": "Highest Viewers"
|
"defaultMessage": "Highest Viewers"
|
||||||
},
|
},
|
||||||
|
@ -15,6 +15,8 @@ import { HTMLProps, ReactNode, useEffect, useMemo, useState } from "react";
|
|||||||
import { FormattedMessage, FormattedNumber } from "react-intl";
|
import { FormattedMessage, FormattedNumber } from "react-intl";
|
||||||
import { Text } from "@/element/text";
|
import { Text } from "@/element/text";
|
||||||
import { StreamTimer } from "@/element/stream-time";
|
import { StreamTimer } from "@/element/stream-time";
|
||||||
|
import * as Dialog from "@radix-ui/react-dialog";
|
||||||
|
import { DashboardRaidMenu } from "@/element/raid-menu";
|
||||||
|
|
||||||
export default function DashboardPage() {
|
export default function DashboardPage() {
|
||||||
const login = useLogin();
|
const login = useLogin();
|
||||||
@ -47,6 +49,7 @@ function DashboardForLink({ link }: { link: NostrLink }) {
|
|||||||
<DashboardStatsCard name={<FormattedMessage defaultMessage="Viewers" id="37mth/" />} value={participants} />
|
<DashboardStatsCard name={<FormattedMessage defaultMessage="Viewers" id="37mth/" />} value={participants} />
|
||||||
<DashboardStatsCard name={<FormattedMessage defaultMessage="Highest Viewers" id="jctiUc" />} value={maxParticipants} />
|
<DashboardStatsCard name={<FormattedMessage defaultMessage="Highest Viewers" id="jctiUc" />} value={maxParticipants} />
|
||||||
</div>
|
</div>
|
||||||
|
<DashboardRaidButton link={streamLink} />
|
||||||
</DashboardCard>
|
</DashboardCard>
|
||||||
<DashboardCard className="flex flex-col gap-4">
|
<DashboardCard className="flex flex-col gap-4">
|
||||||
<h3>
|
<h3>
|
||||||
@ -132,4 +135,19 @@ function DashboardHighlightZap({ zap }: { zap: ParsedZap }) {
|
|||||||
<Text content={zap.content} tags={[]} />
|
<Text content={zap.content} tags={[]} />
|
||||||
</div>}
|
</div>}
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function DashboardRaidButton({ link }: { link: NostrLink }) {
|
||||||
|
const [show, setShow] = useState(false);
|
||||||
|
return <Dialog.Root open={show} onOpenChange={setShow}>
|
||||||
|
<AsyncButton className="btn btn-primary" onClick={() => setShow(true)}>
|
||||||
|
<FormattedMessage defaultMessage="Raid" id="4iBdw1" />
|
||||||
|
</AsyncButton>
|
||||||
|
<Dialog.Portal>
|
||||||
|
<Dialog.Overlay className="dialog-overlay" />
|
||||||
|
<Dialog.Content className="dialog-content">
|
||||||
|
<DashboardRaidMenu link={link} onClose={() => setShow(false)} />
|
||||||
|
</Dialog.Content>
|
||||||
|
</Dialog.Portal>
|
||||||
|
</Dialog.Root>
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"+0zv6g": "Image",
|
"+0zv6g": "Image",
|
||||||
"+AcVD+": "No emails, just awesomeness!",
|
"+AcVD+": "No emails, just awesomeness!",
|
||||||
|
"+sdKx8": "Live now",
|
||||||
"+vVZ/G": "Connect",
|
"+vVZ/G": "Connect",
|
||||||
"/0TOL5": "Amount",
|
"/0TOL5": "Amount",
|
||||||
"/EvlqN": "nostr signer extension",
|
"/EvlqN": "nostr signer extension",
|
||||||
@ -17,6 +18,7 @@
|
|||||||
"3adEeb": "{n} viewers",
|
"3adEeb": "{n} viewers",
|
||||||
"3df560": "Login with private key",
|
"3df560": "Login with private key",
|
||||||
"47FYwb": "Cancel",
|
"47FYwb": "Cancel",
|
||||||
|
"4iBdw1": "Raid",
|
||||||
"4l69eO": "Hmm, your lightning address looks wrong",
|
"4l69eO": "Hmm, your lightning address looks wrong",
|
||||||
"4l6vz1": "Copy",
|
"4l6vz1": "Copy",
|
||||||
"4uI538": "Resolutions",
|
"4uI538": "Resolutions",
|
||||||
@ -24,6 +26,7 @@
|
|||||||
"5QYdPU": "Start Time",
|
"5QYdPU": "Start Time",
|
||||||
"5kx+2v": "Server Url",
|
"5kx+2v": "Server Url",
|
||||||
"5tM0VD": "Stream Started",
|
"5tM0VD": "Stream Started",
|
||||||
|
"69hmpj": "Raid from {name}",
|
||||||
"6Z2pvJ": "Stream Providers",
|
"6Z2pvJ": "Stream Providers",
|
||||||
"6pr6hJ": "Minimum amount for text to speech",
|
"6pr6hJ": "Minimum amount for text to speech",
|
||||||
"79lLl+": "Music",
|
"79lLl+": "Music",
|
||||||
@ -63,6 +66,7 @@
|
|||||||
"KdYELp": "Get stream key",
|
"KdYELp": "Get stream key",
|
||||||
"KkIL3s": "No, I am under 18",
|
"KkIL3s": "No, I am under 18",
|
||||||
"LknBsU": "Stream Key",
|
"LknBsU": "Stream Key",
|
||||||
|
"MTHO1W": "Start Raid",
|
||||||
"My6HwN": "Ok, it's safe",
|
"My6HwN": "Ok, it's safe",
|
||||||
"O2Cy6m": "Yes, I am over 18",
|
"O2Cy6m": "Yes, I am over 18",
|
||||||
"OEW7yJ": "Zaps",
|
"OEW7yJ": "Zaps",
|
||||||
@ -77,6 +81,7 @@
|
|||||||
"Qe1MJu": "{name} with {amount}",
|
"Qe1MJu": "{name} with {amount}",
|
||||||
"RJ2VxG": "A new version has been detected",
|
"RJ2VxG": "A new version has been detected",
|
||||||
"RJOmzk": "I have read and agree with {provider}''s {terms}.",
|
"RJOmzk": "I have read and agree with {provider}''s {terms}.",
|
||||||
|
"RS6smY": "Raid Message",
|
||||||
"RXQdxR": "Please login to write messages!",
|
"RXQdxR": "Please login to write messages!",
|
||||||
"RrCui3": "Summary",
|
"RrCui3": "Summary",
|
||||||
"RtYNX5": "Chat Users",
|
"RtYNX5": "Chat Users",
|
||||||
@ -93,7 +98,9 @@
|
|||||||
"YagVIe": "{n}p",
|
"YagVIe": "{n}p",
|
||||||
"Z8ZOEY": "This method is insecure. We recommend using a {nostrlink}",
|
"Z8ZOEY": "This method is insecure. We recommend using a {nostrlink}",
|
||||||
"ZmqxZs": "You can change this later",
|
"ZmqxZs": "You can change this later",
|
||||||
|
"Zse7yG": "Raid target",
|
||||||
"acrOoz": "Continue",
|
"acrOoz": "Continue",
|
||||||
|
"aqjZxs": "Raid!",
|
||||||
"bfvyfs": "Anon",
|
"bfvyfs": "Anon",
|
||||||
"cPIKU2": "Following",
|
"cPIKU2": "Following",
|
||||||
"cvAsEh": "Streamed on {date}",
|
"cvAsEh": "Streamed on {date}",
|
||||||
@ -113,6 +120,7 @@
|
|||||||
"ieGrWo": "Follow",
|
"ieGrWo": "Follow",
|
||||||
"itPgxd": "Profile",
|
"itPgxd": "Profile",
|
||||||
"izWS4J": "Unfollow",
|
"izWS4J": "Unfollow",
|
||||||
|
"j/jueq": "Raiding {name}",
|
||||||
"jctiUc": "Highest Viewers",
|
"jctiUc": "Highest Viewers",
|
||||||
"jgOqxt": "Widgets",
|
"jgOqxt": "Widgets",
|
||||||
"jkAQj5": "Stream Ended",
|
"jkAQj5": "Stream Ended",
|
||||||
|
30
yarn.lock
30
yarn.lock
@ -2896,14 +2896,14 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@snort/system-react@npm:^1.1.6":
|
"@snort/system-react@npm:^1.1.7":
|
||||||
version: 1.1.6
|
version: 1.1.7
|
||||||
resolution: "@snort/system-react@npm:1.1.6"
|
resolution: "@snort/system-react@npm:1.1.7"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@snort/shared": ^1.0.10
|
"@snort/shared": ^1.0.10
|
||||||
"@snort/system": ^1.1.6
|
"@snort/system": ^1.1.6
|
||||||
react: ^18.2.0
|
react: ^18.2.0
|
||||||
checksum: ea7658d6cf14508e87b6239346b89de34db848817beac7da7cc1b33e1f776920ecc6d079b3470eece3e60c6ec37b50fca94b84bd57b6d7ee24234fa3eb1fc945
|
checksum: 6e958a8b03c473c9c7878893cc1c79e678a713ea8ab717b2c56eb2b5702809fcfd9944fd9215db3f4e5336acef2d27959d2cfff27a753630b28b037a1e74b2a1
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -2961,6 +2961,24 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@snort/system@npm:^1.1.7":
|
||||||
|
version: 1.1.7
|
||||||
|
resolution: "@snort/system@npm:1.1.7"
|
||||||
|
dependencies:
|
||||||
|
"@noble/curves": ^1.2.0
|
||||||
|
"@noble/hashes": ^1.3.2
|
||||||
|
"@scure/base": ^1.1.2
|
||||||
|
"@snort/shared": ^1.0.10
|
||||||
|
"@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: 881101fc44babb7b7ff081ac5c67c78afc81377b019bc9316be13789a7eaf5cd55dd6001248c8a3c3f837ac90b5082d3509d83ea63dff69103daf357b353ab9b
|
||||||
|
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"
|
||||||
@ -7806,8 +7824,8 @@ __metadata:
|
|||||||
"@react-hook/resize-observer": ^1.2.6
|
"@react-hook/resize-observer": ^1.2.6
|
||||||
"@scure/base": ^1.1.3
|
"@scure/base": ^1.1.3
|
||||||
"@snort/shared": ^1.0.10
|
"@snort/shared": ^1.0.10
|
||||||
"@snort/system": ^1.1.6
|
"@snort/system": ^1.1.7
|
||||||
"@snort/system-react": ^1.1.6
|
"@snort/system-react": ^1.1.7
|
||||||
"@snort/system-wasm": ^1.0.1
|
"@snort/system-wasm": ^1.0.1
|
||||||
"@snort/system-web": ^1.0.2
|
"@snort/system-web": ^1.0.2
|
||||||
"@szhsin/react-menu": ^4.0.2
|
"@szhsin/react-menu": ^4.0.2
|
||||||
|
Loading…
Reference in New Issue
Block a user