Updated user data caching
This commit is contained in:
parent
6b96db8cfe
commit
00a1bee73e
2 changed files with 40 additions and 13 deletions
|
|
@ -19,6 +19,9 @@ const UserContext = React.createContext<contextValue | undefined>(undefined);
|
||||||
*/
|
*/
|
||||||
export default function UserProvider(props: { children: React.ReactNode }) {
|
export default function UserProvider(props: { children: React.ReactNode }) {
|
||||||
const storageRef = React.useRef<Record<number, User>>({});
|
const storageRef = React.useRef<Record<number, User>>({});
|
||||||
|
const pendingRef = React.useRef<Record<number, Promise<User> | undefined>>(
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
const { send } = useTTP();
|
const { send } = useTTP();
|
||||||
|
|
||||||
|
|
@ -27,21 +30,45 @@ export default function UserProvider(props: { children: React.ReactNode }) {
|
||||||
* @param userId Parameter userId.
|
* @param userId Parameter userId.
|
||||||
* @returns Promise<User>.
|
* @returns Promise<User>.
|
||||||
*/
|
*/
|
||||||
async function get(userId: number): Promise<User> {
|
const get = React.useCallback(
|
||||||
if (storageRef.current[userId] === undefined) {
|
async (userId: number): Promise<User> => {
|
||||||
|
if (userId == null) {
|
||||||
|
throw new Error("userId is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
const cachedUser = storageRef.current[userId];
|
||||||
|
if (cachedUser !== undefined) {
|
||||||
|
return cachedUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pendingUser = pendingRef.current[userId];
|
||||||
|
if (pendingUser !== undefined) {
|
||||||
|
return pendingUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
const request = (async () => {
|
||||||
const userData = await send("get_user_data", { user_id: userId });
|
const userData = await send("get_user_data", { user_id: userId });
|
||||||
|
const user = {
|
||||||
// Temp, add base64 stuff
|
...userData.data,
|
||||||
userData.data.avatar = userData.data.avatar
|
avatar: userData.data.avatar
|
||||||
? `data:image/png;base64,${userData.data.avatar}`
|
? `data:image/png;base64,${userData.data.avatar}`
|
||||||
: undefined;
|
: undefined,
|
||||||
// Temp end
|
};
|
||||||
|
|
||||||
storageRef.current[userId] = userData.data;
|
storageRef.current[userId] = user;
|
||||||
}
|
return user;
|
||||||
|
})();
|
||||||
|
|
||||||
return storageRef.current[userId];
|
pendingRef.current[userId] = request;
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await request;
|
||||||
|
} finally {
|
||||||
|
delete pendingRef.current[userId];
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
[send],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UserContext.Provider value={{ get }}>
|
<UserContext.Provider value={{ get }}>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ export default function Wrapper(props: {
|
||||||
const [user, setUser] = useState<User | null>(null);
|
const [user, setUser] = useState<User | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!props.userId) {
|
if (props.userId == null) {
|
||||||
setUser(failedUser);
|
setUser(failedUser);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue