Fix accounts under ssr

This commit is contained in:
Zoe Roux 2023-12-01 21:42:37 +01:00
parent d63c601812
commit 07259a7635
5 changed files with 48 additions and 15 deletions

View File

@ -98,6 +98,7 @@ const nextConfig = {
"react-native-web",
"react-native-svg",
"react-native-reanimated",
"react-native-mmkv",
"moti",
"yoshiki",
"@expo/vector-icons",

View File

@ -109,7 +109,7 @@ const YoshikiDebug = ({ children }: { children: JSX.Element }) => {
const App = ({ Component, pageProps }: AppProps) => {
const [queryClient] = useState(() => createQueryClient());
const { queryState, token, randomItems, ...props } = superjson.deserialize<any>(
const { queryState, token, randomItems, account, ...props } = superjson.deserialize<any>(
pageProps ?? { json: {} },
);
const layoutInfo = (Component as QueryPage).getLayout ?? (({ page }) => page);
@ -132,7 +132,7 @@ const App = ({ Component, pageProps }: AppProps) => {
<meta name="description" content="A portable and vast media library solution." />
</Head>
<QueryClientProvider client={queryClient}>
<AccountProvider>
<AccountProvider ssrAccount={account}>
<HydrationBoundary state={queryState}>
<ThemeSelector theme="auto" font={{ normal: "inherit" }}>
<GlobalCssTheme />
@ -160,27 +160,32 @@ const App = ({ Component, pageProps }: AppProps) => {
};
App.getInitialProps = async (ctx: AppContext) => {
const account = readAccountCookie(ctx.ctx.req?.headers.cookie);
const appProps = await NextApp.getInitialProps(ctx);
const Component = ctx.Component as QueryPage;
const items = arrayShuffle(Component.randomItems ?? []);
appProps.pageProps.randomItems = {
[Component.displayName!]: items,
};
if (typeof window !== "undefined") return { pageProps: superjson.serialize(appProps.pageProps) };
const getUrl = Component.getFetchUrls;
const getLayoutUrl =
Component.getLayout && "Layout" in Component.getLayout
? Component.getLayout.Layout.getFetchUrls
: Component.getLayout?.getFetchUrls;
const items = arrayShuffle(Component.randomItems ?? []);
appProps.pageProps.randomItems = {
[Component.displayName!]: items,
};
const urls: QueryIdentifier[] = [
...(getUrl ? getUrl(ctx.router.query as any, items) : []),
...(getLayoutUrl ? getLayoutUrl(ctx.router.query as any, items) : []),
];
const account = readAccountCookie(ctx.ctx.req?.headers.cookie);
const [authToken, token] = await getTokenWJ(account ?? null);
appProps.pageProps.queryState = await fetchQuery(urls, authToken);
appProps.pageProps.token = token;
appProps.pageProps.account = account;
return { pageProps: superjson.serialize(appProps.pageProps) };
};

View File

@ -35,9 +35,9 @@ const writeAccounts = (accounts: Account[]) => {
};
export const setAccountCookie = (account?: Account) => {
const value = JSON.stringify(account);
let value = JSON.stringify(account);
// Remove illegal values from json. There should not be one in the account anyways.
value.replaceAll(";", "");
value = value?.replaceAll(";", "");
const d = new Date();
// A year
d.setTime(d.getTime() + 365 * 24 * 60 * 60 * 1000);

View File

@ -53,16 +53,43 @@ export const ConnectionErrorContext = createContext<{
retry?: () => void;
}>({ error: null });
export const AccountProvider = ({ children }: { children: ReactNode }) => {
/* eslint-disable react-hooks/rules-of-hooks */
export const AccountProvider = ({
children,
ssrAccount,
}: {
children: ReactNode;
ssrAccount?: Account;
}) => {
if (Platform.OS === "web" && typeof window === "undefined") {
const accs = ssrAccount
? [{ ...ssrAccount, selected: true, select: () => { }, remove: () => { } }]
: [];
return (
<AccountContext.Provider value={accs}>
<ConnectionErrorContext.Provider
value={{
error: null,
retry: () => {
queryClient.invalidateQueries({ queryKey: ["auth", "me"] });
},
}}
>
{children}
</ConnectionErrorContext.Provider>
</AccountContext.Provider>
);
}
const [accStr] = useMMKVString("accounts");
const acc = z.array(AccountP).parse(accStr);
const acc = accStr ? z.array(AccountP).parse(accStr) : null;
const accounts = useMemo(
() =>
acc.map((account) => ({
acc?.map((account) => ({
...account,
select: () => updateAccount(account.id, { ...account, selected: true }),
remove: () => removeAccounts((x) => x.id == x.id),
})),
})) ?? [],
[acc],
);

View File

@ -60,7 +60,7 @@ export const login = async (
};
export const getTokenWJ = async (account?: Account | null): Promise<[string, Token] | [null, null]> => {
if (account === null)
if (account === undefined)
account = getCurrentAccount();
if (!account) return [null, null];