diff --git a/.gitignore b/.gitignore index 84c5d7d1e..9506d554d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ /graphql-codegen/dist **/__generated__ **/__generated__/** +.temp* # next-pwa /public/sw.js diff --git a/src/components/organisms/passageNavigation/bookGrid.tsx b/src/components/organisms/passageNavigation/bookGrid.tsx index 0e7343c6a..ee3952668 100644 --- a/src/components/organisms/passageNavigation/bookGrid.tsx +++ b/src/components/organisms/passageNavigation/bookGrid.tsx @@ -2,12 +2,11 @@ import clsx from 'clsx'; import React from 'react'; import { Book } from '.'; -import { PassageNavigationFragment } from './__generated__/index'; import styles from './bookGrid.module.scss'; import ChapterGrid, { ChapterId } from './chapterGrid'; type Props = { - books: Array; + books: Array; selectedBook: Book; selectBook: (book: Book) => void; chapterId: ChapterId; diff --git a/src/components/organisms/passageNavigation/bookList.tsx b/src/components/organisms/passageNavigation/bookList.tsx index 13efdf2ae..fb19693ad 100644 --- a/src/components/organisms/passageNavigation/bookList.tsx +++ b/src/components/organisms/passageNavigation/bookList.tsx @@ -2,12 +2,11 @@ import clsx from 'clsx'; import React from 'react'; import { Book } from '.'; -import { PassageNavigationFragment } from './__generated__/index'; import styles from './bookList.module.scss'; import ChapterGrid, { ChapterId } from './chapterGrid'; type Props = { - books: Array; + books: Array; selectedBook: Book; selectBook: (book: Book) => void; chapterId: ChapterId; diff --git a/src/components/organisms/passageNavigation/chapterGrid.tsx b/src/components/organisms/passageNavigation/chapterGrid.tsx index dd9f65ba2..4ff8b968a 100644 --- a/src/components/organisms/passageNavigation/chapterGrid.tsx +++ b/src/components/organisms/passageNavigation/chapterGrid.tsx @@ -2,10 +2,9 @@ import React from 'react'; import Link from '~components/atoms/linkWithoutPrefetch'; -import { PassageNavigationFragment } from './__generated__/index'; +import { Chapter } from '.'; import styles from './chapterGrid.module.scss'; -type Chapter = NonNullable[0]; export type ChapterId = Chapter['id'] | null; type Props = { diff --git a/src/components/organisms/passageNavigation/index.graphql b/src/components/organisms/passageNavigation/index.graphql index 84c27e73e..6a9081a7f 100644 --- a/src/components/organisms/passageNavigation/index.graphql +++ b/src/components/organisms/passageNavigation/index.graphql @@ -1,11 +1,29 @@ -fragment passageNavigation on Sequence { +fragment passageNavigationChapter on Recording { + id + title + canonicalPath(useFuturePath: true) + collection { + id + contentType + } +} + +fragment passageNavigationBook on Sequence { id title recordings(first: 150) { nodes { - id - title - ...andMiniplayer + ...passageNavigationChapter + } + } +} + +fragment passageNavigationVersion on Collection { + id + title + sequences { + nodes { + ...passageNavigationBook } } } diff --git a/src/components/organisms/passageNavigation/index.tsx b/src/components/organisms/passageNavigation/index.tsx index cdf7b9f48..d01f24826 100644 --- a/src/components/organisms/passageNavigation/index.tsx +++ b/src/components/organisms/passageNavigation/index.tsx @@ -18,20 +18,28 @@ import BibleVersionTypeLockup from '~src/components/molecules/bibleVersionTypeLo import Button from '~src/components/molecules/button'; import Dropdown from '~src/components/molecules/dropdown'; import { PlaybackContext } from '~src/components/templates/andPlaybackContext'; -import { GetAudiobibleIndexDataQuery } from '~src/containers/bible/__generated__'; import { BIBLE_BOOKS } from '~src/lib/constants'; import { getBibleAcronym } from '~src/lib/getBibleAcronym'; import { useLocalStorage } from '~src/lib/hooks/useLocalStorage'; +import { + PassageNavigationBookFragment, + PassageNavigationChapterFragment, + PassageNavigationVersionFragment, +} from './__generated__'; import BookGrid from './bookGrid'; import BookList from './bookList'; import styles from './index.module.scss'; -export type Version = NonNullable< - GetAudiobibleIndexDataQuery['collections']['nodes'] ->[0]; -export type Book = NonNullable[0]; -export type Chapter = NonNullable[0]; +// export type Version = NonNullable< +// GetAudiobibleIndexDataQuery['collections']['nodes'] +// >[0]; +// export type Book = NonNullable[0]; +// export type Chapter = NonNullable[0]; + +export type Version = PassageNavigationVersionFragment; +export type Book = PassageNavigationBookFragment; +export type Chapter = PassageNavigationChapterFragment; type Props = { versions: Array; diff --git a/src/containers/bible/index.graphql b/src/containers/bible/index.graphql index e49df25b3..8f84e5e3b 100644 --- a/src/containers/bible/index.graphql +++ b/src/containers/bible/index.graphql @@ -10,7 +10,7 @@ query getAudiobibleIndexData($language: Language!) { title sequences(first: 66, orderBy: [{ field: ID, direction: ASC }]) { nodes { - ...passageNavigation + ...passageNavigationBook } } } diff --git a/src/lib/api/fetchApi.ts b/src/lib/api/fetchApi.ts index 2eb350296..4bc6e8e43 100644 --- a/src/lib/api/fetchApi.ts +++ b/src/lib/api/fetchApi.ts @@ -1,3 +1,5 @@ +import pMemoize from 'p-memoize'; + import { getCurrentRequest } from '~lib/api/storeRequest'; import { getSessionToken } from '~lib/cookies'; import { sleep } from '~lib/sleep'; @@ -21,6 +23,53 @@ async function getResponse( }); } +const fetchJson = pMemoize( + async ({ + headers, + query, + variables, + }: { + headers: HeadersInit; + query: string; + variables: unknown; + }) => { + let res = await getResponse(headers, query, variables); + let text = await res.text(); + + if (!res.ok) { + await sleep({ ms: 10000 }); + res = await getResponse(headers, query, variables); + text = await res.text(); + } + + if (!res.ok) { + console.error({ text, res, query, variables, headers }); + throw new Error(`HTTP request failed: ${res.status} ${res.statusText}`); + } + + let json; + + try { + json = JSON.parse(text); + } catch (error) { + console.error({ error, text, res, query, variables, headers }); + throw error; + } + + if (json.errors) { + console.error({ + query, + variables, + headers, + errors: json.errors, + }); + throw json; + } + + return json.data; + }, +); + export async function fetchApi( query: string, { variables = {} } = {}, @@ -34,38 +83,5 @@ export async function fetchApi( headers['x-av-session'] = sessionToken; } - let res = await getResponse(headers, query, variables); - let text = await res.text(); - - if (!res.ok) { - await sleep({ ms: 10000 }); - res = await getResponse(headers, query, variables); - text = await res.text(); - } - - if (!res.ok) { - console.error({ text, res, query, variables, headers }); - throw new Error(`HTTP request failed: ${res.status} ${res.statusText}`); - } - - let json; - - try { - json = JSON.parse(text); - } catch (error) { - console.error({ error, text, res, query, variables, headers }); - throw error; - } - - if (json.errors) { - console.error({ - query, - variables, - headers, - errors: json.errors, - }); - throw json; - } - - return json.data; + return fetchJson({ headers, query, variables }); } diff --git a/src/lib/getBibles.ts b/src/lib/getBibles.ts index f013e20f1..e1e6243a3 100644 --- a/src/lib/getBibles.ts +++ b/src/lib/getBibles.ts @@ -1,9 +1,6 @@ -import { - CollectionContentType, - Language, - RecordingContentType, - SequenceContentType, -} from '~src/__generated__/graphql'; +import pMemoize from 'p-memoize'; + +import { CollectionContentType, Language } from '~src/__generated__/graphql'; import { BibleIndexProps } from '~src/containers/bible'; import { getAudiobibleIndexData } from '~src/containers/bible/__generated__'; import { BOOK_ID_MAP } from '~src/services/fcbh/constants'; @@ -49,23 +46,10 @@ async function transform( .bookId(bookId) .chapterNumber(bbChapter.number) .get(), - duration: bbChapter.duration, - recordingContentType: RecordingContentType.BibleChapter, - sequence: { - id: bbChapter.id, - title, - contentType: SequenceContentType.BibleBook, - }, - audioFiles: [], - videoFiles: [], - videoStreams: [], collection: { id: bible.id, - title: bible.title, contentType: CollectionContentType.BibleVersion, }, - speakers: [], - sponsor: null, }; }, ); @@ -121,10 +105,20 @@ function concatBibles( ); } -export default async function getBibles(languageId: Language) { - const fcbh = await getFcbhBibles(languageId); - const api = await getApiBibles(languageId); - const all = concatBibles(fcbh, api); +const getBibles = pMemoize( + async ( + languageId: Language, + ): Promise<{ + fcbh: ApiBible[] | null; + api: ApiBible[] | null; + all: ApiBible[]; + }> => { + const fcbh = await getFcbhBibles(languageId); + const api = await getApiBibles(languageId); + const all = concatBibles(fcbh, api); - return { fcbh, api, all }; -} + return { fcbh, api, all }; + }, +); + +export default getBibles; diff --git a/src/pages/[language]/bibles/index.tsx b/src/pages/[language]/bibles/index.tsx index f68a57ebe..ce87f7e83 100644 --- a/src/pages/[language]/bibles/index.tsx +++ b/src/pages/[language]/bibles/index.tsx @@ -1,3 +1,4 @@ +// import fs from 'fs'; import { GetStaticPathsResult, GetStaticPropsContext, @@ -31,6 +32,10 @@ export async function getStaticProps({ }; } + // write `all` to a file + // fs.writeFileSync('.temp.bibles.json', JSON.stringify(all, null, 2)); + // throw new Error('write `all` to a file'); + return { props: { versions: all,