[SDK] Swap moderation to @bsky.app/sdk and move labeler config to Client statics (#11383)
This commit is contained in:
@@ -1,18 +1,17 @@
|
||||
import {useMemo} from 'react'
|
||||
import {AtpAgent, type ComAtprotoLabelDefs} from '@atproto/api'
|
||||
import {
|
||||
type AppBskyLabelerDefs,
|
||||
AtpAgent,
|
||||
type ComAtprotoLabelDefs,
|
||||
type InterpretedLabelValueDefinition,
|
||||
LABELS,
|
||||
type ModerationCause,
|
||||
type ModerationOpts,
|
||||
type ModerationUI,
|
||||
} from '@atproto/api'
|
||||
} from '@bsky.app/sdk/moderation'
|
||||
|
||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {type AppModerationCause} from '#/components/Pills'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
export const ADULT_CONTENT_LABELS = ['sexual', 'nudity', 'porn'] as const
|
||||
export const OTHER_SELF_LABELS = ['graphic-media'] as const
|
||||
@@ -102,8 +101,8 @@ export function lookupLabelValueDefinition(
|
||||
export function isAppLabeler(
|
||||
labeler:
|
||||
| string
|
||||
| AppBskyLabelerDefs.LabelerView
|
||||
| AppBskyLabelerDefs.LabelerViewDetailed,
|
||||
| app.bsky.labeler.defs.LabelerView
|
||||
| app.bsky.labeler.defs.LabelerViewDetailed,
|
||||
): boolean {
|
||||
if (typeof labeler === 'string') {
|
||||
return AtpAgent.appLabelers.includes(labeler)
|
||||
@@ -114,8 +113,8 @@ export function isAppLabeler(
|
||||
export function isLabelerSubscribed(
|
||||
labeler:
|
||||
| string
|
||||
| AppBskyLabelerDefs.LabelerView
|
||||
| AppBskyLabelerDefs.LabelerViewDetailed,
|
||||
| app.bsky.labeler.defs.LabelerView
|
||||
| app.bsky.labeler.defs.LabelerViewDetailed,
|
||||
modOpts: ModerationOpts,
|
||||
) {
|
||||
labeler = typeof labeler === 'string' ? labeler : labeler.creator.did
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {type ModerationUI} from '@atproto/api'
|
||||
import {type ModerationUI} from '@bsky.app/sdk/moderation'
|
||||
|
||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
import {
|
||||
type AppBskyActorDefs,
|
||||
type AppBskyFeedDefs,
|
||||
type AppBskyGraphDefs,
|
||||
type AppBskyNotificationListNotifications,
|
||||
type AppBskyRichtextFacet,
|
||||
type ChatBskyActorDefs,
|
||||
} from '@atproto/api'
|
||||
import {
|
||||
hasMutedWord as sdkHasMutedWord,
|
||||
moderateFeedGenerator as sdkModerateFeedGenerator,
|
||||
moderateNotification as sdkModerateNotification,
|
||||
moderatePost as sdkModeratePost,
|
||||
moderateProfile as sdkModerateProfile,
|
||||
moderateStatus as sdkModerateStatus,
|
||||
moderateUserList as sdkModerateUserList,
|
||||
type ModerationDecision,
|
||||
type ModerationOpts,
|
||||
} from '@bsky.app/sdk/moderation'
|
||||
|
||||
import {type app, type chat} from '#/lexicons'
|
||||
|
||||
/*
|
||||
* TRANSITIONAL. The moderation implementation now comes from
|
||||
* `@bsky.app/sdk/moderation`, whose subject types are the generated
|
||||
* `#/lexicons` views - so their `did`/`uri`/`cid` fields are branded
|
||||
* (`DidString`, `AtUriString`). Many read paths still emit the identically
|
||||
* shaped `@atproto/api` views, whose same fields are plain `string`.
|
||||
*
|
||||
* A plain `string` is not assignable to a branded template-literal type, so
|
||||
* every `moderate*` call taking an unmigrated view fails to typecheck even
|
||||
* though the value is byte-identical - the runtime only ever reads `.did`,
|
||||
* `.labels` and `.viewer`, none of which the brand affects.
|
||||
*
|
||||
* These wrappers widen each subject parameter to accept a view from either
|
||||
* world and drop the brand on the way in. Delete this module once every
|
||||
* producer emits `#/lexicons` views (the `@atproto/api` removal pass) and point
|
||||
* callers back at `@bsky.app/sdk/moderation` directly.
|
||||
*/
|
||||
|
||||
type AnyProfileSubject =
|
||||
| app.bsky.actor.defs.ProfileViewBasic
|
||||
| app.bsky.actor.defs.ProfileView
|
||||
| app.bsky.actor.defs.ProfileViewDetailed
|
||||
| chat.bsky.actor.defs.ProfileViewBasic
|
||||
| AppBskyActorDefs.ProfileViewBasic
|
||||
| AppBskyActorDefs.ProfileView
|
||||
| AppBskyActorDefs.ProfileViewDetailed
|
||||
| ChatBskyActorDefs.ProfileViewBasic
|
||||
|
||||
type AnyPostSubject = app.bsky.feed.defs.PostView | AppBskyFeedDefs.PostView
|
||||
|
||||
type AnyUserListSubject =
|
||||
| app.bsky.graph.defs.ListViewBasic
|
||||
| app.bsky.graph.defs.ListView
|
||||
| AppBskyGraphDefs.ListViewBasic
|
||||
| AppBskyGraphDefs.ListView
|
||||
|
||||
type AnyFeedGeneratorSubject =
|
||||
| app.bsky.feed.defs.GeneratorView
|
||||
| AppBskyFeedDefs.GeneratorView
|
||||
|
||||
type AnyNotificationSubject =
|
||||
| app.bsky.notification.listNotifications.Notification
|
||||
| AppBskyNotificationListNotifications.Notification
|
||||
|
||||
export function moderateProfile(
|
||||
subject: AnyProfileSubject,
|
||||
opts: ModerationOpts,
|
||||
): ModerationDecision {
|
||||
return sdkModerateProfile(subject as app.bsky.actor.defs.ProfileView, opts)
|
||||
}
|
||||
|
||||
export function moderateStatus(
|
||||
subject: AnyProfileSubject,
|
||||
opts: ModerationOpts,
|
||||
): ModerationDecision {
|
||||
return sdkModerateStatus(subject as app.bsky.actor.defs.ProfileView, opts)
|
||||
}
|
||||
|
||||
export function moderatePost(
|
||||
subject: AnyPostSubject,
|
||||
opts: ModerationOpts,
|
||||
): ModerationDecision {
|
||||
return sdkModeratePost(subject as app.bsky.feed.defs.PostView, opts)
|
||||
}
|
||||
|
||||
export function moderateUserList(
|
||||
subject: AnyUserListSubject,
|
||||
opts: ModerationOpts,
|
||||
): ModerationDecision {
|
||||
return sdkModerateUserList(subject as app.bsky.graph.defs.ListView, opts)
|
||||
}
|
||||
|
||||
export function moderateFeedGenerator(
|
||||
subject: AnyFeedGeneratorSubject,
|
||||
opts: ModerationOpts,
|
||||
): ModerationDecision {
|
||||
return sdkModerateFeedGenerator(
|
||||
subject as app.bsky.feed.defs.GeneratorView,
|
||||
opts,
|
||||
)
|
||||
}
|
||||
|
||||
export function moderateNotification(
|
||||
subject: AnyNotificationSubject,
|
||||
opts: ModerationOpts,
|
||||
): ModerationDecision {
|
||||
return sdkModerateNotification(
|
||||
subject as app.bsky.notification.listNotifications.Notification,
|
||||
opts,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Widens `facets`/`actor` for the same reason the `moderate*` wrappers widen
|
||||
* their subjects: mute-word matching reads only `text`/`features`/`langs`, none
|
||||
* of which the brand affects.
|
||||
*/
|
||||
export function hasMutedWord(params: {
|
||||
mutedWords: app.bsky.actor.defs.MutedWord[]
|
||||
text: string
|
||||
facets?: app.bsky.richtext.facet.Main[] | AppBskyRichtextFacet.Main[]
|
||||
outlineTags?: string[]
|
||||
languages?: string[]
|
||||
actor?: AnyProfileSubject
|
||||
}): boolean {
|
||||
return sdkHasMutedWord({
|
||||
...params,
|
||||
facets: params.facets as app.bsky.richtext.facet.Main[] | undefined,
|
||||
actor: params.actor as app.bsky.actor.defs.ProfileView | undefined,
|
||||
})
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
type InterpretedLabelValueDefinition,
|
||||
type LabelPreference,
|
||||
} from '@atproto/api'
|
||||
} from '@bsky.app/sdk/moderation'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import {type ComAtprotoLabelDefs} from '@atproto/api'
|
||||
import {
|
||||
type AppBskyLabelerDefs,
|
||||
type ComAtprotoLabelDefs,
|
||||
type InterpretedLabelValueDefinition,
|
||||
interpretLabelValueDefinition,
|
||||
LABELS,
|
||||
} from '@atproto/api'
|
||||
} from '@bsky.app/sdk/moderation'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import * as bcp47Match from 'bcp-47-match'
|
||||
|
||||
@@ -13,12 +12,13 @@ import {
|
||||
useGlobalLabelStrings,
|
||||
} from '#/lib/moderation/useGlobalLabelStrings'
|
||||
import {useLabelDefinitions} from '#/state/preferences'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
export interface LabelInfo {
|
||||
label: ComAtprotoLabelDefs.Label
|
||||
def: InterpretedLabelValueDefinition
|
||||
strings: ComAtprotoLabelDefs.LabelValueDefinitionStrings
|
||||
labeler: AppBskyLabelerDefs.LabelerViewDetailed | undefined
|
||||
labeler: app.bsky.labeler.defs.LabelerViewDetailed | undefined
|
||||
}
|
||||
|
||||
export function useLabelInfo(label: ComAtprotoLabelDefs.Label): LabelInfo {
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import {useMemo} from 'react'
|
||||
import {
|
||||
BSKY_LABELER_DID,
|
||||
type ModerationCause,
|
||||
type ModerationCauseSource,
|
||||
} from '@atproto/api'
|
||||
import {BSKY_LABELER_DID} from '@atproto/api'
|
||||
import {type ModerationCause} from '@bsky.app/sdk/moderation'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
@@ -25,7 +22,7 @@ export interface ModerationCauseDescription {
|
||||
description: string
|
||||
source?: string
|
||||
sourceDisplayName?: string
|
||||
sourceType?: ModerationCauseSource['type']
|
||||
sourceType?: ModerationCause['source']['type']
|
||||
sourceAvi?: string
|
||||
sourceDid?: string
|
||||
isSubjectAccount?: boolean
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {type ModerationUI} from '@atproto/api'
|
||||
import {type ModerationUI} from '@bsky.app/sdk/moderation'
|
||||
|
||||
// \u2705 = ✅
|
||||
// \u2713 = ✓
|
||||
|
||||
Reference in New Issue
Block a user