feat: improve profile cache (again)
This commit is contained in:
@ -1,7 +1,9 @@
|
||||
import "./Avatar.css";
|
||||
import Nostrich from "nostrich.webp";
|
||||
|
||||
import { CSSProperties, useEffect, useState } from "react";
|
||||
import type { UserMetadata } from "@snort/nostr";
|
||||
|
||||
import useImgProxy from "Hooks/useImgProxy";
|
||||
|
||||
const Avatar = ({ user, ...rest }: { user?: UserMetadata; onClick?: () => void }) => {
|
||||
|
@ -5,8 +5,8 @@ import { FormattedMessage } from "react-intl";
|
||||
import { dedupeByPubkey } from "Util";
|
||||
import Note from "Element/Note";
|
||||
import { HexKey, TaggedRawEvent } from "@snort/nostr";
|
||||
import { useUserProfiles } from "Feed/ProfileFeed";
|
||||
import { RootState } from "State/Store";
|
||||
import { UserCache } from "State/Users/UserCache";
|
||||
|
||||
import messages from "./messages";
|
||||
|
||||
@ -22,10 +22,9 @@ const Bookmarks = ({ pubkey, bookmarks, related }: BookmarksProps) => {
|
||||
const ps = useMemo(() => {
|
||||
return dedupeByPubkey(bookmarks).map(ev => ev.pubkey);
|
||||
}, [bookmarks]);
|
||||
const profiles = useUserProfiles(ps);
|
||||
|
||||
function renderOption(p: HexKey) {
|
||||
const profile = profiles?.get(p);
|
||||
const profile = UserCache.get(p);
|
||||
return profile ? <option value={p}>{profile?.display_name || profile?.name}</option> : null;
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ export default function DM(props: DMProps) {
|
||||
<NoteTime from={props.data.created_at * 1000} fallback={formatMessage(messages.JustNow)} />
|
||||
</div>
|
||||
<div className="w-max">
|
||||
<Text content={content} tags={[]} users={new Map()} creator={otherPubkey} />
|
||||
<Text content={content} tags={[]} creator={otherPubkey} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useMemo } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { useUserProfile } from "Feed/ProfileFeed";
|
||||
import { useUserProfile } from "Hooks/useUserProfile";
|
||||
import { HexKey } from "@snort/nostr";
|
||||
import { hexToBech32, profileLink } from "Util";
|
||||
|
||||
|
@ -17,7 +17,7 @@ import {
|
||||
import AsyncButton from "Element/AsyncButton";
|
||||
import SendSats from "Element/SendSats";
|
||||
import Copy from "Element/Copy";
|
||||
import { useUserProfile } from "Feed/ProfileFeed";
|
||||
import { useUserProfile } from "Hooks/useUserProfile";
|
||||
import useEventPublisher from "Feed/EventPublisher";
|
||||
import { debounce } from "Util";
|
||||
import { UserMetadata } from "@snort/nostr";
|
||||
|
@ -18,14 +18,15 @@ import {
|
||||
hexToBech32,
|
||||
normalizeReaction,
|
||||
Reaction,
|
||||
profileLink,
|
||||
} from "Util";
|
||||
import NoteFooter, { Translation } from "Element/NoteFooter";
|
||||
import NoteTime from "Element/NoteTime";
|
||||
import { useUserProfiles } from "Feed/ProfileFeed";
|
||||
import { TaggedRawEvent, u256, HexKey, Event as NEvent, EventKind } from "@snort/nostr";
|
||||
import useModeration from "Hooks/useModeration";
|
||||
import { setPinned, setBookmarked } from "State/Login";
|
||||
import type { RootState } from "State/Store";
|
||||
import { UserCache } from "State/Users/UserCache";
|
||||
|
||||
import messages from "./messages";
|
||||
|
||||
@ -72,8 +73,6 @@ export default function Note(props: NoteProps) {
|
||||
const { data, related, highlight, options: opt, ["data-ev"]: parsedEvent, ignoreModeration = false } = props;
|
||||
const [showReactions, setShowReactions] = useState(false);
|
||||
const ev = useMemo(() => parsedEvent ?? new NEvent(data), [data]);
|
||||
const pubKeys = useMemo(() => ev.Thread?.PubKeys || [], [ev]);
|
||||
const users = useUserProfiles(pubKeys);
|
||||
const deletions = useMemo(() => getReactions(related, ev.Id, EventKind.Deletion), [related]);
|
||||
const { isMuted } = useModeration();
|
||||
const isOpMuted = isMuted(ev.PubKey);
|
||||
@ -162,7 +161,7 @@ export default function Note(props: NoteProps) {
|
||||
</b>
|
||||
);
|
||||
}
|
||||
return <Text content={body} tags={ev.Tags} users={users || new Map()} creator={ev.PubKey} />;
|
||||
return <Text content={body} tags={ev.Tags} creator={ev.PubKey} />;
|
||||
}, [ev]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
@ -188,22 +187,14 @@ export default function Note(props: NoteProps) {
|
||||
const replyId = ev.Thread?.ReplyTo?.Event ?? ev.Thread?.Root?.Event;
|
||||
const mentions: { pk: string; name: string; link: ReactNode }[] = [];
|
||||
for (const pk of ev.Thread?.PubKeys ?? []) {
|
||||
const u = users?.get(pk);
|
||||
const u = UserCache.get(pk);
|
||||
const npub = hexToBech32("npub", pk);
|
||||
const shortNpub = npub.substring(0, 12);
|
||||
if (u) {
|
||||
mentions.push({
|
||||
pk,
|
||||
name: u.name ?? shortNpub,
|
||||
link: <Link to={`/p/${npub}`}>{u.name ? `@${u.name}` : shortNpub}</Link>,
|
||||
});
|
||||
} else {
|
||||
mentions.push({
|
||||
pk,
|
||||
name: shortNpub,
|
||||
link: <Link to={`/p/${npub}`}>{shortNpub}</Link>,
|
||||
});
|
||||
}
|
||||
mentions.push({
|
||||
pk,
|
||||
name: u?.name ?? shortNpub,
|
||||
link: <Link to={profileLink(pk)}>{u?.name ? `@${u.name}` : shortNpub}</Link>,
|
||||
});
|
||||
}
|
||||
mentions.sort(a => (a.name.startsWith("npub") ? 1 : -1));
|
||||
const othersLength = mentions.length - maxMentions;
|
||||
|
@ -15,7 +15,7 @@ import { NoteCreator } from "Element/NoteCreator";
|
||||
import Reactions from "Element/Reactions";
|
||||
import SendSats from "Element/SendSats";
|
||||
import { ParsedZap, ZapsSummary } from "Element/Zap";
|
||||
import { useUserProfile } from "Feed/ProfileFeed";
|
||||
import { useUserProfile } from "Hooks/useUserProfile";
|
||||
import { RootState } from "State/Store";
|
||||
import { UserPreferences, setPinned, setBookmarked } from "State/Login";
|
||||
import useModeration from "Hooks/useModeration";
|
||||
|
@ -2,7 +2,7 @@ import "./ProfileImage.css";
|
||||
|
||||
import { useMemo } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { useUserProfile } from "Feed/ProfileFeed";
|
||||
import { useUserProfile } from "Hooks/useUserProfile";
|
||||
import { hexToBech32, profileLink } from "Util";
|
||||
import Avatar from "Element/Avatar";
|
||||
import Nip05 from "Element/Nip05";
|
||||
|
@ -3,7 +3,7 @@ import { ReactNode } from "react";
|
||||
|
||||
import ProfileImage from "Element/ProfileImage";
|
||||
import FollowButton from "Element/FollowButton";
|
||||
import { useUserProfile } from "Feed/ProfileFeed";
|
||||
import { useUserProfile } from "Hooks/useUserProfile";
|
||||
import { HexKey } from "@snort/nostr";
|
||||
import { useInView } from "react-intersection-observer";
|
||||
|
||||
|
@ -10,7 +10,6 @@ import Invoice from "Element/Invoice";
|
||||
import Hashtag from "Element/Hashtag";
|
||||
|
||||
import { Tag } from "@snort/nostr";
|
||||
import { MetadataCache } from "State/Users";
|
||||
import Mention from "Element/Mention";
|
||||
import HyperText from "Element/HyperText";
|
||||
import { HexKey } from "@snort/nostr";
|
||||
@ -21,17 +20,15 @@ export type Fragment = string | React.ReactNode;
|
||||
export interface TextFragment {
|
||||
body: React.ReactNode[];
|
||||
tags: Tag[];
|
||||
users: Map<string, MetadataCache>;
|
||||
}
|
||||
|
||||
export interface TextProps {
|
||||
content: string;
|
||||
creator: HexKey;
|
||||
tags: Tag[];
|
||||
users: Map<string, MetadataCache>;
|
||||
}
|
||||
|
||||
export default function Text({ content, tags, creator, users }: TextProps) {
|
||||
export default function Text({ content, tags, creator }: TextProps) {
|
||||
function extractLinks(fragments: Fragment[]) {
|
||||
return fragments
|
||||
.map(f => {
|
||||
@ -143,9 +140,9 @@ export default function Text({ content, tags, creator, users }: TextProps) {
|
||||
|
||||
const components = useMemo(() => {
|
||||
return {
|
||||
p: (x: { children?: React.ReactNode[] }) => transformParagraph({ body: x.children ?? [], tags, users }),
|
||||
p: (x: { children?: React.ReactNode[] }) => transformParagraph({ body: x.children ?? [], tags }),
|
||||
a: (x: { href?: string }) => <HyperText link={x.href ?? ""} creator={creator} />,
|
||||
li: (x: { children?: Fragment[] }) => transformLi({ body: x.children ?? [], tags, users }),
|
||||
li: (x: { children?: Fragment[] }) => transformLi({ body: x.children ?? [], tags }),
|
||||
};
|
||||
}, [content]);
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
import "@webscopeio/react-textarea-autocomplete/style.css";
|
||||
import "./Textarea.css";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
import ReactTextareaAutocomplete from "@webscopeio/react-textarea-autocomplete";
|
||||
import emoji from "@jukben/emoji-search";
|
||||
@ -11,7 +10,7 @@ import Avatar from "Element/Avatar";
|
||||
import Nip05 from "Element/Nip05";
|
||||
import { hexToBech32 } from "Util";
|
||||
import { MetadataCache } from "State/Users";
|
||||
import { useQuery } from "State/Users/Hooks";
|
||||
import { UserCache } from "State/Users/UserCache";
|
||||
|
||||
import messages from "./messages";
|
||||
|
||||
@ -53,14 +52,10 @@ interface TextareaProps {
|
||||
}
|
||||
|
||||
const Textarea = (props: TextareaProps) => {
|
||||
const [query, setQuery] = useState("");
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
const allUsers = useQuery(query);
|
||||
|
||||
const userDataProvider = (token: string) => {
|
||||
setQuery(token);
|
||||
return allUsers ?? [];
|
||||
const userDataProvider = async (token: string) => {
|
||||
return await UserCache.search(token);
|
||||
};
|
||||
|
||||
const emojiDataProvider = (token: string) => {
|
||||
|
@ -109,7 +109,7 @@ const Zap = ({ zap, showZapped = true }: { zap: ParsedZap; showZapped?: boolean
|
||||
</div>
|
||||
{content.length > 0 && zapper && (
|
||||
<div className="body">
|
||||
<Text creator={zapper} content={content} tags={[]} users={new Map()} />
|
||||
<Text creator={zapper} content={content} tags={[]} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -4,7 +4,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useState } from "react";
|
||||
import { HexKey } from "@snort/nostr";
|
||||
|
||||
import { useUserProfile } from "Feed/ProfileFeed";
|
||||
import { useUserProfile } from "Hooks/useUserProfile";
|
||||
import SendSats from "Element/SendSats";
|
||||
|
||||
const ZapButton = ({ pubkey, lnurl }: { pubkey: HexKey; lnurl?: string }) => {
|
||||
|
Reference in New Issue
Block a user