From ec46821808227ffde9756def1966e701b0fc5427 Mon Sep 17 00:00:00 2001 From: Harjot Singh Date: Sat, 20 Apr 2024 03:44:11 +0100 Subject: [PATCH] feat: add title to banis Restructure content templates Closes #287 --- .../templates/Content/Bani/index.tsx | 38 ++++++++++++ .../Line.spec.tsx | 0 .../{DefaultLines => GroupedLines}/Line.tsx | 0 .../index.spec.tsx | 6 +- .../{DefaultLines => GroupedLines}/index.tsx | 5 +- .../templates/Content/Lines/index.spec.tsx | 37 ++++++++++++ .../templates/Content/Lines/index.tsx | 22 +++++++ .../templates/Content/ReaderLines/index.tsx | 6 +- .../templates/Content/Shabad/index.tsx | 22 +++++++ .../templates/Content/index.int.spec.tsx | 59 ------------------- src/components/templates/Content/index.tsx | 47 +++++---------- src/services/data/banis.ts | 7 +++ src/services/data/shabads.ts | 7 +++ src/services/kv-storage/index.ts | 1 + src/with-contexts.tsx | 5 +- test/providers/AtomProvider.tsx | 29 +++++++++ 16 files changed, 191 insertions(+), 100 deletions(-) create mode 100644 src/components/templates/Content/Bani/index.tsx rename src/components/templates/Content/{DefaultLines => GroupedLines}/Line.spec.tsx (100%) rename src/components/templates/Content/{DefaultLines => GroupedLines}/Line.tsx (100%) rename src/components/templates/Content/{DefaultLines => GroupedLines}/index.spec.tsx (74%) rename src/components/templates/Content/{DefaultLines => GroupedLines}/index.tsx (85%) create mode 100644 src/components/templates/Content/Lines/index.spec.tsx create mode 100644 src/components/templates/Content/Lines/index.tsx create mode 100644 src/components/templates/Content/Shabad/index.tsx delete mode 100644 src/components/templates/Content/index.int.spec.tsx create mode 100644 test/providers/AtomProvider.tsx diff --git a/src/components/templates/Content/Bani/index.tsx b/src/components/templates/Content/Bani/index.tsx new file mode 100644 index 00000000..d07b5a1a --- /dev/null +++ b/src/components/templates/Content/Bani/index.tsx @@ -0,0 +1,38 @@ +import { useSuspenseQuery } from '@tanstack/react-query' +import { StyleSheet } from 'react-native' + +import Container from '~/components/atoms/Container' +import GurmukhiLine from '~/components/molecules/GurmukhiLine' +import { baniQuery } from '~/services/data' +import { units } from '~/themes' + +import Lines from '../Lines' + +const styles = StyleSheet.create( { + header: { + textAlign: 'center', + fontSize: units.title1, + paddingTop: units.base * 2, + }, +} ) + +type BaniProps = { + id: string, +} + +const Bani = ( { id }: BaniProps ) => { + const { data } = useSuspenseQuery( baniQuery( id ) ) + + const header = {data.nameGurmukhi} + + return ( + + header} + lines={data.lines} + /> + + ) +} + +export default Bani diff --git a/src/components/templates/Content/DefaultLines/Line.spec.tsx b/src/components/templates/Content/GroupedLines/Line.spec.tsx similarity index 100% rename from src/components/templates/Content/DefaultLines/Line.spec.tsx rename to src/components/templates/Content/GroupedLines/Line.spec.tsx diff --git a/src/components/templates/Content/DefaultLines/Line.tsx b/src/components/templates/Content/GroupedLines/Line.tsx similarity index 100% rename from src/components/templates/Content/DefaultLines/Line.tsx rename to src/components/templates/Content/GroupedLines/Line.tsx diff --git a/src/components/templates/Content/DefaultLines/index.spec.tsx b/src/components/templates/Content/GroupedLines/index.spec.tsx similarity index 74% rename from src/components/templates/Content/DefaultLines/index.spec.tsx rename to src/components/templates/Content/GroupedLines/index.spec.tsx index 391c9890..9d2afcad 100644 --- a/src/components/templates/Content/DefaultLines/index.spec.tsx +++ b/src/components/templates/Content/GroupedLines/index.spec.tsx @@ -3,13 +3,13 @@ import { toUnicode } from 'gurmukhi-utils' import * as factories from '~/test/factories' -import DefaultLines from '.' +import GroupedLines from '.' -describe( '', () => { +describe( '', () => { const lines = factories.line.buildList( 15 ) it( 'should render lines', () => { - render( ) + render( ) expect( screen.queryByText( toUnicode( lines[ 0 ].gurmukhi ) ) ).toBeTruthy() } ) diff --git a/src/components/templates/Content/DefaultLines/index.tsx b/src/components/templates/Content/GroupedLines/index.tsx similarity index 85% rename from src/components/templates/Content/DefaultLines/index.tsx rename to src/components/templates/Content/GroupedLines/index.tsx index b878230c..0eb34f60 100644 --- a/src/components/templates/Content/DefaultLines/index.tsx +++ b/src/components/templates/Content/GroupedLines/index.tsx @@ -1,4 +1,5 @@ import { FlashList } from '@shopify/flash-list' +import { ComponentType } from 'react' import { StyleSheet, View } from 'react-native' import { units } from '~/themes' @@ -30,14 +31,16 @@ const renderLine = ( { item: { gurmukhi, translations } }: RenderItem ) => ( ) export type NormalLinesProps = { + Header?: ComponentType, lines: LineData[], } -const NormalLines = ( { lines }: NormalLinesProps ) => ( +const NormalLines = ( { lines, Header }: NormalLinesProps ) => ( id} + ListHeaderComponent={Header} data={lines} renderItem={renderLine} estimatedItemSize={120} diff --git a/src/components/templates/Content/Lines/index.spec.tsx b/src/components/templates/Content/Lines/index.spec.tsx new file mode 100644 index 00000000..d84427b2 --- /dev/null +++ b/src/components/templates/Content/Lines/index.spec.tsx @@ -0,0 +1,37 @@ +import { render, screen } from '@testing-library/react-native' + +import { settings } from '~/services/settings' +import * as factories from '~/test/factories' +import AtomProvider from '~/test/providers/AtomProvider' + +import Lines from '.' + +describe( '', () => { + describe( 'given reader mode is off', () => { + it( 'should load and render lines in grouped mode', () => { + const lines = factories.line.buildList( 15 ) + + render( + + + + ) + + expect( screen.queryByText( lines[ 0 ].translations[ 0 ].translation ) ).toBeTruthy() + } ) + } ) + + describe( 'given reader mode is on', () => { + it( 'should load and render lines in reader mode', () => { + const lines = factories.line.buildList( 15 ) + + render( + + + + ) + + expect( screen.queryByText( lines[ 0 ].translations[ 0 ].translation ) ).toBeFalsy() + } ) + } ) +} ) diff --git a/src/components/templates/Content/Lines/index.tsx b/src/components/templates/Content/Lines/index.tsx new file mode 100644 index 00000000..57d0dc36 --- /dev/null +++ b/src/components/templates/Content/Lines/index.tsx @@ -0,0 +1,22 @@ +import { ComponentType } from 'react' + +import { settings, useSetting } from '~/services/settings' +import { LineData } from '~/types/data' + +import GroupedLines from '../GroupedLines' +import ReaderLines from '../ReaderLines' + +type LinesProps = { + lines: LineData[], + Header?: ComponentType, +} + +const Lines = ( { lines, Header }: LinesProps ) => { + const [ isReaderMode ] = useSetting( settings.readerMode ) + + return isReaderMode + ? + : +} + +export default Lines diff --git a/src/components/templates/Content/ReaderLines/index.tsx b/src/components/templates/Content/ReaderLines/index.tsx index a8db72b6..7bc5fb2d 100644 --- a/src/components/templates/Content/ReaderLines/index.tsx +++ b/src/components/templates/Content/ReaderLines/index.tsx @@ -1,5 +1,5 @@ import { FlashList } from '@shopify/flash-list' -import { useMemo } from 'react' +import { ComponentType, useMemo } from 'react' import { StyleSheet, View } from 'react-native' import { getLineSections } from '~/helpers/lines' @@ -19,14 +19,16 @@ const renderLineSection = ( { item }: RenderItem ) =>
export type ReaderLinesProps = { lines: LineData[], + Header?: ComponentType, } -const ReaderLines = ( { lines }: ReaderLinesProps ) => { +const ReaderLines = ( { lines, Header }: ReaderLinesProps ) => { const groupedLines = useMemo( () => getLineSections( lines ), [ lines ] ) return ( { + const { data } = useSuspenseQuery( shabadQuery( id ) ) + + return ( + + + + ) +} + +export default Shabad diff --git a/src/components/templates/Content/index.int.spec.tsx b/src/components/templates/Content/index.int.spec.tsx deleted file mode 100644 index 62056cf1..00000000 --- a/src/components/templates/Content/index.int.spec.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { render, screen, waitForElementToBeRemoved } from '@testing-library/react-native' -import { toUnicode } from 'gurmukhi-utils' -import { atom } from 'jotai' -import { Suspense } from 'react' -import { Text } from 'react-native' - -import * as shabads from '~/services/data/shabads' -import { settings } from '~/services/settings' -import * as factories from '~/test/factories' -import { wrapperOptions } from '~/test/utils/wrapper' -import { ShabadData } from '~/types/data' - -import ContentTemplate from '.' - -type SetupOptions = { - shabad?: ShabadData, - readerMode?: boolean, -} - -const setup = async ( { - shabad = factories.shabad.build(), - readerMode = false, -}: SetupOptions = {} ) => { - settings.readerMode = atom( readerMode ) - jest.spyOn( shabads, 'getShabad' ).mockResolvedValue( shabad ) - - const container = render( - Loading}> - - , - wrapperOptions( { navigationContainer: true } ) - ) - - await waitForElementToBeRemoved( () => screen.queryByText( 'Loading' ) ) - - return container -} - -describe( '', () => { - describe( 'on mount', () => { - it( 'should load and render a target shabad', async () => { - const shabad = factories.shabad.build() - await setup( { shabad } ) - - expect( await screen.findByText( toUnicode( shabad.lines[ 0 ].gurmukhi ) ) ).toBeTruthy() - expect( screen.queryByText( shabad.lines[ 0 ].translations[ 0 ].translation ) ).toBeTruthy() - } ) - } ) - - describe( 'given reader mode is enabled', () => { - it( 'should load and render a target shabad in reader mode', async () => { - const shabad = factories.shabad.build() - await setup( { shabad, readerMode: true } ) - - expect( await screen.findByText( toUnicode( shabad.lines[ 0 ].gurmukhi ) ) ).toBeTruthy() - expect( screen.queryByText( shabad.lines[ 0 ].translations[ 0 ].translation ) ).toBeFalsy() - } ) - } ) -} ) diff --git a/src/components/templates/Content/index.tsx b/src/components/templates/Content/index.tsx index 9b252ef2..6ebe221e 100644 --- a/src/components/templates/Content/index.tsx +++ b/src/components/templates/Content/index.tsx @@ -1,46 +1,27 @@ -import { useSuspenseQuery } from '@tanstack/react-query' +import { ComponentType } from 'react' -import Container from '~/components/atoms/Container' -import { getBani, getShabad } from '~/services/data' -import { settings, useSetting } from '~/services/settings' -import { ContentType, LineData } from '~/types/data' +import Empty from '~/components/atoms/Empty' +import { ContentType } from '~/types/data' -import DefaultLines from './DefaultLines' -import ReaderLines from './ReaderLines' +import Bani from './Bani' +import Shabad from './Shabad' -type Loaders = { - [screen in ContentType]: ( id: string ) => Promise<{ id: string, lines: LineData[] }> -} - -// ? Loaders return a common interface. Is there a better way to deal with specifics of each type? -const loaders: Loaders = { - shabad: ( id: string ) => getShabad( id ), - bani: ( id: string ) => getBani( id ), - ang: () => Promise.resolve( { id: '', lines: [] } ), -} +// Maybe these should be moved into their own standalone templates entirely +const templates = { + ang: Empty, + bani: Bani, + shabad: Shabad, +} satisfies Record> type ContentTemplateProps = { id: string, type: ContentType, } -const ContentTemplate = ( { - id, - type, -}: ContentTemplateProps ) => { - const { data } = useSuspenseQuery( { - queryKey: [ 'content', type, id ], - queryFn: () => loaders[ type ]( id ), - } ) - - const [ isReaderMode ] = useSetting( settings.readerMode ) - const Lines = isReaderMode ? ReaderLines : DefaultLines +const ContentTemplate = ( { id, type }: ContentTemplateProps ) => { + const Template = templates[ type ] - return ( - - - - ) + return