From c3bcd944a2e1bde6a71c521aa9a4ee3893baccda Mon Sep 17 00:00:00 2001 From: Joshua Yoes Date: Tue, 11 Apr 2023 20:27:15 -0700 Subject: [PATCH 1/5] Update prettier to 2.8.7 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index bc453440..18b07c03 100644 --- a/package.json +++ b/package.json @@ -115,7 +115,7 @@ "mocha": "6", "patch-package": "6.4.7", "postinstall-prepare": "1.0.1", - "prettier": "2.6.2", + "prettier": "2.8.7", "query-string": "^7.0.1", "react-devtools-core": "4.24.7", "reactotron-core-client": "^2.8.10", diff --git a/yarn.lock b/yarn.lock index 96c5b308..8ba1f841 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11621,10 +11621,10 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== -prettier@2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032" - integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew== +prettier@2.8.7: + version "2.8.7" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.7.tgz#bb79fc8729308549d28fe3a98fce73d2c0656450" + integrity sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw== pretty-bytes@5.6.0: version "5.6.0" From a6c0ec7a02fe0029bf17e4eee16deda9d8eb4e2d Mon Sep 17 00:00:00 2001 From: Joshua Yoes Date: Tue, 11 Apr 2023 20:28:14 -0700 Subject: [PATCH 2/5] Run `yarn format` --- app/screens/ExploreScreen/ExploreScreen.tsx | 2 +- app/screens/InfoScreen/OurSponsorsScreen.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/screens/ExploreScreen/ExploreScreen.tsx b/app/screens/ExploreScreen/ExploreScreen.tsx index 057c1bdc..d8a7d9b6 100644 --- a/app/screens/ExploreScreen/ExploreScreen.tsx +++ b/app/screens/ExploreScreen/ExploreScreen.tsx @@ -21,7 +21,7 @@ import { groupBy } from "../../utils/groupBy" import { customSortObjectKeys } from "../../utils/customSort" const recommendationTypes = Object.values(WEBFLOW_MAP.recommendationType) -type RecommendationType = typeof recommendationTypes[number] +type RecommendationType = (typeof recommendationTypes)[number] type GroupedRecommendations = Record const initialRecs = recommendationTypes.reduce( diff --git a/app/screens/InfoScreen/OurSponsorsScreen.tsx b/app/screens/InfoScreen/OurSponsorsScreen.tsx index 3379a183..01ca95b1 100644 --- a/app/screens/InfoScreen/OurSponsorsScreen.tsx +++ b/app/screens/InfoScreen/OurSponsorsScreen.tsx @@ -18,7 +18,7 @@ import { SponsorCard } from "./SponsorCard" import { groupBy } from "../../utils/groupBy" const sponsorTiers = Object.values(WEBFLOW_MAP.sponsorTier) -type Tiers = typeof sponsorTiers[number] +type Tiers = (typeof sponsorTiers)[number] const initialTiers = sponsorTiers.reduce>( (acc, tier) => ({ ...acc, [tier]: [] }), From 947e6f9d539bca0ed9b466ed8219387806b35351 Mon Sep 17 00:00:00 2001 From: Joshua Yoes Date: Tue, 11 Apr 2023 20:35:10 -0700 Subject: [PATCH 3/5] Seperate hooks and queryOptions, add prefetchScheduledEvents --- app/services/api/webflow-api.ts | 131 ++++++++++++++++++++++---------- 1 file changed, 91 insertions(+), 40 deletions(-) diff --git a/app/services/api/webflow-api.ts b/app/services/api/webflow-api.ts index a8a48121..a127f5a4 100644 --- a/app/services/api/webflow-api.ts +++ b/app/services/api/webflow-api.ts @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query" +import { useQueries, useQuery, UseQueryOptions } from "@tanstack/react-query" import { Schedule } from "../../screens" import { axiosInstance, PaginatedItems } from "./axios" import type { @@ -31,76 +31,127 @@ import { cleanedWorkshops, convertScheduleToScheduleCard, } from "./webflow-helpers" +import { queryClient } from "./react-query" -const useWebflowAPI = (key: string, collectionId: string, enabled = true) => - useQuery({ - queryKey: [key], - queryFn: async () => { - const { data } = await axiosInstance.get>( - `/collections/${collectionId}/items`, - ) - return data.items - }, - enabled, - }) +const getCollectionById = async (collectionId: string) => { + const { data } = await axiosInstance.get>(`/collections/${collectionId}/items`) + return data.items +} + +const useRecommendationsOptions = { + queryKey: [RECOMMENDATIONS.key, RECOMMENDATIONS.collectionId], + queryFn: async () => getCollectionById(RECOMMENDATIONS.collectionId), +} satisfies UseQueryOptions export const useRecommendations = () => { - return useWebflowAPI(RECOMMENDATIONS.key, RECOMMENDATIONS.collectionId) + return useQuery(useRecommendationsOptions) } +const useRecurringEventsOptions = { + queryKey: [RECURRING_EVENTS.key, RECURRING_EVENTS.collectionId], + queryFn: async () => getCollectionById(RECURRING_EVENTS.collectionId), +} satisfies UseQueryOptions + export const useRecurringEvents = () => { - return useWebflowAPI(RECURRING_EVENTS.key, RECURRING_EVENTS.collectionId) + return useQuery(useRecurringEventsOptions) } +const useSpeakersOptions = { + queryKey: [SPEAKERS.key, SPEAKERS.collectionId], + queryFn: async () => getCollectionById(SPEAKERS.collectionId), +} satisfies UseQueryOptions + export const useSpeakers = () => { - return useWebflowAPI(SPEAKERS.key, SPEAKERS.collectionId) + return useQuery(useSpeakersOptions) } +const useSpeakerNamesOptions = { + queryKey: [SPEAKER_NAMES.key, SPEAKER_NAMES.collectionId], + queryFn: async () => getCollectionById(SPEAKER_NAMES.collectionId), +} satisfies UseQueryOptions + export const useSpeakerNames = () => { - return useWebflowAPI(SPEAKER_NAMES.key, SPEAKER_NAMES.collectionId) + return useQuery(useSpeakerNamesOptions) } -export const useSponsors = (): { isLoading: boolean; data: RawSponsor[] } => { - const { data: sponsors, isLoading } = useWebflowAPI( - SPONSORS.key, - SPONSORS.collectionId, - ) +const useSponsorsOptions = { + queryKey: [SPONSORS.key, SPONSORS.collectionId], + queryFn: async () => getCollectionById(SPONSORS.collectionId), +} satisfies UseQueryOptions + +export const useSponsors = () => { + const { data: sponsors, isLoading } = useQuery(useSponsorsOptions) const data = cleanedSponsors(sponsors) return { isLoading, data } } + +const useTalksOptions = { + queryKey: [TALKS.key, TALKS.collectionId], + queryFn: async () => getCollectionById(TALKS.collectionId), +} satisfies UseQueryOptions + export const useTalks = () => { - return useWebflowAPI(TALKS.key, TALKS.collectionId) + return useQuery(useTalksOptions) } +const useVenuesOptions = { + queryKey: [VENUES.key, VENUES.collectionId], + queryFn: async () => getCollectionById(VENUES.collectionId), +} satisfies UseQueryOptions + export const useVenues = () => { - return useWebflowAPI(VENUES.key, VENUES.collectionId) + return useQuery(useVenuesOptions) } +const useWorkshopsOptions = { + queryKey: [WORKSHOPS.key, WORKSHOPS.collectionId], + queryFn: async () => getCollectionById(WORKSHOPS.collectionId), +} satisfies UseQueryOptions + export const useWorkshops = () => { - return useWebflowAPI(WORKSHOPS.key, WORKSHOPS.collectionId) + return useQuery(useWorkshopsOptions) } -export const useScheduledEvents = () => { - const { data: speakers, isLoading } = useSpeakers() - const { data: workshops } = useWorkshops() - const { data: recurringEvents } = useRecurringEvents() - const { data: talks } = useTalks() - const { data: scheduledEvents, ...rest } = useWebflowAPI( - SCHEDULE.key, - SCHEDULE.collectionId, - !isLoading && !!speakers && !!workshops && !!recurringEvents && !!talks, +const useScheduledEventsOptions = { + queryKey: [SCHEDULE.key, SCHEDULE.collectionId], + queryFn: async () => getCollectionById(SCHEDULE.collectionId), +} satisfies UseQueryOptions + +const useScheduledEventsQueries = [ + useSpeakersOptions, + useWorkshopsOptions, + useRecurringEventsOptions, + useTalksOptions, + useScheduledEventsOptions, +] as const + +export const prefetchScheduledEvents = async () => { + await Promise.all( + useScheduledEventsQueries.map(async (query) => { + return queryClient.prefetchQuery(query) + }), ) +} + +export const useScheduledEvents = () => { + const queries = useQueries({ + queries: useScheduledEventsQueries, + }) + + const [speakers, workshops, recurringEvents, talks, scheduledEvents] = queries return { data: cleanedSchedule({ - recurringEvents, - scheduledEvents, - speakers: cleanedSpeakers(speakers), - talks: cleanedTalks({ speakers, talks }), - workshops: cleanedWorkshops(workshops, cleanedSpeakers(speakers)), + recurringEvents: recurringEvents.data, + scheduledEvents: scheduledEvents.data, + speakers: cleanedSpeakers(speakers.data), + talks: cleanedTalks({ speakers: speakers.data, talks: talks.data }), + workshops: cleanedWorkshops(workshops.data, cleanedSpeakers(speakers.data)), }), - ...rest, + refetch: async () => Promise.all(queries.map((query) => query.refetch())), + isLoading: queries.map((query) => query.isLoading).some((isLoading) => isLoading), + isRefetching: queries.map((query) => query.isFetching).some((isFetching) => isFetching), } } @@ -126,7 +177,7 @@ export const useScheduleScreenData = () => { title: "Conference Day 2", events: convertScheduleToScheduleCard(events, "Friday"), }, - ] as Schedule[], + ] satisfies Schedule[], refetch, } } From 3f2a44440e7b16ab226ece396050e0bd6a4262a9 Mon Sep 17 00:00:00 2001 From: Joshua Yoes Date: Tue, 11 Apr 2023 20:35:26 -0700 Subject: [PATCH 4/5] Add prefetchScheduledEvents to WelcomeScreen --- app/screens/WelcomeScreen.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/screens/WelcomeScreen.tsx b/app/screens/WelcomeScreen.tsx index b1290263..d8f02137 100644 --- a/app/screens/WelcomeScreen.tsx +++ b/app/screens/WelcomeScreen.tsx @@ -1,10 +1,11 @@ -import React from "react" +import React, { useLayoutEffect } from "react" import { Dimensions, Image, ImageStyle, Platform, TextStyle, View, ViewStyle } from "react-native" import { SafeAreaView } from "react-native-safe-area-context" import { Button, Screen, Text } from "../components" import { useAppNavigation } from "../hooks" import { AppStackScreenProps } from "../navigators" import { colors, spacing } from "../theme" +import { prefetchScheduledEvents } from "../services/api" const welcomeLogo = require("../../assets/images/welcome-shapes.png") const { width: screenWidth } = Dimensions.get("screen") @@ -18,6 +19,10 @@ export const WelcomeScreen: React.FC = (_props) => { navigation.navigate("Tabs", { screen: "Schedule" }) } + useLayoutEffect(() => { + prefetchScheduledEvents() + }, []) + return ( From 1127ca1640d4b9f11fe6638fadb6b714e4d2799c Mon Sep 17 00:00:00 2001 From: Joshua Yoes Date: Fri, 21 Apr 2023 11:54:57 -0700 Subject: [PATCH 5/5] Add webflowOptions, add CollectionConst type --- app/services/api/webflow-api.ts | 111 +++++++++-------------------- app/services/api/webflow-consts.ts | 28 +++++--- 2 files changed, 54 insertions(+), 85 deletions(-) diff --git a/app/services/api/webflow-api.ts b/app/services/api/webflow-api.ts index a127f5a4..329d61ee 100644 --- a/app/services/api/webflow-api.ts +++ b/app/services/api/webflow-api.ts @@ -13,6 +13,7 @@ import type { RawWorkshop, } from "./webflow-api.types" import { + CollectionConst, RECOMMENDATIONS, RECURRING_EVENTS, SCHEDULE, @@ -38,105 +39,61 @@ const getCollectionById = async (collectionId: string) => { return data.items } -const useRecommendationsOptions = { - queryKey: [RECOMMENDATIONS.key, RECOMMENDATIONS.collectionId], - queryFn: async () => getCollectionById(RECOMMENDATIONS.collectionId), -} satisfies UseQueryOptions +const webflowOptions = ( + collection: Collection, +) => + ({ + queryKey: [collection.key, collection.collectionId] as const, + queryFn: async () => getCollectionById(collection.collectionId), + } satisfies UseQueryOptions) -export const useRecommendations = () => { - return useQuery(useRecommendationsOptions) -} - -const useRecurringEventsOptions = { - queryKey: [RECURRING_EVENTS.key, RECURRING_EVENTS.collectionId], - queryFn: async () => getCollectionById(RECURRING_EVENTS.collectionId), -} satisfies UseQueryOptions - -export const useRecurringEvents = () => { - return useQuery(useRecurringEventsOptions) -} +const recommendationsOptions = webflowOptions(RECOMMENDATIONS) +export const useRecommendations = () => useQuery(recommendationsOptions) -const useSpeakersOptions = { - queryKey: [SPEAKERS.key, SPEAKERS.collectionId], - queryFn: async () => getCollectionById(SPEAKERS.collectionId), -} satisfies UseQueryOptions +const recurringEventsOptions = webflowOptions(RECURRING_EVENTS) +export const useRecurringEvents = () => useQuery(recurringEventsOptions) -export const useSpeakers = () => { - return useQuery(useSpeakersOptions) -} - -const useSpeakerNamesOptions = { - queryKey: [SPEAKER_NAMES.key, SPEAKER_NAMES.collectionId], - queryFn: async () => getCollectionById(SPEAKER_NAMES.collectionId), -} satisfies UseQueryOptions - -export const useSpeakerNames = () => { - return useQuery(useSpeakerNamesOptions) -} +const speakersOptions = webflowOptions(SPEAKERS) +export const useSpeakers = () => useQuery(speakersOptions) -const useSponsorsOptions = { - queryKey: [SPONSORS.key, SPONSORS.collectionId], - queryFn: async () => getCollectionById(SPONSORS.collectionId), -} satisfies UseQueryOptions +const speakerNamesOptions = webflowOptions(SPEAKER_NAMES) +export const useSpeakerNames = () => useQuery(speakerNamesOptions) +const sponsorsOptions = webflowOptions(SPONSORS) export const useSponsors = () => { - const { data: sponsors, isLoading } = useQuery(useSponsorsOptions) + const { data: sponsors, ...rest } = useQuery(sponsorsOptions) const data = cleanedSponsors(sponsors) - return { isLoading, data } + return { data, ...rest } } -const useTalksOptions = { - queryKey: [TALKS.key, TALKS.collectionId], - queryFn: async () => getCollectionById(TALKS.collectionId), -} satisfies UseQueryOptions +const talksOptions = webflowOptions(TALKS) +export const useTalks = () => useQuery(talksOptions) -export const useTalks = () => { - return useQuery(useTalksOptions) -} - -const useVenuesOptions = { - queryKey: [VENUES.key, VENUES.collectionId], - queryFn: async () => getCollectionById(VENUES.collectionId), -} satisfies UseQueryOptions - -export const useVenues = () => { - return useQuery(useVenuesOptions) -} +const venuesOptions = webflowOptions(VENUES) +export const useVenues = () => useQuery(venuesOptions) -const useWorkshopsOptions = { - queryKey: [WORKSHOPS.key, WORKSHOPS.collectionId], - queryFn: async () => getCollectionById(WORKSHOPS.collectionId), -} satisfies UseQueryOptions +const workshopsOptions = webflowOptions(WORKSHOPS) +export const useWorkshops = () => useQuery(workshopsOptions) -export const useWorkshops = () => { - return useQuery(useWorkshopsOptions) -} - -const useScheduledEventsOptions = { - queryKey: [SCHEDULE.key, SCHEDULE.collectionId], - queryFn: async () => getCollectionById(SCHEDULE.collectionId), -} satisfies UseQueryOptions - -const useScheduledEventsQueries = [ - useSpeakersOptions, - useWorkshopsOptions, - useRecurringEventsOptions, - useTalksOptions, - useScheduledEventsOptions, +const scheduledEventsOptions = webflowOptions(SCHEDULE) +const scheduledEventsQueries = [ + speakersOptions, + workshopsOptions, + recurringEventsOptions, + talksOptions, + scheduledEventsOptions, ] as const - export const prefetchScheduledEvents = async () => { await Promise.all( - useScheduledEventsQueries.map(async (query) => { + scheduledEventsQueries.map(async (query) => { return queryClient.prefetchQuery(query) }), ) } - export const useScheduledEvents = () => { const queries = useQueries({ - queries: useScheduledEventsQueries, + queries: scheduledEventsQueries, }) const [speakers, workshops, recurringEvents, talks, scheduledEvents] = queries diff --git a/app/services/api/webflow-consts.ts b/app/services/api/webflow-consts.ts index 20925245..44fcfddd 100644 --- a/app/services/api/webflow-consts.ts +++ b/app/services/api/webflow-consts.ts @@ -3,12 +3,12 @@ export const SITE_ID = "5ca38f35db5d2ea94aea469d" export const SPONSORS = { collectionId: "640a728fc24f8e73575fe189", key: "sponsors", -} +} as const export const SPEAKERS = { collectionId: "640a728fc24f8e94385fe188", key: "speakers", -} +} as const export const SPEAKER_NAMES = { collectionId: "640a728fc24f8e74d05fe18a", @@ -23,32 +23,44 @@ export const WORKSHOPS = { export const SCHEDULE = { collectionId: "640a728fc24f8e63325fe185", key: "schedule", -} +} as const export const PAST_TALKS = { collectionId: "640a728fc24f8e76ef5fe186", key: "pastTalks", -} +} as const export const RECURRING_EVENTS = { collectionId: "640a728fc24f8e85a75fe18c", key: "recurringEvents", -} +} as const export const TALKS = { collectionId: "640a728fc24f8e31ee5fe18e", key: "talks", -} +} as const export const VENUES = { collectionId: "640a728fc24f8e553c5fe18d", key: "venues", -} +} as const export const RECOMMENDATIONS = { collectionId: "640a728fc24f8e083b5fe18f", key: "recommendations", -} +} as const + +export type CollectionConst = + | typeof SPONSORS + | typeof SPEAKERS + | typeof SPEAKER_NAMES + | typeof WORKSHOPS + | typeof SCHEDULE + | typeof PAST_TALKS + | typeof RECURRING_EVENTS + | typeof TALKS + | typeof VENUES + | typeof RECOMMENDATIONS // [NOTE] these keys probably have to change when webflow is updated // `/collections/${collectionId}` api will the keys