diff --git a/src/components/ModerationLabelPref/SimpleModerationLabelPref.tsx b/src/components/ModerationLabelPref/SimpleModerationLabelPref.tsx new file mode 100644 index 0000000000..550ebdb559 --- /dev/null +++ b/src/components/ModerationLabelPref/SimpleModerationLabelPref.tsx @@ -0,0 +1,93 @@ +import React from 'react' +import {View} from 'react-native' +import {InterprettedLabelValueDefinition, LabelPreference} from '@atproto/api' +import {useLingui} from '@lingui/react' +import {msg} from '@lingui/macro' + +import {useLabelStrings} from '#/lib/moderation/useLabelStrings' +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 SimpleModerationLabelPref({ + labelValueDefinition, + disabled, +}: { + labelValueDefinition: InterprettedLabelValueDefinition + 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 = useLabelStrings() + const labelStrings = + labelValueDefinition.identifier in allLabelStrings + ? allLabelStrings[labelValueDefinition.identifier].general + : { + 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/ModerationLabelPref/index.tsx b/src/components/ModerationLabelPref/index.tsx index e8c1c66d5c..1d61d7a7c9 100644 --- a/src/components/ModerationLabelPref/index.tsx +++ b/src/components/ModerationLabelPref/index.tsx @@ -87,7 +87,7 @@ export function ModerationLabelPref({ a.justify_between, a.gap_sm, a.align_center, - t.atoms.bg_contrast_50, + t.atoms.bg_contrast_25, a.px_lg, a.py_lg, a.rounded_sm, diff --git a/src/lib/moderation/useLabelStrings.ts b/src/lib/moderation/useLabelStrings.ts index 42a1623b67..9f81ef5f34 100644 --- a/src/lib/moderation/useLabelStrings.ts +++ b/src/lib/moderation/useLabelStrings.ts @@ -128,9 +128,7 @@ export function useLabelStrings(): LabelStrings { porn: { general: { name: _(msg`Pornography`), - description: _( - msg`Images of full-frontal nudity (genitalia) in any sexualized context, or explicit sexual activity (meaning contact with genitalia or breasts) even if partially covered. Includes graphic sexual cartoons (often jokes/memes).`, - ), + description: _(msg`Explicit sexual images.`), }, account: { name: _(msg`Adult Content`), @@ -148,9 +146,7 @@ export function useLabelStrings(): LabelStrings { sexual: { general: { name: _(msg`Sexually Suggestive`), - description: _( - msg`Content that does not meet the level of "pornography", but is still sexual. Some common examples have been selfies and "hornyposting" with underwear on, or partially naked (naked but covered, eg with hands or from side perspective). Sheer/see-through nipples may end up in this category.`, - ), + description: _(msg`Does not include nudity.`), }, account: { name: _(msg`Suggestive Content`), @@ -168,9 +164,7 @@ export function useLabelStrings(): LabelStrings { nudity: { general: { name: _(msg`Nudity`), - description: _( - msg`Nudity which is not sexual, or that is primarily "artistic" in nature. For example: breastfeeding; classic art paintings and sculptures; newspaper images with some nudity; fashion modeling. "Erotic photography" is likely to end up in sexual or porn.`, - ), + description: _(msg`Including non-sexual and artistic.`), }, account: { name: _(msg`Adult Content`), @@ -187,10 +181,8 @@ export function useLabelStrings(): LabelStrings { }, gore: { general: { - name: _(msg`Gore`), - description: _( - msg`Intended for shocking images, typically involving blood or visible wounds.`, - ), + name: _(msg`Violent / Bloody`), + description: _(msg`Gore, self-harm, torture`), }, account: { name: _(msg`Graphic Imagery (Gore)`), diff --git a/src/screens/Moderation/index.tsx b/src/screens/Moderation/index.tsx index f8de05c0cf..5eba966383 100644 --- a/src/screens/Moderation/index.tsx +++ b/src/screens/Moderation/index.tsx @@ -4,7 +4,7 @@ import {useFocusEffect} from '@react-navigation/native' import {ComAtprotoLabelDefs} from '@atproto/api' import {Trans, msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {AppBskyLabelerDefs} from '@atproto/api' +import {AppBskyLabelerDefs, LABELS} from '@atproto/api' import {useSafeAreaFrame} from 'react-native-safe-area-context' import {NativeStackScreenProps, CommonNavigatorParams} from '#/lib/routes/types' @@ -38,7 +38,7 @@ import {InlineLink, Link} from '#/components/Link' import {Loader} from '#/components/Loader' import {getModerationServiceTitle} from '#/lib/moderation' import * as ModerationServiceCard from '#/components/ModerationServiceCard' -import {ModerationLabelPref} from '#/components/ModerationLabelPref' +import {SimpleModerationLabelPref} from '#/components/ModerationLabelPref/SimpleModerationLabelPref' function ErrorState({error}: {error: string}) { const t = useTheme() @@ -297,13 +297,25 @@ export function ModerationScreenInner({ {adultContentEnabled && ( <> - + - + - + - + )} diff --git a/src/screens/Profile/Sections/Labels.tsx b/src/screens/Profile/Sections/Labels.tsx index 6e203f57ef..42ffb623ca 100644 --- a/src/screens/Profile/Sections/Labels.tsx +++ b/src/screens/Profile/Sections/Labels.tsx @@ -154,7 +154,7 @@ export function ProfileLabelsSectionInner({