Skip to content

Commit

Permalink
refactor: limit root loader to be session specific
Browse files Browse the repository at this point in the history
  • Loading branch information
edmundhung committed May 23, 2022
1 parent 5b1707f commit 0b5e116
Show file tree
Hide file tree
Showing 18 changed files with 78 additions and 58 deletions.
6 changes: 3 additions & 3 deletions app/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useMatches } from 'remix';
import { GuideMetadata } from '~/types';
import { GuideMetadata, SessionData } from '~/types';

export function useFlashMessage(): string | null {
export function useSessionData(): SessionData {
const [rootMatch] = useMatches();

return rootMatch?.data.message ?? null;
return (rootMatch?.data as SessionData) ?? null;
}

export function useLists(): Required<GuideMetadata>['lists'] {
Expand Down
45 changes: 7 additions & 38 deletions app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,11 @@ import {
Meta,
Links,
Scripts,
useLoaderData,
useLocation,
LiveReload,
useCatch,
Outlet,
json,
} from 'remix';
import clsx from 'clsx';
import Progress from '~/components/Progress';
import SidebarNavigation from '~/components/SidebarNavigation';
import type { Context } from '~/types';
import stylesUrl from '~/styles/tailwind.css';

Expand All @@ -36,24 +31,14 @@ export let meta: MetaFunction = () => {
};

export let loader: LoaderFunction = async ({ context }) => {
const { session, resourceStore } = context as Context;
const [profile, [message, headers], guide] = await Promise.all([
session.isAuthenticated(),
session.getFlashMessage(),
resourceStore.getData(),
]);
const { session } = context as Context;
const [data, setCookieHeader] = await session.getData();

return json(
{
profile,
message,
lists: guide.metadata.lists,
version: process.env.VERSION,
return json(data, {
headers: {
'Set-Cookie': setCookieHeader,
},
{
headers,
},
);
});
};

export const unstable_shouldReload: ShouldReloadFunction = ({ submission }) => {
Expand Down Expand Up @@ -85,25 +70,9 @@ function Document({
}

export default function App() {
const { profile, lists } = useLoaderData();
const location = useLocation();
const isMenuOpened =
new URLSearchParams(location.search).get('open') === 'menu';

return (
<Document>
<Progress />
<nav
className={clsx(
'z-30 xl:block w-full lg:w-96 xl:w-64 border-r',
isMenuOpened ? 'absolute xl:relative bg-gray-900' : 'hidden',
)}
>
<SidebarNavigation profile={profile} lists={lists} />
</nav>
<main className={clsx('flex-1', { 'hidden lg:block': isMenuOpened })}>
<Outlet />
</main>
<Outlet />
</Document>
);
}
Expand Down
45 changes: 45 additions & 0 deletions app/routes/__layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import type { LoaderFunction, ShouldReloadFunction } from 'remix';
import { Outlet, json, useLoaderData, useLocation } from 'remix';
import clsx from 'clsx';
import Progress from '~/components/Progress';
import SidebarNavigation from '~/components/SidebarNavigation';
import { Context } from '~/types';
import { useSessionData } from '~/hooks';

export let loader: LoaderFunction = async ({ context }) => {
const { resourceStore } = context as Context;
const guide = await resourceStore.getData();

return json({
lists: guide.metadata.lists,
});
};

export const unstable_shouldReload: ShouldReloadFunction = ({ submission }) => {
return typeof submission !== 'undefined';
};

export default function Layout() {
const { lists } = useLoaderData();
const { profile } = useSessionData();
const location = useLocation();
const isMenuOpened =
new URLSearchParams(location.search).get('open') === 'menu';

return (
<>
<Progress />
<nav
className={clsx(
'z-30 xl:block w-full lg:w-96 xl:w-64 border-r',
isMenuOpened ? 'absolute xl:relative bg-gray-900' : 'hidden',
)}
>
<SidebarNavigation profile={profile} lists={lists} />
</nav>
<main className={clsx('flex-1', { 'hidden lg:block': isMenuOpened })}>
<Outlet />
</main>
</>
);
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { getSuggestions, patchResource } from '~/resources';
import { getSearchOptions, getTitleBySearchOptions } from '~/search';
import type { Context, Resource, SearchOptions, User } from '~/types';
import BookmarkDetails from '~/components/BookmarkDetails';
import { useFlashMessage } from '~/hooks';
import { useSessionData } from '~/hooks';

interface LoaderData {
resource: Resource;
Expand Down Expand Up @@ -171,7 +171,7 @@ export const unstable_shouldReload: ShouldReloadFunction = ({

export default function UserProfile() {
const { resource, user, suggestions } = useLoaderData<LoaderData>();
const message = useFlashMessage();
const { message } = useSessionData();
const location = useLocation();
const [showBookmark, action] = useMemo(() => {
const searchParams = new URLSearchParams(location.search);
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { getSuggestions, patchResource } from '~/resources';
import { getSearchOptions, getTitleBySearchOptions } from '~/search';
import type { Context, Resource, SearchOptions, User } from '~/types';
import BookmarkDetails from '~/components/BookmarkDetails';
import { useFlashMessage } from '~/hooks';
import { useSessionData } from '~/hooks';

interface LoaderData {
resource: Resource;
Expand Down Expand Up @@ -171,7 +171,7 @@ export const unstable_shouldReload: ShouldReloadFunction = ({

export default function UserProfile() {
const { resource, user, suggestions } = useLoaderData<LoaderData>();
const message = useFlashMessage();
const { message } = useSessionData();
const location = useLocation();
const [showBookmark, action] = useMemo(() => {
const searchParams = new URLSearchParams(location.search);
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions app/routes/submit.tsx → app/routes/__layout/submit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Context } from '~/types';
import { formatMeta, isMaintainer } from '~/helpers';
import { toggleSearchParams } from '~/search';
import IconLink from '~/components/IconLink';
import { useFlashMessage } from '~/hooks';
import { useSessionData } from '~/hooks';

export let meta: MetaFunction = () => {
return formatMeta({
Expand Down Expand Up @@ -115,7 +115,7 @@ export let action: ActionFunction = async ({ request, context }) => {
};

export default function Submit() {
const message = useFlashMessage();
const { message } = useSessionData();
const location = useLocation();
const toggleMenuURL = useMemo(
() => `?${toggleSearchParams(location.search, 'menu')}`,
Expand Down
23 changes: 12 additions & 11 deletions worker/context/session.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Authenticator } from 'remix-auth';
import { GitHubStrategy } from 'remix-auth-github';
import { createCookieSessionStorage, redirect } from 'remix';
import type { Env, MessageType, UserProfile } from '../types';
import type { Env, MessageType, SessionData, UserProfile } from '../types';
import { getUserStore } from '../store/UserStore';

export type Session = ReturnType<typeof createSession>;
Expand Down Expand Up @@ -86,21 +86,22 @@ export function createSession(
redirectTo: '/',
});
},
async isAuthenticated(): Promise<UserProfile | null> {
return await authenticator.isAuthenticated(request);
},
async getFlashMessage(): Promise<[string | null, Record<string, string>]> {
async getData(): Promise<[SessionData, string]> {
const session = await sessionStorage.getSession(
request.headers.get('Cookie'),
);
const profile = session.get(authenticator.sessionKey) ?? null;
const message = session.get('message') ?? null;
const setCookieHeader = !message
? null
: {
'Set-Cookie': await sessionStorage.commitSession(session),
};
const setCookieHeader = await sessionStorage.commitSession(session);
const data = {
profile,
message,
};

return [message, setCookieHeader ?? {}];
return [data, setCookieHeader];
},
async isAuthenticated(): Promise<UserProfile | null> {
return await authenticator.isAuthenticated(request);
},
async commitWithFlashMessage(
message: string,
Expand Down
5 changes: 5 additions & 0 deletions worker/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ export interface Env {
USER_STORE: DurableObjectNamespace;
}

export interface SessionData {
profile: UserProfile | null;
message: string | null;
}

export interface UserProfile {
id: string;
name: string;
Expand Down

0 comments on commit 0b5e116

Please sign in to comment.