2024-02-01 12:40:15 +00:00
|
|
|
import React, {
|
|
|
|
createContext,
|
|
|
|
useContext,
|
|
|
|
ReactNode,
|
|
|
|
useState,
|
|
|
|
useMemo,
|
|
|
|
useCallback,
|
|
|
|
useEffect,
|
|
|
|
} from 'react';
|
|
|
|
import { Octokit, RequestError } from 'octokit';
|
|
|
|
|
|
|
|
import { useGQLClient } from './GQLClientContext';
|
|
|
|
|
|
|
|
const UNAUTHORIZED_ERROR_CODE = 401;
|
|
|
|
|
|
|
|
interface ContextValue {
|
|
|
|
octokit: Octokit | null;
|
2024-02-14 12:05:02 +00:00
|
|
|
isAuth: boolean;
|
2024-02-01 12:40:15 +00:00
|
|
|
updateAuth: () => void;
|
|
|
|
}
|
|
|
|
|
|
|
|
const OctokitContext = createContext<ContextValue>({
|
|
|
|
octokit: null,
|
2024-02-14 12:05:02 +00:00
|
|
|
isAuth: false,
|
2024-02-01 12:40:15 +00:00
|
|
|
updateAuth: () => {},
|
|
|
|
});
|
|
|
|
|
|
|
|
export const OctokitProvider = ({ children }: { children: ReactNode }) => {
|
|
|
|
const [authToken, setAuthToken] = useState<string>('');
|
2024-02-14 12:05:02 +00:00
|
|
|
const [isAuth, setIsAuth] = useState(false);
|
|
|
|
|
2024-02-01 12:40:15 +00:00
|
|
|
const client = useGQLClient();
|
|
|
|
|
|
|
|
const fetchUser = useCallback(async () => {
|
|
|
|
const { user } = await client.getUser();
|
|
|
|
|
|
|
|
if (user.gitHubToken) {
|
|
|
|
setAuthToken(user.gitHubToken);
|
|
|
|
}
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
const updateAuth = useCallback(() => {
|
|
|
|
fetchUser();
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
const octokit = useMemo(() => {
|
|
|
|
if (!authToken) {
|
2024-02-14 12:05:02 +00:00
|
|
|
setIsAuth(false);
|
|
|
|
return new Octokit();
|
2024-02-01 12:40:15 +00:00
|
|
|
}
|
|
|
|
|
2024-02-14 12:05:02 +00:00
|
|
|
setIsAuth(true);
|
2024-02-01 12:40:15 +00:00
|
|
|
return new Octokit({ auth: authToken });
|
|
|
|
}, [authToken]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
fetchUser();
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
// TODO: Handle React component error
|
|
|
|
const interceptor = async (error: RequestError | Error) => {
|
|
|
|
if (
|
|
|
|
error instanceof RequestError &&
|
|
|
|
error.status === UNAUTHORIZED_ERROR_CODE
|
|
|
|
) {
|
|
|
|
await client.unauthenticateGithub();
|
|
|
|
await fetchUser();
|
|
|
|
}
|
|
|
|
|
|
|
|
throw error;
|
|
|
|
};
|
|
|
|
|
|
|
|
octokit.hook.error('request', interceptor);
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
// Remove the interceptor when the component unmounts
|
|
|
|
octokit.hook.remove('request', interceptor);
|
|
|
|
};
|
|
|
|
}, [octokit, client]);
|
|
|
|
|
|
|
|
return (
|
2024-02-14 12:05:02 +00:00
|
|
|
<OctokitContext.Provider value={{ octokit, updateAuth, isAuth }}>
|
2024-02-01 12:40:15 +00:00
|
|
|
{children}
|
|
|
|
</OctokitContext.Provider>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export const useOctokit = () => {
|
2024-02-14 12:05:02 +00:00
|
|
|
const { octokit, updateAuth, isAuth } = useContext(OctokitContext);
|
2024-02-01 12:40:15 +00:00
|
|
|
|
2024-02-14 12:05:02 +00:00
|
|
|
return { octokit, updateAuth, isAuth };
|
2024-02-01 12:40:15 +00:00
|
|
|
};
|