-
Notifications
You must be signed in to change notification settings - Fork 60
Expand file tree
/
Copy pathserver.ts
More file actions
74 lines (63 loc) · 2.06 KB
/
server.ts
File metadata and controls
74 lines (63 loc) · 2.06 KB
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
import {
createCookie,
unstable_createContext,
type unstable_MiddlewareFunction,
type unstable_RouterContextProvider,
} from "react-router";
let cookie = createCookie("menu-collapse", {
// 7 days -- if the user hasn't visit in a while, go ahead and show them everything again
maxAge: 7 * 24 * 60 * 60,
sameSite: "lax",
});
// Default behavior: missing categories are treated as "open" (true)
type MenuCollapseState = Record<string, boolean>;
let menuCollapseStateContext = unstable_createContext<MenuCollapseState>({});
export function menuCollapseContext(
context: Readonly<unstable_RouterContextProvider>,
) {
return {
get: () => {
return context.get(menuCollapseStateContext);
},
set: (category: string, open: boolean) => {
let menuCollapseState = context.get(menuCollapseStateContext);
context.set(menuCollapseStateContext, {
...menuCollapseState,
[category]: open,
});
},
setAll: (state: MenuCollapseState) => {
context.set(menuCollapseStateContext, state);
},
};
}
/**
* Middleware to set the initial menu collapse state from the cookie
* and update the cookie with the current state after processing the request
*
* This is used to persist the menu collapse state across page loads
*/
export let menuCollapseStateMiddleware: unstable_MiddlewareFunction<
Response
> = async ({ request, context }, next) => {
// Set the context to whatever is in the cookie
let menuCollapseCookieState = await parseMenuCollapseState(request);
let menuCollapse = menuCollapseContext(context);
menuCollapse.setAll(menuCollapseCookieState);
let res = await next();
res.headers.append(
"Set-Cookie",
await cookie.serialize({
// Check the context again, because it could be mutated by the action
menuCollapseState: menuCollapse.get(),
}),
);
return res;
};
async function parseMenuCollapseState(
request: Request,
): Promise<MenuCollapseState> {
let header = request.headers.get("Cookie");
let vals = await cookie.parse(header);
return vals?.menuCollapseState || {};
}