diff options
author | Eric Bailey <git@esb.lol> | 2024-07-12 14:55:34 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-12 14:55:34 -0500 |
commit | 3627a249ffb32e4c0f84597f8f9adf228ee90a8f (patch) | |
tree | 68c0d838c7d3624bafed4ea3e7593ca2dd1d8da0 /src/state/queries | |
parent | 7c1c24ef1badb746ecbe707d390bec4934940ced (diff) | |
download | voidsky-3627a249ffb32e4c0f84597f8f9adf228ee90a8f.tar.zst |
Remove invalid labelers when subscribing/unsubscribing (#4771)
* Remove invalid labelers when subscribing/unsubscribing * Let the async lock cook * Use link to associate, leave copy as is
Diffstat (limited to 'src/state/queries')
-rw-r--r-- | src/state/queries/labeler.ts | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/src/state/queries/labeler.ts b/src/state/queries/labeler.ts index 058e8fcde..53e923a85 100644 --- a/src/state/queries/labeler.ts +++ b/src/state/queries/labeler.ts @@ -2,9 +2,13 @@ import {AppBskyLabelerDefs} from '@atproto/api' import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query' import {z} from 'zod' +import {MAX_LABELERS} from '#/lib/constants' import {labelersDetailedInfoQueryKeyRoot} from '#/lib/react-query' import {STALE} from '#/state/queries' -import {preferencesQueryKey} from '#/state/queries/preferences' +import { + preferencesQueryKey, + usePreferencesQuery, +} from '#/state/queries/preferences' import {useAgent} from '#/state/session' const labelerInfoQueryKeyRoot = 'labeler-info' @@ -77,6 +81,7 @@ export function useLabelersDetailedInfoQuery({dids}: {dids: string[]}) { export function useLabelerSubscriptionMutation() { const queryClient = useQueryClient() const agent = useAgent() + const preferences = usePreferencesQuery() return useMutation({ async mutationFn({did, subscribe}: {did: string; subscribe: boolean}) { @@ -86,14 +91,52 @@ export function useLabelerSubscriptionMutation() { subscribe: z.boolean(), }).parse({did, subscribe}) + /** + * If a user has invalid/takendown/deactivated labelers, we need to + * remove them. We don't have a great way to do this atm on the server, + * so we do it here. + * + * We also need to push validation into this method, since we need to + * check {@link MAX_LABELERS} _after_ we've removed invalid or takendown + * labelers. + */ + const labelerDids = ( + preferences.data?.moderationPrefs?.labelers ?? [] + ).map(l => l.did) + const invalidLabelers: string[] = [] + if (labelerDids.length) { + const profiles = await agent.getProfiles({actors: labelerDids}) + if (profiles.data) { + for (const did of labelerDids) { + const exists = profiles.data.profiles.find(p => p.did === did) + if (exists) { + // profile came back but it's not a valid labeler + if (exists.associated && !exists.associated.labeler) { + invalidLabelers.push(did) + } + } else { + // no response came back, might be deactivated or takendown + invalidLabelers.push(did) + } + } + } + } + if (invalidLabelers.length) { + await Promise.all(invalidLabelers.map(did => agent.removeLabeler(did))) + } + if (subscribe) { + const labelerCount = labelerDids.length - invalidLabelers.length + if (labelerCount >= MAX_LABELERS) { + throw new Error('MAX_LABELERS') + } await agent.addLabeler(did) } else { await agent.removeLabeler(did) } }, - onSuccess() { - queryClient.invalidateQueries({ + async onSuccess() { + await queryClient.invalidateQueries({ queryKey: preferencesQueryKey, }) }, |