point the remaining view moderation call sites at the sdk

The rest of the consumer surface - components, screens and the legacy `view`
tree - takes its moderation types from `@bsky.app/sdk/moderation` and its
`moderate*` calls from the `lib/moderation/subjects` seam.

`DebugMod` constructs a `ModerationOpts` by hand for its scenario matrix, so
its literal `userDid` is branded at the construction site.
This commit is contained in:
Samuel Newman
2026-08-04 02:36:13 +03:00
parent de09c83f99
commit d6af1c5d36
83 changed files with 172 additions and 195 deletions
@@ -1,8 +1,9 @@
import {useCallback, useMemo} from 'react'
import {moderateProfile, type ModerationOpts} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {keepPreviousData, useQuery} from '@tanstack/react-query'
import {isJustAMute, moduiContainsHideableOffense} from '#/lib/moderation'
import {moderateProfile} from '#/lib/moderation/subjects'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {STALE} from '#/state/queries'
import {DEFAULT_LOGGED_OUT_PREFERENCES} from '#/state/queries/preferences'
+1 -1
View File
@@ -8,8 +8,8 @@ import Animated, {
withDelay,
withTiming,
} from 'react-native-reanimated'
import {moderateProfile} from '@atproto/api'
import {moderateProfile} from '#/lib/moderation/subjects'
import {useMaybeProfileShadow} from '#/state/cache/profile-shadow'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useSession} from '#/state/session'
+1 -1
View File
@@ -1,6 +1,6 @@
import {View} from 'react-native'
import {moderateProfile} from '@atproto/api'
import {moderateProfile} from '#/lib/moderation/subjects'
import {logger} from '#/logger'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useProfilesQuery} from '#/state/queries/profile'
+3 -5
View File
@@ -1,12 +1,10 @@
import {useRef} from 'react'
import {View} from 'react-native'
import {
type AppBskyActorDefs,
moderateProfile,
type ModerationOpts,
} from '@atproto/api'
import {type AppBskyActorDefs} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {Plural, Trans, useLingui} from '@lingui/react/macro'
import {moderateProfile} from '#/lib/moderation/subjects'
import {makeProfileLink} from '#/lib/routes/links'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {UserAvatar} from '#/view/com/util/UserAvatar'
+3 -6
View File
@@ -1,16 +1,13 @@
import {useEffect, useMemo} from 'react'
import {View} from 'react-native'
import {
type AppBskyGraphDefs,
AtUri,
moderateUserList,
type ModerationUI,
} from '@atproto/api'
import {type AppBskyGraphDefs, AtUri} from '@atproto/api'
import {type ModerationUI} from '@bsky.app/sdk/moderation'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
import {useQueryClient} from '@tanstack/react-query'
import {moderateUserList} from '#/lib/moderation/subjects'
import {sanitizeHandle} from '#/lib/strings/handles'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {precacheList} from '#/state/queries/feed'
+2 -1
View File
@@ -1,6 +1,6 @@
import {useMemo, useState} from 'react'
import {View} from 'react-native'
import {type AppBskyActorDefs, moderateProfile} from '@atproto/api'
import {type AppBskyActorDefs} from '@atproto/api'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
@@ -8,6 +8,7 @@ import {differenceInSeconds} from 'date-fns'
import {HITSLOP_10} from '#/lib/constants'
import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
import {moderateProfile} from '#/lib/moderation/subjects'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useSession} from '#/state/session'
+1 -1
View File
@@ -1,6 +1,6 @@
import {useMemo} from 'react'
import {moderateFeedGenerator} from '@atproto/api'
import {moderateFeedGenerator} from '#/lib/moderation/subjects'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {atoms as a, useTheme} from '#/alf'
import * as FeedCard from '#/components/FeedCard'
+1 -1
View File
@@ -1,6 +1,6 @@
import {useMemo} from 'react'
import {moderateUserList} from '@atproto/api'
import {moderateUserList} from '#/lib/moderation/subjects'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {atoms as a, useTheme} from '#/alf'
import * as ListCard from '#/components/ListCard'
+1 -1
View File
@@ -5,12 +5,12 @@ import {
type AppBskyFeedDefs,
AppBskyFeedPost,
AtUri,
moderatePost,
} from '@atproto/api'
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
import {Trans} from '@lingui/react/macro'
import {useQueryClient} from '@tanstack/react-query'
import {moderatePost} from '#/lib/moderation/subjects'
import {makeProfileLink} from '#/lib/routes/links'
import {asSdkFacets} from '#/lib/strings/rich-text-helpers'
import {getChatInviteCodeFromUrl} from '#/lib/strings/url-helpers'
+2 -1
View File
@@ -1,5 +1,6 @@
import {type StyleProp, type ViewStyle} from 'react-native'
import {type AppBskyFeedDefs, type ModerationDecision} from '@atproto/api'
import {type AppBskyFeedDefs} from '@atproto/api'
import {type ModerationDecision} from '@bsky.app/sdk/moderation'
export enum PostEmbedViewContext {
ThreadHighlighted = 'ThreadHighlighted',
@@ -1,9 +1,6 @@
import {ScrollView, View} from 'react-native'
import {
type ChatBskyActorDefs,
moderateProfile,
type ModerationOpts,
} from '@atproto/api'
import {type ChatBskyActorDefs} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
@@ -11,6 +8,7 @@ import {useNavigation} from '@react-navigation/native'
import {isBlockedOrBlocking, isMuted} from '#/lib/moderation/blocked-and-muted'
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
import {moderateProfile} from '#/lib/moderation/subjects'
import {type NavigationProp} from '#/lib/routes/types'
import {useProfileShadow} from '#/state/cache/profile-shadow'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
+2 -1
View File
@@ -6,11 +6,12 @@ import {
View,
type ViewStyle,
} from 'react-native'
import {moderateProfile, type ModerationOpts} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {RichText as RichTextApi} from '@bsky.app/sdk/richtext'
import {useLingui} from '@lingui/react/macro'
import {getModerationCauseKey} from '#/lib/moderation'
import {moderateProfile} from '#/lib/moderation/subjects'
import {makeProfileLink} from '#/lib/routes/links'
import {forceLTR} from '#/lib/strings/bidi'
import {NON_BREAKING_SPACE} from '#/lib/strings/constants'
@@ -1,16 +1,14 @@
import {memo, useCallback, useEffect, useMemo, useReducer, useRef} from 'react'
import {View} from 'react-native'
import {
type AppBskyActorDefs,
moderateProfile,
type ModerationOpts,
} from '@atproto/api'
import {type AppBskyActorDefs} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {flip, offset, shift, size, useFloating} from '@floating-ui/react-dom'
import {msg, plural} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {useNavigation} from '@react-navigation/native'
import {getModerationCauseKey} from '#/lib/moderation'
import {moderateProfile} from '#/lib/moderation/subjects'
import {makeProfileLink} from '#/lib/routes/links'
import {type NavigationProp} from '#/lib/routes/types'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
@@ -1,6 +1,6 @@
import {memo, useCallback, useEffect, useMemo, useRef, useState} from 'react'
import {TextInput, View, type ViewToken} from 'react-native'
import {type ModerationOpts} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {Trans, useLingui} from '@lingui/react/macro'
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
@@ -4,8 +4,8 @@ import {
type AppBskyActorDefs,
type AppBskyGraphGetList,
AtUri,
type ModerationOpts,
} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {
type InfiniteData,
type UseInfiniteQueryResult,
@@ -1,11 +1,8 @@
import {useRef} from 'react'
import {type ListRenderItemInfo} from 'react-native'
import {View} from 'react-native'
import {
type AppBskyActorDefs,
type AppBskyFeedDefs,
type ModerationOpts,
} from '@atproto/api'
import {type AppBskyActorDefs, type AppBskyFeedDefs} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
@@ -1,17 +1,12 @@
import {Keyboard, View} from 'react-native'
import {
type AppBskyActorDefs,
type AppBskyFeedDefs,
moderateFeedGenerator,
moderateProfile,
type ModerationOpts,
type ModerationUI,
} from '@atproto/api'
import {type AppBskyActorDefs, type AppBskyFeedDefs} from '@atproto/api'
import {type ModerationOpts, type ModerationUI} from '@bsky.app/sdk/moderation'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
import {DISCOVER_FEED_URI, STARTER_PACK_MAX_SIZE} from '#/lib/constants'
import {moderateFeedGenerator, moderateProfile} from '#/lib/moderation/subjects'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles'
import {useSession} from '#/state/session'
+1 -1
View File
@@ -7,8 +7,8 @@ import {
AppBskyEmbedVideo,
type AppBskyFeedDefs,
AppBskyFeedPost,
type ModerationDecision,
} from '@atproto/api'
import {type ModerationDecision} from '@bsky.app/sdk/moderation'
import {useLingui} from '@lingui/react/macro'
import {sanitizeHandle} from '#/lib/strings/handles'
@@ -1,5 +1,5 @@
import {useCallback, useEffect, useState} from 'react'
import {type ModerationOpts} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {Trans, useLingui} from '@lingui/react/macro'
import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerification'
@@ -1,11 +1,8 @@
import {useMemo, useState} from 'react'
import {View} from 'react-native'
import {
type AppBskyNotificationDefs,
type ModerationOpts,
type Un$Typed,
} from '@atproto/api'
import {type AppBskyNotificationDefs, type Un$Typed} from '@atproto/api'
import {type DidString} from '@atproto/syntax'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
@@ -2,8 +2,8 @@ import {useCallback, useMemo, useRef, useState} from 'react'
import {View} from 'react-native'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import * as SMS from 'expo-sms'
import {type ModerationOpts} from '@atproto/api'
import {type DidString} from '@atproto/syntax'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Plural, Trans} from '@lingui/react/macro'
@@ -7,10 +7,11 @@ import {
useState,
} from 'react'
import {TextInput, View} from 'react-native'
import {moderateProfile, type ModerationOpts} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {Plural, Trans, useLingui} from '@lingui/react/macro'
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
import {moderateProfile} from '#/lib/moderation/subjects'
import {sanitizeHandle} from '#/lib/strings/handles'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
@@ -1,6 +1,7 @@
import {useCallback, useMemo} from 'react'
import {View} from 'react-native'
import {type AppBskyGraphDefs, type ModerationOpts} from '@atproto/api'
import {type AppBskyGraphDefs} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
+2 -1
View File
@@ -1,5 +1,6 @@
import {View} from 'react-native'
import {type ChatBskyConvoDefs, type ModerationOpts} from '@atproto/api'
import {type ChatBskyConvoDefs} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {useLingui} from '@lingui/react/macro'
import {MessageContextMenu} from '#/components/dms/MessageContextMenu'
+2 -1
View File
@@ -1,6 +1,7 @@
import {useCallback, useRef, useState} from 'react'
import {Pressable, View} from 'react-native'
import {type ChatBskyConvoDefs, type ModerationOpts} from '@atproto/api'
import {type ChatBskyConvoDefs} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {plural} from '@lingui/core/macro'
import {useLingui} from '@lingui/react/macro'
+1 -1
View File
@@ -1,6 +1,6 @@
import {Fragment} from 'react'
import {View} from 'react-native'
import {type ModerationCause} from '@atproto/api'
import {type ModerationCause} from '@bsky.app/sdk/moderation'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
+1 -1
View File
@@ -1,10 +1,10 @@
import {useCallback, useEffect} from 'react'
import {type ScrollView, View} from 'react-native'
import Animated, {useAnimatedRef, useSharedValue} from 'react-native-reanimated'
import {moderateProfile} from '@atproto/api'
import {useLingui} from '@lingui/react/macro'
import {HITSLOP_10} from '#/lib/constants'
import {moderateProfile} from '#/lib/moderation/subjects'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
+1 -1
View File
@@ -1,6 +1,6 @@
import {memo, useCallback} from 'react'
import {Keyboard, View} from 'react-native'
import {type ModerationCause} from '@atproto/api'
import {type ModerationCause} from '@bsky.app/sdk/moderation'
import {Trans, useLingui} from '@lingui/react/macro'
import {useNavigation} from '@react-navigation/native'
import {useQueryClient} from '@tanstack/react-query'
+2 -1
View File
@@ -7,11 +7,12 @@ import {
useState,
} from 'react'
import {LayoutAnimation, type TextInput, View} from 'react-native'
import {moderateProfile, type ModerationOpts} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {Plural, Trans, useLingui} from '@lingui/react/macro'
import {MAX_GROUP_NAME_GRAPHEME_LENGTH} from '#/lib/constants'
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
import {moderateProfile} from '#/lib/moderation/subjects'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles'
import {isOverMaxGraphemeCount} from '#/lib/strings/helpers'
+2 -1
View File
@@ -2,7 +2,8 @@ import {memo, useCallback} from 'react'
import {Platform} from 'react-native'
import {type GestureType} from 'react-native-gesture-handler'
import * as Clipboard from 'expo-clipboard'
import {type ChatBskyConvoDefs, type ModerationOpts} from '@atproto/api'
import {type ChatBskyConvoDefs} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {RichText} from '@bsky.app/sdk/richtext'
import {plural} from '@lingui/core/macro'
import {useLingui} from '@lingui/react/macro'
+1 -1
View File
@@ -27,7 +27,6 @@ import {
type ChatBskyActorDefs,
ChatBskyConvoDefs,
ChatBskyEmbedJoinLink,
moderateProfile,
} from '@atproto/api'
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
import {plural} from '@lingui/core/macro'
@@ -36,6 +35,7 @@ import {useQueryClient} from '@tanstack/react-query'
import {isBlockedOrBlocking} from '#/lib/moderation/blocked-and-muted'
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
import {moderateProfile} from '#/lib/moderation/subjects'
import {sanitizeHandle} from '#/lib/strings/handles'
import {asSdkFacets} from '#/lib/strings/rich-text-helpers'
import {useMaybeProfileShadow} from '#/state/cache/profile-shadow'
@@ -1,6 +1,6 @@
import {useCallback, useMemo} from 'react'
import {View} from 'react-native'
import {type ModerationDecision} from '@atproto/api'
import {type ModerationDecision} from '@bsky.app/sdk/moderation'
import {Trans, useLingui} from '@lingui/react/macro'
import {useProfileShadow} from '#/state/cache/profile-shadow'
+2 -1
View File
@@ -1,9 +1,10 @@
import {useMemo} from 'react'
import {View} from 'react-native'
import {moderateProfile, type ModerationOpts} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {useLingui} from '@lingui/react/macro'
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
import {moderateProfile} from '#/lib/moderation/subjects'
import {makeProfileLink} from '#/lib/routes/links'
import {sanitizeHandle} from '#/lib/strings/handles'
import {useProfileShadow} from '#/state/cache/profile-shadow'
@@ -1,7 +1,8 @@
import {View} from 'react-native'
import {moderateProfile, type ModerationOpts} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {Trans} from '@lingui/react/macro'
import {moderateProfile} from '#/lib/moderation/subjects'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles'
import {atoms as a, useTheme} from '#/alf'
+3 -7
View File
@@ -1,13 +1,9 @@
import {
type $Typed,
ChatBskyActorDefs,
ChatBskyConvoDefs,
moderateProfile,
type ModerationOpts,
} from '@atproto/api'
import {type $Typed, ChatBskyActorDefs, ChatBskyConvoDefs} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {EMOJI_REACTION_LIMIT} from '#/lib/constants'
import {isBlockedOrBlocking} from '#/lib/moderation/blocked-and-muted'
import {moderateProfile} from '#/lib/moderation/subjects'
import {logger} from '#/logger'
import {type Shadow} from '#/state/cache/profile-shadow'
import {type ConvoState, ConvoStatus} from '#/state/messages/convo/types'
@@ -4,9 +4,8 @@ import {
AppBskyEmbedRecordWithMedia,
type AppBskyFeedDefs,
AppBskyFeedPost,
type ModerationCause,
type ModerationUI,
} from '@atproto/api'
import {type ModerationCause, type ModerationUI} from '@bsky.app/sdk/moderation'
import {unique} from '#/lib/moderation'
import {type AppModerationCause} from '#/components/Pills'
@@ -1,11 +1,12 @@
import {useEffect} from 'react'
import {View} from 'react-native'
import {ChatBskyGroupDefs, moderateProfile} from '@atproto/api'
import {ChatBskyGroupDefs} from '@atproto/api'
import {Plural, Trans, useLingui} from '@lingui/react/macro'
import {useNavigation} from '@react-navigation/native'
import {useQueryClient} from '@tanstack/react-query'
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
import {moderateProfile} from '#/lib/moderation/subjects'
import {useCallOnce} from '#/lib/once'
import {makeProfileLink} from '#/lib/routes/links'
import {type NavigationProp} from '#/lib/routes/types'
@@ -1,8 +1,9 @@
import {useMemo} from 'react'
import {Pressable, View} from 'react-native'
import {type AppBskyUnspeccedDefs, moderateProfile} from '@atproto/api'
import {type AppBskyUnspeccedDefs} from '@atproto/api'
import {Plural, Trans, useLingui} from '@lingui/react/macro'
import {moderateProfile} from '#/lib/moderation/subjects'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {
useTrendingSettings,