v3: follows, notifications, invite-only registration, unread markers
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { useCallback, useState } from "react";
|
||||
import { useNavigationType } from "react-router";
|
||||
|
||||
const TTL = 10 * 60 * 1000; // 10 minutes
|
||||
@@ -13,7 +13,12 @@ interface FeedCacheEntry<T> {
|
||||
|
||||
export interface FeedCacheResult<T> {
|
||||
cached: Omit<FeedCacheEntry<T>, "savedAt"> | null;
|
||||
saveState: (items: T[], page: number, hasMore: boolean, scrollY: number) => void;
|
||||
saveState: (
|
||||
items: T[],
|
||||
page: number,
|
||||
hasMore: boolean,
|
||||
scrollY: number,
|
||||
) => void;
|
||||
}
|
||||
|
||||
export function useFeedCache<T>(
|
||||
@@ -22,9 +27,8 @@ export function useFeedCache<T>(
|
||||
): FeedCacheResult<T> {
|
||||
const navType = useNavigationType();
|
||||
|
||||
// Read ONCE on mount. Empty deps is intentional — nav type and cache are only
|
||||
// relevant at the moment the component first mounts.
|
||||
const cached = useMemo<Omit<FeedCacheEntry<T>, "savedAt"> | null>(() => {
|
||||
// useState initializer runs exactly once on mount — correct for a cache read.
|
||||
const [cached] = useState<Omit<FeedCacheEntry<T>, "savedAt"> | null>(() => {
|
||||
if (navType !== "POP") return null;
|
||||
try {
|
||||
const raw = sessionStorage.getItem(key);
|
||||
@@ -35,15 +39,20 @@ export function useFeedCache<T>(
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
});
|
||||
|
||||
const saveState = useCallback(
|
||||
(items: T[], page: number, hasMore: boolean, scrollY: number) => {
|
||||
try {
|
||||
sessionStorage.setItem(
|
||||
key,
|
||||
JSON.stringify({ items, page, hasMore, scrollY, savedAt: Date.now() }),
|
||||
JSON.stringify({
|
||||
items,
|
||||
page,
|
||||
hasMore,
|
||||
scrollY,
|
||||
savedAt: Date.now(),
|
||||
}),
|
||||
);
|
||||
} catch {
|
||||
// QuotaExceededError or SecurityError — degrade silently
|
||||
|
||||
4
src/hooks/useFollows.ts
Normal file
4
src/hooks/useFollows.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { useContext } from "react";
|
||||
import { FollowContext } from "../contexts/FollowContext.ts";
|
||||
|
||||
export const useFollows = () => useContext(FollowContext);
|
||||
Reference in New Issue
Block a user