From cecb6e4e69eaccedf56f503589a59044fd7c6d19 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Thu, 29 Feb 2024 19:30:30 -0600 Subject: [PATCH] Bump API SDK, add validation to MutedWords (#3055) * Bump API SDK, add validation to MutedWords * Tweaks to error state * Comment * Early return --- package.json | 2 +- src/components/TagMenu/index.tsx | 6 +-- src/components/TagMenu/index.web.tsx | 5 +-- src/components/dialogs/MutedWords.tsx | 60 +++++++++++++++++++++++---- yarn.lock | 40 ++++++++++++++---- 5 files changed, 89 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index e9dd9202df..378d520bcd 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "update-extensions": "scripts/updateExtensions.sh" }, "dependencies": { - "@atproto/api": "^0.10.0", + "@atproto/api": "^0.10.3", "@bam.tech/react-native-image-resizer": "^3.0.4", "@braintree/sanitize-url": "^6.0.2", "@emoji-mart/react": "^1.1.1", diff --git a/src/components/TagMenu/index.tsx b/src/components/TagMenu/index.tsx index 2fec7a1880..c18c0d6a27 100644 --- a/src/components/TagMenu/index.tsx +++ b/src/components/TagMenu/index.tsx @@ -215,14 +215,12 @@ export function TagMenu({ if (isMuted) { resetUpsert() removeMutedWord({ - value: sanitizedTag, + value: tag, targets: ['tag'], }) } else { resetRemove() - upsertMutedWord([ - {value: sanitizedTag, targets: ['tag']}, - ]) + upsertMutedWord([{value: tag, targets: ['tag']}]) } }) }}> diff --git a/src/components/TagMenu/index.web.tsx b/src/components/TagMenu/index.web.tsx index 3aebfbba20..4fcb4c8122 100644 --- a/src/components/TagMenu/index.web.tsx +++ b/src/components/TagMenu/index.web.tsx @@ -104,9 +104,9 @@ export function TagMenu({ : _(msg`Mute ${truncatedTag}`), onPress() { if (isMuted) { - removeMutedWord({value: sanitizedTag, targets: ['tag']}) + removeMutedWord({value: tag, targets: ['tag']}) } else { - upsertMutedWord([{value: sanitizedTag, targets: ['tag']}]) + upsertMutedWord([{value: tag, targets: ['tag']}]) } }, testID: 'tagMenuMute', @@ -127,7 +127,6 @@ export function TagMenu({ preferences, tag, truncatedTag, - sanitizedTag, upsertMutedWord, removeMutedWord, ]) diff --git a/src/components/dialogs/MutedWords.tsx b/src/components/dialogs/MutedWords.tsx index 7c0d4fbcaf..453b135136 100644 --- a/src/components/dialogs/MutedWords.tsx +++ b/src/components/dialogs/MutedWords.tsx @@ -2,7 +2,7 @@ import React from 'react' import {View} from 'react-native' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {AppBskyActorDefs} from '@atproto/api' +import {AppBskyActorDefs, sanitizeMutedWordValue} from '@atproto/api' import { usePreferencesQuery, @@ -10,7 +10,14 @@ import { useRemoveMutedWordMutation, } from '#/state/queries/preferences' import {isNative} from '#/platform/detection' -import {atoms as a, useTheme, useBreakpoints, ViewStyleProp, web} from '#/alf' +import { + atoms as a, + useTheme, + useBreakpoints, + ViewStyleProp, + web, + native, +} from '#/alf' import {Text} from '#/components/Typography' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' @@ -48,24 +55,29 @@ function MutedWordsInner({}: {control: Dialog.DialogOuterProps['control']}) { const {isPending, mutateAsync: addMutedWord} = useUpsertMutedWordsMutation() const [field, setField] = React.useState('') const [options, setOptions] = React.useState(['content']) - const [_error, setError] = React.useState('') + const [error, setError] = React.useState('') const submit = React.useCallback(async () => { - const value = field.trim() + const sanitizedValue = sanitizeMutedWordValue(field) const targets = ['tag', options.includes('content') && 'content'].filter( Boolean, ) as AppBskyActorDefs.MutedWord['targets'] - if (!value || !targets.length) return + if (!sanitizedValue || !targets.length) { + setField('') + setError(_(msg`Please enter a valid word, tag, or phrase to mute`)) + return + } try { - await addMutedWord([{value, targets}]) + // send raw value and rely on SDK as sanitization source of truth + await addMutedWord([{value: field, targets}]) setField('') } catch (e: any) { logger.error(`Failed to save muted word`, {message: e.message}) setError(e.message) } - }, [field, options, addMutedWord, setField]) + }, [_, field, options, addMutedWord, setField]) return ( @@ -87,7 +99,12 @@ function MutedWordsInner({}: {control: Dialog.DialogOuterProps['control']}) { label={_(msg`Enter a word or tag`)} placeholder={_(msg`Enter a word or tag`)} value={field} - onChangeText={setField} + onChangeText={value => { + if (error) { + setError('') + } + setField(value) + }} onSubmitEditing={submit} /> @@ -99,7 +116,7 @@ function MutedWordsInner({}: {control: Dialog.DialogOuterProps['control']}) { + {error && ( + + + {error} + + + )} +