diff --git a/src/components/dialogs/ReportDialog/index.tsx b/src/components/dialogs/ReportDialog/index.tsx index 122a0cef06..ab7eb8eaff 100644 --- a/src/components/dialogs/ReportDialog/index.tsx +++ b/src/components/dialogs/ReportDialog/index.tsx @@ -69,7 +69,7 @@ function LabelGroupButton({labelGroup}: {labelGroup: string}) { interacted && styles.interacted, ]}> - + {groupInfoStrings.name} @@ -88,7 +88,7 @@ function LabelGroupButton({labelGroup}: {labelGroup: string}) { @@ -135,7 +135,7 @@ function ModServiceToggle({title}: {title: string}) { fill={ ctx.selected ? t.palette.primary_200 - : t.atoms.text_contrast_400.color + : t.atoms.text_contrast_low.color } /> @@ -204,7 +204,7 @@ function SubmitView({ - + Select the moderation service(s) to report to @@ -226,7 +226,7 @@ function SubmitView({ - + Optionally provide additional information below: @@ -334,7 +334,7 @@ export function ReportDialog({ {i18n.title} - + {i18n.description} diff --git a/src/screens/Moderation/index.tsx b/src/screens/Moderation/index.tsx index 52bfe1432b..41813f6119 100644 --- a/src/screens/Moderation/index.tsx +++ b/src/screens/Moderation/index.tsx @@ -4,6 +4,11 @@ import {useFocusEffect} from '@react-navigation/native' import {ComAtprotoLabelDefs} from '@atproto/api' import {Trans, msg} from '@lingui/macro' import {useLingui} from '@lingui/react' +import { + LABEL_GROUPS, + LabelGroupDefinition, + DEFAULT_LABEL_GROUP_SETTINGS, +} from '@atproto/api' import {NativeStackScreenProps, CommonNavigatorParams} from '#/lib/routes/types' import {CenteredView} from '#/view/com/util/Views' @@ -22,18 +27,116 @@ import {Divider} from '#/components/Divider' import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/components/icons/CircleBanSign' import {Group3_Stroke2_Corner0_Rounded as Group} from '#/components/icons/Group' import {Person_Stroke2_Corner0_Rounded as Person} from '#/components/icons/Person' +import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check' import {Text} from '#/components/Typography' import * as Toggle from '#/components/forms/Toggle' +import * as ToggleButton from '#/components/forms/ToggleButton' import {InlineLink, Link} from '#/components/Link' import {Loader} from '#/components/Loader' +import {useLabelGroupStrings} from '#/lib/moderation/useLabelGroupStrings' +import * as Dialog from '#/components/Dialog' +import {Button} from '#/components/Button' -type Props = NativeStackScreenProps -export function ModerationScreen({}: Props) { +function ModSettingsToggleItem({name}: {name: string}) { + const t = useTheme() + const ctx = Toggle.useItemContext() + return ( + + {name} + {ctx.selected && } + + ) +} + +function ModSettingsDialog({ + name, + onComplete, +}: { + name: string + onComplete: () => void +}) { + const t = useTheme() + const labelGroupStrings = useLabelGroupStrings() + const [selectedServices, setSelectedServices] = React.useState([ + 'bluesky', + ]) + + const save = React.useCallback(() => { + onComplete() + }, [onComplete]) + + return ( + + + Configure moderation services + + + Select which moderation services' labels you'd like to use to filter + content matching {labelGroupStrings[name].name}. + + + + + + + + + + + + + + + + + + + + + ) +} + +export function ModerationScreen({}: NativeStackScreenProps< + CommonNavigatorParams, + 'Moderation' +>) { const t = useTheme() const {_} = useLingui() const setMinimalShellMode = useSetMinimalShellMode() const {screen} = useAnalytics() const {gtMobile, gtTablet} = useBreakpoints() + const labelGroupStrings = useLabelGroupStrings() + const modSettingsDialogControl = Dialog.useDialogControl() + const [modSettingsDialogLabelGroup, setModSettingsDialogLabelGroup] = + React.useState(() => Object.keys(LABEL_GROUPS)[0]) useFocusEffect( React.useCallback(() => { @@ -42,6 +145,25 @@ export function ModerationScreen({}: Props) { }, [screen, setMinimalShellMode]), ) + const groups = React.useMemo< + [keyof typeof LABEL_GROUPS, LabelGroupDefinition][] + >(() => { + return Object.entries(LABEL_GROUPS).filter(([, def]) => def.configurable) + }, []) + const labelOptions = { + hide: _(msg`Hide`), + warn: _(msg`Warn`), + show: _(msg`Show`), + } + + const openModSettingsDialog = React.useCallback( + ({name}: {name: string}) => { + setModSettingsDialogLabelGroup(name) + modSettingsDialogControl.open() + }, + [modSettingsDialogControl], + ) + return ( + + + + modSettingsDialogControl.close()} + /> + + @@ -119,10 +250,132 @@ export function ModerationScreen({}: Props) { + + + Content filtering settings + + + {groups.map(([name, def], i) => { + const groupStrings = labelGroupStrings[name] + return ( + + {i !== 0 && } + + + + + + {groupStrings.name} + + + {groupStrings.description} + + + + + {}}> + + {labelOptions.hide} + + + {labelOptions.warn} + + + {labelOptions.show} + + + + + + + + + + + ) + })} + + + + Logged-out visibility + + )