From 1d1327d3404a9ee99ab49e56dda9dba2d2d0a9e5 Mon Sep 17 00:00:00 2001 From: Adam Iskounen Date: Fri, 20 Dec 2024 12:56:01 -0500 Subject: [PATCH] refactored a bit --- ios/Podfile.lock | 4 +- .../InfiniteDiscovery/InfiniteDiscovery.tsx | 67 +++++++------ .../InfiniteDiscoveryContext.ts | 29 +++--- .../__tests__/InfiniteDiscovery.tests.tsx | 98 ++++++++++++------- .../InfiniteDiscoveryContext.tests.tsx | 40 ++++---- 5 files changed, 132 insertions(+), 106 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index dde544f0c29..392d904da74 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2703,7 +2703,7 @@ SPEC CHECKSUMS: GTMAppAuth: 99fb010047ba3973b7026e45393f51f27ab965ae GTMSessionFetcher: 0e876eea9782ec6462e91ab872711c357322c94f hermes-engine: ea92f60f37dba025e293cbe4b4a548fd26b610a0 - Interstellar: cd0c3290e249b5f156113a4c6c9c09dd0f418aaa + Interstellar: ab67502af03105f92100a043e178d188a1a437c9 INTUAnimationEngine: 3a7d63738cd51af573d16848a771feedea7cc9f2 iOSSnapshotTestCase: a670511f9ee3829c2b9c23e6e68f315fd7b6790f ISO8601DateFormatter: 8311a2d4e265b269b2fed7ab4db685dcb0a7ccb2 @@ -2729,7 +2729,7 @@ SPEC CHECKSUMS: PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 Pulley: edc993fb57f7eb20541c8453d0fce10559f21dac Quick: ce1276c7c27ba2da3cb2fd0cde053c3648b3b22d - RCT-Folly: 34124ae2e667a0e5f0ea378db071d27548124321 + RCT-Folly: 4464f4d875961fce86008d45f4ecf6cef6de0740 RCTDeprecation: 726d24248aeab6d7180dac71a936bbca6a994ed1 RCTRequired: a94e7febda6db0345d207e854323c37e3a31d93b RCTTypeSafety: 28e24a6e44f5cbf912c66dde6ab7e07d1059a205 diff --git a/src/app/Scenes/InfiniteDiscovery/InfiniteDiscovery.tsx b/src/app/Scenes/InfiniteDiscovery/InfiniteDiscovery.tsx index bfb04f8a381..c982713148d 100644 --- a/src/app/Scenes/InfiniteDiscovery/InfiniteDiscovery.tsx +++ b/src/app/Scenes/InfiniteDiscovery/InfiniteDiscovery.tsx @@ -4,6 +4,7 @@ import { Flex, Image, Screen, + Spacer, Text, Touchable, useScreenDimensions, @@ -14,13 +15,14 @@ import { FancySwiper } from "app/Components/FancySwiper/FancySwiper" import { Card } from "app/Components/FancySwiper/FancySwiperCard" import { InfiniteDiscoveryContext } from "app/Scenes/InfiniteDiscovery/InfiniteDiscoveryContext" import { navigate } from "app/system/navigation/navigate" -import { useEffect } from "react" +import { extractNodes } from "app/utils/extractNodes" +import { NoFallback, withSuspense } from "app/utils/hooks/withSuspense" import { graphql, useLazyLoadQuery } from "react-relay" export const InfiniteDiscoveryView: React.FC = () => { return ( - + ) } @@ -29,30 +31,16 @@ export const InfiniteDiscovery: React.FC = () => { const { color } = useTheme() const { width: screenWidth } = useScreenDimensions() - const data = useLazyLoadQuery(infiniteDiscoveryQuery, {}) - - const artworks = InfiniteDiscoveryContext.useStoreState((state) => state.artworks) - const currentArtworkIndex = InfiniteDiscoveryContext.useStoreState( - (state) => state.currentArtworkIndex - ) - const goToPreviousArtwork = InfiniteDiscoveryContext.useStoreActions( - (action) => action.goToPreviousArtwork - ) - const goToNextArtwork = InfiniteDiscoveryContext.useStoreActions( - (actions) => actions.goToNextArtwork - ) - const setArtworks = InfiniteDiscoveryContext.useStoreActions((actions) => actions.setArtworks) + const currentIndex = InfiniteDiscoveryContext.useStoreState((state) => state.currentIndex) + const goToPrevious = InfiniteDiscoveryContext.useStoreActions((action) => action.goToPrevious) + const goToNext = InfiniteDiscoveryContext.useStoreActions((actions) => actions.goToNext) - useEffect(() => { - setArtworks( - (data.marketingCollection?.artworksConnection?.edges?.map((edge) => edge?.node) as any) || [] - ) - }, [data]) + const data = useLazyLoadQuery(infiniteDiscoveryQuery, {}) - const canGoBack = currentArtworkIndex > 0 + const artworks = extractNodes(data.marketingCollection?.artworksConnection) const handleBackPressed = () => { - goToPreviousArtwork() + goToPrevious() } const handleExitPressed = () => { @@ -64,31 +52,36 @@ export const InfiniteDiscovery: React.FC = () => { } const handleSwipedLeft = () => { - goToNextArtwork() + goToNext() } - const artworkCards: Card[] = artworks.slice(currentArtworkIndex).map((artwork) => { + const artworkCards: Card[] = artworks.map((artwork) => { return { jsx: ( - + {artwork.artistNames} - {artwork.artists[0].formattedNationalityAndBirthday} + {artwork?.artists?.[0]?.formattedNationalityAndBirthday} - + + - + {!!artwork?.images?.[0]?.url && ( + + )} @@ -121,7 +114,7 @@ export const InfiniteDiscovery: React.FC = () => { Back } - hideLeftElements={!canGoBack} + hideLeftElements={currentIndex === 0} rightElements={ Exit @@ -140,7 +133,13 @@ export const InfiniteDiscovery: React.FC = () => { ) } -const infiniteDiscoveryQuery = graphql` +export const InfiniteDiscoveryWithSuspense = withSuspense({ + Component: InfiniteDiscovery, + LoadingFallback: () => Loading..., + ErrorFallback: NoFallback, +}) + +export const infiniteDiscoveryQuery = graphql` query InfiniteDiscoveryQuery { marketingCollection(slug: "curators-picks") { artworksConnection(first: 10) { @@ -148,8 +147,6 @@ const infiniteDiscoveryQuery = graphql` node { artistNames artists(shallow: true) { - initials - formattedNationalityAndBirthday coverArtwork { image { cropped(height: 45, width: 45) { @@ -157,6 +154,8 @@ const infiniteDiscoveryQuery = graphql` } } } + formattedNationalityAndBirthday + initials } date internalID diff --git a/src/app/Scenes/InfiniteDiscovery/InfiniteDiscoveryContext.ts b/src/app/Scenes/InfiniteDiscovery/InfiniteDiscoveryContext.ts index 2963781decf..2df6f086ba8 100644 --- a/src/app/Scenes/InfiniteDiscovery/InfiniteDiscoveryContext.ts +++ b/src/app/Scenes/InfiniteDiscovery/InfiniteDiscoveryContext.ts @@ -1,29 +1,26 @@ import { action, Action, createContextStore } from "easy-peasy" export interface InfiniteDiscoveryContextModel { - artworks: any[] - currentArtworkIndex: number - goToPreviousArtwork: Action - goToNextArtwork: Action - setArtworks: Action + count: number + currentIndex: number + goToPrevious: Action + goToNext: Action } export const initialModel: InfiniteDiscoveryContextModel = { - artworks: [], - currentArtworkIndex: 0, - goToPreviousArtwork: action((state) => { - if (state.currentArtworkIndex > 0) { - state.currentArtworkIndex-- + // TODO: this needs to come from the result of the query + count: 10, + currentIndex: 0, + goToPrevious: action((state) => { + if (state.currentIndex > 0) { + state.currentIndex = state.currentIndex - 1 } }), - goToNextArtwork: action((state) => { - if (state.currentArtworkIndex < state.artworks.length - 1) { - state.currentArtworkIndex++ + goToNext: action((state) => { + if (state.currentIndex < state.count - 1) { + state.currentIndex = state.currentIndex + 1 } }), - setArtworks: action((state, artworks) => { - state.artworks = artworks - }), } export const InfiniteDiscoveryContext = createContextStore((runtimeModel) => { diff --git a/src/app/Scenes/InfiniteDiscovery/__tests__/InfiniteDiscovery.tests.tsx b/src/app/Scenes/InfiniteDiscovery/__tests__/InfiniteDiscovery.tests.tsx index 6c97c557f8f..9f3360e490d 100644 --- a/src/app/Scenes/InfiniteDiscovery/__tests__/InfiniteDiscovery.tests.tsx +++ b/src/app/Scenes/InfiniteDiscovery/__tests__/InfiniteDiscovery.tests.tsx @@ -1,8 +1,11 @@ import { fireEvent, screen } from "@testing-library/react-native" -import { InfiniteDiscovery } from "app/Scenes/InfiniteDiscovery/InfiniteDiscovery" +import { + infiniteDiscoveryQuery, + InfiniteDiscoveryWithSuspense, +} from "app/Scenes/InfiniteDiscovery/InfiniteDiscovery" import { InfiniteDiscoveryContext } from "app/Scenes/InfiniteDiscovery/InfiniteDiscoveryContext" import { navigate } from "app/system/navigation/navigate" -import { renderWithWrappers } from "app/utils/tests/renderWithWrappers" +import { setupTestWrapper } from "app/utils/tests/setupTestWrapper" import { action } from "easy-peasy" jest.mock("app/system/navigation/navigate") @@ -15,50 +18,77 @@ describe("InfiniteDiscovery", () => { }) it("shows the back button if the current artwork is not the first artwork", () => { - renderWithWrappers( - - - - ) + const { renderWithRelay } = setupTestWrapper({ + Component: () => ( + + + + ), + query: infiniteDiscoveryQuery, + }) + renderWithRelay() expect(screen.getByText("Back")).toBeOnTheScreen() }) it("hides the back button if the current artwork is on the first artwork", () => { - renderWithWrappers( - - - - ) + const { renderWithRelay } = setupTestWrapper({ + Component: () => ( + + + + ), + query: infiniteDiscoveryQuery, + }) + renderWithRelay() expect(screen.queryByText("Back")).not.toBeOnTheScreen() }) it("returns to the previous artwork when the back button is pressed", () => { - const mockGoToPreviousArtwork = jest.fn().mockImplementation() - renderWithWrappers( - - - - ) + const mockGoToPrevious = jest.fn().mockImplementation() + const { renderWithRelay } = setupTestWrapper({ + Component: () => ( + + + + ), + query: infiniteDiscoveryQuery, + }) + renderWithRelay() fireEvent.press(screen.getByText("Back")) - expect(mockGoToPreviousArtwork).toHaveBeenCalled() + expect(mockGoToPrevious).toHaveBeenCalled() }) it("navigates to home view when the exit button is pressed", () => { - renderWithWrappers( - - - - ) + const { renderWithRelay } = setupTestWrapper({ + Component: () => ( + + + + ), + query: infiniteDiscoveryQuery, + }) + renderWithRelay() fireEvent.press(screen.getByText("Exit")) expect(mockNavigate).toHaveBeenCalledWith("/home-view") }) diff --git a/src/app/Scenes/InfiniteDiscovery/__tests__/InfiniteDiscoveryContext.tests.tsx b/src/app/Scenes/InfiniteDiscovery/__tests__/InfiniteDiscoveryContext.tests.tsx index 23489f5de4c..ae11ad6b2f2 100644 --- a/src/app/Scenes/InfiniteDiscovery/__tests__/InfiniteDiscoveryContext.tests.tsx +++ b/src/app/Scenes/InfiniteDiscovery/__tests__/InfiniteDiscoveryContext.tests.tsx @@ -30,47 +30,47 @@ describe("InfiniteDiscoveryContext", () => { it("sets up intial state and action helpers", () => { const { getState, actions } = setup({}) - expect(Object.keys(getState())).toEqual(["artworks", "currentArtwork"]) - expect(Object.keys(actions)).toEqual(["goToPreviousArtwork", "goToNextArtwork"]) + expect(Object.keys(getState())).toEqual(["count", "currentIndex"]) + expect(Object.keys(actions)).toEqual(["goToPrevious", "goToNext"]) }) - describe("goToPreviousArtwork", () => { + describe("goToPrevious", () => { it("sets the current artwork to the previous one in the list of artworks", () => { const { getState, actions } = setup({ - artworks: ["1", "2", "3"], - currentArtwork: "2", + count: 3, + currentIndex: 2, }) - act(() => actions.goToPreviousArtwork()) - expect(getState().currentArtwork).toEqual("1") + act(() => actions.goToPrevious()) + expect(getState().currentIndex).toEqual(1) }) it("stops at the first artwork", () => { const { getState, actions } = setup({ - artworks: ["1", "2", "3"], - currentArtwork: "1", + count: 3, + currentIndex: 0, }) - act(() => actions.goToPreviousArtwork()) - expect(getState().currentArtwork).toEqual("1") + act(() => actions.goToPrevious()) + expect(getState().currentIndex).toEqual(0) }) }) - describe("goToNextArtwork", () => { + describe("goToNext", () => { it("sets the current artwork to the next one in the list of artworks", () => { const { getState, actions } = setup({ - artworks: ["1", "2", "3"], - currentArtwork: "2", + count: 3, + currentIndex: 1, }) - act(() => actions.goToNextArtwork()) - expect(getState().currentArtwork).toEqual("3") + act(() => actions.goToNext()) + expect(getState().currentIndex).toEqual(2) }) it("stops at the last artwork", () => { const { getState, actions } = setup({ - artworks: ["1", "2", "3"], - currentArtwork: "3", + count: 3, + currentIndex: 2, }) - act(() => actions.goToNextArtwork()) - expect(getState().currentArtwork).toEqual("3") + act(() => actions.goToNext()) + expect(getState().currentIndex).toEqual(2) }) }) })