flip the preferences and labeler reads to sdk types
`UsePreferencesQueryResponse` now derives from the sdk's `BskyPreferences` rather than the legacy one, which removes the cast the previous slice put on the assembled response - the query already returns the sdk action's result, so the two now type structurally. `labeler.ts`'s three service reads move to the appview client and return `app.bsky.labeler.defs` views, because `interpretLabelValueDefinitions` takes the lexicon-typed view. `moderation-opts.tsx` reads `Client.appLabelers` instead of `AtpAgent.appLabelers`: the lex static is already branded, so the fallback labeler list satisfies `ModerationPrefsLabeler` without a cast. `MutedWords` follows the prefs types: `expiresAt` is a `DatetimeString` now, built with `toDatetimeString` rather than `Date.toISOString`, and `sanitizeMutedWordValue` comes from `@bsky.app/sdk/utils`.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import {useCallback, useState} from 'react'
|
import {useCallback, useState} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type AppBskyActorDefs, sanitizeMutedWordValue} from '@atproto/api'
|
import {type DatetimeString, toDatetimeString} from '@atproto/syntax'
|
||||||
|
import {sanitizeMutedWordValue} from '@bsky.app/sdk/utils'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
@@ -35,6 +36,7 @@ import * as Menu from '#/components/Menu'
|
|||||||
import * as Prompt from '#/components/Prompt'
|
import * as Prompt from '#/components/Prompt'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {IS_NATIVE} from '#/env'
|
import {IS_NATIVE} from '#/env'
|
||||||
|
import {type app} from '#/lexicons'
|
||||||
|
|
||||||
const ONE_DAY = 24 * 60 * 60 * 1000
|
const ONE_DAY = 24 * 60 * 60 * 1000
|
||||||
|
|
||||||
@@ -68,20 +70,20 @@ function MutedWordsInner() {
|
|||||||
const sanitizedValue = sanitizeMutedWordValue(field)
|
const sanitizedValue = sanitizeMutedWordValue(field)
|
||||||
const surfaces = ['tag', targets.includes('content') && 'content'].filter(
|
const surfaces = ['tag', targets.includes('content') && 'content'].filter(
|
||||||
Boolean,
|
Boolean,
|
||||||
) as AppBskyActorDefs.MutedWord['targets']
|
) as app.bsky.actor.defs.MutedWord['targets']
|
||||||
const actorTarget = excludeFollowing ? 'exclude-following' : 'all'
|
const actorTarget = excludeFollowing ? 'exclude-following' : 'all'
|
||||||
|
|
||||||
const now = Date.now()
|
const now = Date.now()
|
||||||
const rawDuration = durations.at(0)
|
const rawDuration = durations.at(0)
|
||||||
// undefined evaluates to 'forever'
|
// undefined evaluates to 'forever'
|
||||||
let duration: string | undefined
|
let duration: DatetimeString | undefined
|
||||||
|
|
||||||
if (rawDuration === '24_hours') {
|
if (rawDuration === '24_hours') {
|
||||||
duration = new Date(now + ONE_DAY).toISOString()
|
duration = toDatetimeString(new Date(now + ONE_DAY))
|
||||||
} else if (rawDuration === '7_days') {
|
} else if (rawDuration === '7_days') {
|
||||||
duration = new Date(now + 7 * ONE_DAY).toISOString()
|
duration = toDatetimeString(new Date(now + 7 * ONE_DAY))
|
||||||
} else if (rawDuration === '30_days') {
|
} else if (rawDuration === '30_days') {
|
||||||
duration = new Date(now + 30 * ONE_DAY).toISOString()
|
duration = toDatetimeString(new Date(now + 30 * ONE_DAY))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sanitizedValue || !surfaces.length) {
|
if (!sanitizedValue || !surfaces.length) {
|
||||||
@@ -421,7 +423,7 @@ function MutedWordsInner() {
|
|||||||
function MutedWordRow({
|
function MutedWordRow({
|
||||||
style,
|
style,
|
||||||
word,
|
word,
|
||||||
}: ViewStyleProp & {word: AppBskyActorDefs.MutedWord}) {
|
}: ViewStyleProp & {word: app.bsky.actor.defs.MutedWord}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const {isPending, mutateAsync: removeMutedWord} = useRemoveMutedWordMutation()
|
const {isPending, mutateAsync: removeMutedWord} = useRemoveMutedWordMutation()
|
||||||
@@ -440,7 +442,7 @@ function MutedWordRow({
|
|||||||
updateMutedWord({
|
updateMutedWord({
|
||||||
...word,
|
...word,
|
||||||
expiresAt: days
|
expiresAt: days
|
||||||
? new Date(Date.now() + days * ONE_DAY).toISOString()
|
? toDatetimeString(new Date(Date.now() + days * ONE_DAY))
|
||||||
: undefined,
|
: undefined,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import {PostInteractionSettingsForm} from '#/components/dialogs/PostInteractionS
|
|||||||
import * as Layout from '#/components/Layout'
|
import * as Layout from '#/components/Layout'
|
||||||
import {Loader} from '#/components/Loader'
|
import {Loader} from '#/components/Loader'
|
||||||
import * as Toast from '#/components/Toast'
|
import * as Toast from '#/components/Toast'
|
||||||
import {type app} from '#/lexicons'
|
|
||||||
|
|
||||||
export function Screen() {
|
export function Screen() {
|
||||||
const gutters = useGutters(['base'])
|
const gutters = useGutters(['base'])
|
||||||
@@ -76,15 +75,14 @@ function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) {
|
|||||||
* Preferences are still typed against the legacy client, so the stored
|
* Preferences are still typed against the legacy client, so the stored
|
||||||
* rules arrive unbranded. Wave B migrates `getPreferences`.
|
* rules arrive unbranded. Wave B migrates `getPreferences`.
|
||||||
*/
|
*/
|
||||||
allow: preferences.postInteractionSettings
|
allow: preferences.postInteractionSettings.threadgateAllowRules,
|
||||||
.threadgateAllowRules as app.bsky.feed.threadgate.Main['allow'],
|
|
||||||
})
|
})
|
||||||
}, [preferences.postInteractionSettings.threadgateAllowRules])
|
}, [preferences.postInteractionSettings.threadgateAllowRules])
|
||||||
const postgate = useMemo(() => {
|
const postgate = useMemo(() => {
|
||||||
return createPostgateRecord({
|
return createPostgateRecord({
|
||||||
post: '',
|
post: '',
|
||||||
embeddingRules: preferences.postInteractionSettings
|
embeddingRules:
|
||||||
.postgateEmbeddingRules as app.bsky.feed.postgate.Main['embeddingRules'],
|
preferences.postInteractionSettings.postgateEmbeddingRules,
|
||||||
})
|
})
|
||||||
}, [preferences.postInteractionSettings.postgateEmbeddingRules])
|
}, [preferences.postInteractionSettings.postgateEmbeddingRules])
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
import {createContext, useContext} from 'react'
|
import {createContext, useContext} from 'react'
|
||||||
import {
|
import {type InterpretedLabelValueDefinition} from '@bsky.app/sdk/moderation'
|
||||||
type AppBskyLabelerDefs,
|
|
||||||
type InterpretedLabelValueDefinition,
|
|
||||||
} from '@atproto/api'
|
|
||||||
|
|
||||||
|
import {type app} from '#/lexicons'
|
||||||
import {useLabelDefinitionsQuery} from '../queries/preferences'
|
import {useLabelDefinitionsQuery} from '../queries/preferences'
|
||||||
|
|
||||||
interface StateContext {
|
interface StateContext {
|
||||||
labelDefs: Record<string, InterpretedLabelValueDefinition[]>
|
labelDefs: Record<string, InterpretedLabelValueDefinition[]>
|
||||||
labelers: AppBskyLabelerDefs.LabelerViewDetailed[]
|
labelers: app.bsky.labeler.defs.LabelerViewDetailed[]
|
||||||
}
|
}
|
||||||
|
|
||||||
const stateContext = createContext<StateContext>({
|
const stateContext = createContext<StateContext>({
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {createContext, useContext, useMemo} from 'react'
|
import {createContext, useContext, useMemo} from 'react'
|
||||||
import {AtpAgent, type ModerationOpts} from '@atproto/api'
|
import {Client} from '@atproto/lex'
|
||||||
|
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||||
|
|
||||||
import {useHiddenPosts, useLabelDefinitions} from '#/state/preferences'
|
import {useHiddenPosts, useLabelDefinitions} from '#/state/preferences'
|
||||||
import {DEFAULT_LOGGED_OUT_LABEL_PREFERENCES} from '#/state/queries/preferences/const'
|
import {DEFAULT_LOGGED_OUT_LABEL_PREFERENCES} from '#/state/queries/preferences/const'
|
||||||
@@ -38,16 +39,21 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
userDid,
|
/*
|
||||||
|
* `did`/`hiddenPosts` come from persisted storage typed as plain
|
||||||
|
* `string`, so brand them to the SDK's `DidString`/`AtUriString` slots.
|
||||||
|
*/
|
||||||
|
userDid: userDid as ModerationOpts['userDid'],
|
||||||
prefs: {
|
prefs: {
|
||||||
...moderationPrefs,
|
...moderationPrefs,
|
||||||
labelers: moderationPrefs.labelers.length
|
labelers: moderationPrefs.labelers.length
|
||||||
? moderationPrefs.labelers
|
? moderationPrefs.labelers
|
||||||
: AtpAgent.appLabelers.map(did => ({
|
: Client.appLabelers.map(did => ({
|
||||||
did,
|
did,
|
||||||
labels: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES,
|
labels: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES,
|
||||||
})),
|
})),
|
||||||
hiddenPosts: hiddenPosts || [],
|
hiddenPosts: (hiddenPosts ||
|
||||||
|
[]) as ModerationOpts['prefs']['hiddenPosts'],
|
||||||
},
|
},
|
||||||
labelDefs,
|
labelDefs,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import {type AppBskyLabelerDefs} from '@atproto/api'
|
|
||||||
import {type DidString} from '@atproto/syntax'
|
import {type DidString} from '@atproto/syntax'
|
||||||
import {addLabeler, removeLabeler} from '@bsky.app/sdk'
|
import {addLabeler, removeLabeler} from '@bsky.app/sdk'
|
||||||
import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query'
|
import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query'
|
||||||
@@ -11,7 +10,8 @@ import {
|
|||||||
usePreferencesQuery,
|
usePreferencesQuery,
|
||||||
} from '#/state/queries/preferences'
|
} from '#/state/queries/preferences'
|
||||||
import {createQueryKey} from '#/state/queries/util'
|
import {createQueryKey} from '#/state/queries/util'
|
||||||
import {useAgent, usePdsClient} from '#/state/session'
|
import {useAppviewClient, usePdsClient} from '#/state/session'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
|
|
||||||
const labelerInfoQueryKeyRoot = 'labeler-info'
|
const labelerInfoQueryKeyRoot = 'labeler-info'
|
||||||
export const labelerInfoQueryKey = (did: string) => [
|
export const labelerInfoQueryKey = (did: string) => [
|
||||||
@@ -35,45 +35,47 @@ export function useLabelerInfoQuery({
|
|||||||
did?: string
|
did?: string
|
||||||
enabled?: boolean
|
enabled?: boolean
|
||||||
}) {
|
}) {
|
||||||
const agent = useAgent()
|
const client = useAppviewClient()
|
||||||
return useQuery({
|
return useQuery({
|
||||||
enabled: !!did && enabled !== false,
|
enabled: !!did && enabled !== false,
|
||||||
queryKey: labelerInfoQueryKey(did as string),
|
queryKey: labelerInfoQueryKey(did as string),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await agent.app.bsky.labeler.getServices({
|
const res = await client.call(app.bsky.labeler.getServices, {
|
||||||
dids: [did!],
|
dids: [did! as DidString],
|
||||||
detailed: true,
|
detailed: true,
|
||||||
})
|
})
|
||||||
return res.data.views[0] as AppBskyLabelerDefs.LabelerViewDetailed
|
return res.views[0] as app.bsky.labeler.defs.LabelerViewDetailed
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useLabelersInfoQuery({dids}: {dids: string[]}) {
|
export function useLabelersInfoQuery({dids}: {dids: string[]}) {
|
||||||
const agent = useAgent()
|
const client = useAppviewClient()
|
||||||
return useQuery({
|
return useQuery({
|
||||||
enabled: !!dids.length,
|
enabled: !!dids.length,
|
||||||
queryKey: labelersInfoQueryKey(dids),
|
queryKey: labelersInfoQueryKey(dids),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await agent.app.bsky.labeler.getServices({dids})
|
const res = await client.call(app.bsky.labeler.getServices, {
|
||||||
return res.data.views as AppBskyLabelerDefs.LabelerView[]
|
dids: dids as DidString[],
|
||||||
|
})
|
||||||
|
return res.views as app.bsky.labeler.defs.LabelerView[]
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useLabelersDetailedInfoQuery({dids}: {dids: string[]}) {
|
export function useLabelersDetailedInfoQuery({dids}: {dids: string[]}) {
|
||||||
const agent = useAgent()
|
const client = useAppviewClient()
|
||||||
return useQuery({
|
return useQuery({
|
||||||
enabled: !!dids.length,
|
enabled: !!dids.length,
|
||||||
queryKey: createLabelersDetailedInfoQueryKey(dids),
|
queryKey: createLabelersDetailedInfoQueryKey(dids),
|
||||||
gcTime: GCTIME.INFINITY,
|
gcTime: GCTIME.INFINITY,
|
||||||
staleTime: STALE.MINUTES.ONE,
|
staleTime: STALE.MINUTES.ONE,
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await agent.app.bsky.labeler.getServices({
|
const res = await client.call(app.bsky.labeler.getServices, {
|
||||||
dids,
|
dids: dids as DidString[],
|
||||||
detailed: true,
|
detailed: true,
|
||||||
})
|
})
|
||||||
return res.data.views as AppBskyLabelerDefs.LabelerViewDetailed[]
|
return res.views as app.bsky.labeler.defs.LabelerViewDetailed[]
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -98,7 +100,7 @@ export function useRemoveLabelersMutation() {
|
|||||||
|
|
||||||
export function useLabelerSubscriptionMutation() {
|
export function useLabelerSubscriptionMutation() {
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const agent = useAgent()
|
const appviewClient = useAppviewClient()
|
||||||
const pdsClient = usePdsClient()
|
const pdsClient = usePdsClient()
|
||||||
const preferences = usePreferencesQuery()
|
const preferences = usePreferencesQuery()
|
||||||
|
|
||||||
@@ -122,28 +124,30 @@ export function useLabelerSubscriptionMutation() {
|
|||||||
const labelerDids = (
|
const labelerDids = (
|
||||||
preferences.data?.moderationPrefs?.labelers ?? []
|
preferences.data?.moderationPrefs?.labelers ?? []
|
||||||
).map(l => l.did)
|
).map(l => l.did)
|
||||||
const invalidLabelers: string[] = []
|
const invalidLabelers: DidString[] = []
|
||||||
if (labelerDids.length) {
|
if (labelerDids.length) {
|
||||||
const profiles = await agent.getProfiles({actors: labelerDids})
|
const profiles = await appviewClient.call(app.bsky.actor.getProfiles, {
|
||||||
if (profiles.data) {
|
actors: labelerDids,
|
||||||
for (const did of labelerDids) {
|
})
|
||||||
const exists = profiles.data.profiles.find(p => p.did === did)
|
if (profiles) {
|
||||||
|
for (const labelerDid of labelerDids) {
|
||||||
|
const exists = profiles.profiles.find(p => p.did === labelerDid)
|
||||||
if (exists) {
|
if (exists) {
|
||||||
// profile came back but it's not a valid labeler
|
// profile came back but it's not a valid labeler
|
||||||
if (exists.associated && !exists.associated.labeler) {
|
if (exists.associated && !exists.associated.labeler) {
|
||||||
invalidLabelers.push(did)
|
invalidLabelers.push(labelerDid)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// no response came back, might be deactivated or takendown
|
// no response came back, might be deactivated or takendown
|
||||||
invalidLabelers.push(did)
|
invalidLabelers.push(labelerDid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (invalidLabelers.length) {
|
if (invalidLabelers.length) {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
invalidLabelers.map(did =>
|
invalidLabelers.map(labelerDid =>
|
||||||
pdsClient.call(removeLabeler, did as DidString),
|
pdsClient.call(removeLabeler, labelerDid),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {DEFAULT_LABEL_SETTINGS} from '@atproto/api'
|
import {DEFAULT_LABEL_SETTINGS} from '@bsky.app/sdk/moderation'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type ThreadViewPreferences,
|
type ThreadViewPreferences,
|
||||||
|
|||||||
@@ -89,13 +89,10 @@ export function usePreferencesQuery() {
|
|||||||
agent.configureLabelers(labelerDids)
|
agent.configureLabelers(labelerDids)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The sdk's `BskyPreferences` is field-for-field identical to the
|
* `BskyPreferences` is now the sdk's own type, so the assembled
|
||||||
* legacy one that `UsePreferencesQueryResponse` is still derived from;
|
* response types structurally with no cast at this seam.
|
||||||
* only its strings are branded (`AtUriString`, `DidString`). Cast at
|
|
||||||
* this one seam so every downstream consumer of the response - notably
|
|
||||||
* the `moderationPrefs` readers - keeps its current types.
|
|
||||||
*/
|
*/
|
||||||
const preferences = {
|
const preferences: UsePreferencesQueryResponse = {
|
||||||
...res,
|
...res,
|
||||||
savedFeeds: res.savedFeeds.filter(f => f.type !== 'unknown'),
|
savedFeeds: res.savedFeeds.filter(f => f.type !== 'unknown'),
|
||||||
/**
|
/**
|
||||||
@@ -111,7 +108,7 @@ export function usePreferencesQuery() {
|
|||||||
...(res.threadViewPrefs ?? {}),
|
...(res.threadViewPrefs ?? {}),
|
||||||
},
|
},
|
||||||
userAge: res.birthDate ? getAge(res.birthDate) : undefined,
|
userAge: res.birthDate ? getAge(res.birthDate) : undefined,
|
||||||
} as UsePreferencesQueryResponse
|
}
|
||||||
return preferences
|
return preferences
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -381,11 +378,8 @@ export function useUpsertMutedWordsMutation() {
|
|||||||
const client = usePdsClient()
|
const client = usePdsClient()
|
||||||
|
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async (mutedWords: AppBskyActorDefs.MutedWord[]) => {
|
mutationFn: async (mutedWords: app.bsky.actor.defs.MutedWord[]) => {
|
||||||
await client.call(
|
await client.call(upsertMutedWords, mutedWords)
|
||||||
upsertMutedWords,
|
|
||||||
mutedWords as app.bsky.actor.defs.MutedWord[],
|
|
||||||
)
|
|
||||||
// triggers a refetch
|
// triggers a refetch
|
||||||
await queryClient.invalidateQueries({
|
await queryClient.invalidateQueries({
|
||||||
queryKey: preferencesQueryKey,
|
queryKey: preferencesQueryKey,
|
||||||
@@ -399,11 +393,8 @@ export function useUpdateMutedWordMutation() {
|
|||||||
const client = usePdsClient()
|
const client = usePdsClient()
|
||||||
|
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async (mutedWord: AppBskyActorDefs.MutedWord) => {
|
mutationFn: async (mutedWord: app.bsky.actor.defs.MutedWord) => {
|
||||||
await client.call(
|
await client.call(updateMutedWord, mutedWord)
|
||||||
updateMutedWord,
|
|
||||||
mutedWord as app.bsky.actor.defs.MutedWord,
|
|
||||||
)
|
|
||||||
// triggers a refetch
|
// triggers a refetch
|
||||||
await queryClient.invalidateQueries({
|
await queryClient.invalidateQueries({
|
||||||
queryKey: preferencesQueryKey,
|
queryKey: preferencesQueryKey,
|
||||||
@@ -417,11 +408,8 @@ export function useRemoveMutedWordMutation() {
|
|||||||
const client = usePdsClient()
|
const client = usePdsClient()
|
||||||
|
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async (mutedWord: AppBskyActorDefs.MutedWord) => {
|
mutationFn: async (mutedWord: app.bsky.actor.defs.MutedWord) => {
|
||||||
await client.call(
|
await client.call(removeMutedWord, mutedWord)
|
||||||
removeMutedWord,
|
|
||||||
mutedWord as app.bsky.actor.defs.MutedWord,
|
|
||||||
)
|
|
||||||
// triggers a refetch
|
// triggers a refetch
|
||||||
await queryClient.invalidateQueries({
|
await queryClient.invalidateQueries({
|
||||||
queryKey: preferencesQueryKey,
|
queryKey: preferencesQueryKey,
|
||||||
@@ -435,11 +423,8 @@ export function useRemoveMutedWordsMutation() {
|
|||||||
const client = usePdsClient()
|
const client = usePdsClient()
|
||||||
|
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async (mutedWords: AppBskyActorDefs.MutedWord[]) => {
|
mutationFn: async (mutedWords: app.bsky.actor.defs.MutedWord[]) => {
|
||||||
await client.call(
|
await client.call(removeMutedWords, mutedWords)
|
||||||
removeMutedWords,
|
|
||||||
mutedWords as app.bsky.actor.defs.MutedWord[],
|
|
||||||
)
|
|
||||||
// triggers a refetch
|
// triggers a refetch
|
||||||
await queryClient.invalidateQueries({
|
await queryClient.invalidateQueries({
|
||||||
queryKey: preferencesQueryKey,
|
queryKey: preferencesQueryKey,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {useMemo} from 'react'
|
import {useMemo} from 'react'
|
||||||
import {AtpAgent, interpretLabelValueDefinitions} from '@atproto/api'
|
import {AtpAgent} from '@atproto/api'
|
||||||
|
import {interpretLabelValueDefinitions} from '@bsky.app/sdk/moderation'
|
||||||
|
|
||||||
import {isNonConfigurableModerationAuthority} from '#/state/session/additional-moderation-authorities'
|
import {isNonConfigurableModerationAuthority} from '#/state/session/additional-moderation-authorities'
|
||||||
import {useLabelersDetailedInfoQuery} from '../labeler'
|
import {useLabelersDetailedInfoQuery} from '../labeler'
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {type BskyFeedViewPreference, type BskyPreferences} from '@atproto/api'
|
import {type BskyFeedViewPreference, type BskyPreferences} from '@bsky.app/sdk'
|
||||||
|
|
||||||
export type UsePreferencesQueryResponse = Omit<
|
export type UsePreferencesQueryResponse = Omit<
|
||||||
BskyPreferences,
|
BskyPreferences,
|
||||||
|
|||||||
Reference in New Issue
Block a user