From bd4965e80fb4801d247ccb4472455911eabf154b Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 20 Mar 2024 15:39:33 -0500 Subject: [PATCH] Dry up label pref comp --- .../moderation/GlobalModerationLabelPref.tsx | 93 ------ src/components/moderation/LabelPreference.tsx | 294 ++++++++++++++++++ .../moderation/ModerationLabelPref.tsx | 177 ----------- src/screens/Moderation/index.tsx | 12 +- src/screens/Profile/Sections/Labels.tsx | 6 +- 5 files changed, 303 insertions(+), 279 deletions(-) delete mode 100644 src/components/moderation/GlobalModerationLabelPref.tsx create mode 100644 src/components/moderation/LabelPreference.tsx delete mode 100644 src/components/moderation/ModerationLabelPref.tsx diff --git a/src/components/moderation/GlobalModerationLabelPref.tsx b/src/components/moderation/GlobalModerationLabelPref.tsx deleted file mode 100644 index 7633cb9f21..0000000000 --- a/src/components/moderation/GlobalModerationLabelPref.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import React from 'react' -import {View} from 'react-native' -import {InterpretedLabelValueDefinition, LabelPreference} from '@atproto/api' -import {useLingui} from '@lingui/react' -import {msg} from '@lingui/macro' - -import {useGlobalLabelStrings} from '#/lib/moderation/useGlobalLabelStrings' -import { - usePreferencesQuery, - usePreferencesSetContentLabelMutation, -} from '#/state/queries/preferences' - -import {useTheme, atoms as a} from '#/alf' -import {Text} from '#/components/Typography' -import * as ToggleButton from '#/components/forms/ToggleButton' - -export function GlobalModerationLabelPref({ - labelValueDefinition, - disabled, -}: { - labelValueDefinition: InterpretedLabelValueDefinition - disabled?: boolean -}) { - const {_} = useLingui() - const t = useTheme() - - const {identifier} = labelValueDefinition - const {data: preferences} = usePreferencesQuery() - const {mutate, variables} = usePreferencesSetContentLabelMutation() - const savedPref = preferences?.moderationPrefs.labels[identifier] - const pref = variables?.visibility ?? savedPref ?? 'warn' - - const allLabelStrings = useGlobalLabelStrings() - const labelStrings = - labelValueDefinition.identifier in allLabelStrings - ? allLabelStrings[labelValueDefinition.identifier] - : { - name: labelValueDefinition.identifier, - description: `Labeled "${labelValueDefinition.identifier}"`, - } - - const labelOptions = { - hide: _(msg`Hide`), - warn: _(msg`Warn`), - ignore: _(msg`Show`), - } - - return ( - - - {labelStrings.name} - - {labelStrings.description} - - - - {!disabled && ( - - mutate({ - label: identifier, - visibility: newPref[0] as LabelPreference, - labelerDid: undefined, - }) - }> - - {labelOptions.ignore} - - - {labelOptions.warn} - - - {labelOptions.hide} - - - )} - - - ) -} diff --git a/src/components/moderation/LabelPreference.tsx b/src/components/moderation/LabelPreference.tsx new file mode 100644 index 0000000000..7d4bd9c321 --- /dev/null +++ b/src/components/moderation/LabelPreference.tsx @@ -0,0 +1,294 @@ +import React from 'react' +import {View} from 'react-native' +import {InterpretedLabelValueDefinition, LabelPreference} from '@atproto/api' +import {useLingui} from '@lingui/react' +import {msg, Trans} from '@lingui/macro' + +import {useGlobalLabelStrings} from '#/lib/moderation/useGlobalLabelStrings' +import { + usePreferencesQuery, + usePreferencesSetContentLabelMutation, +} from '#/state/queries/preferences' +import {useLabelBehaviorDescription} from '#/lib/moderation/useLabelBehaviorDescription' +import {getLabelStrings} from '#/lib/moderation/useLabelInfo' + +import {useTheme, atoms as a, useBreakpoints} from '#/alf' +import {Text} from '#/components/Typography' +import {InlineLink} from '#/components/Link' +import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '../icons/CircleInfo' +import * as ToggleButton from '#/components/forms/ToggleButton' + +export function Outer({children}: React.PropsWithChildren<{}>) { + return ( + + {children} + + ) +} + +export function Content({ + children, + name, + description, +}: React.PropsWithChildren<{ + name: string + description: string +}>) { + const t = useTheme() + const {gtPhone} = useBreakpoints() + + return ( + + {name} + + {description} + + + {children} + + ) +} + +export function Buttons({ + name, + values, + onChange, + ignoreLabel, + warnLabel, + hideLabel, +}: { + name: string + values: ToggleButton.GroupProps['values'] + onChange: ToggleButton.GroupProps['onChange'] + ignoreLabel?: string + warnLabel?: string + hideLabel?: string +}) { + const {_} = useLingui() + const {gtPhone} = useBreakpoints() + + return ( + + + {ignoreLabel && ( + + {ignoreLabel} + + )} + {warnLabel && ( + + {warnLabel} + + )} + {hideLabel && ( + + {hideLabel} + + )} + + + ) +} + +/** + * For use on the global Moderation screen to set prefs for a "global" label, + * not scoped to a single labeler. + */ +export function GlobalLabelPreference({ + labelDefinition, + disabled, +}: { + labelDefinition: InterpretedLabelValueDefinition + disabled?: boolean +}) { + const {_} = useLingui() + + const {identifier} = labelDefinition + const {data: preferences} = usePreferencesQuery() + const {mutate, variables} = usePreferencesSetContentLabelMutation() + const savedPref = preferences?.moderationPrefs.labels[identifier] + const pref = variables?.visibility ?? savedPref ?? 'warn' + + const allLabelStrings = useGlobalLabelStrings() + const labelStrings = + labelDefinition.identifier in allLabelStrings + ? allLabelStrings[labelDefinition.identifier] + : { + name: labelDefinition.identifier, + description: `Labeled "${labelDefinition.identifier}"`, + } + + const labelOptions = { + hide: _(msg`Hide`), + warn: _(msg`Warn`), + ignore: _(msg`Show`), + } + + return ( + + + {!disabled && ( + { + mutate({ + label: identifier, + visibility: values[0] as LabelPreference, + labelerDid: undefined, + }) + }} + ignoreLabel={labelOptions.ignore} + warnLabel={labelOptions.warn} + hideLabel={labelOptions.hide} + /> + )} + + ) +} + +/** + * For use on individual labeler pages + */ +export function LabelerLabelPreference({ + labelDefinition, + disabled, + labelerDid, +}: { + labelDefinition: InterpretedLabelValueDefinition + disabled?: boolean + labelerDid?: string +}) { + const {i18n} = useLingui() + const t = useTheme() + const {gtPhone} = useBreakpoints() + + const isGlobalLabel = !labelDefinition.definedBy + const {identifier} = labelDefinition + const {data: preferences} = usePreferencesQuery() + const {mutate, variables} = usePreferencesSetContentLabelMutation() + const savedPref = + labelerDid && !isGlobalLabel + ? preferences?.moderationPrefs.labelers.find(l => l.did === labelerDid) + ?.labels[identifier] + : preferences?.moderationPrefs.labels[identifier] + const pref = + variables?.visibility ?? + savedPref ?? + labelDefinition.defaultSetting ?? + 'warn' + + // does the 'warn' setting make sense for this label? + const canWarn = !( + labelDefinition.blurs === 'none' && labelDefinition.severity === 'none' + ) + // is this label adult only? + const adultOnly = labelDefinition.flags.includes('adult') + // is this label disabled because it's adult only? + const adultDisabled = + adultOnly && !preferences?.moderationPrefs.adultContentEnabled + // are there any reasons we cant configure this label here? + const cantConfigure = isGlobalLabel || adultDisabled + const showConfig = !disabled && (gtPhone || !cantConfigure) + + // adjust the pref based on whether warn is available + let prefAdjusted = pref + if (adultDisabled) { + prefAdjusted = 'hide' + } else if (!canWarn && pref === 'warn') { + prefAdjusted = 'ignore' + } + + // grab localized descriptions of the label and its settings + const currentPrefLabel = useLabelBehaviorDescription( + labelDefinition, + prefAdjusted, + ) + const hideLabel = useLabelBehaviorDescription(labelDefinition, 'hide') + const warnLabel = useLabelBehaviorDescription(labelDefinition, 'warn') + const ignoreLabel = useLabelBehaviorDescription(labelDefinition, 'ignore') + const globalLabelStrings = useGlobalLabelStrings() + const labelStrings = getLabelStrings( + i18n.locale, + globalLabelStrings, + labelDefinition, + ) + + return ( + + + {cantConfigure && ( + + + + + {adultDisabled ? ( + Adult content is disabled. + ) : isGlobalLabel ? ( + + Configured in{' '} + + moderation settings + + . + + ) : null} + + + )} + + + {showConfig && ( + + {cantConfigure ? ( + + + {currentPrefLabel} + + + ) : ( + { + mutate({ + label: identifier, + visibility: values[0] as LabelPreference, + labelerDid, + }) + }} + ignoreLabel={ignoreLabel} + warnLabel={canWarn ? warnLabel : undefined} + hideLabel={hideLabel} + /> + )} + + )} + + ) +} diff --git a/src/components/moderation/ModerationLabelPref.tsx b/src/components/moderation/ModerationLabelPref.tsx deleted file mode 100644 index b16c248592..0000000000 --- a/src/components/moderation/ModerationLabelPref.tsx +++ /dev/null @@ -1,177 +0,0 @@ -import React from 'react' -import {View} from 'react-native' -import {InterpretedLabelValueDefinition, LabelPreference} from '@atproto/api' -import {useLingui} from '@lingui/react' -import {msg, Trans} from '@lingui/macro' - -import {useGlobalLabelStrings} from '#/lib/moderation/useGlobalLabelStrings' -import {useLabelBehaviorDescription} from '#/lib/moderation/useLabelBehaviorDescription' -import { - usePreferencesQuery, - usePreferencesSetContentLabelMutation, -} from '#/state/queries/preferences' -import {getLabelStrings} from '#/lib/moderation/useLabelInfo' - -import {useTheme, atoms as a, useBreakpoints} from '#/alf' -import {Text} from '#/components/Typography' -import {InlineLink} from '#/components/Link' -import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '../icons/CircleInfo' -import * as ToggleButton from '#/components/forms/ToggleButton' - -export function ModerationLabelPref({ - labelValueDefinition, - labelerDid, - disabled, -}: { - labelValueDefinition: InterpretedLabelValueDefinition - labelerDid: string | undefined - disabled?: boolean -}) { - const {_, i18n} = useLingui() - const t = useTheme() - const {gtPhone} = useBreakpoints() - - const isGlobalLabel = !labelValueDefinition.definedBy - const {identifier} = labelValueDefinition - const {data: preferences} = usePreferencesQuery() - const {mutate, variables} = usePreferencesSetContentLabelMutation() - const savedPref = - labelerDid && !isGlobalLabel - ? preferences?.moderationPrefs.labelers.find(l => l.did === labelerDid) - ?.labels[identifier] - : preferences?.moderationPrefs.labels[identifier] - const pref = - variables?.visibility ?? - savedPref ?? - labelValueDefinition.defaultSetting ?? - 'warn' - - // does the 'warn' setting make sense for this label? - const canWarn = !( - labelValueDefinition.blurs === 'none' && - labelValueDefinition.severity === 'none' - ) - // is this label adult only? - const adultOnly = labelValueDefinition.flags.includes('adult') - // is this label disabled because it's adult only? - const adultDisabled = - adultOnly && !preferences?.moderationPrefs.adultContentEnabled - // are there any reasons we cant configure this label here? - const cantConfigure = isGlobalLabel || adultDisabled - const showConfig = !disabled && (gtPhone || !cantConfigure) - - // adjust the pref based on whether warn is available - let prefAdjusted = pref - if (adultDisabled) { - prefAdjusted = 'hide' - } else if (!canWarn && pref === 'warn') { - prefAdjusted = 'ignore' - } - - // grab localized descriptions of the label and its settings - const currentPrefLabel = useLabelBehaviorDescription( - labelValueDefinition, - prefAdjusted, - ) - const hideLabel = useLabelBehaviorDescription(labelValueDefinition, 'hide') - const warnLabel = useLabelBehaviorDescription(labelValueDefinition, 'warn') - const ignoreLabel = useLabelBehaviorDescription( - labelValueDefinition, - 'ignore', - ) - const globalLabelStrings = useGlobalLabelStrings() - const labelStrings = getLabelStrings( - i18n.locale, - globalLabelStrings, - labelValueDefinition, - ) - - return ( - - - - {labelStrings.name} - - - {labelStrings.description} - - - {cantConfigure && ( - - - - - {adultDisabled ? ( - Adult content is disabled. - ) : isGlobalLabel ? ( - - Configured in{' '} - - moderation settings - - . - - ) : null} - - - )} - - - {showConfig && ( - - {cantConfigure ? ( - - - {currentPrefLabel} - - - ) : ( - - - mutate({ - label: identifier, - visibility: newPref[0] as LabelPreference, - labelerDid, - }) - }> - - {ignoreLabel} - - {canWarn && ( - - {warnLabel} - - )} - - {hideLabel} - - - - )} - - )} - - ) -} diff --git a/src/screens/Moderation/index.tsx b/src/screens/Moderation/index.tsx index d73823fadf..7d991cc711 100644 --- a/src/screens/Moderation/index.tsx +++ b/src/screens/Moderation/index.tsx @@ -41,7 +41,7 @@ import {InlineLink, Link} from '#/components/Link' import {Button, ButtonText} from '#/components/Button' import {Loader} from '#/components/Loader' import * as LabelingService from '#/components/LabelingServiceCard' -import {GlobalModerationLabelPref} from '#/components/moderation/GlobalModerationLabelPref' +import {GlobalLabelPreference} from '#/components/moderation/LabelPreference' import {useGlobalDialogsControlContext} from '#/components/dialogs/Context' import {Props as SVGIconProps} from '#/components/icons/common' import {BirthDateSettingsDialog} from '#/components/dialogs/BirthDateSettings' @@ -352,17 +352,17 @@ export function ModerationScreenInner({ )} {!isUnderage && adultContentEnabled && ( <> - + - + - )} - + diff --git a/src/screens/Profile/Sections/Labels.tsx b/src/screens/Profile/Sections/Labels.tsx index 08db4a861d..2b2b995940 100644 --- a/src/screens/Profile/Sections/Labels.tsx +++ b/src/screens/Profile/Sections/Labels.tsx @@ -23,7 +23,7 @@ import {Loader} from '#/components/Loader' import {Divider} from '#/components/Divider' import {CenteredView, ScrollView} from '#/view/com/util/Views' import {ErrorState} from '../ErrorState' -import {ModerationLabelPref} from '#/components/moderation/ModerationLabelPref' +import {LabelerLabelPreference} from '#/components/moderation/LabelPreference' import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' interface LabelsSectionProps { @@ -197,9 +197,9 @@ export function ProfileLabelsSectionInner({ return ( {i !== 0 && } -