diff --git a/src/favorites/FavoritesProvider.tsx b/src/favorites/FavoritesProvider.tsx index b62982b..7e93cb8 100644 --- a/src/favorites/FavoritesProvider.tsx +++ b/src/favorites/FavoritesProvider.tsx @@ -30,19 +30,22 @@ export function FavoritesProvider({ children }: { children: ReactNode }) { const { t } = useI18n(); const { showToast } = useToast(); const wallet = useWallet(); + const { address, openLoginModal, status, token } = wallet; const [favoriteIds, setFavoriteIds] = useState>(() => new Set()); const [knownIds, setKnownIds] = useState>(() => new Set()); const [pendingIds, setPendingIds] = useState>(() => new Set()); const pendingAfterLoginRef = useRef(null); + const lastAddressRef = useRef(null); useEffect(() => { - if (wallet.status === "loggedOut") { - setFavoriteIds(new Set()); - setKnownIds(new Set()); - setPendingIds(new Set()); - pendingAfterLoginRef.current = null; - } - }, [wallet.status]); + const nextAddress = status === "loggedIn" ? address : null; + if (lastAddressRef.current === nextAddress) return; + lastAddressRef.current = nextAddress; + setFavoriteIds(new Set()); + setKnownIds(new Set()); + setPendingIds(new Set()); + if (!nextAddress) pendingAfterLoginRef.current = null; + }, [address, status]); const markFavorite = useCallback((resourceId: string, favorited: boolean) => { setKnownIds((prev) => new Set(prev).add(resourceId)); @@ -56,12 +59,12 @@ export function FavoritesProvider({ children }: { children: ReactNode }) { const ensureFavoriteIds = useCallback( async (resourceIds: string[]) => { - if (!wallet.token || wallet.status !== "loggedIn") return; + if (!token || status !== "loggedIn") return; const missing = [...new Set(resourceIds)].filter( (id) => !knownIds.has(id), ); if (missing.length === 0) return; - const ids = await getFavoriteIds(wallet.token, missing); + const ids = await getFavoriteIds(token, missing); setKnownIds((prev) => { const next = new Set(prev); missing.forEach((id) => next.add(id)); @@ -73,18 +76,18 @@ export function FavoritesProvider({ children }: { children: ReactNode }) { return next; }); }, - [knownIds, wallet.status, wallet.token], + [knownIds, status, token], ); const runFavoriteMutation = useCallback( async (resourceId: string) => { - if (!wallet.token) return; + if (!token) return; const currentlyFavorite = favoriteIds.has(resourceId); setPendingIds((prev) => new Set(prev).add(resourceId)); markFavorite(resourceId, !currentlyFavorite); try { - if (currentlyFavorite) await removeFavorite(wallet.token, resourceId); - else await addFavorite(wallet.token, resourceId); + if (currentlyFavorite) await removeFavorite(token, resourceId); + else await addFavorite(token, resourceId); showToast( currentlyFavorite ? t("favoriteRemoved") : t("favoriteAdded"), ); @@ -100,29 +103,29 @@ export function FavoritesProvider({ children }: { children: ReactNode }) { }); } }, - [favoriteIds, markFavorite, showToast, t, wallet.token], + [favoriteIds, markFavorite, showToast, t, token], ); const toggleFavorite = useCallback( async (resourceId: string) => { - if (!wallet.token || wallet.status !== "loggedIn") { + if (!token || status !== "loggedIn") { pendingAfterLoginRef.current = resourceId; - wallet.openLoginModal(); + openLoginModal(); showToast(t("favoriteLoginRequired")); return; } await runFavoriteMutation(resourceId); }, - [runFavoriteMutation, showToast, t, wallet], + [openLoginModal, runFavoriteMutation, showToast, status, t, token], ); useEffect(() => { - if (wallet.status !== "loggedIn" || !wallet.token) return; + if (status !== "loggedIn" || !token) return; const pending = pendingAfterLoginRef.current; if (!pending) return; pendingAfterLoginRef.current = null; void runFavoriteMutation(pending).catch(() => undefined); - }, [runFavoriteMutation, wallet.status, wallet.token]); + }, [runFavoriteMutation, status, token]); const statusFor = useCallback( (resourceId: string): FavoriteStatus => { diff --git a/src/pages/Favorites/index.tsx b/src/pages/Favorites/index.tsx index 6be9937..86c09aa 100644 --- a/src/pages/Favorites/index.tsx +++ b/src/pages/Favorites/index.tsx @@ -52,7 +52,7 @@ function FavoriteResourceCard({ resource }: { resource: Resource }) { const lp = useLocalizedPath(); const unavailable = resource.availability === "unavailable"; const cover = resource.coverImage || resource.previewUrl; - const content = ( + return (
-
+ {!unavailable ? ( + + ) : null} +
{cover && !unavailable ? ( -
+

{resource.title}

@@ -107,17 +114,10 @@ function FavoriteResourceCard({ resource }: { resource: Resource }) {
); - - if (unavailable) return content; - return ( - - {content} - - ); } export default function Favorites() { diff --git a/src/wallet/WalletLoginModal.tsx b/src/wallet/WalletLoginModal.tsx index 77521ad..7bd86cf 100644 --- a/src/wallet/WalletLoginModal.tsx +++ b/src/wallet/WalletLoginModal.tsx @@ -21,7 +21,8 @@ type ModalState = "idle" | "tpLoading" | "tpPolling" | "rainbowSigning"; export function WalletLoginModal() { const { t } = useI18n(); const { showToast } = useToast(); - const wallet = useWallet(); + const { closeLoginModal, completeLogin, loginModalOpen, signInInjected } = + useWallet(); const { openConnectModal } = useConnectModal(); const { address, isConnected } = useAccount(); const { signMessageAsync } = useSignMessage(); @@ -35,12 +36,12 @@ export function WalletLoginModal() { const close = () => { if (state === "tpLoading" || state === "rainbowSigning") return; - wallet.closeLoginModal(); + closeLoginModal(); setError(""); }; useEffect(() => { - if (!wallet.loginModalOpen || !tpRequest) return; + if (!loginModalOpen || !tpRequest) return; if (state !== "tpPolling") return; let cancelled = false; @@ -55,7 +56,7 @@ export function WalletLoginModal() { signature: result.signature, }); if (cancelled) return; - wallet.completeLogin(verified.token, verified.wallet); + completeLogin(verified.token, verified.wallet); showToast(t("walletLoginSuccess")); setState("idle"); setTpRequest(null); @@ -76,7 +77,7 @@ export function WalletLoginModal() { cancelled = true; window.clearInterval(timer); }; - }, [state, tpRequest, t, showToast, wallet]); + }, [completeLogin, loginModalOpen, state, tpRequest, t, showToast]); useEffect(() => { if (!rainbowPending || !isConnected || !address) return; @@ -94,7 +95,7 @@ export function WalletLoginModal() { message: nonce.message, signature, }); - wallet.completeLogin(verified.token, verified.wallet); + completeLogin(verified.token, verified.wallet); showToast(t("walletLoginSuccess")); } catch (err) { const message = @@ -114,15 +115,15 @@ export function WalletLoginModal() { showToast, signMessageAsync, t, - wallet, + completeLogin, ]); - if (!wallet.loginModalOpen) return null; + if (!loginModalOpen) return null; const startInjected = async () => { setError(""); setState("idle"); - await wallet.signInInjected().catch(() => undefined); + await signInInjected().catch(() => undefined); }; const startTokenPocketQr = async () => {