fix: clean up wallet favorites state
This commit is contained in:
@@ -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<Set<string>>(() => new Set());
|
||||
const [knownIds, setKnownIds] = useState<Set<string>>(() => new Set());
|
||||
const [pendingIds, setPendingIds] = useState<Set<string>>(() => new Set());
|
||||
const pendingAfterLoginRef = useRef<string | null>(null);
|
||||
const lastAddressRef = useRef<string | null>(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 => {
|
||||
|
||||
Reference in New Issue
Block a user