Override prefs in all locations
This commit is contained in:
@@ -2,7 +2,7 @@ import {createContext, useContext, useMemo} from 'react'
|
||||
import {type AppBskyUnspeccedDefs} from '@atproto/api'
|
||||
import {useQuery, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {wait} from '#/lib/async/wait'
|
||||
// import {wait} from '#/lib/async/wait'
|
||||
import {isNetworkError} from '#/lib/strings/errors'
|
||||
import {Logger} from '#/logger'
|
||||
import {
|
||||
@@ -39,14 +39,27 @@ export function Provider({children}: {children: React.ReactNode}) {
|
||||
const {geolocation} = useGeolocation()
|
||||
|
||||
const {data, isFetched, refetch} = useQuery({
|
||||
enabled: !!agent.session,
|
||||
/**
|
||||
* This is load bearing. We always want this query to run and end in a
|
||||
* "fetched" state, even if we fall back to defaults. This lets the rest of
|
||||
* the app know that we've at least attempted to load the AA state.
|
||||
*/
|
||||
enabled: true,
|
||||
queryKey: createAgeAssuranceQueryKey(agent.session?.did ?? 'never'),
|
||||
async queryFn() {
|
||||
if (!agent.session) return null
|
||||
|
||||
try {
|
||||
const {data} = await wait(
|
||||
1e3,
|
||||
agent.app.bsky.unspecced.getAgeAssuranceState(),
|
||||
)
|
||||
const {data} = await agent.app.bsky.unspecced.getAgeAssuranceState()
|
||||
// const {data} = await wait(
|
||||
// 1e3,
|
||||
// (() => ({
|
||||
// data: {
|
||||
// lastInitiatedAt: new Date().toISOString(),
|
||||
// status: 'assured',
|
||||
// } as AppBskyUnspeccedDefs.AgeAssuranceState,
|
||||
// }))(),
|
||||
// )
|
||||
|
||||
logger.debug(`fetch`, {
|
||||
data,
|
||||
|
||||
@@ -1,21 +1,42 @@
|
||||
import {useCallback} from 'react'
|
||||
import {type ModerationPrefs} from '@atproto/api'
|
||||
|
||||
// import {Logger} from '#/logger'
|
||||
import {useAgeAssuranceContext} from '#/state/age-assurance'
|
||||
import {AGE_RESTRICTED_MODERATION_PREFS} from '#/state/age-assurance/const'
|
||||
|
||||
// const logger = Logger.create(Logger.Context.AgeAssurance)
|
||||
|
||||
/**
|
||||
* Hook to conditionally apply age-restricted moderation preferences, if
|
||||
* needed. If not needed, the mod prefs passed to the callback will be used.
|
||||
*/
|
||||
export function useMaybeApplyAgeRestrictedModerationPrefs() {
|
||||
const {isLoaded, isAgeRestricted, isExempt} = useAgeAssuranceContext()
|
||||
const state = useAgeAssuranceContext()
|
||||
return useCallback(
|
||||
(prev: ModerationPrefs) => {
|
||||
const isDefinitelyAgeRestricted = isLoaded && isAgeRestricted
|
||||
const notSureYet = !isLoaded && isAgeRestricted
|
||||
const isDefinitelyAgeRestricted = state.isLoaded && state.isAgeRestricted
|
||||
const notSureYet = !state.isLoaded && state.isAgeRestricted
|
||||
|
||||
if (isExempt) return prev
|
||||
if (notSureYet || isDefinitelyAgeRestricted)
|
||||
if (state.isExempt) {
|
||||
// logger.debug('useMaybeApplyAgeRestrictedModerationPrefs: exempt', state)
|
||||
return prev
|
||||
}
|
||||
|
||||
if (notSureYet || isDefinitelyAgeRestricted) {
|
||||
// logger.debug(
|
||||
// 'useMaybeApplyAgeRestrictedModerationPrefs: overridden',
|
||||
// state,
|
||||
// )
|
||||
return AGE_RESTRICTED_MODERATION_PREFS
|
||||
}
|
||||
|
||||
// logger.debug(
|
||||
// 'useMaybeApplyAgeRestrictedModerationPrefs: not overridden',
|
||||
// state,
|
||||
// )
|
||||
return prev
|
||||
},
|
||||
[isLoaded, isAgeRestricted, isExempt],
|
||||
[state],
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import React from 'react'
|
||||
import {AppBskyActorDefs, moderateProfile, ModerationOpts} from '@atproto/api'
|
||||
import {
|
||||
type AppBskyActorDefs,
|
||||
moderateProfile,
|
||||
type ModerationOpts,
|
||||
} from '@atproto/api'
|
||||
import {keepPreviousData, useQuery, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {isJustAMute, moduiContainsHideableOffense} from '#/lib/moderation'
|
||||
import {logger} from '#/logger'
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
import {STALE} from '#/state/queries'
|
||||
import {usePreferencesQuery} from '#/state/queries/preferences'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useModerationOpts} from '../preferences/moderation-opts'
|
||||
import {DEFAULT_LOGGED_OUT_PREFERENCES} from './preferences'
|
||||
|
||||
const DEFAULT_MOD_OPTS = {
|
||||
userDid: undefined,
|
||||
prefs: DEFAULT_LOGGED_OUT_PREFERENCES.moderationPrefs,
|
||||
}
|
||||
|
||||
const RQKEY_ROOT = 'actor-autocomplete'
|
||||
export const RQKEY = (prefix: string) => [RQKEY_ROOT, prefix]
|
||||
|
||||
@@ -24,6 +24,7 @@ export function useActorAutocompleteQuery(
|
||||
) {
|
||||
const moderationOpts = useModerationOpts()
|
||||
const agent = useAgent()
|
||||
const {data: preferences} = usePreferencesQuery()
|
||||
|
||||
prefix = prefix.toLowerCase().trim()
|
||||
if (prefix.endsWith('.')) {
|
||||
@@ -48,10 +49,15 @@ export function useActorAutocompleteQuery(
|
||||
return computeSuggestions({
|
||||
q: prefix,
|
||||
searched: data,
|
||||
moderationOpts: moderationOpts || DEFAULT_MOD_OPTS,
|
||||
moderationOpts: moderationOpts || {
|
||||
userDid: undefined,
|
||||
prefs:
|
||||
preferences?.moderationPrefs ||
|
||||
DEFAULT_LOGGED_OUT_PREFERENCES.moderationPrefs,
|
||||
},
|
||||
})
|
||||
},
|
||||
[prefix, moderationOpts],
|
||||
[prefix, moderationOpts, preferences],
|
||||
),
|
||||
placeholderData: maintainData ? keepPreviousData : undefined,
|
||||
})
|
||||
@@ -62,6 +68,7 @@ export function useActorAutocompleteFn() {
|
||||
const queryClient = useQueryClient()
|
||||
const moderationOpts = useModerationOpts()
|
||||
const agent = useAgent()
|
||||
const {data: preferences} = usePreferencesQuery()
|
||||
|
||||
return React.useCallback(
|
||||
async ({query, limit = 8}: {query: string; limit?: number}) => {
|
||||
@@ -88,10 +95,15 @@ export function useActorAutocompleteFn() {
|
||||
return computeSuggestions({
|
||||
q: query,
|
||||
searched: res?.data.actors,
|
||||
moderationOpts: moderationOpts || DEFAULT_MOD_OPTS,
|
||||
moderationOpts: moderationOpts || {
|
||||
userDid: undefined,
|
||||
prefs:
|
||||
preferences?.moderationPrefs ||
|
||||
DEFAULT_LOGGED_OUT_PREFERENCES.moderationPrefs,
|
||||
},
|
||||
})
|
||||
},
|
||||
[queryClient, moderationOpts, agent],
|
||||
[queryClient, moderationOpts, agent, preferences],
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
type BskyAgent,
|
||||
moderatePost,
|
||||
type ModerationDecision,
|
||||
type ModerationPrefs,
|
||||
} from '@atproto/api'
|
||||
import {
|
||||
type InfiniteData,
|
||||
@@ -206,7 +207,11 @@ export function usePostFeedQuery(
|
||||
* some not.
|
||||
*/
|
||||
if (!agent.session) {
|
||||
assertSomePostsPassModeration(res.feed)
|
||||
assertSomePostsPassModeration(
|
||||
res.feed,
|
||||
preferences?.moderationPrefs ||
|
||||
DEFAULT_LOGGED_OUT_PREFERENCES.moderationPrefs,
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -596,7 +601,10 @@ export function* findAllProfilesInQueryData(
|
||||
}
|
||||
}
|
||||
|
||||
function assertSomePostsPassModeration(feed: AppBskyFeedDefs.FeedViewPost[]) {
|
||||
function assertSomePostsPassModeration(
|
||||
feed: AppBskyFeedDefs.FeedViewPost[],
|
||||
moderationPrefs: ModerationPrefs,
|
||||
) {
|
||||
// no posts in this feed
|
||||
if (feed.length === 0) return true
|
||||
|
||||
@@ -606,7 +614,7 @@ function assertSomePostsPassModeration(feed: AppBskyFeedDefs.FeedViewPost[]) {
|
||||
for (const item of feed) {
|
||||
const moderation = moderatePost(item.post, {
|
||||
userDid: undefined,
|
||||
prefs: DEFAULT_LOGGED_OUT_PREFERENCES.moderationPrefs,
|
||||
prefs: moderationPrefs,
|
||||
})
|
||||
|
||||
if (!moderation.ui('contentList').filter) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import {useCallback} from 'react'
|
||||
import {
|
||||
type AppBskyActorDefs,
|
||||
type BskyFeedViewPreference,
|
||||
@@ -9,6 +10,7 @@ import {PROD_DEFAULT_FEED} from '#/lib/constants'
|
||||
import {replaceEqualDeep} from '#/lib/functions'
|
||||
import {getAge} from '#/lib/strings/time'
|
||||
import {logger} from '#/logger'
|
||||
import {useAgeAssuranceContext} from '#/state/age-assurance'
|
||||
import {useMaybeApplyAgeRestrictedModerationPrefs} from '#/state/age-assurance/useMaybeApplyAgeRestrictedModerationPrefs'
|
||||
import {STALE} from '#/state/queries'
|
||||
import {
|
||||
@@ -32,16 +34,23 @@ export const preferencesQueryKey = [preferencesQueryKeyRoot]
|
||||
|
||||
export function usePreferencesQuery() {
|
||||
const agent = useAgent()
|
||||
const overrideModPrefs = useMaybeApplyAgeRestrictedModerationPrefs()
|
||||
const query = useQuery({
|
||||
const {isLoaded: isAAStateLoaded} = useAgeAssuranceContext()
|
||||
const maybeOverrideModPrefs = useMaybeApplyAgeRestrictedModerationPrefs()
|
||||
|
||||
return useQuery({
|
||||
/*
|
||||
* We must await AA state, otherwise users may see a FOUC - esb
|
||||
*/
|
||||
enabled: isAAStateLoaded,
|
||||
staleTime: STALE.SECONDS.FIFTEEN,
|
||||
structuralSharing: replaceEqualDeep,
|
||||
refetchOnWindowFocus: true,
|
||||
queryKey: preferencesQueryKey,
|
||||
queryFn: async () => {
|
||||
if (!agent.did) {
|
||||
return DEFAULT_LOGGED_OUT_PREFERENCES
|
||||
} else {
|
||||
let preferences: UsePreferencesQueryResponse =
|
||||
DEFAULT_LOGGED_OUT_PREFERENCES
|
||||
|
||||
if (agent.did) {
|
||||
const res = await agent.getPreferences()
|
||||
|
||||
// save to local storage to ensure there are labels on initial requests
|
||||
@@ -50,7 +59,7 @@ export function usePreferencesQuery() {
|
||||
res.moderationPrefs.labelers.map(l => l.did),
|
||||
)
|
||||
|
||||
const preferences: UsePreferencesQueryResponse = {
|
||||
preferences = {
|
||||
...res,
|
||||
savedFeeds: res.savedFeeds.filter(f => f.type !== 'unknown'),
|
||||
/**
|
||||
@@ -67,16 +76,18 @@ export function usePreferencesQuery() {
|
||||
},
|
||||
userAge: res.birthDate ? getAge(res.birthDate) : undefined,
|
||||
}
|
||||
return preferences
|
||||
}
|
||||
|
||||
return preferences
|
||||
},
|
||||
select: useCallback(
|
||||
(data: UsePreferencesQueryResponse) => {
|
||||
data.moderationPrefs = maybeOverrideModPrefs(data.moderationPrefs)
|
||||
return data
|
||||
},
|
||||
[maybeOverrideModPrefs],
|
||||
),
|
||||
})
|
||||
|
||||
if (query.data) {
|
||||
query.data.moderationPrefs = overrideModPrefs(query.data.moderationPrefs)
|
||||
}
|
||||
|
||||
return query
|
||||
}
|
||||
|
||||
export function useClearPreferencesMutation() {
|
||||
|
||||
Reference in New Issue
Block a user