Run prettier
This commit is contained in:
parent
e99f323cfa
commit
5ef3fb0337
@ -4,3 +4,4 @@ build/
|
||||
.github/
|
||||
transifex.yml
|
||||
dist/
|
||||
src-tauri/
|
@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
@ -38,7 +38,7 @@ export class GiftWrapCache extends RefreshFeedCache<UnwrappedGift> {
|
||||
} catch (e) {
|
||||
console.debug(e, v);
|
||||
}
|
||||
})
|
||||
}),
|
||||
)
|
||||
)
|
||||
.filter(a => a !== undefined)
|
||||
|
@ -26,7 +26,7 @@ export default function CashuNuts({ token }: { token: string }) {
|
||||
e.stopPropagation();
|
||||
const lnurl = profile?.lud16 ?? "";
|
||||
const url = `https://redeem.cashu.me?token=${encodeURIComponent(token)}&lightning=${encodeURIComponent(
|
||||
lnurl
|
||||
lnurl,
|
||||
)}&autopay=yes`;
|
||||
window.open(url, "_blank");
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ export default function FollowButton(props: FollowButtonProps) {
|
||||
if (publisher) {
|
||||
const ev = await publisher.contactList(
|
||||
follows.item.filter(a => a !== pubkey),
|
||||
relays.item
|
||||
relays.item,
|
||||
);
|
||||
System.BroadcastEvent(ev);
|
||||
}
|
||||
|
@ -261,9 +261,7 @@ export default function Nip5Service(props: Nip05ServiceProps) {
|
||||
/>
|
||||
@
|
||||
<select value={domain} onChange={onDomainChange}>
|
||||
{serviceConfig?.domains.map(a => (
|
||||
<option key={a.name}>{a.name}</option>
|
||||
))}
|
||||
{serviceConfig?.domains.map(a => <option key={a.name}>{a.name}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
)}
|
||||
|
@ -135,7 +135,7 @@ export function NoteInner(props: NoteProps) {
|
||||
{
|
||||
[Reaction.Positive]: [] as TaggedNostrEvent[],
|
||||
[Reaction.Negative]: [] as TaggedNostrEvent[],
|
||||
}
|
||||
},
|
||||
);
|
||||
return {
|
||||
[Reaction.Positive]: dedupeByPubkey(result[Reaction.Positive]),
|
||||
@ -150,7 +150,7 @@ export function NoteInner(props: NoteProps) {
|
||||
...getReactions(related, ev.id, EventKind.TextNote).filter(e => e.tags.some(tagFilterOfTextRepost(e, ev.id))),
|
||||
...getReactions(related, ev.id, EventKind.Repost),
|
||||
]),
|
||||
[related, ev]
|
||||
[related, ev],
|
||||
);
|
||||
const zaps = useMemo(() => {
|
||||
const sortedZaps = getReactions(related, ev.id, EventKind.ZapReceipt)
|
||||
@ -241,7 +241,7 @@ export function NoteInner(props: NoteProps) {
|
||||
function goToEvent(
|
||||
e: React.MouseEvent,
|
||||
eTarget: TaggedNostrEvent,
|
||||
isTargetAllowed: boolean = e.target === e.currentTarget
|
||||
isTargetAllowed: boolean = e.target === e.currentTarget,
|
||||
) {
|
||||
if (!isTargetAllowed || opt?.canClick === false) {
|
||||
return;
|
||||
|
@ -2,7 +2,8 @@
|
||||
border: 1px solid transparent;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0px 0px 6px 1px rgba(182, 108, 156, 0.3);
|
||||
background: linear-gradient(var(--gray-superdark), var(--gray-superdark)) padding-box,
|
||||
background:
|
||||
linear-gradient(var(--gray-superdark), var(--gray-superdark)) padding-box,
|
||||
linear-gradient(90deg, #ef9644, #fd7c49, #ff5e58, #ff3b70, #ff088e, #eb00b1, #c31ed5, #7b41f6) border-box;
|
||||
}
|
||||
|
||||
|
@ -76,8 +76,8 @@ export function NoteCreator() {
|
||||
setError(
|
||||
formatMessage({
|
||||
defaultMessage: "Invalid LNURL",
|
||||
})
|
||||
)
|
||||
}),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -256,9 +256,9 @@ export function NoteCreator() {
|
||||
? false
|
||||
: // otherwise return selectedCustomRelays with target relay added / removed
|
||||
a.filter(el =>
|
||||
el === r ? e.target.checked : !selectedCustomRelays || selectedCustomRelays.includes(el)
|
||||
)
|
||||
)
|
||||
el === r ? e.target.checked : !selectedCustomRelays || selectedCustomRelays.includes(el),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
@ -71,7 +71,7 @@ export default function NoteFooter(props: NoteFooterProps) {
|
||||
},
|
||||
{
|
||||
captureEvent: true,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
function hasReacted(emoji: string) {
|
||||
|
@ -46,15 +46,15 @@ export default function Poll(props: PollProps) {
|
||||
},
|
||||
{
|
||||
amount,
|
||||
}
|
||||
)
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
setVoting(opt);
|
||||
const r = Object.keys(relays.item);
|
||||
const zap = await publisher.zap(amount * 1000, props.ev.pubkey, r, props.ev.id, undefined, eb =>
|
||||
eb.tag(["poll_option", opt.toString()])
|
||||
eb.tag(["poll_option", opt.toString()]),
|
||||
);
|
||||
|
||||
const lnurl = props.ev.tags.find(a => a[0] === "zap")?.[1] || pollerProfile?.lud16 || pollerProfile?.lud06;
|
||||
@ -67,7 +67,7 @@ export default function Poll(props: PollProps) {
|
||||
throw new Error(
|
||||
formatMessage({
|
||||
defaultMessage: "Can't vote because LNURL service does not support zaps",
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ export default function Poll(props: PollProps) {
|
||||
setError(
|
||||
formatMessage({
|
||||
defaultMessage: "Failed to send vote",
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
|
@ -34,7 +34,7 @@ export default function PubkeyList({ ev, className }: { ev: NostrEvent; classNam
|
||||
pk,
|
||||
Object.keys(login.relays.item),
|
||||
undefined,
|
||||
`Zap from ${hexToBech32("note", ev.id)}`
|
||||
`Zap from ${hexToBech32("note", ev.id)}`,
|
||||
);
|
||||
const invoice = await svc.getInvoice(amtSend, undefined, zap);
|
||||
if (invoice.pr) {
|
||||
|
@ -55,9 +55,9 @@ export function ReBroadcaster() {
|
||||
? false
|
||||
: // otherwise return selectedCustomRelays with target relay added / removed
|
||||
a.filter(el =>
|
||||
el === r ? e.target.checked : !selectedCustomRelays || selectedCustomRelays.includes(el)
|
||||
)
|
||||
)
|
||||
el === r ? e.target.checked : !selectedCustomRelays || selectedCustomRelays.includes(el),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
@ -60,7 +60,7 @@ const Reactions = ({ show, setShow, positive, negative, reposts, zaps }: Reactio
|
||||
value: 3,
|
||||
},
|
||||
]
|
||||
: []
|
||||
: [],
|
||||
);
|
||||
|
||||
const [tab, setTab] = useState(tabs[0]);
|
||||
|
@ -22,7 +22,7 @@ export default function Relay(props: RelayProps) {
|
||||
const navigate = useNavigate();
|
||||
const login = useLogin();
|
||||
const relaySettings = unwrap(
|
||||
login.relays.item[props.addr] ?? System.Sockets.find(a => a.address === props.addr)?.settings ?? {}
|
||||
login.relays.item[props.addr] ?? System.Sockets.find(a => a.address === props.addr)?.settings ?? {},
|
||||
);
|
||||
const state = useRelayState(props.addr);
|
||||
const name = useMemo(() => getRelayName(props.addr), [props.addr]);
|
||||
@ -34,7 +34,7 @@ export default function Relay(props: RelayProps) {
|
||||
...login.relays.item,
|
||||
[props.addr]: o,
|
||||
},
|
||||
unixNowMs()
|
||||
unixNowMs(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -285,7 +285,7 @@ export default function SendSats(props: SendSatsProps) {
|
||||
{makeTab(ZapType.AnonZap, <FormattedMessage defaultMessage="Anon" description="Anonymous Zap" />)}
|
||||
{makeTab(
|
||||
ZapType.NonZap,
|
||||
<FormattedMessage defaultMessage="Non-Zap" description="Non-Zap, Regular LN payment" />
|
||||
<FormattedMessage defaultMessage="Non-Zap" description="Non-Zap, Regular LN payment" />,
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
|
@ -243,7 +243,7 @@ export default function Thread() {
|
||||
if (t?.root?.key === "a" && t?.root?.value) {
|
||||
const parsed = t.root.value.split(":");
|
||||
replyTo = thread.data?.find(
|
||||
a => a.kind === Number(parsed[0]) && a.pubkey === parsed[1] && findTag(a, "d") === parsed[2]
|
||||
a => a.kind === Number(parsed[0]) && a.pubkey === parsed[1] && findTag(a, "d") === parsed[2],
|
||||
)?.id;
|
||||
}
|
||||
if (replyTo) {
|
||||
@ -264,7 +264,7 @@ export default function Thread() {
|
||||
thread.data?.find(
|
||||
ne =>
|
||||
ne.id === currentId ||
|
||||
(link.type === NostrPrefix.Address && findTag(ne, "d") === currentId && ne.pubkey === link.author)
|
||||
(link.type === NostrPrefix.Address && findTag(ne, "d") === currentId && ne.pubkey === link.author),
|
||||
) ?? (location.state && "sig" in location.state ? (location.state as TaggedNostrEvent) : undefined);
|
||||
if (currentNote) {
|
||||
const currentThread = EventExt.extractThread(currentNote);
|
||||
@ -280,7 +280,7 @@ export default function Thread() {
|
||||
if (replyTo.key === "a" && replyTo.value) {
|
||||
const parsed = replyTo.value.split(":");
|
||||
return thread.data?.find(
|
||||
a => a.kind === Number(parsed[0]) && a.pubkey === parsed[1] && findTag(a, "d") === parsed[2]
|
||||
a => a.kind === Number(parsed[0]) && a.pubkey === parsed[1] && findTag(a, "d") === parsed[2],
|
||||
);
|
||||
}
|
||||
if (replyTo.value) {
|
||||
@ -348,7 +348,7 @@ export default function Thread() {
|
||||
notes={replies}
|
||||
related={getAllReactions(
|
||||
thread.data,
|
||||
replies.map(a => a.id)
|
||||
replies.map(a => a.id),
|
||||
)}
|
||||
chains={chains}
|
||||
onNavigate={navigateThread}
|
||||
|
@ -47,7 +47,7 @@ const Timeline = (props: TimelineProps) => {
|
||||
?.filter(a => (props.postsOnly ? !a.tags.some(b => b[0] === "e") : true))
|
||||
.filter(a => props.ignoreModeration || !isMuted(a.pubkey));
|
||||
},
|
||||
[props.postsOnly, muted, props.ignoreModeration]
|
||||
[props.postsOnly, muted, props.ignoreModeration],
|
||||
);
|
||||
|
||||
const mainFeed = useMemo(() => {
|
||||
@ -60,7 +60,7 @@ const Timeline = (props: TimelineProps) => {
|
||||
(id: u256) => {
|
||||
return (feed.related ?? []).filter(a => findTag(a, "e") === id);
|
||||
},
|
||||
[feed.related]
|
||||
[feed.related],
|
||||
);
|
||||
const liveStreams = useMemo(() => {
|
||||
return (feed.main ?? []).filter(a => a.kind === EventKind.LiveEvent && findTag(a, "status") === "live");
|
||||
|
@ -28,11 +28,11 @@ const TimelineFollows = (props: TimelineFollowsProps) => {
|
||||
const [latest, setLatest] = useState(unixNow());
|
||||
const feed = useSyncExternalStore(
|
||||
cb => FollowsFeed.hook(cb, "*"),
|
||||
() => FollowsFeed.snapshot()
|
||||
() => FollowsFeed.snapshot(),
|
||||
);
|
||||
const reactions = useReactions(
|
||||
"follows-feed-reactions",
|
||||
feed.map(a => a.id)
|
||||
feed.map(a => a.id),
|
||||
);
|
||||
const system = useContext(SnortContext);
|
||||
const login = useLogin();
|
||||
@ -48,7 +48,7 @@ const TimelineFollows = (props: TimelineFollowsProps) => {
|
||||
?.filter(a => (props.postsOnly ? !a.tags.some(b => b[0] === "e") : true))
|
||||
.filter(a => !isMuted(a.pubkey) && login.follows.item.includes(a.pubkey));
|
||||
},
|
||||
[props.postsOnly, muted, login.follows.timestamp]
|
||||
[props.postsOnly, muted, login.follows.timestamp],
|
||||
);
|
||||
|
||||
const mainFeed = useMemo(() => {
|
||||
@ -63,7 +63,7 @@ const TimelineFollows = (props: TimelineFollowsProps) => {
|
||||
(id: u256) => {
|
||||
return (reactions?.data ?? []).filter(a => findTag(a, "e") === id);
|
||||
},
|
||||
[reactions]
|
||||
[reactions],
|
||||
);
|
||||
|
||||
const liveStreams = useMemo(() => {
|
||||
|
@ -17,7 +17,7 @@ export default function ZapstrEmbed({ ev }: { ev: NostrEvent }) {
|
||||
ev.tags.find(a => a[0] === "d")?.[1] ?? "",
|
||||
undefined,
|
||||
ev.kind,
|
||||
ev.pubkey
|
||||
ev.pubkey,
|
||||
);
|
||||
return (
|
||||
<>
|
||||
|
@ -23,7 +23,7 @@ export default function useProfileBadges(pubkey?: HexKey) {
|
||||
if (profileBadges.data) {
|
||||
return chunks(
|
||||
profileBadges.data.tags.filter(t => t[0] === "a" || t[0] === "e"),
|
||||
2
|
||||
2,
|
||||
).reduce((acc, [a, e]) => {
|
||||
return {
|
||||
...acc,
|
||||
@ -44,7 +44,7 @@ export default function useProfileBadges(pubkey?: HexKey) {
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{ pubkeys: [], ds: [] } as BadgeAwards
|
||||
{ pubkeys: [], ds: [] } as BadgeAwards,
|
||||
) as BadgeAwards;
|
||||
}, [profile]);
|
||||
|
||||
@ -77,7 +77,7 @@ export default function useProfileBadges(pubkey?: HexKey) {
|
||||
})
|
||||
.filter(
|
||||
({ award, badge }) =>
|
||||
badge && award.pubkey === badge.pubkey && award.tags.find(t => t[0] === "p" && t[1] === pubkey)
|
||||
badge && award.pubkey === badge.pubkey && award.tags.find(t => t[0] === "p" && t[1] === pubkey),
|
||||
)
|
||||
.map(({ badge }) => unwrap(badge));
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ export function useReactions(subId: string, ids: Array<string>, others?: (rb: Re
|
||||
.kinds(
|
||||
pref.enableReactions
|
||||
? [EventKind.Reaction, EventKind.Repost, EventKind.ZapReceipt]
|
||||
: [EventKind.ZapReceipt, EventKind.Repost]
|
||||
: [EventKind.ZapReceipt, EventKind.Repost],
|
||||
)
|
||||
.tag("e", ids);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ export default function useFollowersFeed(pubkey?: HexKey) {
|
||||
|
||||
const followers = useMemo(() => {
|
||||
const contactLists = followersFeed.data?.filter(
|
||||
a => a.kind === EventKind.ContactList && a.tags.some(b => b[0] === "p" && b[1] === pubkey)
|
||||
a => a.kind === EventKind.ContactList && a.tags.some(b => b[0] === "p" && b[1] === pubkey),
|
||||
);
|
||||
return [...new Set(contactLists?.map(a => a.pubkey))];
|
||||
}, [followersFeed, pubkey]);
|
||||
|
@ -85,7 +85,7 @@ export default function useLoginFeed() {
|
||||
Nip4Chats.onEvent(loginFeed.data);
|
||||
|
||||
const subs = loginFeed.data.filter(
|
||||
a => a.kind === EventKind.SnortSubscriptions && a.pubkey === bech32ToHex(SnortPubKey)
|
||||
a => a.kind === EventKind.SnortSubscriptions && a.pubkey === bech32ToHex(SnortPubKey),
|
||||
);
|
||||
Promise.all(
|
||||
subs.map(async a => {
|
||||
@ -97,7 +97,7 @@ export default function useLoginFeed() {
|
||||
...ex,
|
||||
} as SubscriptionEvent;
|
||||
}
|
||||
})
|
||||
}),
|
||||
).then(a => addSubscription(login, ...a.filter(a => a !== undefined).map(unwrap)));
|
||||
}
|
||||
}, [loginFeed, publisher]);
|
||||
@ -106,7 +106,7 @@ export default function useLoginFeed() {
|
||||
useEffect(() => {
|
||||
if (loginFeed.data) {
|
||||
const replies = loginFeed.data.filter(
|
||||
a => a.kind === EventKind.TextNote && !isMuted(a.pubkey) && a.created_at > readNotifications
|
||||
a => a.kind === EventKind.TextNote && !isMuted(a.pubkey) && a.created_at > readNotifications,
|
||||
);
|
||||
replies.forEach(async nx => {
|
||||
const n = await makeNotification(nx);
|
||||
|
@ -35,11 +35,11 @@ export default function useThreadFeed(link: NostrLink) {
|
||||
.kinds(
|
||||
pref.enableReactions
|
||||
? [EventKind.Reaction, EventKind.TextNote, EventKind.Repost, EventKind.ZapReceipt]
|
||||
: [EventKind.TextNote, EventKind.ZapReceipt, EventKind.Repost]
|
||||
: [EventKind.TextNote, EventKind.ZapReceipt, EventKind.Repost],
|
||||
)
|
||||
.tag(
|
||||
"e",
|
||||
allEvents.map(a => a.id)
|
||||
allEvents.map(a => a.id),
|
||||
);
|
||||
}
|
||||
if (trackingATags.length > 0) {
|
||||
@ -50,7 +50,7 @@ export default function useThreadFeed(link: NostrLink) {
|
||||
.authors(parsed.map(a => a[1]))
|
||||
.tag(
|
||||
"d",
|
||||
parsed.map(a => a[2])
|
||||
parsed.map(a => a[2]),
|
||||
);
|
||||
sub.withFilter().tag("a", trackingATags);
|
||||
}
|
||||
@ -85,7 +85,7 @@ export default function useThreadFeed(link: NostrLink) {
|
||||
id: b[1],
|
||||
relay: b[2],
|
||||
};
|
||||
})
|
||||
}),
|
||||
)
|
||||
.flat();
|
||||
const eTagsMissing = eTags.filter(a => !mainNotes.some(b => b.id === a.id));
|
||||
|
@ -43,7 +43,7 @@ export default function useTimelineFeed(subject: TimelineSubject, options: Timel
|
||||
.kinds(
|
||||
subject.type === "profile_keyword"
|
||||
? [EventKind.SetMetadata]
|
||||
: [EventKind.TextNote, EventKind.Repost, EventKind.Polls]
|
||||
: [EventKind.TextNote, EventKind.Repost, EventKind.Polls],
|
||||
);
|
||||
|
||||
if (subject.relay) {
|
||||
@ -149,7 +149,7 @@ export default function useTimelineFeed(subject: TimelineSubject, options: Timel
|
||||
.map(a => unwrap(a)[1]);
|
||||
const repostsByKind1 = main.data
|
||||
.filter(
|
||||
a => (a.kind === EventKind.Repost || a.kind === EventKind.TextNote) && a.tags.some(tagFilterOfTextRepost(a))
|
||||
a => (a.kind === EventKind.Repost || a.kind === EventKind.TextNote) && a.tags.some(tagFilterOfTextRepost(a)),
|
||||
)
|
||||
.map(a => a.tags.find(tagFilterOfTextRepost(a)))
|
||||
.filter(a => a)
|
||||
|
@ -21,7 +21,7 @@ export default function useImgProxy() {
|
||||
const result = hmacSha256(
|
||||
utils.hexToBytes(unwrap(settings).key),
|
||||
utils.hexToBytes(unwrap(settings).salt),
|
||||
te.encode(u)
|
||||
te.encode(u),
|
||||
);
|
||||
return urlSafe(base64.encode(result));
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ export function useInteractionCache(pubkey?: HexKey, event?: u256) {
|
||||
const data =
|
||||
useSyncExternalStore(
|
||||
c => InteractionCache.hook(c, id),
|
||||
() => InteractionCache.snapshot().find(a => a.id === id)
|
||||
() => InteractionCache.snapshot().find(a => a.id === id),
|
||||
) || EmptyInteraction;
|
||||
return {
|
||||
data: data,
|
||||
|
@ -4,6 +4,6 @@ import { useSyncExternalStore } from "react";
|
||||
export default function useLogin() {
|
||||
return useSyncExternalStore(
|
||||
s => LoginStore.hook(s),
|
||||
() => LoginStore.snapshot()
|
||||
() => LoginStore.snapshot(),
|
||||
);
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ export class MultiAccountStore extends ExternalStore<LoginSession> {
|
||||
type: LoginSessionType,
|
||||
relays?: Record<string, RelaySettings>,
|
||||
remoteSignerRelays?: Array<string>,
|
||||
privateKey?: string
|
||||
privateKey?: string,
|
||||
) {
|
||||
if (this.#accounts.has(key)) {
|
||||
throw new Error("Already logged in with this pubkey");
|
||||
|
@ -97,7 +97,7 @@ export class ServiceProvider {
|
||||
path: string,
|
||||
method?: "GET" | string,
|
||||
body?: unknown,
|
||||
headers?: { [key: string]: string }
|
||||
headers?: { [key: string]: string },
|
||||
): Promise<T | ServiceError> {
|
||||
try {
|
||||
const rsp = await fetch(`${this.url}${path}`, {
|
||||
|
@ -54,7 +54,7 @@ export default class SnortServiceProvider extends ServiceProvider {
|
||||
path: string,
|
||||
method?: "GET" | string,
|
||||
body?: unknown,
|
||||
headers?: { [key: string]: string }
|
||||
headers?: { [key: string]: string },
|
||||
): Promise<T | ServiceError> {
|
||||
const auth = await this.#publisher.generic(eb => {
|
||||
eb.kind(EventKind.HttpAuthentication);
|
||||
|
@ -25,7 +25,7 @@ const ErrorPage = () => {
|
||||
{JSON.stringify(
|
||||
error instanceof Error ? { name: error.name, message: error.message, stack: error.stack } : error,
|
||||
undefined,
|
||||
" "
|
||||
" ",
|
||||
)}
|
||||
</pre>
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ export default function Layout() {
|
||||
useEffect(() => {
|
||||
const osTheme = window.matchMedia("(prefers-color-scheme: light)");
|
||||
setTheme(
|
||||
preferences.theme === "system" && osTheme.matches ? "light" : preferences.theme === "light" ? "light" : "dark"
|
||||
preferences.theme === "system" && osTheme.matches ? "light" : preferences.theme === "light" ? "light" : "dark",
|
||||
);
|
||||
|
||||
osTheme.onchange = e => {
|
||||
@ -174,7 +174,7 @@ const AccountHeader = () => {
|
||||
|
||||
const hasNotifications = useMemo(
|
||||
() => latestNotification > readNotifications,
|
||||
[latestNotification, readNotifications]
|
||||
[latestNotification, readNotifications],
|
||||
);
|
||||
const unreadDms = useMemo(() => (publicKey ? 0 : 0), [publicKey]);
|
||||
|
||||
|
@ -55,7 +55,7 @@ const Artwork: Array<ArtworkEntry> = [
|
||||
export async function getNip05PubKey(addr: string): Promise<string> {
|
||||
const [username, domain] = addr.split("@");
|
||||
const rsp = await fetch(
|
||||
`https://${domain}/.well-known/nostr.json?name=${encodeURIComponent(username.toLocaleLowerCase())}`
|
||||
`https://${domain}/.well-known/nostr.json?name=${encodeURIComponent(username.toLocaleLowerCase())}`,
|
||||
);
|
||||
if (rsp.ok) {
|
||||
const data = await rsp.json();
|
||||
@ -103,7 +103,7 @@ export default function LoginPage() {
|
||||
setError(
|
||||
formatMessage({
|
||||
defaultMessage: "Unknown login error",
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
console.error(e);
|
||||
|
@ -75,7 +75,7 @@ export default function NotificationsPage() {
|
||||
|
||||
const notifications = useSyncExternalStore(
|
||||
c => Notifications.hook(c, "*"),
|
||||
() => Notifications.snapshot()
|
||||
() => Notifications.snapshot(),
|
||||
);
|
||||
|
||||
const timeKey = (ev: NostrEvent) => {
|
||||
@ -119,7 +119,7 @@ function NotificationGroup({ evs }: { evs: Array<TaggedNostrEvent> }) {
|
||||
return zap.anonZap ? "anon" : zap.sender ?? a.pubkey;
|
||||
}
|
||||
return a.pubkey;
|
||||
})
|
||||
}),
|
||||
);
|
||||
const firstPubkey = pubkeys[0];
|
||||
const firstPubkeyProfile = useUserProfile(inView ? (firstPubkey === "anon" ? "" : firstPubkey) : "");
|
||||
@ -213,7 +213,7 @@ function NotificationGroup({ evs }: { evs: Array<TaggedNostrEvent> }) {
|
||||
pubkeys.length - 1,
|
||||
firstPubkey === "anon"
|
||||
? formatMessage({ defaultMessage: "Anon" })
|
||||
: getDisplayName(firstPubkeyProfile, firstPubkey)
|
||||
: getDisplayName(firstPubkeyProfile, firstPubkey),
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
@ -221,7 +221,7 @@ export default function ProfilePage() {
|
||||
} as { [key: string]: Tab };
|
||||
const [tab, setTab] = useState<Tab>(ProfileTab.Notes);
|
||||
const optionalTabs = [ProfileTab.Zaps, ProfileTab.Relays, ProfileTab.Bookmarks, ProfileTab.Muted].filter(a =>
|
||||
unwrap(a)
|
||||
unwrap(a),
|
||||
) as Tab[];
|
||||
const horizontalScroll = useHorizontalScroll();
|
||||
|
||||
@ -433,7 +433,7 @@ export default function ProfilePage() {
|
||||
type: TLVEntryType.Author,
|
||||
length: 64,
|
||||
value: id,
|
||||
})}`
|
||||
})}`,
|
||||
)
|
||||
}>
|
||||
<Icon name="envelope" size={16} />
|
||||
|
@ -73,7 +73,7 @@ export default function ZapPoolPage() {
|
||||
const login = useLogin();
|
||||
const zapPool = useSyncExternalStore(
|
||||
c => ZapPoolController.hook(c),
|
||||
() => ZapPoolController.snapshot()
|
||||
() => ZapPoolController.snapshot(),
|
||||
);
|
||||
const { wallet } = useWallet();
|
||||
|
||||
|
@ -27,7 +27,7 @@ export default function AccountsPage() {
|
||||
setError(
|
||||
formatMessage({
|
||||
defaultMessage: "Unknown login error",
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
console.error(e);
|
||||
|
@ -29,7 +29,7 @@ export default function LNForwardAddress({ handle }: { handle: ManageHandle }) {
|
||||
setError(
|
||||
formatMessage({
|
||||
defaultMessage: "Invalid LNURL",
|
||||
})
|
||||
}),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ const ConnectCashu = () => {
|
||||
setError(
|
||||
formatMessage({
|
||||
defaultMessage: "Unknown error",
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ const ConnectLNC = () => {
|
||||
setError(
|
||||
formatMessage({
|
||||
defaultMessage: "Unknown error",
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ const ConnectLNDHub = () => {
|
||||
setError(
|
||||
formatMessage({
|
||||
defaultMessage: "Unknown error",
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ const ConnectNostrWallet = () => {
|
||||
setError(
|
||||
formatMessage({
|
||||
defaultMessage: "Unknown error",
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ export default class SnortApi {
|
||||
path: string,
|
||||
method?: "GET" | string,
|
||||
body?: { [key: string]: string },
|
||||
headers?: { [key: string]: string }
|
||||
headers?: { [key: string]: string },
|
||||
): Promise<T> {
|
||||
if (!this.#publisher) {
|
||||
throw new Error("Publisher not set");
|
||||
@ -110,7 +110,7 @@ export default class SnortApi {
|
||||
path: string,
|
||||
method?: "GET" | string,
|
||||
body?: { [key: string]: string },
|
||||
headers?: { [key: string]: string }
|
||||
headers?: { [key: string]: string },
|
||||
): Promise<T> {
|
||||
const rsp = await fetch(`${this.#url}${path}`, {
|
||||
method: method,
|
||||
|
@ -50,7 +50,7 @@ export async function openFile(): Promise<File | undefined> {
|
||||
}
|
||||
}, 300);
|
||||
},
|
||||
{ once: true }
|
||||
{ once: true },
|
||||
);
|
||||
});
|
||||
}
|
||||
@ -209,7 +209,7 @@ export function dedupeByPubkey(events: TaggedNostrEvent[]) {
|
||||
list: [...list, ev],
|
||||
};
|
||||
},
|
||||
{ list: [], seen: new Set([]) }
|
||||
{ list: [], seen: new Set([]) },
|
||||
);
|
||||
return deduped.list as TaggedNostrEvent[];
|
||||
}
|
||||
@ -226,7 +226,7 @@ export function dedupeById<T extends { id: string }>(events: Array<T>) {
|
||||
list: [...list, ev],
|
||||
};
|
||||
},
|
||||
{ list: [], seen: new Set([]) }
|
||||
{ list: [], seen: new Set([]) },
|
||||
);
|
||||
return deduped.list as Array<T>;
|
||||
}
|
||||
@ -487,7 +487,7 @@ export function kvToObject<T>(o: string, sep?: string) {
|
||||
return [match[1], match[2]];
|
||||
}
|
||||
return [];
|
||||
})
|
||||
}),
|
||||
) as T;
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ export const Toastore = new ToasterSlots();
|
||||
export default function Toaster() {
|
||||
const toast = useSyncExternalStore(
|
||||
c => Toastore.hook(c),
|
||||
() => Toastore.snapshot()
|
||||
() => Toastore.snapshot(),
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -12,7 +12,7 @@ import { magnetURIDecode } from "SnortUtils";
|
||||
export default async function VoidCatUpload(
|
||||
file: File | Blob,
|
||||
filename: string,
|
||||
publisher?: EventPublisher
|
||||
publisher?: EventPublisher,
|
||||
): Promise<UploadResult> {
|
||||
const api = new VoidApi(VoidCatHost);
|
||||
const uploader = api.getUploader(file);
|
||||
|
@ -57,6 +57,6 @@ export interface NutStashBackup {
|
||||
mints: [
|
||||
{
|
||||
mintURL: string;
|
||||
}
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ export class LNCWallet implements LNWallet {
|
||||
err => {
|
||||
this.#log(err);
|
||||
reject(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ export class NostrConnectWallet implements LNWallet {
|
||||
],
|
||||
() => {
|
||||
// ignored
|
||||
}
|
||||
},
|
||||
);
|
||||
await this.#conn.SendAsync(evCommand);
|
||||
return await new Promise<T>((resolve, reject) => {
|
||||
|
@ -84,7 +84,7 @@ export class WebLNWallet implements LNWallet {
|
||||
await window.webln?.makeInvoice({
|
||||
amount: req.amount,
|
||||
defaultMemo: req.memo,
|
||||
})
|
||||
}),
|
||||
);
|
||||
if (rsp) {
|
||||
const invoice = prToWalletInvoice(rsp.paymentRequest);
|
||||
|
@ -248,7 +248,7 @@ window.document.addEventListener("close", () => {
|
||||
export function useWallet() {
|
||||
const wallet = useSyncExternalStore<WalletStoreSnapshot>(
|
||||
h => Wallets.hook(h),
|
||||
() => Wallets.snapshot()
|
||||
() => Wallets.snapshot(),
|
||||
);
|
||||
useEffect(() => {
|
||||
if (wallet.wallet?.isReady() === false && wallet.wallet.canAutoLogin()) {
|
||||
|
@ -54,7 +54,7 @@ class ZapPool extends ExternalStore<Array<ZapPoolRecipient>> {
|
||||
Toastore.push({
|
||||
element: `Sent ${amtSend.toLocaleString()} sats to ${getDisplayName(
|
||||
profile,
|
||||
x.pubkey
|
||||
x.pubkey,
|
||||
)} from your zap pool`,
|
||||
expire: unixNow() + 10,
|
||||
icon: "zap",
|
||||
|
@ -116,7 +116,7 @@ export function createChatLink(type: ChatType, ...params: Array<string>) {
|
||||
type: TLVEntryType.Author,
|
||||
length: params[0].length,
|
||||
value: params[0],
|
||||
} as TLVEntry
|
||||
} as TLVEntry,
|
||||
)}`;
|
||||
}
|
||||
case ChatType.PrivateDirectMessage: {
|
||||
@ -127,7 +127,7 @@ export function createChatLink(type: ChatType, ...params: Array<string>) {
|
||||
type: TLVEntryType.Author,
|
||||
length: params[0].length,
|
||||
value: params[0],
|
||||
} as TLVEntry
|
||||
} as TLVEntry,
|
||||
)}`;
|
||||
}
|
||||
case ChatType.PrivateGroupChat: {
|
||||
@ -139,8 +139,8 @@ export function createChatLink(type: ChatType, ...params: Array<string>) {
|
||||
type: TLVEntryType.Author,
|
||||
length: a.length,
|
||||
value: a,
|
||||
} as TLVEntry)
|
||||
)
|
||||
}) as TLVEntry,
|
||||
),
|
||||
)}`;
|
||||
}
|
||||
}
|
||||
@ -161,14 +161,14 @@ export function useNip4Chat() {
|
||||
const { publicKey } = useLogin();
|
||||
return useSyncExternalStore(
|
||||
c => Nip4Chats.hook(c),
|
||||
() => Nip4Chats.snapshot(publicKey)
|
||||
() => Nip4Chats.snapshot(publicKey),
|
||||
);
|
||||
}
|
||||
|
||||
export function useNip29Chat() {
|
||||
return useSyncExternalStore(
|
||||
c => Nip29Chats.hook(c),
|
||||
() => Nip29Chats.snapshot()
|
||||
() => Nip29Chats.snapshot(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -176,7 +176,7 @@ export function useNip24Chat() {
|
||||
const { publicKey } = useLogin();
|
||||
return useSyncExternalStore(
|
||||
c => Nip24Chats.hook(c),
|
||||
() => Nip24Chats.snapshot(publicKey)
|
||||
() => Nip24Chats.snapshot(publicKey),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,8 @@ export class Nip24ChatSystem extends ExternalStore<Array<Chat>> implements ChatS
|
||||
value: v,
|
||||
type: TLVEntryType.Author,
|
||||
length: v.length,
|
||||
} as TLVEntry)
|
||||
)
|
||||
}) as TLVEntry,
|
||||
),
|
||||
);
|
||||
};
|
||||
return dedupe(messages.map(a => chatId(a))).map(a => {
|
||||
@ -72,7 +72,7 @@ export class Nip24ChatSystem extends ExternalStore<Array<Chat>> implements ChatS
|
||||
} as {
|
||||
t: number;
|
||||
title: string | undefined;
|
||||
}
|
||||
},
|
||||
);
|
||||
return {
|
||||
type: ChatType.PrivateDirectMessage,
|
||||
|
@ -46,12 +46,12 @@ export class Nip29ChatSystem extends ExternalStore<Array<Chat>> implements ChatS
|
||||
.map(a => a.tags.find(b => b[0] === "g"))
|
||||
.filter(a => a !== undefined)
|
||||
.map(a => unwrap(a))
|
||||
.map(a => `${a[2]}${a[1]}`)
|
||||
.map(a => `${a[2]}${a[1]}`),
|
||||
);
|
||||
return groups.map(g => {
|
||||
const [relay, channel] = g.split("/", 2);
|
||||
const messages = allMessages.filter(
|
||||
a => `${a.tags.find(b => b[0] === "g")?.[2]}${a.tags.find(b => b[0] === "g")?.[1]}` === g
|
||||
a => `${a.tags.find(b => b[0] === "g")?.[2]}${a.tags.find(b => b[0] === "g")?.[1]}` === g,
|
||||
);
|
||||
const lastRead = lastReadInChat(g);
|
||||
return {
|
||||
|
@ -34,7 +34,7 @@ export class Nip4ChatSystem extends ExternalStore<Array<Chat>> implements ChatSy
|
||||
const dms = this.#cache.snapshot();
|
||||
const dmSince = dms.reduce(
|
||||
(acc, v) => (v.created_at > acc && v.kind === EventKind.DirectMessage ? (acc = v.created_at) : acc),
|
||||
0
|
||||
0,
|
||||
);
|
||||
|
||||
this.#log("Loading DMS since %s", new Date(dmSince * 1000));
|
||||
@ -49,12 +49,15 @@ export class Nip4ChatSystem extends ExternalStore<Array<Chat>> implements ChatSy
|
||||
|
||||
listChats(pk: string): Chat[] {
|
||||
const myDms = this.#nip4Events();
|
||||
const chats = myDms.reduce((acc, v) => {
|
||||
const chatId = inChatWith(v, pk);
|
||||
acc[chatId] ??= [];
|
||||
acc[chatId].push(v);
|
||||
return acc;
|
||||
}, {} as Record<string, Array<NostrEvent>>);
|
||||
const chats = myDms.reduce(
|
||||
(acc, v) => {
|
||||
const chatId = inChatWith(v, pk);
|
||||
acc[chatId] ??= [];
|
||||
acc[chatId].push(v);
|
||||
return acc;
|
||||
},
|
||||
{} as Record<string, Array<NostrEvent>>,
|
||||
);
|
||||
|
||||
return [...Object.entries(chats)].map(([k, v]) => Nip4ChatSystem.createChatObj(k, v));
|
||||
}
|
||||
|
@ -173,5 +173,5 @@ root.render(
|
||||
</SnortContext.Provider>
|
||||
</IntlProvider>
|
||||
</Provider>
|
||||
</StrictMode>
|
||||
</StrictMode>,
|
||||
);
|
||||
|
@ -64,7 +64,7 @@ export class Nip46Signer implements EventSigner {
|
||||
}
|
||||
|
||||
get supports(): string[] {
|
||||
return ["nip04"]
|
||||
return ["nip04"];
|
||||
}
|
||||
|
||||
get relays() {
|
||||
|
@ -64,7 +64,7 @@ export interface SystemInterface {
|
||||
* @param req Request to send to relays
|
||||
* @param cb A callback which will fire every 100ms when new data is received
|
||||
*/
|
||||
Fetch(req: RequestBuilder, cb?: (evs: Array<TaggedNostrEvent>) => void) : Promise<NoteStoreSnapshotData>;
|
||||
Fetch(req: RequestBuilder, cb?: (evs: Array<TaggedNostrEvent>) => void): Promise<NoteStoreSnapshotData>;
|
||||
|
||||
/**
|
||||
* Create a new permanent connection to a relay
|
||||
|
@ -14,20 +14,20 @@ export interface NostrLink {
|
||||
export function createNostrLinkToEvent(ev: TaggedNostrEvent | NostrEvent) {
|
||||
const relays = "relays" in ev ? ev.relays : undefined;
|
||||
|
||||
if (ev.kind >= 30_000 && ev.kind < 40_000) {
|
||||
const dTag = unwrap(findTag(ev, "d"));
|
||||
return createNostrLink(NostrPrefix.Address, dTag, relays, ev.kind, ev.pubkey);
|
||||
}
|
||||
return createNostrLink(NostrPrefix.Event, ev.id, relays, ev.kind, ev.pubkey);
|
||||
if (ev.kind >= 30_000 && ev.kind < 40_000) {
|
||||
const dTag = unwrap(findTag(ev, "d"));
|
||||
return createNostrLink(NostrPrefix.Address, dTag, relays, ev.kind, ev.pubkey);
|
||||
}
|
||||
return createNostrLink(NostrPrefix.Event, ev.id, relays, ev.kind, ev.pubkey);
|
||||
}
|
||||
|
||||
export function linkMatch(link: NostrLink, ev: NostrEvent) {
|
||||
if(link.type === NostrPrefix.Address) {
|
||||
if (link.type === NostrPrefix.Address) {
|
||||
const dTag = findTag(ev, "d");
|
||||
if(dTag && dTag === link.id && unwrap(link.author) === ev.pubkey && unwrap(link.kind) === ev.kind) {
|
||||
if (dTag && dTag === link.id && unwrap(link.author) === ev.pubkey && unwrap(link.kind) === ev.kind) {
|
||||
return true;
|
||||
}
|
||||
} else if(link.type === NostrPrefix.Event || link.type === NostrPrefix.Note) {
|
||||
} else if (link.type === NostrPrefix.Event || link.type === NostrPrefix.Note) {
|
||||
return link.id === ev.id;
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ export class NostrSystem extends ExternalStore<SystemSnapshot> implements System
|
||||
this.#relayCache.preload(),
|
||||
this.#profileCache.preload(),
|
||||
this.#relayMetricsCache.preload(),
|
||||
this.#eventsCache.preload()
|
||||
this.#eventsCache.preload(),
|
||||
];
|
||||
await Promise.all(t);
|
||||
}
|
||||
@ -206,29 +206,31 @@ export class NostrSystem extends ExternalStore<SystemSnapshot> implements System
|
||||
|
||||
Fetch(req: RequestBuilder, cb?: (evs: Array<TaggedNostrEvent>) => void) {
|
||||
const q = this.Query(NoteCollection, req);
|
||||
return new Promise<NoteStoreSnapshotData>((resolve) => {
|
||||
return new Promise<NoteStoreSnapshotData>(resolve => {
|
||||
let t: ReturnType<typeof setTimeout> | undefined;
|
||||
let tBuf: Array<TaggedNostrEvent> = [];
|
||||
const releaseOnEvent = cb ? q.feed.onEvent(evs => {
|
||||
if(!t) {
|
||||
tBuf = [...evs];
|
||||
t = setTimeout(() => {
|
||||
t = undefined;
|
||||
cb(tBuf);
|
||||
}, 100);
|
||||
} else {
|
||||
tBuf.push(...evs);
|
||||
}
|
||||
}) : undefined;
|
||||
const releaseOnEvent = cb
|
||||
? q.feed.onEvent(evs => {
|
||||
if (!t) {
|
||||
tBuf = [...evs];
|
||||
t = setTimeout(() => {
|
||||
t = undefined;
|
||||
cb(tBuf);
|
||||
}, 100);
|
||||
} else {
|
||||
tBuf.push(...evs);
|
||||
}
|
||||
})
|
||||
: undefined;
|
||||
const releaseFeedHook = q.feed.hook(() => {
|
||||
if(q.progress === 1) {
|
||||
if (q.progress === 1) {
|
||||
releaseOnEvent?.();
|
||||
releaseFeedHook();
|
||||
q.cancel();
|
||||
resolve(unwrap(q.feed.snapshot.data));
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Query<T extends NoteStore>(type: { new (): T }, req: RequestBuilder): Query {
|
||||
@ -255,7 +257,7 @@ export class NostrSystem extends ExternalStore<SystemSnapshot> implements System
|
||||
|
||||
const filters = req.build(this.#relayCache);
|
||||
const q = new Query(req.id, req.instance, store, req.options?.leaveOpen);
|
||||
if(filters.some(a => a.filters.some(b=>b.ids))) {
|
||||
if (filters.some(a => a.filters.some(b => b.ids))) {
|
||||
q.feed.onEvent(async evs => {
|
||||
await this.#eventsCache.bulkSet(evs);
|
||||
});
|
||||
@ -271,10 +273,10 @@ export class NostrSystem extends ExternalStore<SystemSnapshot> implements System
|
||||
|
||||
async SendQuery(q: Query, qSend: BuiltRawReqFilter) {
|
||||
// trim query of cached ids
|
||||
for(const f of qSend.filters) {
|
||||
for (const f of qSend.filters) {
|
||||
if (f.ids) {
|
||||
const cacheResults = await this.#eventsCache.bulkGet(f.ids);
|
||||
if(cacheResults.length > 0) {
|
||||
if (cacheResults.length > 0) {
|
||||
const resultIds = new Set(cacheResults.map(a => a.id));
|
||||
f.ids = f.ids.filter(a => !resultIds.has(a));
|
||||
q.feed.add(cacheResults as Array<TaggedNostrEvent>);
|
||||
@ -283,10 +285,13 @@ export class NostrSystem extends ExternalStore<SystemSnapshot> implements System
|
||||
}
|
||||
|
||||
// check for empty filters
|
||||
qSend.filters = qSend.filters.filter(a => Object.values(a).filter(v => Array.isArray(v)).every(b => (b as Array<string | number>).length > 0));
|
||||
if(qSend.filters.length === 0) {
|
||||
qSend.filters = qSend.filters.filter(a =>
|
||||
Object.values(a)
|
||||
.filter(v => Array.isArray(v))
|
||||
.every(b => (b as Array<string | number>).length > 0),
|
||||
);
|
||||
if (qSend.filters.length === 0) {
|
||||
return;
|
||||
|
||||
}
|
||||
if (qSend.relay) {
|
||||
this.#log("Sending query to %s %O", qSend.relay, qSend);
|
||||
|
@ -34,7 +34,7 @@ export class PrivateKeySigner implements EventSigner {
|
||||
}
|
||||
|
||||
get supports(): string[] {
|
||||
return ["nip04", "nip44"]
|
||||
return ["nip04", "nip44"];
|
||||
}
|
||||
|
||||
get privateKey() {
|
||||
|
@ -21,7 +21,7 @@ export class SystemWorker extends ExternalStore<SystemSnapshot> implements Syste
|
||||
}
|
||||
}
|
||||
|
||||
Fetch(req: RequestBuilder, cb?: (evs: Array<TaggedNostrEvent>) => void) : Promise<NoteStoreSnapshotData> {
|
||||
Fetch(req: RequestBuilder, cb?: (evs: Array<TaggedNostrEvent>) => void): Promise<NoteStoreSnapshotData> {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ describe("splitByUrl", () => {
|
||||
"https://i.imgur.com/rkqhjeq.png",
|
||||
" Every form of money that could be inflated by way of force or technological advancement has been. ",
|
||||
"https://www.dw.com/de/amtsinhaber-mnangagwa-gewinnt-präsidentenwahl-in-simbabwe/a-66640006?maca=de-rss-de-all-1119-xml-atom",
|
||||
" and some shit."
|
||||
" and some shit.",
|
||||
];
|
||||
|
||||
expect(splitByUrl(inputStr)).toEqual(expectedOutput);
|
||||
|
Loading…
x
Reference in New Issue
Block a user