Skip to content

Commit

Permalink
Render Discover page server side
Browse files Browse the repository at this point in the history
  • Loading branch information
jakecoble committed Aug 23, 2024
1 parent dadb79f commit c63a3f7
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 171 deletions.
11 changes: 8 additions & 3 deletions graphql-codegen/graphql-plugin-prefetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,14 @@ type Vars = {
const options = { cacheTime: 24 * 60 * 60 * 1000 };
async function doPrefetch<T extends Key>(k: T, v: Vars[T], client: QueryClient) {
const r = await fns[k](v as any);
await client.prefetchQuery([k, v], () => r, options);
await client.prefetchInfiniteQuery([\`\${k}.infinite\`, v], () => r, options);
try {
const r = await fns[k](v as any);
await client.prefetchQuery([k, v], () => r, options);
await client.prefetchInfiniteQuery([\`\${k}.infinite\`, v], () => r, options);
} catch (e: unknown) {
console.error('Failed to prefetch', k, v);
console.dir(e, {depth: null});
}
}
export async function prefetchQueries(
Expand Down
92 changes: 3 additions & 89 deletions src/containers/discover/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { __loadQuery } from 'next/router';
import { mockWidth } from '~components/organisms/cardSlider/index.spec';
import { __swiper } from '~lib/swiper';
import { buildLoader } from '~lib/test/buildLoader';
import { buildStaticRenderer } from '~lib/test/buildStaticRenderer';
import Discover, { getStaticProps } from '~pages/[language]/discover';
import Discover, { getServerSideProps } from '~pages/[language]/discover';
import {
RecordingContentType,
SequenceContentType,
Expand Down Expand Up @@ -35,10 +34,9 @@ import {
GetSectionTrendingTeachingsQuery,
} from '~src/components/organisms/cardSlider/section/__generated__/trendingTeachings';
import { __apiDocumentMock } from '~src/lib/api/fetchApi';
import { buildServerRenderer } from '~src/lib/test/buildServerRenderer';

import { getTopSection } from '.';

const renderPage = buildStaticRenderer(Discover, getStaticProps);
const renderPage = buildServerRenderer(Discover, getServerSideProps);

const base = {
pageInfo: {
Expand Down Expand Up @@ -215,87 +213,3 @@ describe('discover page', () => {
expect(next).toBeDisabled();
});
});

describe('discover getTopSection', () => {
it('works', () => {
getTopSection({
isUserLoggedIn: false,
isLoading: false,
count: 0,
isLoadingCount: false,
isServerSide: false,
});
});

it('returns nothing when not logged in and is loading and no count and is loading count', () => {
const result = getTopSection({
isUserLoggedIn: false,
isLoading: true,
count: undefined,
isLoadingCount: true,
isServerSide: false,
});

expect(result).toEqual('nothing');
});

it('returns featured when not logged in and not loading and no count and is loading count', () => {
const result = getTopSection({
isUserLoggedIn: false,
isLoading: false,
count: undefined,
isLoadingCount: true,
isServerSide: false,
});

expect(result).toEqual('featured');
});

it('returns nothing when logged in and not loading and no count and is loading count', () => {
const result = getTopSection({
isUserLoggedIn: true,
isLoading: false,
count: undefined,
isLoadingCount: true,
isServerSide: false,
});

expect(result).toEqual('nothing');
});

it('returns continue listening when logged in and not loading and non-zero count and not loading count', () => {
const result = getTopSection({
isUserLoggedIn: true,
isLoading: false,
count: 1,
isLoadingCount: false,
isServerSide: false,
});

expect(result).toEqual('continueListening');
});

it('returns featured when logged in and not loading and zero count and not loading count', () => {
const result = getTopSection({
isUserLoggedIn: true,
isLoading: false,
count: 0,
isLoadingCount: false,
isServerSide: false,
});

expect(result).toEqual('featured');
});

it('returns nothing when isServerSide is true', () => {
const result = getTopSection({
isUserLoggedIn: true,
isLoading: false,
count: 0,
isLoadingCount: false,
isServerSide: true,
});

expect(result).toEqual('nothing');
});
});
44 changes: 5 additions & 39 deletions src/containers/discover/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useMemo } from 'react';
import React from 'react';
import { FormattedMessage } from 'react-intl';

import BlogPosts from '~components/organisms/cardSlider/section/blogPosts';
Expand All @@ -9,59 +9,25 @@ import StorySeasons from '~components/organisms/cardSlider/section/storySeasons'
import Topics from '~components/organisms/cardSlider/section/topics';
import TrendingMusic from '~components/organisms/cardSlider/section/trendingMusic';
import TrendingTeachings from '~components/organisms/cardSlider/section/trendingTeachings';
import useIsAuthenticated from '~lib/hooks/useIsAuthenticated';
import Audiobooks from '~src/components/organisms/cardSlider/section/audiobooks';
import BibleBooks from '~src/components/organisms/cardSlider/section/bibleBooks';
import ContinueListening from '~src/components/organisms/cardSlider/section/continueListening';
import EgwAudiobooks from '~src/components/organisms/cardSlider/section/egwAudiobooks'; //egw
import Presenters from '~src/components/organisms/cardSlider/section/presenters';
import isServerSide from '~src/lib/isServerSide';
import { useLanguageId } from '~src/lib/useLanguageId';

import { useGetDiscoverPageDataQuery } from './__generated__/index';

export function getTopSection(options: {
isUserLoggedIn: boolean;
isLoading: boolean;
count: number | undefined;
isLoadingCount: boolean;
isServerSide: boolean;
}): 'nothing' | 'featured' | 'continueListening' {
if (options.isServerSide) return 'nothing';
if (!options.isUserLoggedIn && !options.isLoading) return 'featured';
if (options.isLoading || options.isLoadingCount) return 'nothing';
if (options.isUserLoggedIn && !options.isLoadingCount) {
if (options.count ?? 0 > 0) return 'continueListening';
return 'featured';
}
if (!options.isUserLoggedIn) return 'featured';
return 'nothing';
}

export default function Discover(): JSX.Element {
const language = useLanguageId();
const { isUserLoggedIn, isFetching } = useIsAuthenticated();
const { data, isLoading: isLoadingCount } = useGetDiscoverPageDataQuery({
language,
});
const { data } = useGetDiscoverPageDataQuery({ language });
const count = data?.me?.user.continueListening?.aggregate?.count ?? 0;

const topSection = useMemo(():
| 'nothing'
| 'featured'
| 'continueListening' => {
return getTopSection({
isUserLoggedIn,
isLoading: isFetching,
count: data?.me?.user.continueListening?.aggregate?.count,
isLoadingCount,
isServerSide: isServerSide(),
});
}, [isUserLoggedIn, isFetching, data, isLoadingCount]);
console.dir({ data, count }, { depth: null });

return (
<div>
{topSection === 'continueListening' && <ContinueListening />}
{topSection === 'featured' && <FeaturedTeachings />}
{count > 0 ? <ContinueListening /> : <FeaturedTeachings />}
<RecentTeachings />
<Topics />
<Presenters
Expand Down
5 changes: 4 additions & 1 deletion src/lib/api/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@ export const USER_SESSION_QUERY_KEYS = [
['isSequenceFavorited'],
['sequenceIsFavorited'],
['isSponsorFavorited'],
['getDiscoverPageData'],
['getSectionContinueListening'],
['getSectionContinueListening.infinite'],
];

export async function resetUserQueries(
queryClient: QueryClient
): Promise<void> {
await Promise.all(
USER_SESSION_QUERY_KEYS.map((key) => queryClient.resetQueries(key))
USER_SESSION_QUERY_KEYS.map((key) => queryClient.removeQueries(key))
);
}

Expand Down
3 changes: 2 additions & 1 deletion src/lib/hooks/useIsAuthenticated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import { useGetWithAuthGuardDataQuery } from '~components/HOCs/__generated__/wit
import { getSessionToken } from '~lib/cookies';

import { GetWithAuthGuardDataQuery } from '../__generated__/useIsAuthenticated';
import { getCurrentRequest } from '../api/storeRequest';

export default function useIsAuthenticated(): UseQueryResult<
GetWithAuthGuardDataQuery,
unknown
> & {
isUserLoggedIn: boolean;
} {
const token = getSessionToken();
const token = getSessionToken(getCurrentRequest());
const result = useGetWithAuthGuardDataQuery(
{},
{ retry: false, enabled: !!token }
Expand Down
56 changes: 18 additions & 38 deletions src/pages/[language]/discover/index.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,27 @@
import { DehydratedState } from '@tanstack/react-query';
import {
GetStaticPathsResult,
GetStaticPropsContext,
GetStaticPropsResult,
} from 'next';
import { GetServerSidePropsContext } from 'next';

import { IBaseProps } from '~containers/base';
import { REVALIDATE } from '~lib/constants';
import getIntl from '~lib/getIntl';
import { getLanguageIdByRoute } from '~lib/getLanguageIdByRoute';
import { getLanguageRoutes } from '~lib/getLanguageRoutes';
import root from '~lib/routes';
import { prefetchQueries } from '~src/__generated__/prefetch';
import Discover from '~src/containers/discover';
import serializableDehydrate from '~src/lib/serializableDehydrate';
import { storeRequest } from '~src/lib/api/storeRequest';
import getDehydratedProps, {
DehydratedProps,
} from '~src/lib/getDehydratedProps';

export default Discover;

export async function getStaticProps({
export async function getServerSideProps({
params,
}: GetStaticPropsContext<{ language: string }>): Promise<
GetStaticPropsResult<
{
dehydratedState: DehydratedState;
} & IBaseProps
>
> {
req,
}: GetServerSidePropsContext<{ language: string }>): Promise<DehydratedProps> {
storeRequest(req);

const language = getLanguageIdByRoute(params?.language);
const intl = await getIntl(language);
const client = await prefetchQueries({
getDiscoverPageData: { language },
getSectionContinueListening: { language },
getSectionRecentTeachings: { language },
getSectionTrendingTeachings: { language },
getSectionFeaturedTeachings: { language },
Expand All @@ -42,23 +35,10 @@ export async function getStaticProps({
getSectionTrendingMusic: { language },
});

return {
props: {
title: intl.formatMessage({
id: 'discover__title',
defaultMessage: 'Discover',
}),
dehydratedState: serializableDehydrate(client),
},
revalidate: REVALIDATE,
};
}

export async function getStaticPaths(): Promise<GetStaticPathsResult> {
return {
paths: getLanguageRoutes().map((base_url) =>
root.lang(base_url).discover.get()
),
fallback: false,
};
return getDehydratedProps(client, {
title: intl.formatMessage({
id: 'discover__title',
defaultMessage: 'Discover',
}),
});
}

0 comments on commit c63a3f7

Please sign in to comment.