-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy pathuser-context.tsx
75 lines (63 loc) · 2.69 KB
/
user-context.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/**
* Copyright (c) 2021 Gitpod GmbH. All rights reserved.
* Licensed under the GNU Affero General Public License (AGPL).
* See License.AGPL.txt in the project root for license information.
*/
import { User } from "@gitpod/public-api/lib/gitpod/v1/user_pb";
import { useQueryClient } from "@tanstack/react-query";
import React, { createContext, useState, useContext, useMemo, useCallback } from "react";
import { updateCommonErrorDetails } from "./service/metrics";
import { updateUserForExperiments } from "./service/public-api";
import { getPrimaryEmail } from "@gitpod/public-api-common/lib/user-utils";
const UserContext = createContext<{
user?: User;
setUser: React.Dispatch<User>;
}>({
setUser: () => null,
});
const UserContextProvider: React.FC = ({ children }) => {
const [user, setUser] = useState<User>();
const updateServiceUser = (user?: User) => {
updateCommonErrorDetails({ userId: user?.id });
updateUserForExperiments(!!user ? { id: user.id, email: getPrimaryEmail(user) } : undefined);
};
updateServiceUser(user);
const client = useQueryClient();
const doSetUser = useCallback(
(updatedUser: User) => {
updateServiceUser(updatedUser);
// If user has changed clear cache
// Ignore the case where user hasn't been set yet - initial load
if (user && user?.id !== updatedUser.id) {
client.clear();
}
setUser(updatedUser);
// Schedule a periodic refresh of JWT cookie
const w = window as any;
const _gp = w._gp || (w._gp = {});
const frequencyMs = 1000 * 60 * 60; // 1 hour
if (!_gp.jwttimer) {
// Store the timer on the window, to avoid queuing up multiple
_gp.jwtTimer = setInterval(() => {
fetch("/api/auth/jwt-cookie", {
credentials: "include",
})
.then((resp) => resp.text())
.then((text) => console.log(`Completed JWT Cookie refresh: ${text}`))
.catch((err) => {
console.log("Failed to update jwt-cookie", err);
});
}, frequencyMs);
}
},
[user, client],
);
// Wrap value in useMemo to avoid unnecessary re-renders
const ctxValue = useMemo(() => ({ user, setUser: doSetUser }), [user, doSetUser]);
return <UserContext.Provider value={ctxValue}>{children}</UserContext.Provider>;
};
export { UserContext, UserContextProvider };
export const useCurrentUser = () => {
const { user } = useContext(UserContext);
return user;
};