eslint fixes
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Martti Malmi 2024-01-04 13:13:28 +02:00
parent 9f88b44b91
commit eeb6ec9dd8
12 changed files with 93 additions and 54 deletions

View File

@ -17,7 +17,7 @@
"deck": true,
"zapPool": true,
"notificationGraph": false,
"communityLeaders": false
"communityLeaders": true
},
"signUp": {
"moderation": false,
@ -27,6 +27,9 @@
"bypassImgProxyError": true,
"preferLargeMedia": true
},
"communityLeaders": {
"list": "naddr1qq4xc6tnw3ez6vp58y6rywpjxckngdtyxukngwr9vckkze33vcknzcnrxcenje35xqmn2cczyp3lucccm3v9s087z6qslpkap8schltk427zfgqgrn3g2menq5zw6qcyqqq82vqprpmhxue69uhhyetvv9ujuumwdae8gtnnda3kjctv7rajfl"
},
"noteCreatorToast": false,
"hideFromNavbar": [],
"eventLinkPrefix": "note",

View File

@ -25,6 +25,7 @@ class IndexedDB extends Dexie {
super("EventDB");
this.version(5).stores({
// TODO use multientry index for *tags
events: "id, pubkey, kind, created_at, [pubkey+kind]",
tags: "id, eventId, [type+value]",
});
@ -108,40 +109,63 @@ class IndexedDB extends Dexie {
subscribeToAuthors = this._throttle(async function (callback: (event: TaggedNostrEvent) => void, limit?: number) {
const authors = [...this.subscribedAuthors];
this.subscribedAuthors.clear();
// Start timing
console.time("subscribeToAuthors");
await this.events
.where("pubkey")
.anyOf(authors)
.limit(limit || 1000)
.each(callback);
}, 200);
subscribeToEventIds = this._throttle(async function (callback: (event: TaggedNostrEvent) => void) {
// End timing and log the elapsed time
console.timeEnd("subscribeToAuthors");
}, 200);
subscribeToEventIds = this._throttle(async function (callback: (event: TaggedNostrEvent) => void) {
const ids = [...this.subscribedEventIds];
this.subscribedEventIds.clear();
await this.events.where("id").anyOf(ids).each(callback);
}, 200);
subscribeToTags = this._throttle(async function (callback: (event: TaggedNostrEvent) => void) {
console.time("subscribeToEventIds");
await this.events.where("id").anyOf(ids).each(callback);
console.timeEnd("subscribeToEventIds");
}, 200);
subscribeToTags = this._throttle(async function (callback: (event: TaggedNostrEvent) => void) {
const tagPairs = [...this.subscribedTags].map(tag => tag.split("|"));
this.subscribedTags.clear();
console.time("subscribeToTags");
await this.tags
.where("[type+value]")
.anyOf(tagPairs)
.each(tag => this.subscribedEventIds.add(tag.eventId));
await this.subscribeToEventIds(callback);
}, 200);
subscribeToAuthorsAndKinds = this._throttle(async function (callback: (event: TaggedNostrEvent) => void) {
console.timeEnd("subscribeToTags");
}, 200);
subscribeToAuthorsAndKinds = this._throttle(async function (callback: (event: TaggedNostrEvent) => void) {
const authorsAndKinds = [...this.subscribedAuthorsAndKinds];
this.subscribedAuthorsAndKinds.clear();
console.time("subscribeToAuthorsAndKinds");
// parse pair[1] as int
const pairs = authorsAndKinds.map(pair => {
const [author, kind] = pair.split("|");
return [author, parseInt(kind)];
});
await this.events.where("[pubkey+kind]").anyOf(pairs).each(callback);
}, 200);
console.timeEnd("subscribeToAuthorsAndKinds");
}, 200);
async find(filter: Filter, callback: (event: TaggedNostrEvent) => void): Promise<void> {
if (!filter) return;

View File

@ -119,7 +119,7 @@ function renderToken(t: Token | Footnotes | Footnote | FootnoteRef, tags: Array<
}
}
export const Markdown = forwardRef<HTMLDivElement, MarkdownProps>((props: MarkdownProps, ref) => {
const Markdown = forwardRef<HTMLDivElement, MarkdownProps>((props: MarkdownProps, ref) => {
const parsed = useMemo(() => {
return marked.use(markedFootnote()).lexer(props.content);
}, [props.content, props.tags]);
@ -130,4 +130,7 @@ export const Markdown = forwardRef<HTMLDivElement, MarkdownProps>((props: Markdo
</div>
);
});
Markdown.displayName = "Markdown";
export { Markdown };

View File

@ -325,4 +325,5 @@ const AsyncFooterIcon = forwardRef((props: AsyncIconProps & { value: number }, r
</AsyncIcon>
);
});
AsyncFooterIcon.displayName = "AsyncFooterIcon";

View File

@ -33,15 +33,6 @@ export default function NoteReaction(props: NoteReactionProps) {
return null;
}, [ev]);
if (
ev.kind !== EventKind.Reaction &&
ev.kind !== EventKind.Repost &&
(ev.kind !== EventKind.TextNote ||
ev.tags.every((a, i) => a[1] !== refEvent?.[1] || a[3] !== "mention" || ev.content !== `#[${i}]`))
) {
return null;
}
/**
* Some clients embed the reposted note in the content
*/
@ -63,6 +54,15 @@ export default function NoteReaction(props: NoteReactionProps) {
return props.root;
}
if (
ev.kind !== EventKind.Reaction &&
ev.kind !== EventKind.Repost &&
(ev.kind !== EventKind.TextNote ||
ev.tags.every((a, i) => a[1] !== refEvent?.[1] || a[3] !== "mention" || ev.content !== `#[${i}]`))
) {
return null;
}
if (!inView) {
return <div className="card reaction" ref={ref}></div>;
}

View File

@ -1,7 +1,12 @@
import { useNavigate } from "react-router-dom";
import { FormattedMessage } from "react-intl";
export default function AccountName({ name = "", link = true }) {
interface AccountNameProps {
name?: string;
link?: boolean;
}
export default function AccountName({ name = "", link = true }: AccountNameProps) {
const navigate = useNavigate();
return (
<>

View File

@ -7,7 +7,12 @@ import { UserCache } from "@/Cache";
import useEventPublisher from "@/Hooks/useEventPublisher";
import { FormattedMessage } from "react-intl";
export default function ActiveAccount({ name = "", setAsPrimary = () => {} }) {
interface ActiveAccountProps {
name?: string;
setAsPrimary: () => void;
}
export default function ActiveAccount({ name = "", setAsPrimary = () => {} }: ActiveAccountProps) {
const { publicKey, readonly } = useLogin(s => ({
publicKey: s.publicKey,
readonly: s.readonly,

View File

@ -1,7 +1,13 @@
import AccountName from "./AccountName";
import { FormattedMessage } from "react-intl";
export default function ReservedAccount({ name = "", enableReserved = () => {}, declineReserved = () => {} }) {
interface ReservedAccountProps {
name?: string;
enableReserved: () => void;
declineReserved: () => void;
}
export default function ReservedAccount({ name = "", enableReserved = () => {}, declineReserved = () => {} }: ReservedAccountProps) {
return (
<div>
<p className="success">

View File

@ -1,19 +1,13 @@
import { LoginSession, LoginStore } from "@/Login";
import { useSyncExternalStore } from "react";
import { useSyncExternalStoreWithSelector } from "use-sync-external-store/with-selector";
export default function useLogin<T = LoginSession>(selector?: (v: LoginSession) => T) {
if (selector) {
return useSyncExternalStoreWithSelector(
s => LoginStore.hook(s),
() => LoginStore.snapshot(),
undefined,
selector,
);
} else {
return useSyncExternalStore<T>(
s => LoginStore.hook(s),
() => LoginStore.snapshot() as T,
);
}
const defaultSelector = (v: LoginSession) => v as unknown as T;
return useSyncExternalStoreWithSelector<LoginSession, T>(
s => LoginStore.hook(s),
() => LoginStore.snapshot(),
undefined,
selector || defaultSelector,
);
}

View File

@ -26,9 +26,7 @@ export default function Index() {
useTheme();
useLoginRelays();
useLoginFeed();
if (CONFIG.features.communityLeaders) {
useCommunityLeaders();
}
useCommunityLeaders();
const hideHeaderPaths = ["/login", "/new"];
const shouldHideFooter = location.pathname.startsWith("/messages/");

View File

@ -6,7 +6,13 @@ import { subscribeToNotifications } from "@/Notifications";
import useEventPublisher from "@/Hooks/useEventPublisher";
import messages from "./messages";
const StatusIndicator = ({ status, enabledMessage, disabledMessage }) => {
interface StatusIndicatorProps {
status: boolean;
enabledMessage: React.ComponentProps<typeof FormattedMessage>;
disabledMessage: React.ComponentProps<typeof FormattedMessage>;
}
const StatusIndicator = ({ status, enabledMessage, disabledMessage }: StatusIndicatorProps) => {
return status ? (
<div className="flex items-center">
<Icon name="check" size={20} className="text-green-500 mr-2" />

View File

@ -1,7 +1,6 @@
import { ExternalStore } from "@snort/shared";
import { NostrEvent, TaggedNostrEvent } from "@snort/system";
import { ZapTarget } from "@/Zapper";
import { useSyncExternalStore } from "react";
import { useSyncExternalStoreWithSelector } from "use-sync-external-store/with-selector";
interface NoteCreatorDataSnapshot {
@ -90,17 +89,12 @@ const NoteCreatorState = new NoteCreatorStore();
export function useNoteCreator<T extends object = NoteCreatorDataSnapshot>(
selector?: (v: NoteCreatorDataSnapshot) => T,
) {
if (selector) {
return useSyncExternalStoreWithSelector<NoteCreatorDataSnapshot, T>(
c => NoteCreatorState.hook(c),
() => NoteCreatorState.snapshot(),
undefined,
selector,
);
} else {
return useSyncExternalStore<T>(
c => NoteCreatorState.hook(c),
() => NoteCreatorState.snapshot() as T,
);
}
const defaultSelector = (v: NoteCreatorDataSnapshot) => v as unknown as T;
return useSyncExternalStoreWithSelector<NoteCreatorDataSnapshot, T>(
c => NoteCreatorState.hook(c),
() => NoteCreatorState.snapshot(),
undefined,
selector || defaultSelector,
);
}