about summary refs log tree commit diff
path: root/src/lib/moderation.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/moderation.ts')
-rw-r--r--src/lib/moderation.ts196
1 files changed, 64 insertions, 132 deletions
diff --git a/src/lib/moderation.ts b/src/lib/moderation.ts
index b6ebb47a0..4105c2c2d 100644
--- a/src/lib/moderation.ts
+++ b/src/lib/moderation.ts
@@ -1,149 +1,81 @@
-import {ModerationCause, ProfileModeration, PostModeration} from '@atproto/api'
+import {
+  ModerationCause,
+  ModerationUI,
+  InterpretedLabelValueDefinition,
+  LABELS,
+  AppBskyLabelerDefs,
+  BskyAgent,
+  ModerationOpts,
+} from '@atproto/api'
 
-export interface ModerationCauseDescription {
-  name: string
-  description: string
-}
+import {sanitizeDisplayName} from '#/lib/strings/display-names'
+import {sanitizeHandle} from '#/lib/strings/handles'
 
-export function describeModerationCause(
-  cause: ModerationCause | undefined,
-  context: 'account' | 'content',
-): ModerationCauseDescription {
-  if (!cause) {
-    return {
-      name: 'Content Warning',
-      description:
-        'Moderator has chosen to set a general warning on the content.',
-    }
-  }
-  if (cause.type === 'blocking') {
-    if (cause.source.type === 'list') {
-      return {
-        name: `User Blocked by "${cause.source.list.name}"`,
-        description:
-          'You have blocked this user. You cannot view their content.',
-      }
-    } else {
-      return {
-        name: 'User Blocked',
-        description:
-          'You have blocked this user. You cannot view their content.',
-      }
-    }
-  }
-  if (cause.type === 'blocked-by') {
-    return {
-      name: 'User Blocking You',
-      description: 'This user has blocked you. You cannot view their content.',
-    }
-  }
-  if (cause.type === 'block-other') {
-    return {
-      name: 'Content Not Available',
-      description:
-        'This content is not available because one of the users involved has blocked the other.',
-    }
-  }
-  if (cause.type === 'muted') {
-    if (cause.source.type === 'list') {
-      return {
-        name:
-          context === 'account'
-            ? `Muted by "${cause.source.list.name}"`
-            : `Post by muted user ("${cause.source.list.name}")`,
-        description: 'You have muted this user',
-      }
-    } else {
-      return {
-        name: context === 'account' ? 'Muted User' : 'Post by muted user',
-        description: 'You have muted this user',
-      }
-    }
-  }
-  // @ts-ignore Temporary extension to the moderation system -prf
-  if (cause.type === 'post-hidden') {
-    return {
-      name: 'Post Hidden by You',
-      description: 'You have hidden this post',
-    }
-  }
-  // @ts-ignore Temporary extension to the moderation system -prf
-  if (cause.type === 'muted-word') {
-    return {
-      name: 'Post hidden by muted word',
-      description: `You've chosen to hide a word or tag within this post.`,
-    }
+export function getModerationCauseKey(cause: ModerationCause): string {
+  const source =
+    cause.source.type === 'labeler'
+      ? cause.source.did
+      : cause.source.type === 'list'
+      ? cause.source.list.uri
+      : 'user'
+  if (cause.type === 'label') {
+    return `label:${cause.label.val}:${source}`
   }
-  return cause.labelDef.strings[context].en
+  return `${cause.type}:${source}`
 }
 
-export function getProfileModerationCauses(
-  moderation: ProfileModeration,
-): ModerationCause[] {
-  /*
-  Gather everything on profile and account that blurs or alerts
-  */
-  return [
-    moderation.decisions.profile.cause,
-    ...moderation.decisions.profile.additionalCauses,
-    moderation.decisions.account.cause,
-    ...moderation.decisions.account.additionalCauses,
-  ].filter(cause => {
-    if (!cause) {
-      return false
-    }
-    if (cause?.type === 'label') {
-      if (
-        cause.labelDef.onwarn === 'blur' ||
-        cause.labelDef.onwarn === 'alert'
-      ) {
-        return true
-      } else {
-        return false
-      }
-    }
-    return true
-  }) as ModerationCause[]
+export function isJustAMute(modui: ModerationUI): boolean {
+  return modui.filters.length === 1 && modui.filters[0].type === 'muted'
 }
 
-export function isPostMediaBlurred(
-  decisions: PostModeration['decisions'],
-): boolean {
-  return decisions.post.blurMedia
+export function getLabelingServiceTitle({
+  displayName,
+  handle,
+}: {
+  displayName?: string
+  handle: string
+}) {
+  return displayName
+    ? sanitizeDisplayName(displayName)
+    : sanitizeHandle(handle, '@')
 }
 
-export function isQuoteBlurred(
-  decisions: PostModeration['decisions'],
-): boolean {
-  return (
-    decisions.quote?.blur ||
-    decisions.quote?.blurMedia ||
-    decisions.quote?.filter ||
-    decisions.quotedAccount?.blur ||
-    decisions.quotedAccount?.filter ||
-    false
-  )
+export function lookupLabelValueDefinition(
+  labelValue: string,
+  customDefs: InterpretedLabelValueDefinition[] | undefined,
+): InterpretedLabelValueDefinition | undefined {
+  let def
+  if (!labelValue.startsWith('!') && customDefs) {
+    def = customDefs.find(d => d.identifier === labelValue)
+  }
+  if (!def) {
+    def = LABELS[labelValue as keyof typeof LABELS]
+  }
+  return def
 }
 
-export function isCauseALabelOnUri(
-  cause: ModerationCause | undefined,
-  uri: string,
+export function isAppLabeler(
+  labeler:
+    | string
+    | AppBskyLabelerDefs.LabelerView
+    | AppBskyLabelerDefs.LabelerViewDetailed,
 ): boolean {
-  if (cause?.type !== 'label') {
-    return false
+  if (typeof labeler === 'string') {
+    return BskyAgent.appLabelers.includes(labeler)
   }
-  return cause.label.uri === uri
+  return BskyAgent.appLabelers.includes(labeler.creator.did)
 }
 
-export function getModerationCauseKey(cause: ModerationCause): string {
-  const source =
-    cause.source.type === 'labeler'
-      ? cause.source.labeler.did
-      : cause.source.type === 'list'
-      ? cause.source.list.uri
-      : 'user'
-  if (cause.type === 'label') {
-    return `label:${cause.label.val}:${source}`
+export function isLabelerSubscribed(
+  labeler:
+    | string
+    | AppBskyLabelerDefs.LabelerView
+    | AppBskyLabelerDefs.LabelerViewDetailed,
+  modOpts: ModerationOpts,
+) {
+  labeler = typeof labeler === 'string' ? labeler : labeler.creator.did
+  if (isAppLabeler(labeler)) {
+    return true
   }
-  return `${cause.type}:${source}`
+  return modOpts.prefs.labelers.find(l => l.did === labeler)
 }