JavaScript-optional public web frontend for Bluesky anartia.kelinci.net
sveltekit atcute bluesky typescript svelte
at trunk 150 lines 3.1 kB view raw
1import type { ComAtprotoLabelDefs } from '@atcute/atproto'; 2import type { Did } from '@atcute/lexicons'; 3 4export const FlagsNone = 0; 5 6/** Label blurs media (images and videos in posts) */ 7export const FlagsBlurMedia = 1 << 0; 8/** Label blurs content (text in posts), assumes FlagsBlurMedia */ 9export const FlagsBlurContent = 1 << 1; 10/** Label can't be self-applied */ 11export const FlagsNoSelf = 1 << 2; 12 13type Label = ComAtprotoLabelDefs.Label; 14 15export interface LabelDefinition { 16 name: string; 17 flags: number; 18} 19 20export const LABEL_MAPPING: Record<string, LabelDefinition> = { 21 // Global "system" labels 22 '!hide': { 23 name: `Hidden by moderators`, 24 flags: FlagsBlurContent | FlagsNoSelf, 25 }, 26 '!warn': { 27 name: `Content warning`, 28 flags: FlagsBlurContent | FlagsNoSelf, 29 }, 30 31 // Global user-applicable labels 32 porn: { 33 name: `Adult content`, 34 flags: FlagsBlurMedia, 35 }, 36 sexual: { 37 name: `Sexually suggestive`, 38 flags: FlagsBlurMedia, 39 }, 40 'graphic-media': { 41 name: `Graphic media`, 42 flags: FlagsBlurMedia, 43 }, 44 nudity: { 45 name: `Nudity`, 46 flags: FlagsBlurMedia, 47 }, 48 49 // @moderation.bsky.app's labels 50 'sexual-figurative': { 51 name: `Sexually suggestive (cartoon)`, 52 flags: FlagsBlurMedia | FlagsNoSelf, 53 }, 54 55 'self-harm': { 56 name: `Self-harm`, 57 flags: FlagsBlurContent | FlagsNoSelf, 58 }, 59 sensitive: { 60 name: `Sensitive content`, 61 flags: FlagsBlurContent | FlagsNoSelf, 62 }, 63 extremist: { 64 name: `Extremism`, 65 flags: FlagsBlurContent | FlagsNoSelf, 66 }, 67 intolerant: { 68 name: `Intolerance`, 69 flags: FlagsBlurContent | FlagsNoSelf, 70 }, 71 threat: { 72 name: `Threats`, 73 flags: FlagsBlurContent | FlagsNoSelf, 74 }, 75 rude: { 76 name: `Rude`, 77 flags: FlagsBlurContent | FlagsNoSelf, 78 }, 79 illicit: { 80 name: `Illicit content`, 81 flags: FlagsBlurContent | FlagsNoSelf, 82 }, 83 security: { 84 name: `Security risk`, 85 flags: FlagsBlurContent | FlagsNoSelf, 86 }, 87 'unsafe-link': { 88 name: `Unsafe link`, 89 flags: FlagsBlurContent | FlagsNoSelf, 90 }, 91 impersonation: { 92 name: `Impersonation`, 93 flags: FlagsBlurContent | FlagsNoSelf, 94 }, 95 misinformation: { 96 name: `Misinformation`, 97 flags: FlagsBlurContent | FlagsNoSelf, 98 }, 99 scam: { 100 name: `Scam`, 101 flags: FlagsBlurContent | FlagsNoSelf, 102 }, 103 'engagement-farming': { 104 name: `Engagement farming`, 105 flags: FlagsBlurContent | FlagsNoSelf, 106 }, 107 spam: { 108 name: `Spam`, 109 flags: FlagsBlurContent | FlagsNoSelf, 110 }, 111 rumor: { 112 name: `Rumor`, 113 flags: FlagsBlurContent | FlagsNoSelf, 114 }, 115 misleading: { 116 name: `Misleading`, 117 flags: FlagsBlurContent | FlagsNoSelf, 118 }, 119 inauthentic: { 120 name: `Inauthentic`, 121 flags: FlagsBlurContent | FlagsNoSelf, 122 }, 123}; 124 125export const findLabel = ( 126 labels: Label[] | undefined, 127 authorDid: Did, 128 mask: number, 129): LabelDefinition | undefined => { 130 if (labels?.length) { 131 for (let idx = 0, len = labels.length; idx < len; idx++) { 132 const label = labels[idx]; 133 const val = label.val; 134 135 if (!(val in LABEL_MAPPING)) { 136 continue; 137 } 138 139 const def = LABEL_MAPPING[val]; 140 141 if (def.flags & FlagsNoSelf && label.src === authorDid) { 142 continue; 143 } 144 145 if (def.flags & mask) { 146 return def; 147 } 148 } 149 } 150};