code cleanup

This commit is contained in:
hzrd149 2024-12-01 20:03:26 -06:00
parent f94a3450eb
commit 4e7e856b95
70 changed files with 125 additions and 118 deletions

View File

@ -11,9 +11,9 @@
"start": "vite serve",
"dev": "VITE_APP_VERSION=dev vite serve",
"build": "tsc --project tsconfig.json && vite build",
"format": "prettier --ignore-path .prettierignore -w .",
"build-icons": "node ./scripts/build-icons.mjs",
"analyze": "pnpm dlx vite-bundle-visualizer -o ./stats.html",
"build-icons": "node ./scripts/build-icons.mjs"
"format": "prettier --ignore-path .prettierignore -w ."
},
"dependencies": {
"@cashu/cashu-ts": "2.0.0-rc1",

View File

@ -73,7 +73,7 @@ export default class ChunkedRequest {
}
let filters: Filter[] = mergeFilter(this.filters, { limit: this.chunkSize });
let oldestEvent = this.getLastEvent();
const oldestEvent = this.getLastEvent();
if (oldestEvent) {
filters = mergeFilter(filters, { until: oldestEvent.created_at - 1 });
}

View File

@ -108,7 +108,7 @@ export class PubkeyGraph extends EventEmitter<EventMap> {
const refCount = new Map<string, number>();
const walkLevel = (level = 0) => {
if (next.size === 0) return;
let keys = new Set(next);
const keys = new Set(next);
next.clear();
for (const key of keys) {
@ -141,7 +141,7 @@ export class PubkeyGraph extends EventEmitter<EventMap> {
}
getPaths(pubkey: string, maxLength = 2) {
let paths: string[][] = [];
const paths: string[][] = [];
const walk = (p: string, maxLvl = 0, path: string[] = []) => {
if (path.includes(p)) return;

View File

@ -106,7 +106,7 @@ export default class RelayPool implements IConnectionPool {
}
async waitForOpen(relayOrUrl: string | URL | AbstractRelay, quite = true) {
let relay = this.getRelay(relayOrUrl);
const relay = this.getRelay(relayOrUrl);
if (!relay) return Promise.reject("Missing relay");
if (relay.connected) return true;
@ -123,7 +123,7 @@ export default class RelayPool implements IConnectionPool {
}
async requestConnect(relayOrUrl: string | URL | AbstractRelay, quite = true) {
let relay = this.getRelay(relayOrUrl);
const relay = this.getRelay(relayOrUrl);
if (!relay) return;
if (!relay.connected && !offlineMode.value) {
@ -144,11 +144,11 @@ export default class RelayPool implements IConnectionPool {
}
getRelayAuthStorageKey(relayOrUrl: string | URL | AbstractRelay) {
let relay = this.getRelay(relayOrUrl);
const relay = this.getRelay(relayOrUrl);
return `${relay!.url}-auth-mode`;
}
getRelayAuthMode(relayOrUrl: string | URL | AbstractRelay): RelayAuthMode | undefined {
let relay = this.getRelay(relayOrUrl);
const relay = this.getRelay(relayOrUrl);
if (!relay) return;
const defaultMode = localSettings.defaultAuthenticationMode.value;
@ -157,7 +157,7 @@ export default class RelayPool implements IConnectionPool {
return mode || defaultMode;
}
setRelayAuthMode(relayOrUrl: string | URL | AbstractRelay, mode: RelayAuthMode) {
let relay = this.getRelay(relayOrUrl);
const relay = this.getRelay(relayOrUrl);
if (!relay) return;
localStorage.setItem(this.getRelayAuthStorageKey(relay), mode);
@ -169,7 +169,7 @@ export default class RelayPool implements IConnectionPool {
sign: Parameters<AbstractRelay["auth"]>[0],
quite = true,
) {
let relay = this.getRelay(relayOrUrl);
const relay = this.getRelay(relayOrUrl);
if (!relay) return;
const pending = this.pendingAuth.get(relay);
@ -204,7 +204,7 @@ export default class RelayPool implements IConnectionPool {
}
canSubscribe(relayOrUrl: string | URL | AbstractRelay) {
let relay = this.getRelay(relayOrUrl);
const relay = this.getRelay(relayOrUrl);
if (!relay) return false;
return this.authForSubscribe.get(relay).value !== false;

View File

@ -270,7 +270,7 @@ export default class NostrWebRTCPeer extends EventEmitter<EventMap> {
this.log(`Got ${candidates.length} candidates`);
for (let candidate of candidates) {
for (const candidate of candidates) {
await pc.addIceCandidate(candidate);
}
}

View File

@ -90,7 +90,7 @@ export default class WebRtcRelayServer extends EventEmitter<EventMap> {
handleCloseMessage(data: any[]) {
const [_, id] = data as [string, string, ...Filter[]];
let sub = this.subscriptions.get(id);
const sub = this.subscriptions.get(id);
if (sub) {
sub.close();
this.subscriptions.delete(id);

View File

@ -49,7 +49,7 @@ export function renderYoutubePlaylistURL(match: URL) {
function YoutubeVideoEmbed({ url }: { url: URL }) {
const { youtubeRedirect } = useAppSettings();
var videoId = url.searchParams.get("v");
let videoId = url.searchParams.get("v");
if (url.hostname === "youtu.be") videoId = url.pathname.split("/")[1];
if (!videoId) return null;
@ -74,7 +74,7 @@ export function renderYoutubeVideoURL(match: URL) {
if (!YOUTUBE_DOMAINS.includes(match.hostname)) return null;
if (match.pathname.startsWith("/live")) return null;
var videoId = match.searchParams.get("v");
let videoId = match.searchParams.get("v");
if (match.hostname === "youtu.be") videoId = match.pathname.split("/")[1];
if (!videoId) return null;

View File

@ -10,7 +10,7 @@ export default function DebugEventCachePage({ event }: { event: NostrEvent }) {
const update = () => eventStore.update(event);
const renderValue = (field: symbol) => {
let value = Reflect.get(event, field);
const value = Reflect.get(event, field);
if (value instanceof Map) return JSON.stringify(Object.fromEntries(value.entries()));
if (value instanceof Set) return JSON.stringify(Array.from(value));

View File

@ -44,7 +44,7 @@ function TimelineItem({ event }: { event: NostrEvent }) {
const renderContent = () => {
switch (event.kind) {
case kinds.EncryptedDirectMessage:
case kinds.EncryptedDirectMessage: {
const sender = getDMSender(event);
const recipient = getDMRecipient(event);
return (
@ -52,13 +52,15 @@ function TimelineItem({ event }: { event: NostrEvent }) {
<UserName pubkey={sender} fontWeight="bold" /> messaged <UserName pubkey={recipient} fontWeight="bold" />
</Text>
);
case kinds.Contacts:
}
case kinds.Contacts: {
return (
<Text noOfLines={1} isTruncated>
Updated contacts
</Text>
);
case kinds.Reaction:
}
case kinds.Reaction: {
const pointer = nip25.getReactedEventPointer(event);
return (
<HoverLinkOverlay
@ -70,12 +72,14 @@ function TimelineItem({ event }: { event: NostrEvent }) {
{event.content}
</HoverLinkOverlay>
);
default:
}
default: {
return (
<HoverLinkOverlay as={RouterLink} to={`/l/${getSharableEventAddress(event)}`} noOfLines={1} isTruncated>
{event.content}
</HoverLinkOverlay>
);
}
}
};

View File

@ -135,4 +135,6 @@ const MagicTextArea = forwardRef<HTMLTextAreaElement, TextareaProps & { instance
},
);
MagicTextArea.displayName = "MagicTextArea";
export { MagicInput, MagicTextArea as default };

View File

@ -9,7 +9,6 @@ import StreamNote from "./stream-note";
import RelayRecommendation from "./relay-recommendation";
import BadgeAwardCard from "../../../views/badges/components/badge-award-card";
import { isReply } from "../../../helpers/nostr/event";
import { STREAM_KIND } from "../../../helpers/nostr/stream";
import { NostrEvent } from "../../../types/nostr-event";
import { FLARE_VIDEO_KIND } from "../../../helpers/nostr/video";
import EmbeddedFlareVideo from "../../embed-event/event-types/embedded-flare-video";

View File

@ -37,13 +37,13 @@ function ImageGallery({ images }: { images: PhotoWithEvent[] }) {
export default function MediaTimeline({ timeline }: { timeline: NostrEvent[] }) {
const images = useMemo(() => {
var images: PhotoWithEvent[] = [];
const images: PhotoWithEvent[] = [];
for (const event of timeline) {
if (event.kind === kinds.Repost || event.kind === kinds.GenericRepost) continue;
const urls = event.content.matchAll(getMatchLink());
let i = 0;
const i = 0;
for (const match of urls) {
if (isImageURL(match[0])) images.push({ event, src: match[0] });
}

View File

@ -121,14 +121,14 @@ export function UserFollowButton({ pubkey, showLists, ...props }: UserFollowButt
const signed = await requestSignature(draft);
await publish("Follow", signed);
setLoading(false);
}, [contacts, requestSignature]);
}, [contacts, requestSignature, pubkey, publish]);
const handleUnfollow = useAsyncErrorHandler(async () => {
setLoading(true);
const draft = listRemovePerson(contacts || createEmptyContactList(), pubkey);
const signed = await requestSignature(draft);
await publish("Unfollow", signed);
setLoading(false);
}, [contacts, requestSignature]);
}, [contacts, requestSignature, pubkey, publish]);
if (showLists) {
return (

View File

@ -1,7 +1,7 @@
// based on https://stackoverflow.com/a/10469752
export function humanReadableSats(sats: number) {
if (sats === 0) return "0";
var s = ["", "K", "M"];
var e = Math.floor(Math.log(sats) / Math.log(1000));
const s = ["", "K", "M"];
const e = Math.floor(Math.log(sats) / Math.log(1000));
return Math.round((sats / Math.pow(1000, e)) * 100) / 100 + s[e];
}

View File

@ -115,7 +115,7 @@ export function getContentTagRefs(content: string, tags: Tag[]) {
break;
}
let matchingTags = tags.filter((t) => t[0] === type && t[1] === id);
const matchingTags = tags.filter((t) => t[0] === type && t[1] === id);
for (const t of matchingTags) foundTags.add(t);
}

View File

@ -6,7 +6,7 @@ import { cloneEvent } from "./event";
/** fixes or removes any bad r tags */
export function cleanRTags(tags: Tag[]) {
let newTags: Tag[] = [];
const newTags: Tag[] = [];
for (const tag of tags) {
if (tag[0] === "r") {
if (!tag[1]) continue;
@ -39,7 +39,7 @@ export function getRelaysFromMailbox(list: NostrEvent | DraftNostrEvent): { url:
}
export function addRelayModeToMailbox(list: NostrEvent | undefined, relay: string, mode: RelayMode): DraftNostrEvent {
let draft = cloneEvent(kinds.RelayList, list);
const draft = cloneEvent(kinds.RelayList, list);
draft.tags = cleanRTags(draft.tags);
const existing = draft.tags.find((t) => t[0] === "r" && t[1] === relay) as RTag;
@ -54,7 +54,7 @@ export function removeRelayModeFromMailbox(
relay: string,
mode: RelayMode,
): DraftNostrEvent {
let draft = cloneEvent(kinds.RelayList, list);
const draft = cloneEvent(kinds.RelayList, list);
draft.tags = cleanRTags(draft.tags);
const existing = draft.tags.find((t) => t[0] === "r" && t[1] === relay) as RTag;

View File

@ -6,20 +6,20 @@ import { getZapPayment, isETag, isPTag, ProfileContent } from "applesauce-core/h
export async function getZapEndpoint(metadata: ProfileContent): Promise<null | string> {
try {
let lnurl: string = "";
let { lud06, lud16 } = metadata;
const { lud06, lud16 } = metadata;
if (lud06) {
let { words } = bech32.decode(lud06 as `${string}1${string}`, 1000);
let data = bech32.fromWords(words);
const { words } = bech32.decode(lud06 as `${string}1${string}`, 1000);
const data = bech32.fromWords(words);
lnurl = utils.utf8Decoder.decode(data);
} else if (lud16) {
let [name, domain] = lud16.split("@");
const [name, domain] = lud16.split("@");
lnurl = `https://${domain}/.well-known/lnurlp/${name}`;
} else {
return null;
}
let res = await fetch(lnurl);
let body = await res.json();
const res = await fetch(lnurl);
const body = await res.json();
if (body.allowsNostr && body.nostrPubkey) {
return body.callback;

View File

@ -2,7 +2,7 @@ import { QrCode } from "../lib/qrcodegen";
export function drawSvgPath(qr: QrCode, border: number): string {
if (border < 0) throw new RangeError("Border must be non-negative");
let parts: Array<string> = [];
const parts: Array<string> = [];
for (let y = 0; y < qr.size; y++) {
for (let x = 0; x < qr.size; x++) {
if (qr.getModule(x, y)) parts.push(`M${x + border},${y + border}h1v1h-1z`);

View File

@ -151,7 +151,7 @@ export function subscribeMany(relays: string[], filters: Filter[], params: Subsc
return;
}
let subscription = relay.subscribe(filters, {
const subscription = relay.subscribe(filters, {
...params,
oneose: () => handleEose(i),
onclose: (reason) => handleClose(i, reason),

View File

@ -12,7 +12,7 @@ export type NumberCache = {
export default function useNumberCache(cacheKey: string): NumberCache {
const get = useCallback(
(key: string) => {
let map = cache.get(cacheKey);
const map = cache.get(cacheKey);
if (!map) return undefined;
return map.get(key);

View File

@ -99,7 +99,7 @@ export function mediaSetup(ogObject: OgObjectInteral) {
ogObject.ogImageURL = ogObject.ogImageURL ? ogObject.ogImageURL : [];
ogObject.ogImageProperty = ogObject.ogImageProperty ? ogObject.ogImageProperty : [];
// set ogImageProperty to ogImageSecureURL if it exists
// eslint-disable-next-line max-len
ogObject.ogImageProperty =
ogObject.ogImageSecureURL.length !== 0 ? ogObject.ogImageSecureURL : ogObject.ogImageProperty;
// fall back to ogImageURL if ogImageProperty isn't set
@ -150,7 +150,7 @@ export function mediaSetup(ogObject: OgObjectInteral) {
ogObject.twitterImageAlt
) {
ogObject.twitterImageSrc = ogObject.twitterImageSrc ? ogObject.twitterImageSrc : [];
// eslint-disable-next-line max-len
ogObject.twitterImageProperty = ogObject.twitterImageProperty
? ogObject.twitterImageProperty
: ogObject.twitterImageSrc; // deafult to twitterImageSrc

View File

@ -114,7 +114,7 @@ export class QrCode {
}
// Concatenate all segments to create the data bit string
let bb: Array<bit> = [];
const bb: Array<bit> = [];
for (const seg of segs) {
appendBits(seg.mode.modeBits, 4, bb);
appendBits(seg.numChars, seg.mode.numCharCountBits(version), bb);
@ -133,7 +133,7 @@ export class QrCode {
for (let padByte = 0xec; bb.length < dataCapacityBits; padByte ^= 0xec ^ 0x11) appendBits(padByte, 8, bb);
// Pack bits into bytes in big endian
let dataCodewords: Array<byte> = [];
const dataCodewords: Array<byte> = [];
while (dataCodewords.length * 8 < bb.length) dataCodewords.push(0);
bb.forEach((b: bit, i: int) => (dataCodewords[i >>> 3] |= b << (7 - (i & 7))));
@ -184,7 +184,7 @@ export class QrCode {
this.size = version * 4 + 17;
// Initialize both grids to be size*size arrays of Boolean false
let row: Array<boolean> = [];
const row: Array<boolean> = [];
for (let i = 0; i < this.size; i++) row.push(false);
for (let i = 0; i < this.size; i++) {
this.modules.push(row.slice()); // Initially all light
@ -350,10 +350,10 @@ export class QrCode {
const shortBlockLen: int = Math.floor(rawCodewords / numBlocks);
// Split data into blocks and append ECC to each block
let blocks: Array<Array<byte>> = [];
const blocks: Array<Array<byte>> = [];
const rsDiv: Array<byte> = QrCode.reedSolomonComputeDivisor(blockEccLen);
for (let i = 0, k = 0; i < numBlocks; i++) {
let dat: Array<byte> = data.slice(k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1));
const dat: Array<byte> = data.slice(k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1));
k += dat.length;
const ecc: Array<byte> = QrCode.reedSolomonComputeRemainder(dat, rsDiv);
if (i < numShortBlocks) dat.push(0);
@ -361,7 +361,7 @@ export class QrCode {
}
// Interleave (not concatenate) the bytes from every block into a single sequence
let result: Array<byte> = [];
const result: Array<byte> = [];
for (let i = 0; i < blocks[0].length; i++) {
blocks.forEach((block, j) => {
// Skip the padding byte in short blocks
@ -452,7 +452,7 @@ export class QrCode {
for (let y = 0; y < this.size; y++) {
let runColor = false;
let runX = 0;
let runHistory = [0, 0, 0, 0, 0, 0, 0];
const runHistory = [0, 0, 0, 0, 0, 0, 0];
for (let x = 0; x < this.size; x++) {
if (this.modules[y][x] == runColor) {
runX++;
@ -471,7 +471,7 @@ export class QrCode {
for (let x = 0; x < this.size; x++) {
let runColor = false;
let runY = 0;
let runHistory = [0, 0, 0, 0, 0, 0, 0];
const runHistory = [0, 0, 0, 0, 0, 0, 0];
for (let y = 0; y < this.size; y++) {
if (this.modules[y][x] == runColor) {
runY++;
@ -518,7 +518,7 @@ export class QrCode {
else {
const numAlign: int = Math.floor(this.version / 7) + 2;
const step: int = this.version == 32 ? 26 : Math.ceil((this.version * 4 + 4) / (numAlign * 2 - 2)) * 2;
let result: Array<int> = [6];
const result: Array<int> = [6];
for (let pos = this.size - 7; result.length < numAlign; pos -= step) result.splice(1, 0, pos);
return result;
}
@ -555,7 +555,7 @@ export class QrCode {
if (degree < 1 || degree > 255) throw new RangeError("Degree out of range");
// Polynomial coefficients are stored from highest to lowest power, excluding the leading term which is always 1.
// For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array [255, 8, 93].
let result: Array<byte> = [];
const result: Array<byte> = [];
for (let i = 0; i < degree - 1; i++) result.push(0);
result.push(1); // Start off with the monomial x^0
@ -576,7 +576,7 @@ export class QrCode {
// Returns the Reed-Solomon error correction codeword for the given data and divisor polynomials.
private static reedSolomonComputeRemainder(data: Readonly<Array<byte>>, divisor: Readonly<Array<byte>>): Array<byte> {
let result: Array<byte> = divisor.map((_) => 0);
const result: Array<byte> = divisor.map((_) => 0);
for (const b of data) {
// Polynomial division
const factor: byte = b ^ (result.shift() as byte);
@ -730,7 +730,7 @@ export class QrSegment {
// byte mode. All input byte arrays are acceptable. Any text string
// can be converted to UTF-8 bytes and encoded as a byte mode segment.
public static makeBytes(data: Readonly<Array<byte>>): QrSegment {
let bb: Array<bit> = [];
const bb: Array<bit> = [];
for (const b of data) appendBits(b, 8, bb);
return new QrSegment(Mode.BYTE, data.length, bb);
}
@ -738,7 +738,7 @@ export class QrSegment {
// Returns a segment representing the given string of decimal digits encoded in numeric mode.
public static makeNumeric(digits: string): QrSegment {
if (!QrSegment.isNumeric(digits)) throw new RangeError("String contains non-numeric characters");
let bb: Array<bit> = [];
const bb: Array<bit> = [];
for (let i = 0; i < digits.length; ) {
// Consume up to 3 digits per iteration
const n: int = Math.min(digits.length - i, 3);
@ -754,7 +754,7 @@ export class QrSegment {
public static makeAlphanumeric(text: string): QrSegment {
if (!QrSegment.isAlphanumeric(text))
throw new RangeError("String contains unencodable characters in alphanumeric mode");
let bb: Array<bit> = [];
const bb: Array<bit> = [];
let i: int;
for (i = 0; i + 2 <= text.length; i += 2) {
// Process groups of 2
@ -781,7 +781,7 @@ export class QrSegment {
// Returns a segment representing an Extended Channel Interpretation
// (ECI) designator with the given assignment value.
public static makeEci(assignVal: int): QrSegment {
let bb: Array<bit> = [];
const bb: Array<bit> = [];
if (assignVal < 0) throw new RangeError("ECI assignment value out of range");
else if (assignVal < 1 << 7) appendBits(assignVal, 8, bb);
else if (assignVal < 1 << 14) {
@ -850,7 +850,7 @@ export class QrSegment {
// Returns a new array of bytes representing the given string encoded in UTF-8.
private static toUtf8ByteArray(str: string): Array<byte> {
str = encodeURI(str);
let result: Array<byte> = [];
const result: Array<byte> = [];
for (let i = 0; i < str.length; i++) {
if (str.charAt(i) != "%") result.push(str.charCodeAt(i));
else {

View File

@ -65,7 +65,7 @@ export default function NotificationsProvider({ children }: PropsWithChildren) {
const n = new AccountNotifications(account.pubkey);
setNotifications(n);
if (import.meta.env.DEV) {
// @ts-expect-error
// @ts-expect-error debug
window.accountNotifications = n;
}

View File

@ -112,7 +112,7 @@ export default function PublishProvider({ children }: PropsWithChildren) {
if (!Object.hasOwn(event, "pubkey")) event = await finalizeDraft(event);
// sign event
let signed = !Object.hasOwn(event, "sig") ? await requestSignature(event) : (event as NostrEvent);
const signed = !Object.hasOwn(event, "sig") ? await requestSignature(event) : (event as NostrEvent);
const pub = new PublishAction(label, relays, signed);
setLog((arr) => arr.concat(pub));

View File

@ -75,7 +75,7 @@ export default function WebOfTrustProvider({ pubkey, children }: PropsWithChildr
if (!graph) return;
if (import.meta.env.DEV) {
//@ts-expect-error
//@ts-expect-error debug
window.webOfTrust = graph;
}

View File

@ -6,7 +6,7 @@ import accountService from "../../services/account";
import { deleteDatabase } from "../../services/db";
export default function RequireCurrentAccount({ children }: { children: JSX.Element }) {
let location = useLocation();
const location = useLocation();
const loading = useObservable(accountService.loading);
const account = useObservable(accountService.current);

View File

@ -28,7 +28,7 @@ export default function TrustedMintsQuery(pubkey: string): Query<TrustedMints |
case "relay":
if (tag[1]) {
let safe = safeRelayUrl(tag[1]);
const safe = safeRelayUrl(tag[1]);
if (safe) mints.push(safe);
}
break;

View File

@ -161,7 +161,7 @@ class AccountService {
const accountService = new AccountService();
if (import.meta.env.DEV) {
// @ts-ignore
// @ts-expect-error debug
window.accountService = accountService;
}

View File

@ -150,7 +150,7 @@ class ChannelMetadataService {
const channelMetadataService = new ChannelMetadataService();
if (import.meta.env.DEV) {
//@ts-ignore
//@ts-expect-error debug
window.channelMetadataService = channelMetadataService;
}

View File

@ -119,7 +119,7 @@ class DecryptionCache {
const decryptionCacheService = new DecryptionCache();
if (import.meta.env.DEV) {
// @ts-expect-error
// @ts-expect-error debug
window.decryptionCacheService = decryptionCacheService;
}

View File

@ -92,7 +92,7 @@ class DictionaryService {
const dictionaryService = new DictionaryService(eventStore);
if (import.meta.env.DEV) {
// @ts-expect-error
// @ts-expect-error debug
window.dictionaryService = dictionaryService;
}

View File

@ -155,7 +155,7 @@ setInterval(() => {
}, 1000 * 60);
if (import.meta.env.DEV) {
// @ts-ignore
// @ts-expect-error debug
window.dnsIdentityService = dnsIdentityService;
}

View File

@ -38,7 +38,7 @@ class EventCountService {
const eventCountService = new EventCountService();
if (import.meta.env.DEV) {
// @ts-ignore
// @ts-expect-error debug
window.eventCountService = eventCountService;
}

View File

@ -47,7 +47,7 @@ class EventReactionsService {
const eventReactionsService = new EventReactionsService();
if (import.meta.env.DEV) {
// @ts-ignore
// @ts-expect-error debug
window.eventReactionsService = eventReactionsService;
}

View File

@ -4,8 +4,8 @@ export const eventStore = new EventStore();
export const queryStore = new QueryStore(eventStore);
if (import.meta.env.DEV) {
// @ts-expect-error
// @ts-expect-error debug
window.eventStore = eventStore;
// @ts-expect-error
// @ts-expect-error debug
window.queryStore = queryStore;
}

View File

@ -47,7 +47,7 @@ class EventZapsService {
const eventZapsService = new EventZapsService();
if (import.meta.env.DEV) {
// @ts-ignore
// @ts-expect-error debug
window.eventZapsService = eventZapsService;
}

View File

@ -109,8 +109,8 @@ setInterval(() => {
}, 60_000);
if (import.meta.env.DEV) {
//@ts-ignore
//@ts-expect-error debug
window.localDatabase = localDatabase;
//@ts-ignore
//@ts-expect-error debug
window.localRelay = localRelay;
}

View File

@ -77,7 +77,7 @@ const localSettings = {
};
if (import.meta.env.DEV) {
// @ts-expect-error
// @ts-expect-error debug
window.localSettings = localSettings;
}

View File

@ -48,6 +48,6 @@ const noStrudel = {
localSettings.debugApi.subscribe((enabled) => {
if (enabled) Reflect.set(window, "noStrudel", noStrudel);
// @ts-expect-error
// @ts-expect-error debug
else delete window.noStrudel;
});

View File

@ -40,7 +40,7 @@ class ProcessManager {
const processManager = new ProcessManager();
if (import.meta.env.DEV) {
// @ts-expect-error
// @ts-expect-error debug
window.processManager = processManager;
}

View File

@ -107,7 +107,7 @@ const readStatusService = new ReadStatusService();
setInterval(readStatusService.prune.bind(readStatusService), 30_000);
if (import.meta.env.DEV) {
// @ts-expect-error
// @ts-expect-error debug
window.readStatusService = readStatusService;
}

View File

@ -26,7 +26,7 @@ if (localRelay instanceof AbstractRelay) {
}
if (import.meta.env.DEV) {
// @ts-ignore
// @ts-expect-error debug
window.relayPoolService = relayPoolService;
}

View File

@ -264,7 +264,7 @@ setInterval(() => {
}, 1000 * 30);
if (import.meta.env.DEV) {
// @ts-ignore
// @ts-expect-error debug
window.relayScoreboardService = relayScoreboardService;
}

View File

@ -98,7 +98,7 @@ class RelayStatsService {
const relayStatsService = new RelayStatsService();
if (import.meta.env.DEV) {
//@ts-ignore
//@ts-expect-error debug
window.relayStatsService = relayStatsService;
}

View File

@ -114,7 +114,7 @@ class ReplaceableEventsService {
const replaceableEventsService = new ReplaceableEventsService(eventStore);
if (import.meta.env.DEV) {
//@ts-ignore
//@ts-expect-error debug
window.replaceableEventsService = replaceableEventsService;
}

View File

@ -28,7 +28,7 @@ const updates = eventStore.stream([{ kinds: [kinds.Metadata] }]).pipe(
const updates: UserDirectory = {};
const transaction = db.transaction("userSearch", "readwrite");
for (let metadata of events) {
for (const metadata of events) {
const profile = getProfileContent(metadata);
const names = getSearchNames(profile);
updates[metadata.pubkey] = names;

View File

@ -13,7 +13,7 @@ export default function CommunityModList({
return (
<AvatarGroup {...props}>
{mods.map((pubkey) => (
<UserAvatarLink pubkey={pubkey} />
<UserAvatarLink key={pubkey} pubkey={pubkey} />
))}
</AvatarGroup>
);

View File

@ -72,7 +72,7 @@ export default function HorizontalCommunityDetails({
</Heading>
<Flex direction="column" gap="2">
{mods.map((pubkey) => (
<Flex gap="2">
<Flex key={pubkey} gap="2">
<UserAvatarLink pubkey={pubkey} size="xs" />
<UserLink pubkey={pubkey} />
</Flex>
@ -117,7 +117,7 @@ export default function HorizontalCommunityDetails({
</Heading>
<Box>
{links.map(([url, name]) => (
<Link href={url} isTruncated isExternal display="block">
<Link key={url + name} href={url} isTruncated isExternal display="block">
{name || url}
</Link>
))}

View File

@ -54,7 +54,7 @@ export default function VerticalCommunityDetails({
</Heading>
<Flex direction="column" gap="2">
{mods.map((pubkey) => (
<Flex gap="2">
<Flex key={pubkey} gap="2">
<UserAvatarLink pubkey={pubkey} size="xs" />
<UserLink pubkey={pubkey} />
</Flex>
@ -99,7 +99,7 @@ export default function VerticalCommunityDetails({
</Heading>
<Box>
{links.map(([url, name]) => (
<Link href={url} isTruncated isExternal display="block">
<Link key={url + name} href={url} isTruncated isExternal display="block">
{name || url}
</Link>
))}

View File

@ -1,5 +1,6 @@
import FeedStatus from "./feed-status";
import { AddressPointer } from "nostr-tools/nip19";
import { getEventUID } from "applesauce-core/helpers";
import { ChainedDVMJob, getEventIdsFromJobs } from "../../../../helpers/nostr/dvm";
import useSingleEvents from "../../../../hooks/use-single-events";
@ -12,7 +13,7 @@ function FeedEvents({ chain }: { chain: ChainedDVMJob[] }) {
return (
<>
{events.map((event) => (
<TimelineItem event={event} visible />
<TimelineItem key={getEventUID(event)} event={event} visible />
))}
</>
);

View File

@ -15,7 +15,7 @@ export default function GoalContents({ goal }: { goal: NostrEvent }) {
<EmbedEventPointer key={encodeDecodeResult(pointer)} pointer={pointer} />
))}
{links.map((link) => (
<OpenGraphCard url={new URL(link)} />
<OpenGraphCard key={link} url={new URL(link)} />
))}
</>
);

View File

@ -44,7 +44,7 @@ function RenderRedirect({ event, link }: { event?: NostrEvent; link: string }) {
return <Navigate to={`/n/${link}`} replace />;
case "nevent":
case "naddr": {
let k = decoded.data.kind || event?.kind;
const k = decoded.data.kind || event?.kind;
if (k === kinds.ShortTextNote) return <Navigate to={`/n/${link}`} replace />;
if (k === TORRENT_KIND) return <Navigate to={`/torrents/${link}`} replace />;
if (k === kinds.LiveEvent) return <Navigate to={`/streams/${link}`} replace />;

View File

@ -85,7 +85,7 @@ function ListPage({ list }: { list: NostrEvent }) {
<Heading size="lg">People</Heading>
<SimpleGrid columns={{ base: 1, lg: 2, xl: 3 }} spacing="2">
{people.map(({ pubkey, relay }) => (
<UserCard pubkey={pubkey} relay={relay} list={list} />
<UserCard key={pubkey} pubkey={pubkey} relay={relay} list={list} />
))}
</SimpleGrid>
</>
@ -96,7 +96,7 @@ function ListPage({ list }: { list: NostrEvent }) {
<Heading size="lg">Notes</Heading>
<Flex gap="2" direction="column">
{notes.map(({ id, relays }) => (
<BookmarkedEvent id={id} relays={relays} />
<BookmarkedEvent key={id} id={id} relays={relays} />
))}
</Flex>
</>

View File

@ -23,7 +23,7 @@ function RelaySetCard({ set }: { set: NostrEvent }) {
<CardHeader p="4">{name}</CardHeader>
<CardBody px="4" pb="4" pt="0" display="flex" flexDirection="row" gap="2" flexWrap="wrap">
{relays.map((relay) => (
<Text>
<Text key={relay}>
<RelayFavicon relay={relay} /> {relay}
</Text>
))}

View File

@ -82,7 +82,7 @@ function MediaServersPage() {
const [confirmServer, setConfirmServer] = useState("");
const submit = handleSubmit(async (values) => {
let url = new URL(values.server.startsWith("http") ? values.server : "https://" + values.server).toString();
const url = new URL(values.server.startsWith("http") ? values.server : "https://" + values.server).toString();
if (event?.tags.some((t) => isServerTag(t) && areServersEqual(t[1], url)))
return toast({ status: "error", description: "Server already in list" });

View File

@ -102,7 +102,7 @@ export default function RelayDetailsTab({ relay }: { relay: string }) {
const token = theme.semanticTokens.colors["chakra-body-text"];
const color = useColorModeValue(token._light, token._dark) as string;
const [_, update] = useState<Object>();
const [_, update] = useState<object>();
const store = useMemo(() => new EventStore(), []);
const [loading, setLoading] = useState(false);

View File

@ -32,7 +32,7 @@ export function SearchPage() {
const searchQuery = params.get("q") || "";
const relayURL = params.get("relay");
let searchRelay = useMemo(() => {
const searchRelay = useMemo(() => {
if (relayURL === "local") return localRelay;
else if (relayURL) return relayPoolService.requestRelay(relayURL);
else if (localSearchSupported) return localRelay;

View File

@ -27,7 +27,7 @@ export default function LoginNostrAddressView() {
async () => {
if (!address) return setNip05(undefined);
if (!getMatchSimpleEmail().test(address)) return setNip05(undefined);
let [name, domain] = address.split("@");
const [name, domain] = address.split("@");
if (!name || !domain) return setNip05(undefined);
setNip05((await dnsIdentityService.fetchIdentity(address)) ?? null);
setRootNip05((await dnsIdentityService.fetchIdentity(`_@${domain}`)) ?? null);

View File

@ -58,7 +58,7 @@ function ClientConnectForm() {
<>
{signer ? (
<>
<a href={connectionURL} target="_blank">
<a href={connectionURL} target="_blank" rel="noreferrer">
<QrCodeSvg content={connectionURL} />
</a>
<Flex gap="2">
@ -109,7 +109,7 @@ export default function LoginNostrConnectView() {
try {
setLoading("Connecting...");
let client = await NostrConnectSigner.fromBunkerURI(connection, relayPoolService, NOSTR_CONNECT_PERMISSIONS);
const client = await NostrConnectSigner.fromBunkerURI(connection, relayPoolService, NOSTR_CONNECT_PERMISSIONS);
const pubkey = await client.getPublicKey();
const account = new NostrConnectAccount(pubkey, client);

View File

@ -4,7 +4,7 @@ import { ComponentWithAs, IconProps } from "@chakra-ui/react";
import Process from "../../../../classes/process";
export default function ProcessIcon({ process, ...props }: { process: Process } & IconProps) {
let IconComponent: ComponentWithAs<"svg", IconProps> = process.icon || QuestionIcon;
const IconComponent: ComponentWithAs<"svg", IconProps> = process.icon || QuestionIcon;
return <IconComponent color={process.active ? "green.500" : "gray.500"} {...props} />;
}

View File

@ -4,7 +4,7 @@ import { Button, Flex, Spinner, Text, Textarea, useToast } from "@chakra-ui/reac
import { EventTemplate, NostrEvent } from "nostr-tools";
import { MultiSubscription } from "applesauce-net/subscription";
import { useStoreQuery } from "applesauce-react/hooks";
import { unixNow } from "applesauce-core/helpers";
import { getEventUID, unixNow } from "applesauce-core/helpers";
import { useUserInbox } from "../../../../../hooks/use-user-mailboxes";
import useCurrentAccount from "../../../../../hooks/use-current-account";
@ -86,7 +86,7 @@ export default function EventSummarizePage({ event }: { event: NostrEvent }) {
{responses ? (
<>
{Object.entries(responses).map(([pubkey, event]) => (
<DVMStatusCard status={event} />
<DVMStatusCard key={getEventUID(event)} status={event} />
))}
</>
) : submitted ? (

View File

@ -104,7 +104,7 @@ export default function EventConsoleView() {
}
await new Promise<void>((res) => {
let buffer: NostrEvent[] = [];
const buffer: NostrEvent[] = [];
const flush = _throttle(() => setEvents([...buffer]), 1000 / 10, { trailing: true });
setError("");

View File

@ -5,11 +5,11 @@ import { SearchDirectory, userSearchDirectory } from "../../../services/username
let users: SearchDirectory = [];
export function codeMirrorUserAutocomplete(context: CompletionContext): CompletionResult | null {
let nodeBefore = syntaxTree(context.state).resolveInner(context.pos, -1);
const nodeBefore = syntaxTree(context.state).resolveInner(context.pos, -1);
if (nodeBefore.name !== "String") return null;
let textBefore = context.state.sliceDoc(nodeBefore.from, context.pos);
let tagBefore = /@\w*$/.exec(textBefore);
const textBefore = context.state.sliceDoc(nodeBefore.from, context.pos);
const tagBefore = /@\w*$/.exec(textBefore);
if (!tagBefore && !context.explicit) return null;
return {

View File

@ -158,7 +158,9 @@ function EventPublisherPage({ initDraft }: { initDraft?: LooseEventTemplate }) {
<Text fontWeight="bold">Template</Text>
<Select onChange={(e) => selectTemplate(e.target.value)} w="auto">
{TEMPLATES.map((template) => (
<option value={template.name}>{template.name}</option>
<option key={template.name} value={template.name}>
{template.name}
</option>
))}
</Select>
<Spacer />

View File

@ -72,7 +72,7 @@ export function NoteTranslationsPage({ note }: { note: NostrEvent }) {
<Flex gap="2">
<Select value={lang} onChange={(e) => setLang(e.target.value)} w="60">
{codes.map((code) => (
<option value={code.iso639_1}>
<option key={code.iso639_1} value={code.iso639_1}>
{code.name} ({code.nativeName})
</option>
))}

View File

@ -45,7 +45,7 @@ function TorrentTableRow({ torrent }: { torrent: NostrEvent }) {
<Td>
{categories
.map((c) => (
<Link as={RouterLink} to={createTagLink(c)}>
<Link key={c.name} as={RouterLink} to={createTagLink(c)}>
{c.name}
</Link>
))

View File

@ -202,7 +202,7 @@ export default function NewTorrentView() {
</Flex>
<Flex direction="column" gap="2">
{getValues().files.map((file, i) => (
<Flex gap="2">
<Flex gap="2" key={file.name + file.size}>
<Input
type="text"
value={file.name}

View File

@ -27,7 +27,7 @@ export default function TrackPlayer({ track }: { track: NostrEvent }) {
position="relative"
>
<IconButton aria-label="Play" mr="4" icon={<Play />} onClick={showPlayer.onOpen} size="md" variant="outline" />
{waveform?.map((v) => <Box h={v + "%"} w="3px" bg="primary.800" />)}
{waveform?.map((v, i) => <Box key={v + i} h={v + "%"} w="3px" bg="primary.800" />)}
</Flex>
);

View File

@ -11,7 +11,7 @@ export default function UserZapButton({ pubkey, ...props }: { pubkey: string } &
if (!metadata) return null;
// use lud06 and lud16 fields interchangeably
let tipAddress = metadata.lud06 || metadata.lud16;
const tipAddress = metadata.lud06 || metadata.lud16;
if (!tipAddress) return null;

View File

@ -2,7 +2,7 @@ import { Box, Card, CardBody, CardHeader, CardProps, Heading, LinkBox, Text } fr
import { Link as RouterLink } from "react-router-dom";
import { NostrEvent } from "../../../types/nostr-event";
import { getVideoDuration, getVideoImages, getVideoSummary, getVideoTitle } from "../../../helpers/nostr/video";
import { getVideoImages, getVideoSummary, getVideoTitle } from "../../../helpers/nostr/video";
import HoverLinkOverlay from "../../../components/hover-link-overlay";
import useEventIntersectionRef from "../../../hooks/use-event-intersection-ref";
import useShareableEventAddress from "../../../hooks/use-shareable-event-address";
@ -10,14 +10,13 @@ import useShareableEventAddress from "../../../hooks/use-shareable-event-address
export default function VideoCard({ video, ...props }: Omit<CardProps, "children"> & { video: NostrEvent }) {
const title = getVideoTitle(video);
const { thumb } = getVideoImages(video);
const duration = getVideoDuration(video);
const summary = getVideoSummary(video);
const ref = useEventIntersectionRef(video);
const address = useShareableEventAddress(video);
return (
<Card as={LinkBox} {...props}>
<Card as={LinkBox} ref={ref} {...props}>
<Box
backgroundImage={thumb}
aspectRatio={16 / 9}