You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
59 lines
1.4 KiB
59 lines
1.4 KiB
2 years ago
|
import { useCallback, useEffect, useState } from 'react';
|
||
|
|
||
|
import useIsFirstRender from './useIsFirstRender';
|
||
|
|
||
|
const useCookieJar = (): {
|
||
|
cookieJar: CookieJar;
|
||
|
getCookie: <T>(key: string) => T | undefined;
|
||
|
getSessionUser: () => SessionUser | undefined;
|
||
|
} => {
|
||
|
const isFirstRender = useIsFirstRender();
|
||
|
|
||
|
const [cookieJar, setCookieJar] = useState<CookieJar>({});
|
||
|
|
||
|
const getCookie = useCallback(
|
||
|
<T>(key: string, prefix = 'suiapi.') =>
|
||
|
cookieJar[`${prefix}${key}`] as T | undefined,
|
||
|
[cookieJar],
|
||
|
);
|
||
|
|
||
|
const getSessionUser = useCallback(
|
||
|
() => getCookie<SessionUser>('user'),
|
||
|
[getCookie],
|
||
|
);
|
||
|
|
||
|
useEffect(() => {
|
||
|
if (isFirstRender) {
|
||
|
const lines = document.cookie.split(/\s*;\s*/);
|
||
|
|
||
|
setCookieJar(
|
||
|
lines.reduce<CookieJar>((previous, line) => {
|
||
|
const [key, value] = line.split('=', 2);
|
||
|
|
||
|
const decoded = decodeURIComponent(value);
|
||
|
|
||
|
let result: unknown;
|
||
|
|
||
|
if (decoded.startsWith('j:')) {
|
||
|
try {
|
||
|
result = JSON.parse(decoded.substring(2));
|
||
|
} catch (error) {
|
||
|
result = value;
|
||
|
}
|
||
|
} else {
|
||
|
result = value;
|
||
|
}
|
||
|
|
||
|
previous[key] = result;
|
||
|
|
||
|
return previous;
|
||
|
}, {}),
|
||
|
);
|
||
|
}
|
||
|
}, [isFirstRender]);
|
||
|
|
||
|
return { cookieJar, getCookie, getSessionUser };
|
||
|
};
|
||
|
|
||
|
export default useCookieJar;
|