feat: upgrade caches to worker

This commit is contained in:
2024-01-17 15:47:01 +00:00
parent 3c808688f8
commit aa58ec4185
32 changed files with 698 additions and 417 deletions

View File

@ -10,7 +10,6 @@ import { ZapperQueue } from "@/Components/Event/Note/NoteFooter/ZapperQueue";
import { ZapsSummary } from "@/Components/Event/ZapsSummary";
import ZapModal from "@/Components/ZapModal/ZapModal";
import useEventPublisher from "@/Hooks/useEventPublisher";
import { useInteractionCache } from "@/Hooks/useInteractionCache";
import useLogin from "@/Hooks/useLogin";
import { getDisplayName } from "@/Utils";
import { Zapper, ZapTarget } from "@/Utils/Zapper";
@ -35,10 +34,9 @@ export const FooterZapButton = ({ ev, zaps, onClickZappers }: ZapIconProps) => {
}));
const walletState = useWallet();
const wallet = walletState.wallet;
const interactionCache = useInteractionCache(publicKey, ev.id);
const link = NostrLink.fromEvent(ev);
const zapTotal = zaps.reduce((acc, z) => acc + z.amount, 0);
const didZap = interactionCache.data.zapped || zaps.some(a => a.sender === publicKey);
const didZap = zaps.some(a => a.sender === publicKey);
const [showZapModal, setShowZapModal] = useState(false);
const { formatMessage } = useIntl();
const [zapping, setZapping] = useState(false);
@ -102,7 +100,6 @@ export const FooterZapButton = ({ ev, zaps, onClickZappers }: ZapIconProps) => {
if (CONFIG.features.zapPool) {
ZapPoolController?.allocate(totalSent);
}
await interactionCache.zap();
}
});
}
@ -143,7 +140,7 @@ export const FooterZapButton = ({ ev, zaps, onClickZappers }: ZapIconProps) => {
value={zapTotal}
onClick={fastZap}
/>
<ZapsSummary zaps={zaps} onClick={onClickZappers} />
<ZapsSummary zaps={zaps} onClick={onClickZappers ?? (() => { })} />
</div>
{showZapModal && (
<ZapModal

View File

@ -5,7 +5,6 @@ import { useIntl } from "react-intl";
import { AsyncFooterIcon } from "@/Components/Event/Note/NoteFooter/AsyncFooterIcon";
import useEventPublisher from "@/Hooks/useEventPublisher";
import { useInteractionCache } from "@/Hooks/useInteractionCache";
import useLogin from "@/Hooks/useLogin";
export const LikeButton = ({
@ -17,12 +16,10 @@ export const LikeButton = ({
}) => {
const { formatMessage } = useIntl();
const { publicKey } = useLogin(s => ({ publicKey: s.publicKey }));
const interactionCache = useInteractionCache(publicKey, ev.id);
const { publisher, system } = useEventPublisher();
const hasReacted = (emoji: string) => {
return (
interactionCache.data.reacted ||
positiveReactions?.some(({ pubkey, content }) => normalizeReaction(content) === emoji && pubkey === publicKey)
);
};
@ -31,7 +28,6 @@ export const LikeButton = ({
if (!hasReacted(content) && publisher) {
const evLike = await publisher.react(ev, content);
system.BroadcastEvent(evLike);
interactionCache.react();
}
};

View File

@ -1,5 +1,5 @@
import { NostrLink, TaggedNostrEvent } from "@snort/system";
import { useEventReactions, useReactions } from "@snort/system-react";
import { useEventReactions } from "@snort/system-react";
import React, { useMemo, useState } from "react";
import { FooterZapButton } from "@/Components/Event/Note/NoteFooter/FooterZapButton";
@ -8,6 +8,7 @@ import { PowIcon } from "@/Components/Event/Note/NoteFooter/PowIcon";
import { ReplyButton } from "@/Components/Event/Note/NoteFooter/ReplyButton";
import { RepostButton } from "@/Components/Event/Note/NoteFooter/RepostButton";
import ReactionsModal from "@/Components/Event/Note/ReactionsModal";
import { useReactionsView } from "@/Feed/WorkerRelayView";
import useLogin from "@/Hooks/useLogin";
export interface NoteFooterProps {
@ -21,7 +22,7 @@ export default function NoteFooter(props: NoteFooterProps) {
const ids = useMemo(() => [link], [link]);
const [showReactions, setShowReactions] = useState(false);
const related = useReactions("note:reactions", ids, undefined, false);
const related = useReactionsView(ids, false);
const { reactions, zaps, reposts } = useEventReactions(link, related);
const { positive } = reactions;

View File

@ -7,7 +7,6 @@ import { AsyncFooterIcon } from "@/Components/Event/Note/NoteFooter/AsyncFooterI
import Icon from "@/Components/Icons/Icon";
import messages from "@/Components/messages";
import useEventPublisher from "@/Hooks/useEventPublisher";
import { useInteractionCache } from "@/Hooks/useInteractionCache";
import useLogin from "@/Hooks/useLogin";
import { useNoteCreator } from "@/State/NoteCreator";
@ -18,11 +17,10 @@ export const RepostButton = ({ ev, reposts }: { ev: TaggedNostrEvent; reposts: T
preferences: s.appData.item.preferences,
publicKey: s.publicKey,
}));
const interactionCache = useInteractionCache(publicKey, ev.id);
const note = useNoteCreator(n => ({ show: n.show, replyTo: n.replyTo, update: n.update, quote: n.quote }));
const hasReposted = () => {
return interactionCache.data.reposted || reposts.some(a => a.pubkey === publicKey);
return reposts.some(a => a.pubkey === publicKey);
};
const repost = async () => {
@ -30,7 +28,6 @@ export const RepostButton = ({ ev, reposts }: { ev: TaggedNostrEvent; reposts: T
if (!prefs.confirmReposts || window.confirm(formatMessage(messages.ConfirmRepost, { id: ev.id }))) {
const evRepost = await publisher.repost(ev);
system.BroadcastEvent(evRepost);
await interactionCache.repost();
}
}
};

View File

@ -1,4 +1,4 @@
import React, { ReactNode, useCallback, useEffect, useMemo, useState } from "react";
import React, { ReactNode, useCallback, useMemo, useState } from "react";
import { FormattedMessage } from "react-intl";
export interface NoteTimeProps {
@ -38,7 +38,7 @@ const NoteTime: React.FC<NoteTimeProps> = ({ from, fallback }) => {
}
}, []);
const [time, setTime] = useState<string | ReactNode>(calcTime(from));
const [time] = useState<string | ReactNode>(calcTime(from));
const absoluteTime = useMemo(
() =>
@ -51,15 +51,6 @@ const NoteTime: React.FC<NoteTimeProps> = ({ from, fallback }) => {
const isoDate = useMemo(() => new Date(from).toISOString(), [from]);
useEffect(() => {
const t = setInterval(() => {
const newTime = calcTime(from);
setTime(s => (s !== newTime ? newTime : s));
}, 60_000); // update every minute
return () => clearInterval(t);
}, [from]);
return (
<time dateTime={isoDate} title={absoluteTime}>
{time || fallback}

View File

@ -2,16 +2,15 @@ import "./Timeline.css";
import { unixNow } from "@snort/shared";
import { EventKind, NostrEvent, TaggedNostrEvent } from "@snort/system";
import { SnortContext } from "@snort/system-react";
import { ReactNode, useCallback, useContext, useMemo, useState, useSyncExternalStore } from "react";
import { ReactNode, useCallback, useMemo, useState } from "react";
import { Link } from "react-router-dom";
import { FollowsFeed } from "@/Cache";
import { ShowMoreInView } from "@/Components/Event/ShowMore";
import { DisplayAs, DisplayAsSelector } from "@/Components/Feed/DisplayAsSelector";
import { TimelineRenderer } from "@/Components/Feed/TimelineRenderer";
import { LiveStreams } from "@/Components/LiveStream/LiveStreams";
import useHashtagsFeed from "@/Feed/HashtagsFeed";
import { useFollowsTimelineView } from "@/Feed/WorkerRelayView";
import useHistoryState from "@/Hooks/useHistoryState";
import useLogin from "@/Hooks/useLogin";
import useModeration from "@/Hooks/useModeration";
@ -35,11 +34,8 @@ const TimelineFollows = (props: TimelineFollowsProps) => {
const displayAsInitial = props.displayAs ?? login.feedDisplayAs ?? "list";
const [displayAs, setDisplayAs] = useState<DisplayAs>(displayAsInitial);
const [latest, setLatest] = useHistoryState(unixNow(), "TimelineFollowsLatest");
const feed = useSyncExternalStore(
cb => FollowsFeed.hook(cb, "*"),
() => FollowsFeed.snapshot(),
);
const system = useContext(SnortContext);
const [limit, setLimit] = useState(50);
const feed = useFollowsTimelineView(limit);
const { muted, isEventMuted } = useModeration();
const sortedFeed = useMemo(() => orderDescending(feed), [feed]);
@ -125,7 +121,9 @@ const TimelineFollows = (props: TimelineFollowsProps) => {
displayAs={displayAs}
/>
{sortedFeed.length > 0 && (
<ShowMoreInView onClick={async () => await FollowsFeed.loadMore(system, login, oldest ?? unixNow())} />
<ShowMoreInView onClick={() => {
setLimit(s => s + 20);
}} />
)}
</>
);

View File

@ -1,7 +1,6 @@
import { HexKey } from "@snort/system";
import { FormattedMessage } from "react-intl";
import { FollowsFeed } from "@/Cache";
import AsyncButton from "@/Components/Button/AsyncButton";
import useEventPublisher from "@/Hooks/useEventPublisher";
import useLogin from "@/Hooks/useLogin";
@ -24,7 +23,6 @@ export default function FollowButton(props: FollowButtonProps) {
if (publisher) {
const ev = await publisher.contactList([pubkey, ...follows.item].map(a => ["p", a]));
system.BroadcastEvent(ev);
await FollowsFeed.backFill(system, [pubkey]);
}
}

View File

@ -3,7 +3,6 @@ import { HexKey } from "@snort/system";
import { ReactNode, useMemo } from "react";
import { FormattedMessage } from "react-intl";
import { FollowsFeed } from "@/Cache";
import ProfilePreview from "@/Components/User/ProfilePreview";
import useEventPublisher from "@/Hooks/useEventPublisher";
import useLogin from "@/Hooks/useLogin";
@ -43,7 +42,6 @@ export default function FollowListBase({
const ev = await publisher.contactList(newFollows.map(a => ["p", a]));
setFollows(id, newFollows, ev.created_at);
await system.BroadcastEvent(ev);
await FollowsFeed.backFill(system, pubkeys);
}
}