From 8870c5a183a30ef535027398faa711470a321089 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Thu, 15 Feb 2024 17:01:00 -0600 Subject: [PATCH] Improve Moderation screen and dialog --- src/components/Link.tsx | 11 +- src/components/ModerationServiceCard/Card.tsx | 21 +++- src/screens/Moderation/SettingsDialog.tsx | 115 ++++++++++++------ 3 files changed, 106 insertions(+), 41 deletions(-) diff --git a/src/components/Link.tsx b/src/components/Link.tsx index 25f3497014..0cd68d014c 100644 --- a/src/components/Link.tsx +++ b/src/components/Link.tsx @@ -171,11 +171,18 @@ export type LinkProps = Omit & * Intended to behave as a web anchor tag. For more complex routing, use a * `Button`. */ -export function Link({children, to, action = 'push', ...rest}: LinkProps) { +export function Link({ + children, + to, + action = 'push', + onPress: outerOnPress, + ...rest +}: LinkProps) { const {href, isExternal, onPress} = useLink({ to, displayText: typeof children === 'string' ? children : '', action, + onPress: outerOnPress, }) return ( @@ -218,6 +225,7 @@ export function InlineLink({ action = 'push', warnOnMismatchingTextChild, style, + onPress: outerOnPress, ...rest }: InlineLinkProps) { const t = useTheme() @@ -227,6 +235,7 @@ export function InlineLink({ displayText: stringChildren ? children : '', action, warnOnMismatchingTextChild, + onPress: outerOnPress, }) const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState() const { diff --git a/src/components/ModerationServiceCard/Card.tsx b/src/components/ModerationServiceCard/Card.tsx index 2dfff4c280..c86b4cdc7b 100644 --- a/src/components/ModerationServiceCard/Card.tsx +++ b/src/components/ModerationServiceCard/Card.tsx @@ -7,6 +7,7 @@ import {Text} from '#/components/Typography' import {RichText} from '#/components/RichText' import {RaisingHande4Finger_Stroke2_Corner0_Rounded as RaisingHand} from '#/components/icons/RaisingHand' import {UserAvatar} from '#/view/com/util/UserAvatar' +import {sanitizeHandle} from '#/lib/strings/handles' export function Outer({ children, @@ -43,6 +44,22 @@ export function Avatar({avatar}: {avatar?: string}) { return } +export function Title({value}: {value: string}) { + return {value} +} + +export function Description({value, handle}: {value?: string; handle: string}) { + return value ? ( + + ) : ( + + + Moderation service managed by @{sanitizeHandle(handle, '@')} + + + ) +} + export function Content({ title, description, @@ -63,7 +80,9 @@ export function Content({ ) : ( - Moderation service managed by @{handle} + + Moderation service managed by @{sanitizeHandle(handle, '@')} + )} diff --git a/src/screens/Moderation/SettingsDialog.tsx b/src/screens/Moderation/SettingsDialog.tsx index 11c7596cea..b84882286c 100644 --- a/src/screens/Moderation/SettingsDialog.tsx +++ b/src/screens/Moderation/SettingsDialog.tsx @@ -13,6 +13,10 @@ import * as ModerationServiceCard from '#/components/ModerationServiceCard' import {getModerationServiceTitle} from '#/lib/moderation' import {UsePreferencesQueryResponse} from '#/state/queries/preferences' import {useModServiceLabelGroupEnableMutation} from '#/state/queries/modservice' +import {Divider} from '#/components/Divider' +import {InlineLink} from '#/components/Link' +import {useDialogStateControlContext} from '#/state/dialogs' +import {logger} from '#/logger' function LabelerToggle({ labelGroup, @@ -24,14 +28,24 @@ function LabelerToggle({ preferences: UsePreferencesQueryResponse }) { const t = useTheme() - const {mutateAsync, variables} = useModServiceLabelGroupEnableMutation() + const { + mutateAsync: toggleGroupEnabled, + variables: optimisticToggleGroupEnabled, + } = useModServiceLabelGroupEnableMutation() + const {closeAllDialogs} = useDialogStateControlContext() - const modservicePreferences = preferences.moderationOpts.mods.find( - ({did}) => did === labeler.creator.did, + const labelerPrefs = React.useMemo( + () => + preferences.moderationOpts.mods.find( + ({did}) => did === labeler.creator.did, + ), + [preferences.moderationOpts.mods, labeler.creator.did], ) - const enabled = - variables?.enabled ?? - !modservicePreferences?.disabledLabelGroups?.includes(labelGroup) + const isLabelerEnabled = !!labelerPrefs?.enabled + const isEnabled = isLabelerEnabled + ? optimisticToggleGroupEnabled?.enabled ?? + !labelerPrefs?.disabledLabelGroups?.includes(labelGroup) + : false const title = getModerationServiceTitle({ displayName: labeler.creator.displayName, handle: labeler.creator.handle, @@ -39,42 +53,66 @@ function LabelerToggle({ const onToggleEnabled = React.useCallback(async () => { try { - await mutateAsync({ - // @ts-ignore TODO - did: modservicePreferences?.did, + if (!labelerPrefs) throw new Error(`labelerPrefs not found`) + + await toggleGroupEnabled({ + did: labelerPrefs.did, group: labelGroup, - enabled: !enabled, + enabled: !isEnabled, }) } catch (e: any) { - // TODO - console.error(e) + logger.error(`Failed to toggle label group enabled`, { + message: e.message, + labelGroup, + }) } - }, [mutateAsync, enabled, modservicePreferences, labelGroup]) + }, [toggleGroupEnabled, isEnabled, labelerPrefs, labelGroup]) + return ( - - {ctx => ( - + + + - - - )} - + + + + + + + + {isEnabled ? 'Enabled' : 'Disabled'} + + + + + + + + + Configure more settings for this labeler{' '} + + here. + + + + ) } @@ -115,11 +153,10 @@ export function SettingsDialog({ a.p_md, a.rounded_md, a.mb_xl, - a.border, - t.atoms.border_contrast_low, + t.atoms.bg_contrast_25, ]}> - {groupInfoStrings.name} + {groupInfoStrings.name} {groupInfoStrings.description}