From 7c675b4a2f5aed9f2e502d67ff49498d93676462 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Thu, 14 Mar 2024 20:41:51 -0700 Subject: [PATCH] Move label defs into a context to reduce recomputes --- src/components/ReportDialog/index.tsx | 8 ++++-- src/lib/moderation/useLabelInfo.ts | 6 ++--- .../useModerationCauseDescription.ts | 6 ++--- src/screens/Moderation/index.tsx | 4 +-- src/state/preferences/index.tsx | 6 ++++- src/state/preferences/label-defs.tsx | 25 +++++++++++++++++++ src/state/queries/preferences/index.ts | 3 +-- src/state/queries/preferences/moderation.ts | 6 ++--- 8 files changed, 48 insertions(+), 16 deletions(-) create mode 100644 src/state/preferences/label-defs.tsx diff --git a/src/components/ReportDialog/index.tsx b/src/components/ReportDialog/index.tsx index 548b9a29fa..b35727c7dd 100644 --- a/src/components/ReportDialog/index.tsx +++ b/src/components/ReportDialog/index.tsx @@ -2,7 +2,7 @@ import React from 'react' import {View, Pressable} from 'react-native' import {Trans} from '@lingui/macro' -import {useMyLabelers} from '#/state/queries/preferences' +import {useMyLabelersQuery} from '#/state/queries/preferences' import {ReportOption} from '#/lib/moderation/useReportOptions' export {useDialogControl as useReportDialogControl} from '#/components/Dialog' @@ -27,7 +27,11 @@ export function ReportDialog(props: ReportDialogProps) { } function ReportDialogInner(props: ReportDialogProps) { - const {isLoading: isLabelerLoading, data: labelers, error} = useMyLabelers() + const { + isLoading: isLabelerLoading, + data: labelers, + error, + } = useMyLabelersQuery() const isLoading = useDelayedLoading(500, isLabelerLoading) const [selectedReportOption, setSelectedReportOption] = React.useState< ReportOption | undefined diff --git a/src/lib/moderation/useLabelInfo.ts b/src/lib/moderation/useLabelInfo.ts index 21e3260be5..b1cffe1e71 100644 --- a/src/lib/moderation/useLabelInfo.ts +++ b/src/lib/moderation/useLabelInfo.ts @@ -9,10 +9,10 @@ import {useLingui} from '@lingui/react' import * as bcp47Match from 'bcp-47-match' import { - useGlobalLabelStrings, GlobalLabelStrings, + useGlobalLabelStrings, } from '#/lib/moderation/useGlobalLabelStrings' -import {useLabelDefinitions} from '#/state/queries/preferences' +import {useLabelDefinitions} from '#/state/preferences' export interface LabelInfo { label: ComAtprotoLabelDefs.Label @@ -23,8 +23,8 @@ export interface LabelInfo { export function useLabelInfo(label: ComAtprotoLabelDefs.Label): LabelInfo { const {i18n} = useLingui() - const globalLabelStrings = useGlobalLabelStrings() const {labelDefs, labelers} = useLabelDefinitions() + const globalLabelStrings = useGlobalLabelStrings() const def = getDefinition(labelDefs, label) return { label, diff --git a/src/lib/moderation/useModerationCauseDescription.ts b/src/lib/moderation/useModerationCauseDescription.ts index af05feae66..c2aa5555ca 100644 --- a/src/lib/moderation/useModerationCauseDescription.ts +++ b/src/lib/moderation/useModerationCauseDescription.ts @@ -2,9 +2,9 @@ import React from 'react' import {ModerationCause, ModerationCauseSource} from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {useGlobalLabelStrings} from './useGlobalLabelStrings' -import {useLabelDefinitions} from '#/state/queries/preferences' import {getDefinition, getLabelStrings} from './useLabelInfo' +import {useLabelDefinitions} from '#/state/preferences' +import {useGlobalLabelStrings} from './useGlobalLabelStrings' import {Props as SVGIconProps} from '#/components/icons/common' import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning' @@ -24,8 +24,8 @@ export function useModerationCauseDescription( cause: ModerationCause | undefined, ): ModerationCauseDescription { const {_, i18n} = useLingui() - const globalLabelStrings = useGlobalLabelStrings() const {labelDefs, labelers} = useLabelDefinitions() + const globalLabelStrings = useGlobalLabelStrings() return React.useMemo(() => { if (!cause) { diff --git a/src/screens/Moderation/index.tsx b/src/screens/Moderation/index.tsx index aab6079f60..69e7c56811 100644 --- a/src/screens/Moderation/index.tsx +++ b/src/screens/Moderation/index.tsx @@ -21,7 +21,7 @@ import {ScrollView} from '#/view/com/util/Views' import { UsePreferencesQueryResponse, - useMyLabelers, + useMyLabelersQuery, usePreferencesQuery, usePreferencesSetAdultContentMutation, } from '#/state/queries/preferences' @@ -170,7 +170,7 @@ export function ModerationScreenInner({ isLoading: isLabelersLoading, data: labelers, error: labelersError, - } = useMyLabelers() + } = useMyLabelersQuery() useFocusEffect( React.useCallback(() => { diff --git a/src/state/preferences/index.tsx b/src/state/preferences/index.tsx index a442b763ad..68aa89dbc7 100644 --- a/src/state/preferences/index.tsx +++ b/src/state/preferences/index.tsx @@ -4,6 +4,7 @@ import {Provider as AltTextRequiredProvider} from '../preferences/alt-text-requi import {Provider as HiddenPostsProvider} from '../preferences/hidden-posts' import {Provider as ExternalEmbedsProvider} from './external-embeds-prefs' import {Provider as InAppBrowserProvider} from './in-app-browser' +import {Provider as LabelDefsProvider} from './label-defs' export {useLanguagePrefs, useLanguagePrefsApi} from './languages' export { @@ -15,6 +16,7 @@ export { useSetExternalEmbedPref, } from './external-embeds-prefs' export * from './hidden-posts' +export {useLabelDefinitions} from './label-defs' export function Provider({children}: React.PropsWithChildren<{}>) { return ( @@ -22,7 +24,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { - {children} + + {children} + diff --git a/src/state/preferences/label-defs.tsx b/src/state/preferences/label-defs.tsx new file mode 100644 index 0000000000..d60f8ccb88 --- /dev/null +++ b/src/state/preferences/label-defs.tsx @@ -0,0 +1,25 @@ +import React from 'react' +import {InterpretedLabelValueDefinition, AppBskyLabelerDefs} from '@atproto/api' +import {useLabelDefinitionsQuery} from '../queries/preferences' + +interface StateContext { + labelDefs: Record + labelers: AppBskyLabelerDefs.LabelerViewDetailed[] +} + +const stateContext = React.createContext({ + labelDefs: {}, + labelers: [], +}) + +export function Provider({children}: React.PropsWithChildren<{}>) { + const {labelDefs, labelers} = useLabelDefinitionsQuery() + + const state = {labelDefs, labelers} + + return {children} +} + +export function useLabelDefinitions() { + return React.useContext(stateContext) +} diff --git a/src/state/queries/preferences/index.ts b/src/state/queries/preferences/index.ts index 8ffaf23c88..cfc5c5bbe5 100644 --- a/src/state/queries/preferences/index.ts +++ b/src/state/queries/preferences/index.ts @@ -20,8 +20,7 @@ import { DEFAULT_LOGGED_OUT_PREFERENCES, } from '#/state/queries/preferences/const' import {STALE} from '#/state/queries' -import {useLabelDefinitions} from '#/state/queries/preferences/moderation' -import {useHiddenPosts} from '#/state/preferences' +import {useHiddenPosts, useLabelDefinitions} from '#/state/preferences' import {saveLabelers} from '#/state/session/agent-config' export * from '#/state/queries/preferences/types' diff --git a/src/state/queries/preferences/moderation.ts b/src/state/queries/preferences/moderation.ts index b404b5d32e..9cd183e8b1 100644 --- a/src/state/queries/preferences/moderation.ts +++ b/src/state/queries/preferences/moderation.ts @@ -16,7 +16,7 @@ export const DEFAULT_LOGGED_OUT_LABEL_PREFERENCES: typeof DEFAULT_LABEL_SETTINGS Object.entries(DEFAULT_LABEL_SETTINGS).map(([key, _pref]) => [key, 'hide']), ) -export function useMyLabelers() { +export function useMyLabelersQuery() { const prefs = usePreferencesQuery() const dids = Array.from( new Set( @@ -37,8 +37,8 @@ export function useMyLabelers() { }, [labelers, isLoading, error]) } -export function useLabelDefinitions() { - const labelers = useMyLabelers() +export function useLabelDefinitionsQuery() { + const labelers = useMyLabelersQuery() return React.useMemo(() => { return { labelDefs: Object.fromEntries(