From d3634d8b1cc2fc3f6a7e0ba6c09a34c55373feb0 Mon Sep 17 00:00:00 2001 From: MartinBraquet Date: Fri, 13 Mar 2026 14:35:20 +0100 Subject: [PATCH] Move interestChoices to app context to fix db blast --- web/components/filters/filters.tsx | 14 ++---- web/components/filters/interest-filter.tsx | 4 +- web/components/filters/search.tsx | 6 +-- web/components/profile-about.tsx | 12 +++-- web/components/profile-grid.tsx | 4 +- web/components/searches/button.tsx | 4 +- web/hooks/{use-choices.ts => use-choices.tsx} | 44 ++++++++++++++----- web/pages/_app.tsx | 13 +++--- 8 files changed, 59 insertions(+), 42 deletions(-) rename web/hooks/{use-choices.ts => use-choices.tsx} (58%) diff --git a/web/components/filters/filters.tsx b/web/components/filters/filters.tsx index 483fba7a..c6946e8b 100644 --- a/web/components/filters/filters.tsx +++ b/web/components/filters/filters.tsx @@ -37,7 +37,7 @@ import {Col} from 'web/components/layout/col' import {Row} from 'web/components/layout/row' import {NewBadge} from 'web/components/new-badge' import {ResetFiltersButton} from 'web/components/searches/button' -import {useAllChoices, useChoices} from 'web/hooks/use-choices' +import {useChoicesContext} from 'web/hooks/use-choices' import {useMeasurementSystem} from 'web/hooks/use-measurement-system' import {useT} from 'web/lib/locale' import {DietType, RelationshipType, RomanticType} from 'web/lib/util/convert-types' @@ -76,7 +76,7 @@ function SelectedFiltersSummary(props: { }) { const {locationFilterProps, raisedInLocationFilterProps, updateFilter, clearFilters} = props const t = useT() - const choicesIdsToLabels = useAllChoices() + const choicesIdsToLabels = useChoicesContext() const {measurementSystem} = useMeasurementSystem() const filters = removeNullOrUndefinedProps({...props.filters, orderBy: undefined}) @@ -870,14 +870,8 @@ export function FiltersElement(props: { updateDisplayOptions, } = props const youSeekingRelationship = youProfile?.pref_relation_styles?.includes('relationship') - const {choices: interestChoices} = useChoices('interests') - const {choices: causeChoices} = useChoices('causes') - const {choices: workChoices} = useChoices('work') - const choices = { - interests: interestChoices, - causes: causeChoices, - work: workChoices, - } + const _choices = useChoicesContext() + const choices = {interests: _choices.interests, causes: _choices.causes, work: _choices.work} return ( { if (isHolding) return @@ -195,7 +195,7 @@ export const Search = forwardRef< setTimeout(() => { setPlaceholder('') setCharIndex(0) - setTextToType(getRandomPair(Object.values(interestChoices))) // pick new pair + setTextToType(getRandomPair(Object.values(choices?.['interests']))) // pick new pair setIsHolding(false) }, HOLD_TIME) return prev diff --git a/web/components/profile-about.tsx b/web/components/profile-about.tsx index 8f86867e..ab86dc26 100644 --- a/web/components/profile-about.tsx +++ b/web/components/profile-about.tsx @@ -33,7 +33,7 @@ import {TbBulb, TbCheck, TbMoodSad, TbUsers} from 'react-icons/tb' import {Col} from 'web/components/layout/col' import {Row} from 'web/components/layout/row' import {UserHandles} from 'web/components/user/user-handles' -import {useChoices} from 'web/hooks/use-choices' +import {useChoicesContext} from 'web/hooks/use-choices' import {useLocale, useT} from 'web/lib/locale' import {getSeekingConnectionText} from 'web/lib/profile/seeking' import {convertRace} from 'web/lib/util/convert-types' @@ -83,9 +83,7 @@ export default function ProfileAbout(props: { }) { const {profile, userActivity, isCurrentUser} = props const t = useT() - const {choices: interestsById} = useChoices('interests') - const {choices: causesById} = useChoices('causes') - const {choices: workById} = useChoices('work') + const choices = useChoicesContext() const {locale} = useLocale() return ( @@ -98,7 +96,7 @@ export default function ProfileAbout(props: { icon={} text={ profile.work - ?.map((id) => workById[id]) + ?.map((id) => choices?.['work']?.[id]) .filter(Boolean) .sort((a, b) => a.localeCompare(b, locale)) as string[] } @@ -124,7 +122,7 @@ export default function ProfileAbout(props: { icon={} text={ profile.interests - ?.map((id) => interestsById[id]) + ?.map((id) => choices?.['interests']?.[id]) .filter(Boolean) .sort((a, b) => a.localeCompare(b, locale)) as string[] } @@ -134,7 +132,7 @@ export default function ProfileAbout(props: { icon={} text={ profile.causes - ?.map((id) => causesById[id]) + ?.map((id) => choices?.['causes']?.[id]) .filter(Boolean) .sort((a, b) => a.localeCompare(b, locale)) as string[] } diff --git a/web/components/profile-grid.tsx b/web/components/profile-grid.tsx index 7730e5bb..a9c0953d 100644 --- a/web/components/profile-grid.tsx +++ b/web/components/profile-grid.tsx @@ -31,7 +31,7 @@ import {Content} from 'web/components/widgets/editor' import HideProfileButton from 'web/components/widgets/hide-profile-button' import {CompassLoadingIndicator} from 'web/components/widgets/loading-indicator' import {LoadMoreUntilNotVisible} from 'web/components/widgets/visibility-observer' -import {useAllChoices} from 'web/hooks/use-choices' +import {useChoicesContext} from 'web/hooks/use-choices' import {useUser} from 'web/hooks/use-user' import {useT} from 'web/lib/locale' import {getSeekingConnectionText} from 'web/lib/profile/seeking' @@ -157,7 +157,7 @@ function ProfilePreview(props: { cardSize, } = displayOptions ?? {} const {user} = profile - const choicesIdsToLabels = useAllChoices() + const choicesIdsToLabels = useChoicesContext() const t = useT() // const currentUser = useUser() diff --git a/web/components/searches/button.tsx b/web/components/searches/button.tsx index 3ca0b24d..f464f472 100644 --- a/web/components/searches/button.tsx +++ b/web/components/searches/button.tsx @@ -13,7 +13,7 @@ import {Modal, MODAL_CLASS, SCROLLABLE_MODAL_CLASS} from 'web/components/layout/ import {Row} from 'web/components/layout/row' import {Avatar} from 'web/components/widgets/avatar' import {BookmarkedSearchesType} from 'web/hooks/use-bookmarked-searches' -import {useAllChoices} from 'web/hooks/use-choices' +import {useChoicesContext} from 'web/hooks/use-choices' import {useMeasurementSystem} from 'web/hooks/use-measurement-system' import {useUser} from 'web/hooks/use-user' import {api} from 'web/lib/api' @@ -68,7 +68,7 @@ function ButtonModal(props: { }) { const {open, setOpen, bookmarkedSearches, refreshBookmarkedSearches} = props const t = useT() - const choicesIdsToLabels = useAllChoices() + const choicesIdsToLabels = useChoicesContext() const {measurementSystem} = useMeasurementSystem() return ( (null) + +export const ChoicesProvider = ({children}: {children: ReactNode}) => { + const choices = useAllChoices() + return {children} +} + +export const useChoicesContext = () => { + const ctx = useContext(ChoicesContext) + if (!ctx) throw new Error('useChoicesContext must be used within a ChoicesProvider') + return ctx +} + export async function fetchChoices(label: OptionTableKey, locale: string) { + debug('Fetching choices for', label) const choicesById: Record = {} const {data} = await run( db @@ -32,7 +47,7 @@ export async function fetchChoices(label: OptionTableKey, locale: string) { return choicesById } -export const useChoices = (label: OptionTableKey) => { +const useChoices = (label: OptionTableKey) => { const [choices, setChoices] = usePersistentInMemoryState>( {}, `${label}-choices`, @@ -40,24 +55,31 @@ export const useChoices = (label: OptionTableKey) => { const {locale} = useLocale() const refreshChoices = async () => { - try { - const results = await fetchChoices(label, locale) - setChoices(results) - } catch (err) { - console.error('Error fetching choices:', err) - return {} - } + fetchChoices(label, locale) + .then(setChoices) + .catch((err) => { + console.error('Error fetching choices:', err?.message ?? err) + return {} + }) } useEffect(() => { - // debug('Fetching choices in use effect...') refreshChoices() }, [locale]) return {choices, refreshChoices} } -export const useAllChoices = () => { +export type UseAllChoices = { + interests: Record + causes: Record + work: Record + refreshInterests: () => void + refreshCauses: () => void + refreshWork: () => void +} + +const useAllChoices = () => { const {choices: interests, refreshChoices: refreshInterests} = useChoices('interests') const {choices: causes, refreshChoices: refreshCauses} = useChoices('causes') const {choices: work, refreshChoices: refreshWork} = useChoices('work') diff --git a/web/pages/_app.tsx b/web/pages/_app.tsx index ef482fc6..514df419 100644 --- a/web/pages/_app.tsx +++ b/web/pages/_app.tsx @@ -20,6 +20,7 @@ import {useEffect, useState} from 'react' import {AuthProvider, AuthUser} from 'web/components/auth-context' import {ErrorBoundary} from 'web/components/error-boundary' import {LiveRegionProvider} from 'web/components/live-region' +import {ChoicesProvider} from 'web/hooks/use-choices' import {useFontPreferenceManager} from 'web/hooks/use-font-preference' import {useHasLoaded} from 'web/hooks/use-has-loaded' import {HiddenProfilesProvider} from 'web/hooks/use-hidden-profiles' @@ -196,11 +197,13 @@ function MyApp(props: AppProps) { - - - - - + + + + + + +