diff --git a/src/components/ModerationLabelPref/index.tsx b/src/components/ModerationLabelPref/index.tsx
index 0407704889..96c219f083 100644
--- a/src/components/ModerationLabelPref/index.tsx
+++ b/src/components/ModerationLabelPref/index.tsx
@@ -2,25 +2,29 @@ import React from 'react'
import {View} from 'react-native'
import {useLingui} from '@lingui/react'
import {msg} from '@lingui/macro'
-import {LABEL_GROUPS} from '@atproto/api'
-import {useLabelGroupStrings} from '#/lib/moderation/useLabelGroupStrings'
+import {useLabelStrings} from '#/lib/moderation/useLabelStrings'
import {useTheme, atoms as a} from '#/alf'
import {Text} from '#/components/Typography'
import * as ToggleButton from '#/components/forms/ToggleButton'
export function ModerationLabelPref({
- labelGroup,
+ label,
disabled,
}: {
- labelGroup: keyof typeof LABEL_GROUPS
+ label: string
disabled?: boolean
}) {
const t = useTheme()
const {_} = useLingui()
- const labelGroupStrings = useLabelGroupStrings()
- const groupInfoStrings = labelGroupStrings[labelGroup]
+ const allLabelStrings = useLabelStrings()
+ const labelStrings = allLabelStrings[label] || {
+ general: {
+ name: label,
+ description: `Labeled "${label}"`,
+ },
+ }
// TODO add onChange behavior when mod prefs are updated
@@ -42,16 +46,16 @@ export function ModerationLabelPref({
a.align_center,
]}>
- {groupInfoStrings.name}
+ {labelStrings.general.name}
- {groupInfoStrings.description}
+ {labelStrings.general.description}
{!disabled && (
{}}>
diff --git a/src/components/ReportDialog/index.tsx b/src/components/ReportDialog/index.tsx
index f222d49a3f..fbbe3b7269 100644
--- a/src/components/ReportDialog/index.tsx
+++ b/src/components/ReportDialog/index.tsx
@@ -32,7 +32,6 @@ import {
getModerationServiceTitle,
useConfigurableContentLabelGroups,
useConfigurableProfileLabelGroups,
- getLabelGroupToLabelerMap,
} from '#/lib/moderation'
import {DMCA_LINK} from '#/components/ReportDialog/const'
import {Link} from '#/components/Link'
@@ -165,12 +164,10 @@ function SubmitView({
selectedLabelGroup,
goBack,
onSubmitComplete,
- labelGroupToLabelerMap,
}: ReportDialogProps & {
selectedLabelGroup: ReportDialogLabelIds
goBack: () => void
onSubmitComplete: () => void
- labelGroupToLabelerMap: ReturnType
}) {
const t = useTheme()
const {_} = useLingui()
@@ -178,7 +175,7 @@ function SubmitView({
const groupInfoStrings = labelGroupStrings[selectedLabelGroup]
const [details, setDetails] = React.useState('')
const [submitting, setSubmitting] = React.useState(false)
- const supportedLabelers = labelGroupToLabelerMap[selectedLabelGroup]
+ const supportedLabelers = [] //labelGroupToLabelerMap[selectedLabelGroup]
const [selectedServices, setSelectedServices] = React.useState(
supportedLabelers?.map(labeler => labeler.creator.did) || [],
)
diff --git a/src/lib/moderation.ts b/src/lib/moderation.ts
index fd22d7de8a..065bad4cc4 100644
--- a/src/lib/moderation.ts
+++ b/src/lib/moderation.ts
@@ -2,8 +2,6 @@ import React from 'react'
import {
ModerationCause,
ModerationUI,
- LABEL_GROUPS,
- LabelGroupDefinition,
AppBskyModerationDefs,
} from '@atproto/api'
@@ -27,54 +25,19 @@ export function isJustAMute(modui: ModerationUI): boolean {
return modui.filters.length === 1 && modui.filters[0].type === 'muted'
}
-export function getLabelGroupsFromLabels(labels: string[]) {
- const groups: LabelGroupDefinition[] = []
-
- for (const label of labels) {
- for (const group in LABEL_GROUPS) {
- const def = LABEL_GROUPS[group as LabelGroupDefinition['id']]
- if (def.labels.find(l => l.id === label)) {
- groups.push(def)
- }
- }
- }
-
- return Array.from(groups)
-}
-
-export function getConfigurableLabelGroups() {
- return Object.values(LABEL_GROUPS).filter(group => group.configurable)
-}
-
-export function useConfigurableLabelGroups() {
- return React.useMemo(() => getConfigurableLabelGroups(), [])
-}
-
export function useConfigurableContentLabelGroups() {
- return React.useMemo(() => {
- const groups = getConfigurableLabelGroups()
- return groups.filter(group => {
- return group.labels.every(l => l.targets.includes('content'))
- })
- }, [])
+ // TODO removeme
+ return []
}
export function useConfigurableProfileLabelGroups() {
- return React.useMemo(() => {
- const groups = getConfigurableLabelGroups()
- return groups.filter(group => {
- return group.labels.every(l => l.targets.includes('profile'))
- })
- }, [])
+ // TODO removeme
+ return []
}
export function useConfigurableAccountLabelGroups() {
- return React.useMemo(() => {
- const groups = getConfigurableLabelGroups()
- return groups.filter(group => {
- return group.labels.every(l => l.targets.includes('account'))
- })
- }, [])
+ // TODO removeme
+ return []
}
export function getModerationServiceTitle({
@@ -88,31 +51,3 @@ export function getModerationServiceTitle({
? sanitizeDisplayName(displayName)
: sanitizeHandle(handle, '@')
}
-
-export function getLabelGroupToLabelerMap(
- labelers: AppBskyModerationDefs.ModServiceViewDetailed[],
-) {
- if (!labelers) return {}
-
- const groups: Partial<
- Record<
- LabelGroupDefinition['id'] | 'other',
- AppBskyModerationDefs.ModServiceViewDetailed[]
- >
- > = {
- // `other` reports go to all labelers TODO confirm this
- other: labelers,
- }
-
- for (const modservice of labelers) {
- const labelGroups = getLabelGroupsFromLabels(
- modservice.policies.labelValues,
- )
- for (const group of labelGroups) {
- const g = (groups[group.id] = groups[group.id] || [])
- g.push(modservice)
- }
- }
-
- return groups
-}
diff --git a/src/lib/moderation/useLabelStrings.ts b/src/lib/moderation/useLabelStrings.ts
index e6a376976f..5542f53d3f 100644
--- a/src/lib/moderation/useLabelStrings.ts
+++ b/src/lib/moderation/useLabelStrings.ts
@@ -1,10 +1,9 @@
-import {LABELS} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useMemo} from 'react'
export type LabelStrings = Record<
- keyof typeof LABELS,
+ string,
{
general: {name: string; description: string}
account: {name: string; description: string}
diff --git a/src/lib/moderation/useModerationCauseDescription.ts b/src/lib/moderation/useModerationCauseDescription.ts
index 2df72a3d55..17283566a7 100644
--- a/src/lib/moderation/useModerationCauseDescription.ts
+++ b/src/lib/moderation/useModerationCauseDescription.ts
@@ -1,4 +1,4 @@
-import {ModerationCause} from '@atproto/api'
+import {ModerationCause, LABELS} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useLabelStrings} from './useLabelStrings'
@@ -76,8 +76,9 @@ export function useModerationCauseDescription(
}
}
if (cause.type === 'label') {
- if (cause.labelDef.id in labelStrings) {
- const strings = labelStrings[cause.labelDef.id]
+ if (cause.labelDef.identifier in labelStrings) {
+ const strings =
+ labelStrings[cause.labelDef.identifier as keyof typeof LABELS]
return {
name:
context === 'account' ? strings.account.name : strings.content.name,
@@ -88,8 +89,8 @@ export function useModerationCauseDescription(
}
}
return {
- name: cause.labelDef.id,
- description: _(msg`Labeled ${cause.labelDef.id}`),
+ name: cause.labelDef.identifier,
+ description: _(msg`Labeled ${cause.labelDef.identifier}`),
}
}
// should never happen
diff --git a/src/screens/Moderation/index.tsx b/src/screens/Moderation/index.tsx
index c13a37098f..633447b739 100644
--- a/src/screens/Moderation/index.tsx
+++ b/src/screens/Moderation/index.tsx
@@ -86,7 +86,7 @@ export function ModerationScreen(
data: modservices,
error: modservicesError,
} = useModServicesDetailedInfoQuery({
- dids: preferences ? preferences.moderationOpts.mods.map(m => m.did) : [],
+ dids: preferences ? preferences.moderationPrefs.mods.map(m => m.did) : [],
})
const {gtMobile} = useBreakpoints()
const {height} = useSafeAreaFrame()
@@ -149,7 +149,7 @@ export function ModerationScreenInner({
usePreferencesSetAdultContentMutation()
const adultContentEnabled = !!(
(optimisticAdultContent && optimisticAdultContent.enabled) ||
- (!optimisticAdultContent && preferences.moderationOpts.adultContentEnabled)
+ (!optimisticAdultContent && preferences.moderationPrefs.adultContentEnabled)
)
const onToggleAdultContentEnabled = React.useCallback(
@@ -323,7 +323,9 @@ export function ModerationScreenInner({
modservice={{
uri: '',
cid: '',
- policies: {},
+ policies: {
+ labelValues: [],
+ },
creator: {
did: '',
handle: 'safety.bsky.app',
@@ -360,7 +362,7 @@ export function ModerationScreenInner({
handle: mod.creator.handle,
})}
handle={mod.creator.handle}
- description={mod.description}
+ description={mod.creator.description || ''}
/>
diff --git a/src/screens/Profile/Header/ProfileHeaderModerator.tsx b/src/screens/Profile/Header/ProfileHeaderModerator.tsx
index eb2499a082..773178bcc1 100644
--- a/src/screens/Profile/Header/ProfileHeaderModerator.tsx
+++ b/src/screens/Profile/Header/ProfileHeaderModerator.tsx
@@ -69,7 +69,7 @@ let ProfileHeaderModerator = ({
useModServiceSubscriptionMutation()
const isSubscribed =
variables?.subscribe ??
- preferences?.moderationOpts.mods.find(mod => mod.did === profile.did)
+ preferences?.moderationPrefs.mods.find(mod => mod.did === profile.did)
const {mutateAsync: likeMod, isPending: isLikePending} = useLikeMutation()
const {mutateAsync: unlikeMod, isPending: isUnlikePending} =
useUnlikeMutation()
diff --git a/src/screens/Profile/Sections/ContentFilters.tsx b/src/screens/Profile/Sections/ContentFilters.tsx
index 89d307265c..1e6f3547b8 100644
--- a/src/screens/Profile/Sections/ContentFilters.tsx
+++ b/src/screens/Profile/Sections/ContentFilters.tsx
@@ -6,7 +6,6 @@ import {useLingui} from '@lingui/react'
import {useSafeAreaFrame} from 'react-native-safe-area-context'
import {useModServiceSubscriptionMutation} from '#/state/queries/modservice'
-import {getLabelGroupsFromLabels} from '#/lib/moderation'
import {logger} from '#/logger'
import {useTheme, atoms as a} from '#/alf'
@@ -76,15 +75,8 @@ export function ProfileContentFiltersSectionInner({
}) {
const {_} = useLingui()
const t = useTheme()
- const groups = React.useMemo(() => {
- return getLabelGroupsFromLabels(modservice.policies.labelValues).filter(
- def => def.configurable,
- )
- }, [modservice.policies.labelValues])
const isEnabled = Boolean(
- moderationOpts.mods.find(
- mod => mod.did === modservice.creator.did && mod.enabled,
- ),
+ moderationOpts.prefs.mods.find(mod => mod.did === modservice.creator.did),
)
const hasSession = true // TODO
@@ -92,7 +84,7 @@ export function ProfileContentFiltersSectionInner({
useModServiceSubscriptionMutation()
const isSubscribed =
variables?.subscribe ??
- moderationOpts.mods.find(mod => mod.did === modservice.creator.did)
+ moderationOpts.prefs.mods.find(mod => mod.did === modservice.creator.did)
const onPressSubscribe = React.useCallback(async () => {
try {
@@ -142,7 +134,8 @@ export function ProfileContentFiltersSectionInner({
a.border,
t.atoms.border_contrast_low,
]}>
- {groups.map((def, i) => {
+ {
+ undefined /* TODO modservice.policies.labelValues.map((def, i) => {
return (
{i !== 0 && }
@@ -152,7 +145,8 @@ export function ProfileContentFiltersSectionInner({
/>
)
- })}
+ })*/
+ }
diff --git a/src/state/modals/index.tsx b/src/state/modals/index.tsx
index c39d72a8c3..36b2d6ddc9 100644
--- a/src/state/modals/index.tsx
+++ b/src/state/modals/index.tsx
@@ -119,10 +119,6 @@ export interface AddAppPasswordModal {
name: 'add-app-password'
}
-export interface ContentFilteringSettingsModal {
- name: 'content-filtering-settings'
-}
-
export interface ContentLanguagesSettingsModal {
name: 'content-languages-settings'
}
@@ -182,7 +178,6 @@ export type Modal =
| SwitchAccountModal
// Curation
- | ContentFilteringSettingsModal
| ContentLanguagesSettingsModal
| PostLanguagesSettingsModal
diff --git a/src/state/queries/actor-autocomplete.ts b/src/state/queries/actor-autocomplete.ts
index 9559d671ea..f14b3d65f1 100644
--- a/src/state/queries/actor-autocomplete.ts
+++ b/src/state/queries/actor-autocomplete.ts
@@ -10,7 +10,10 @@ import {DEFAULT_LOGGED_OUT_PREFERENCES, useModerationOpts} from './preferences'
import {isInvalidHandle} from '#/lib/strings/handles'
import {isJustAMute} from '#/lib/moderation'
-const DEFAULT_MOD_OPTS = DEFAULT_LOGGED_OUT_PREFERENCES.moderationOpts
+const DEFAULT_MOD_OPTS = {
+ userDid: undefined,
+ prefs: DEFAULT_LOGGED_OUT_PREFERENCES.moderationPrefs,
+}
export const RQKEY = (prefix: string) => ['actor-autocomplete', prefix]
diff --git a/src/state/queries/modservice.ts b/src/state/queries/modservice.ts
index 3a2e708cc7..15fc6ae84e 100644
--- a/src/state/queries/modservice.ts
+++ b/src/state/queries/modservice.ts
@@ -26,10 +26,11 @@ export function useModServiceInfoQuery({
enabled: !!did && enabled !== false,
queryKey: modServiceInfoQueryKey(did as string),
queryFn: async () => {
- const res = await getAgent().app.bsky.moderation.getService({
- did: did as string,
+ const res = await getAgent().app.bsky.moderation.getServices({
+ dids: [did as string],
+ detailed: true,
})
- return res.data
+ return res.data.views[0] as AppBskyModerationDefs.ModServiceViewDetailed
},
})
}
@@ -40,7 +41,7 @@ export function useModServicesInfoQuery({dids}: {dids: string[]}) {
queryKey: modServicesInfoQueryKey(dids),
queryFn: async () => {
const res = await getAgent().app.bsky.moderation.getServices({dids})
- return res.data.views
+ return res.data.views as AppBskyModerationDefs.ModServiceView[]
},
})
}
@@ -50,23 +51,11 @@ export function useModServicesDetailedInfoQuery({dids}: {dids: string[]}) {
enabled: !!dids.length,
queryKey: modServicesDetailedInfoQueryKey(dids),
queryFn: async () => {
- const views: AppBskyModerationDefs.ModServiceViewDetailed[] = []
-
- await Promise.all(
- dids.map(did => {
- return getAgent()
- .app.bsky.moderation.getService({did})
- .then(res => {
- views.push(res.data)
- })
- .catch(e => {
- console.error(e)
- return null
- })
- }),
- )
-
- return views
+ const res = await getAgent().app.bsky.moderation.getServices({
+ dids,
+ detailed: true,
+ })
+ return res.data.views as AppBskyModerationDefs.ModServiceViewDetailed[]
},
})
}
@@ -95,50 +84,3 @@ export function useModServiceSubscriptionMutation() {
},
})
}
-
-export function useModServiceEnableMutation() {
- const queryClient = useQueryClient()
-
- return useMutation({
- async mutationFn({did, enabled}: {did: string; enabled: boolean}) {
- // TODO
- z.object({
- did: z.string(),
- enabled: z.boolean(),
- }).parse({did, enabled})
- await getAgent().setModServiceEnabled(did, enabled)
- await queryClient.invalidateQueries({
- queryKey: preferencesQueryKey,
- })
- },
- })
-}
-
-export function useModServiceLabelGroupEnableMutation() {
- const queryClient = useQueryClient()
-
- return useMutation({
- async mutationFn({
- did,
- group,
- enabled,
- }: {
- did: string
- group: string
- enabled: boolean
- }) {
- // TODO
- z.object({
- did: z.string(),
- group: z.string(),
- enabled: z.boolean(),
- }).parse({did, group, enabled})
- await getAgent().setModServiceLabelGroupEnabled(did, group, enabled)
- },
- onSuccess() {
- queryClient.invalidateQueries({
- queryKey: preferencesQueryKey,
- })
- },
- })
-}
diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts
index 51aa941a57..4899e53ff7 100644
--- a/src/state/queries/post-feed.ts
+++ b/src/state/queries/post-feed.ts
@@ -423,10 +423,10 @@ function assertSomePostsPassModeration(feed: AppBskyFeedDefs.FeedViewPost[]) {
let somePostsPassModeration = false
for (const item of feed) {
- const moderation = moderatePost(
- item.post,
- DEFAULT_LOGGED_OUT_PREFERENCES.moderationOpts,
- )
+ const moderation = moderatePost(item.post, {
+ userDid: undefined,
+ prefs: DEFAULT_LOGGED_OUT_PREFERENCES.moderationPrefs,
+ })
if (!moderation.ui('contentList').filter) {
// we have a sfw post
diff --git a/src/state/queries/preferences/const.ts b/src/state/queries/preferences/const.ts
index 84db427a95..f03103581c 100644
--- a/src/state/queries/preferences/const.ts
+++ b/src/state/queries/preferences/const.ts
@@ -34,14 +34,15 @@ export const DEFAULT_LOGGED_OUT_PREFERENCES: UsePreferencesQueryResponse = {
pinned: [],
unpinned: [],
},
- moderationOpts: {
- userDid: '',
+ moderationPrefs: {
adultContentEnabled: false,
- labelGroups: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES,
+ labels: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES,
mods: [],
},
feedViewPrefs: DEFAULT_HOME_FEED_PREFS,
threadViewPrefs: DEFAULT_THREAD_VIEW_PREFS,
userAge: 13, // TODO(pwi)
interests: {tags: []},
+ mutedWords: [],
+ hiddenPosts: [],
}
diff --git a/src/state/queries/preferences/index.ts b/src/state/queries/preferences/index.ts
index 101713f80e..76fff47ab7 100644
--- a/src/state/queries/preferences/index.ts
+++ b/src/state/queries/preferences/index.ts
@@ -4,7 +4,6 @@ import {
LabelPreference,
BskyFeedViewPreference,
ModerationOpts,
- LabelGroupDefinition,
} from '@atproto/api'
import {track} from '#/lib/analytics/analytics'
@@ -77,17 +76,20 @@ export function useModerationOpts() {
const override = useContext(moderationOptsOverrideContext)
const prefs = usePreferencesQuery()
const hiddenPosts = useHiddenPosts()
- const opts = useMemo(() => {
+ const opts = useMemo(() => {
if (override) {
return override
}
if (!prefs.data) {
return
}
- const moderationOpts = prefs.data.moderationOpts
+ const moderationPrefs = prefs.data.moderationPrefs
return {
- ...moderationOpts,
- hiddenPosts,
+ userDid: '', // TODO
+ prefs: {
+ ...moderationPrefs,
+ hiddenPosts,
+ },
}
}, [override, prefs.data, hiddenPosts])
return opts
@@ -130,13 +132,15 @@ export function useSetContentLabelMutation() {
return useMutation({
mutationFn: async ({
- labelGroup,
+ label,
visibility,
+ labelerDid,
}: {
- labelGroup: LabelGroupDefinition['id']
+ label: string
visibility: LabelPreference
+ labelerDid?: string
}) => {
- await getAgent().setContentLabelPref(labelGroup, visibility)
+ await getAgent().setContentLabelPref(label, visibility, labelerDid)
// triggers a refetch
await queryClient.invalidateQueries({
queryKey: preferencesQueryKey,
diff --git a/src/state/queries/preferences/moderation.ts b/src/state/queries/preferences/moderation.ts
index f5d3367018..c26d25fef2 100644
--- a/src/state/queries/preferences/moderation.ts
+++ b/src/state/queries/preferences/moderation.ts
@@ -1,4 +1,4 @@
-import {ComAtprotoLabelDefs, DEFAULT_LABEL_GROUP_SETTINGS} from '@atproto/api'
+import {ComAtprotoLabelDefs, DEFAULT_LABEL_SETTINGS} from '@atproto/api'
import {
LabelGroup,
@@ -21,12 +21,9 @@ export type LabelGroupConfig = {
*
* TODO(pwi)
*/
-export const DEFAULT_LOGGED_OUT_LABEL_PREFERENCES: typeof DEFAULT_LABEL_GROUP_SETTINGS =
+export const DEFAULT_LOGGED_OUT_LABEL_PREFERENCES: typeof DEFAULT_LABEL_SETTINGS =
Object.fromEntries(
- Object.entries(DEFAULT_LABEL_GROUP_SETTINGS).map(([key, _pref]) => [
- key,
- 'hide',
- ]),
+ Object.entries(DEFAULT_LABEL_SETTINGS).map(([key, _pref]) => [key, 'hide']),
)
export const CONFIGURABLE_LABEL_GROUPS: Record<
diff --git a/src/view/com/modals/ContentFilteringSettings.tsx b/src/view/com/modals/ContentFilteringSettings.tsx
deleted file mode 100644
index 77f0082b31..0000000000
--- a/src/view/com/modals/ContentFilteringSettings.tsx
+++ /dev/null
@@ -1,406 +0,0 @@
-import React from 'react'
-import {LabelPreference} from '@atproto/api'
-import {StyleSheet, Pressable, View, Linking} from 'react-native'
-import LinearGradient from 'react-native-linear-gradient'
-import {ScrollView} from './util'
-import {s, colors, gradients} from 'lib/styles'
-import {Text} from '../util/text/Text'
-import {TextLink} from '../util/Link'
-import {ToggleButton} from '../util/forms/ToggleButton'
-import {Button} from '../util/forms/Button'
-import {usePalette} from 'lib/hooks/usePalette'
-import {isIOS} from 'platform/detection'
-import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
-import * as Toast from '../util/Toast'
-import {logger} from '#/logger'
-import {Trans, msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
-import {useModalControls} from '#/state/modals'
-import {
- usePreferencesQuery,
- usePreferencesSetContentLabelMutation,
- usePreferencesSetAdultContentMutation,
- ConfigurableLabelGroup,
- CONFIGURABLE_LABEL_GROUPS,
- UsePreferencesQueryResponse,
-} from '#/state/queries/preferences'
-
-export const snapPoints = ['90%']
-
-export function Component({}: {}) {
- const {isMobile} = useWebMediaQueries()
- const pal = usePalette('default')
- const {_} = useLingui()
- const {closeModal} = useModalControls()
- const {data: preferences} = usePreferencesQuery()
-
- const onPressDone = React.useCallback(() => {
- closeModal()
- }, [closeModal])
-
- return (
-
-
- Content Filtering
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Done
-
-
-
-
-
- )
-}
-
-function AdultContentEnabledPref() {
- const pal = usePalette('default')
- const {_} = useLingui()
- const {data: preferences} = usePreferencesQuery()
- const {mutate, variables} = usePreferencesSetAdultContentMutation()
- const {openModal} = useModalControls()
-
- const onSetAge = React.useCallback(
- () => openModal({name: 'birth-date-settings'}),
- [openModal],
- )
-
- const onToggleAdultContent = React.useCallback(async () => {
- if (isIOS) return
-
- try {
- mutate({
- enabled: !(
- variables?.enabled ?? preferences?.moderationOpts.adultContentEnabled
- ),
- })
- } catch (e) {
- Toast.show(
- _(msg`There was an issue syncing your preferences with the server`),
- )
- logger.error('Failed to update preferences with server', {message: e})
- }
- }, [variables, preferences, mutate, _])
-
- const onAdultContentLinkPress = React.useCallback(() => {
- Linking.openURL('https://bsky.app/')
- }, [])
-
- return (
-
- {isIOS ? (
- preferences?.moderationOpts.adultContentEnabled ? null : (
-
-
- Adult content can only be enabled via the Web at{' '}
-
- .
-
-
- )
- ) : typeof preferences?.birthDate === 'undefined' ? (
-
-
- Confirm your age to enable adult content.
-
-
-
- ) : (preferences.userAge || 0) >= 18 ? (
-
- ) : (
-
-
- You must be 18 or older to enable adult content.
-
-
-
- )}
-
- )
-}
-
-// TODO: Refactor this component to pass labels down to each tab
-function ContentLabelPref({
- preferences,
- labelGroup,
- disabled,
-}: {
- preferences?: UsePreferencesQueryResponse
- labelGroup: ConfigurableLabelGroup
- disabled?: boolean
-}) {
- const pal = usePalette('default')
- const visibility = preferences?.moderationOpts.labelGroups?.[labelGroup]
- const {mutate, variables} = usePreferencesSetContentLabelMutation()
-
- const onChange = React.useCallback(
- (vis: LabelPreference) => {
- mutate({labelGroup, visibility: vis})
- },
- [mutate, labelGroup],
- )
-
- return (
-
-
-
- {CONFIGURABLE_LABEL_GROUPS[labelGroup].title}
-
- {typeof CONFIGURABLE_LABEL_GROUPS[labelGroup].subtitle === 'string' && (
-
- {CONFIGURABLE_LABEL_GROUPS[labelGroup].subtitle}
-
- )}
-
-
- {disabled || !visibility ? (
-
- Hide
-
- ) : (
-
- )}
-
- )
-}
-
-interface SelectGroupProps {
- current: LabelPreference
- onChange: (v: LabelPreference) => void
- labelGroup: ConfigurableLabelGroup
-}
-
-function SelectGroup({current, onChange, labelGroup}: SelectGroupProps) {
- const {_} = useLingui()
-
- return (
-
-
-
-
-
- )
-}
-
-interface SelectableBtnProps {
- current: string
- value: LabelPreference
- label: string
- left?: boolean
- right?: boolean
- onChange: (v: LabelPreference) => void
- labelGroup: ConfigurableLabelGroup
-}
-
-function SelectableBtn({
- current,
- value,
- label,
- left,
- right,
- onChange,
- labelGroup,
-}: SelectableBtnProps) {
- const pal = usePalette('default')
- const palPrimary = usePalette('inverted')
- const {_} = useLingui()
-
- return (
- onChange(value)}
- accessibilityRole="button"
- accessibilityLabel={value}
- accessibilityHint={_(
- msg`Set ${value} for ${labelGroup} content moderation policy`,
- )}>
-
- {label}
-
-
- )
-}
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- },
- title: {
- textAlign: 'center',
- fontWeight: 'bold',
- fontSize: 24,
- marginBottom: 12,
- },
- description: {
- paddingHorizontal: 2,
- marginBottom: 10,
- },
- scrollContainer: {
- flex: 1,
- paddingHorizontal: 10,
- },
- btnContainer: {
- paddingTop: 10,
- paddingHorizontal: 10,
- },
- btnContainerMobile: {
- paddingBottom: 40,
- borderTopWidth: 1,
- },
-
- agePrompt: {
- flexDirection: 'row',
- justifyContent: 'space-between',
- alignItems: 'center',
- paddingLeft: 14,
- paddingRight: 10,
- paddingVertical: 8,
- borderRadius: 8,
- },
-
- contentLabelPref: {
- flexDirection: 'row',
- justifyContent: 'space-between',
- alignItems: 'center',
- paddingTop: 14,
- paddingLeft: 4,
- marginBottom: 14,
- borderTopWidth: 1,
- },
-
- selectableBtns: {
- flexDirection: 'row',
- marginLeft: 10,
- },
- selectableBtn: {
- flexDirection: 'row',
- justifyContent: 'center',
- borderWidth: 1,
- borderLeftWidth: 0,
- paddingHorizontal: 10,
- paddingVertical: 10,
- },
- selectableBtnLeft: {
- borderTopLeftRadius: 8,
- borderBottomLeftRadius: 8,
- borderLeftWidth: 1,
- },
- selectableBtnRight: {
- borderTopRightRadius: 8,
- borderBottomRightRadius: 8,
- },
-
- btn: {
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'center',
- width: '100%',
- borderRadius: 32,
- padding: 14,
- backgroundColor: colors.gray1,
- },
- toggleBtn: {
- paddingHorizontal: 0,
- },
-})
diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx
index 5664b941c7..822e1020c0 100644
--- a/src/view/com/modals/Modal.tsx
+++ b/src/view/com/modals/Modal.tsx
@@ -22,7 +22,6 @@ import * as ChangeHandleModal from './ChangeHandle'
import * as WaitlistModal from './Waitlist'
import * as InviteCodesModal from './InviteCodes'
import * as AddAppPassword from './AddAppPasswords'
-import * as ContentFilteringSettingsModal from './ContentFilteringSettings'
import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguagesSettings'
import * as PostLanguagesSettingsModal from './lang-settings/PostLanguagesSettings'
import * as BirthDateSettingsModal from './BirthDateSettings'
@@ -113,9 +112,6 @@ export function ModalsContainer() {
} else if (activeModal?.name === 'add-app-password') {
snapPoints = AddAppPassword.snapPoints
element =
- } else if (activeModal?.name === 'content-filtering-settings') {
- snapPoints = ContentFilteringSettingsModal.snapPoints
- element =
} else if (activeModal?.name === 'content-languages-settings') {
snapPoints = ContentLanguagesSettingsModal.snapPoints
element =
diff --git a/src/view/com/modals/Modal.web.tsx b/src/view/com/modals/Modal.web.tsx
index 10966364e6..2d2a6f6e6e 100644
--- a/src/view/com/modals/Modal.web.tsx
+++ b/src/view/com/modals/Modal.web.tsx
@@ -24,7 +24,6 @@ import * as ChangeHandleModal from './ChangeHandle'
import * as WaitlistModal from './Waitlist'
import * as InviteCodesModal from './InviteCodes'
import * as AddAppPassword from './AddAppPasswords'
-import * as ContentFilteringSettingsModal from './ContentFilteringSettings'
import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguagesSettings'
import * as PostLanguagesSettingsModal from './lang-settings/PostLanguagesSettings'
import * as BirthDateSettingsModal from './BirthDateSettings'
@@ -107,8 +106,6 @@ function Modal({modal}: {modal: ModalIface}) {
element =
} else if (modal.name === 'add-app-password') {
element =
- } else if (modal.name === 'content-filtering-settings') {
- element =
} else if (modal.name === 'content-languages-settings') {
element =
} else if (modal.name === 'post-languages-settings') {
diff --git a/src/view/com/moderation/AdultContentPref.tsx b/src/view/com/moderation/AdultContentPref.tsx
deleted file mode 100644
index 6e34fcaa37..0000000000
--- a/src/view/com/moderation/AdultContentPref.tsx
+++ /dev/null
@@ -1,103 +0,0 @@
-import React from 'react'
-import {StyleSheet, View} from 'react-native'
-import {s} from 'lib/styles'
-import {Text} from '../util/text/Text'
-import {TextLink} from '../util/Link'
-import {ToggleButton} from '../util/forms/ToggleButton'
-import {Button} from '../util/forms/Button'
-import {usePalette} from 'lib/hooks/usePalette'
-import {isIOS} from 'platform/detection'
-import * as Toast from '../util/Toast'
-import {logger} from '#/logger'
-import {Trans, msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
-import {useModalControls} from '#/state/modals'
-import {
- usePreferencesQuery,
- usePreferencesSetAdultContentMutation,
-} from '#/state/queries/preferences'
-
-export function AdultContentEnabledPref() {
- const pal = usePalette('default')
- const {_} = useLingui()
- const {data: preferences} = usePreferencesQuery()
- const {mutate, variables} = usePreferencesSetAdultContentMutation()
- const {openModal} = useModalControls()
-
- const onSetAge = React.useCallback(
- () => openModal({name: 'birth-date-settings'}),
- [openModal],
- )
-
- const onToggleAdultContent = React.useCallback(async () => {
- if (isIOS) return
-
- try {
- mutate({
- enabled: !(
- variables?.enabled ?? preferences?.moderationOpts.adultContentEnabled
- ),
- })
- } catch (e) {
- Toast.show(
- _(msg`There was an issue syncing your preferences with the server`),
- )
- logger.error('Failed to update preferences with server', {error: e})
- }
- }, [variables, preferences, mutate, _])
-
- return (
-
- {isIOS ? (
- preferences?.moderationOpts.adultContentEnabled ? null : (
-
-
-
- Adult content can only be enabled via the Web at{' '}
-
- .
-
-
-
- )
- ) : (preferences?.userAge || 0) >= 18 ? (
-
-
-
- ) : (
-
-
- You must be 18 or older to enable adult content.
-
-
- )}
-
- )
-}
-
-const styles = StyleSheet.create({
- agePrompt: {
- flexDirection: 'row',
- justifyContent: 'space-between',
- alignItems: 'center',
- paddingVertical: 12,
- },
- toggleBtn: {
- paddingHorizontal: 0,
- backgroundColor: 'transparent',
- },
-})
diff --git a/src/view/com/moderation/LabelGroupPref.tsx b/src/view/com/moderation/LabelGroupPref.tsx
deleted file mode 100644
index 187ded725f..0000000000
--- a/src/view/com/moderation/LabelGroupPref.tsx
+++ /dev/null
@@ -1,178 +0,0 @@
-import React from 'react'
-import {LabelPreference} from '@atproto/api'
-import {StyleSheet, Pressable, View} from 'react-native'
-import {s} from 'lib/styles'
-import {Text} from '../util/text/Text'
-import {usePalette} from 'lib/hooks/usePalette'
-import {Trans, msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
-import {
- usePreferencesSetContentLabelMutation,
- ConfigurableLabelGroup,
- CONFIGURABLE_LABEL_GROUPS,
- UsePreferencesQueryResponse,
-} from '#/state/queries/preferences'
-
-export function LabelGroupPref({
- preferences,
- labelGroup,
- disabled,
-}: {
- preferences?: UsePreferencesQueryResponse
- labelGroup: ConfigurableLabelGroup
- disabled?: boolean
-}) {
- const pal = usePalette('default')
- const visibility = preferences?.moderationOpts.labelGroups?.[labelGroup]
- const {mutate, variables} = usePreferencesSetContentLabelMutation()
-
- const onChange = React.useCallback(
- (vis: LabelPreference) => {
- mutate({labelGroup, visibility: vis})
- },
- [mutate, labelGroup],
- )
-
- return (
-
-
-
- {CONFIGURABLE_LABEL_GROUPS[labelGroup].title}
-
- {typeof CONFIGURABLE_LABEL_GROUPS[labelGroup].subtitle === 'string' && (
-
- {CONFIGURABLE_LABEL_GROUPS[labelGroup].subtitle}
-
- )}
-
-
- {disabled || !visibility ? (
-
- Hide
-
- ) : (
-
- )}
-
- )
-}
-
-interface SelectGroupProps {
- current: LabelPreference
- onChange: (v: LabelPreference) => void
- labelGroup: ConfigurableLabelGroup
-}
-
-function SelectGroup({current, onChange, labelGroup}: SelectGroupProps) {
- const {_} = useLingui()
-
- return (
-
-
-
-
-
- )
-}
-
-interface SelectableBtnProps {
- current: string
- value: LabelPreference
- label: string
- left?: boolean
- right?: boolean
- onChange: (v: LabelPreference) => void
- labelGroup: ConfigurableLabelGroup
-}
-
-function SelectableBtn({
- current,
- value,
- label,
- left,
- right,
- onChange,
- labelGroup,
-}: SelectableBtnProps) {
- const pal = usePalette('default')
- const palPrimary = usePalette('inverted')
- const {_} = useLingui()
-
- return (
- onChange(value)}
- accessibilityRole="button"
- accessibilityLabel={value}
- accessibilityHint={_(
- msg`Set ${value} for ${labelGroup} content moderation policy`,
- )}>
-
- {label}
-
-
- )
-}
-const styles = StyleSheet.create({
- labelGroupPref: {
- flexDirection: 'row',
- justifyContent: 'space-between',
- alignItems: 'center',
- paddingVertical: 14,
- paddingLeft: 14,
- paddingRight: 10,
- borderTopWidth: 1,
- },
-
- selectableBtns: {
- flexDirection: 'row',
- marginLeft: 10,
- },
- selectableBtn: {
- flexDirection: 'row',
- justifyContent: 'center',
- borderWidth: 1,
- borderLeftWidth: 0,
- paddingHorizontal: 10,
- paddingVertical: 10,
- },
- selectableBtnLeft: {
- borderTopLeftRadius: 8,
- borderBottomLeftRadius: 8,
- borderLeftWidth: 1,
- },
- selectableBtnRight: {
- borderTopRightRadius: 8,
- borderBottomRightRadius: 8,
- },
-})
diff --git a/src/view/com/moderation/ModServiceHeader.tsx b/src/view/com/moderation/ModServiceHeader.tsx
deleted file mode 100644
index 63f2872a1f..0000000000
--- a/src/view/com/moderation/ModServiceHeader.tsx
+++ /dev/null
@@ -1,226 +0,0 @@
-import React from 'react'
-import {Pressable, StyleSheet, View} from 'react-native'
-import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
-import {useNavigation} from '@react-navigation/native'
-import {usePalette} from 'lib/hooks/usePalette'
-import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
-import {Text} from '../util/text/Text'
-import {TextLink} from '../util/Link'
-import {CenteredView} from '../util/Views'
-import {sanitizeHandle} from 'lib/strings/handles'
-import {makeProfileLink} from 'lib/routes/links'
-import {NavigationProp} from 'lib/routes/types'
-import {BACK_HITSLOP} from 'lib/constants'
-import {isNative} from 'platform/detection'
-import {useLingui} from '@lingui/react'
-import {Trans, msg} from '@lingui/macro'
-import {useSetDrawerOpen} from '#/state/shell'
-import {emitSoftReset} from '#/state/events'
-import {AppBskyModerationDefs} from '@atproto/api'
-import {HandIcon} from '#/lib/icons'
-import {shareUrl} from 'lib/sharing'
-import {sanitizeDisplayName} from '#/lib/strings/display-names'
-import {Button} from '../util/forms/Button'
-import {NativeDropdown, DropdownItem} from 'view/com/util/forms/NativeDropdown'
-import {useSession} from '#/state/session'
-import {useModalControls} from '#/state/modals'
-
-export function ModServiceHeader({
- info,
-}: {
- info: AppBskyModerationDefs.ModServiceViewDetailed
-}) {
- const setDrawerOpen = useSetDrawerOpen()
- const navigation = useNavigation()
- const {_} = useLingui()
- const {isMobile} = useWebMediaQueries()
- const pal = usePalette('default')
- const canGoBack = navigation.canGoBack()
-
- const onPressBack = React.useCallback(() => {
- if (navigation.canGoBack()) {
- navigation.goBack()
- } else {
- navigation.navigate('Home')
- }
- }, [navigation])
-
- const onPressMenu = React.useCallback(() => {
- setDrawerOpen(true)
- }, [setDrawerOpen])
-
- return (
-
- {isMobile && (
-
-
- {canGoBack ? (
-
- ) : (
-
- )}
-
-
-
-
- )}
-
-
-
-
-
-
-
- Moderation service
-
-
-
-
- {!isMobile && }
-
-
-
- )
-}
-
-function CommonControls({
- info,
-}: {
- info: AppBskyModerationDefs.ModServiceViewDetailed
-}) {
- const pal = usePalette('default')
- const {hasSession} = useSession()
- const {openModal} = useModalControls()
- const {_} = useLingui()
-
- const onPressShare = React.useCallback(() => {
- const url = makeProfileLink(info.creator, 'modservice')
- shareUrl(url)
- // track('CustomFeed:Share') TODO
- }, [info /*, track*/])
-
- const onPressReport = React.useCallback(() => {
- if (!info) return
- openModal({
- name: 'report',
- uri: info.uri,
- cid: info.cid,
- })
- }, [openModal, info])
-
- const dropdownItems: DropdownItem[] = React.useMemo(() => {
- return [
- hasSession && {
- testID: 'modHeaderDropdownReportBtn',
- label: _(msg`Report mod service`),
- onPress: onPressReport,
- icon: {
- ios: {
- name: 'exclamationmark.triangle',
- },
- android: 'ic_menu_report_image',
- web: 'circle-exclamation',
- },
- },
- {
- testID: 'modHeaderDropdownShareBtn',
- label: _(msg`Share mod service`),
- onPress: onPressShare,
- icon: {
- ios: {
- name: 'square.and.arrow.up',
- },
- android: 'ic_menu_share',
- web: 'share',
- },
- },
- ].filter(Boolean) as DropdownItem[]
- }, [hasSession, onPressReport, onPressShare, _])
-
- return (
- <>
-
-
-
-
-
- >
- )
-}
-
-const styles = StyleSheet.create({
- backBtn: {
- width: 20,
- height: 30,
- },
- backBtnWide: {
- width: 20,
- height: 30,
- paddingHorizontal: 6,
- },
- backIcon: {
- marginTop: 6,
- },
- btn: {
- flexDirection: 'row',
- alignItems: 'center',
- gap: 6,
- paddingVertical: 7,
- paddingHorizontal: 14,
- borderRadius: 50,
- },
-})
diff --git a/src/view/com/moderation/ModServicePrefs.tsx b/src/view/com/moderation/ModServicePrefs.tsx
deleted file mode 100644
index 1234281769..0000000000
--- a/src/view/com/moderation/ModServicePrefs.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import React from 'react'
-import {View} from 'react-native'
-import {usePreferencesQuery} from '#/state/queries/preferences'
-import {LabelGroupPref} from './LabelGroupPref'
-import {Text} from '../util/text/Text'
-import {usePalette} from '#/lib/hooks/usePalette'
-
-export function ModServicePrefs({}: {}) {
- const pal = usePalette('default')
- const {data: preferences} = usePreferencesQuery()
-
- return (
-
-
- Settings
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx
index 69a959bf62..16c20be13b 100644
--- a/src/view/com/posts/FeedItem.tsx
+++ b/src/view/com/posts/FeedItem.tsx
@@ -302,7 +302,6 @@ let FeedItemInner = ({
moderation={moderation}
richText={richText}
postEmbed={post.embed}
- postAuthor={post.author}
/>
{
return {
- ...MOCK_MOD_OPTS,
userDid: isLoggedOut ? '' : isTargetMe ? did : 'did:web:alice.test',
- adultContentEnabled: !noAdult,
- labelGroups: {
- [LABELS[label[0] as keyof typeof LABELS].groupId]:
- visibility[0] as LabelPreference,
+ prefs: {
+ ...MOCK_MOD_PREFS,
+ adultContentEnabled: !noAdult,
+ labels: {
+ [label[0]]: visibility[0] as LabelPreference,
+ },
},
}
}, [label, visibility, noAdult, isLoggedOut, isTargetMe, did])
@@ -353,11 +353,8 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
targetFixed = 'content'
}
const disabled =
- !LABELS[labelValue].targets.includes(
- targetFixed as LabelTarget,
- ) ||
- (isSelfLabel &&
- LABELS[labelValue].flags.includes('no-self'))
+ isSelfLabel &&
+ LABELS[labelValue].flags.includes('no-self')
return (