feat: upgrade caches to worker
This commit is contained in:
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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}
|
||||
|
@ -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);
|
||||
}} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user