Bluesky app fork with some witchin' additions 馃挮
at main 184 lines 5.7 kB view raw
1import React from 'react' 2import { 3 BSKY_LABELER_DID, 4 type ModerationCause, 5 type ModerationCauseSource, 6} from '@atproto/api' 7import {msg} from '@lingui/macro' 8import {useLingui} from '@lingui/react' 9 10import {sanitizeHandle} from '#/lib/strings/handles' 11import {useLabelDefinitions} from '#/state/preferences' 12import {useSession} from '#/state/session' 13import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/components/icons/CircleBanSign' 14import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' 15import {type Props as SVGIconProps} from '#/components/icons/common' 16import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlash} from '#/components/icons/EyeSlash' 17import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning' 18import {type AppModerationCause} from '#/components/Pills' 19import {useGlobalLabelStrings} from './useGlobalLabelStrings' 20import {getDefinition, getLabelStrings} from './useLabelInfo' 21 22export interface ModerationCauseDescription { 23 icon: React.ComponentType<SVGIconProps> 24 name: string 25 description: string 26 source?: string 27 sourceDisplayName?: string 28 sourceType?: ModerationCauseSource['type'] 29 sourceAvi?: string 30 sourceDid?: string 31 isSubjectAccount?: boolean 32} 33 34export function useModerationCauseDescription( 35 cause: ModerationCause | AppModerationCause | undefined, 36): ModerationCauseDescription { 37 const {currentAccount} = useSession() 38 const {_, i18n} = useLingui() 39 const {labelDefs, labelers} = useLabelDefinitions() 40 const globalLabelStrings = useGlobalLabelStrings() 41 42 return React.useMemo(() => { 43 if (!cause) { 44 return { 45 icon: Warning, 46 name: _(msg`Content Warning`), 47 description: _( 48 msg`Moderator has chosen to set a general warning on the content.`, 49 ), 50 } 51 } 52 if (cause.type === 'blocking') { 53 if (cause.source.type === 'list') { 54 return { 55 icon: CircleBanSign, 56 name: _(msg`User Blocked by "${cause.source.list.name}"`), 57 description: _( 58 msg`You have blocked this user. You cannot view their content.`, 59 ), 60 } 61 } else { 62 return { 63 icon: CircleBanSign, 64 name: _(msg`User Blocked`), 65 description: _( 66 msg`You have blocked this user. You cannot view their content.`, 67 ), 68 } 69 } 70 } 71 if (cause.type === 'blocked-by') { 72 return { 73 icon: CircleBanSign, 74 name: _(msg`User Blocking You`), 75 description: _( 76 msg`This user has blocked you. You cannot view their content.`, 77 ), 78 } 79 } 80 if (cause.type === 'block-other') { 81 return { 82 icon: CircleBanSign, 83 name: _(msg`Content Not Available`), 84 description: _( 85 msg`This content is not available because one of the users involved has blocked the other.`, 86 ), 87 } 88 } 89 if (cause.type === 'muted') { 90 if (cause.source.type === 'list') { 91 return { 92 icon: EyeSlash, 93 name: _(msg`Muted by "${cause.source.list.name}"`), 94 description: _(msg`You have muted this user`), 95 } 96 } else { 97 return { 98 icon: EyeSlash, 99 name: _(msg`Account Muted`), 100 description: _(msg`You have muted this account.`), 101 } 102 } 103 } 104 if (cause.type === 'mute-word') { 105 return { 106 icon: EyeSlash, 107 name: _(msg`Skeet Hidden by Muted Word`), 108 description: _( 109 msg`You've chosen to hide a word or tag within this skeet.`, 110 ), 111 } 112 } 113 if (cause.type === 'hidden') { 114 return { 115 icon: EyeSlash, 116 name: _(msg`Skeet Hidden by You`), 117 description: _(msg`You have hidden this skeet.`), 118 } 119 } 120 if (cause.type === 'reply-hidden') { 121 const isMe = currentAccount?.did === cause.source.did 122 return { 123 icon: EyeSlash, 124 name: isMe 125 ? _(msg`Reply Hidden by You`) 126 : _(msg`Reply Hidden by Thread Author`), 127 description: isMe 128 ? _(msg`You hid this reply.`) 129 : _(msg`The author of this thread has hidden this reply.`), 130 } 131 } 132 if (cause.type === 'label') { 133 const def = cause.labelDef || getDefinition(labelDefs, cause.label) 134 const strings = getLabelStrings(i18n.locale, globalLabelStrings, def) 135 const labeler = labelers.find(l => l.creator.did === cause.label.src) 136 let source = labeler 137 ? sanitizeHandle(labeler.creator.handle, '@') 138 : undefined 139 let sourceDisplayName = labeler?.creator.displayName 140 if (!source) { 141 if (cause.label.src === BSKY_LABELER_DID) { 142 source = 'moderation.bsky.app' 143 sourceDisplayName = 'Bluesky Moderation Service' 144 } else { 145 source = _(msg`an unknown labeler`) 146 } 147 } 148 if (def.identifier === 'porn' || def.identifier === 'sexual') { 149 strings.name = _(msg`Adult Content`) 150 } 151 152 return { 153 icon: 154 def.identifier === '!no-unauthenticated' 155 ? EyeSlash 156 : def.severity === 'alert' 157 ? Warning 158 : CircleInfo, 159 name: strings.name, 160 description: strings.description, 161 source, 162 sourceDisplayName, 163 sourceType: cause.source.type, 164 sourceAvi: labeler?.creator.avatar, 165 sourceDid: cause.label.src, 166 isSubjectAccount: cause.label.uri.startsWith('did:'), 167 } 168 } 169 // should never happen 170 return { 171 icon: CircleInfo, 172 name: '', 173 description: ``, 174 } 175 }, [ 176 labelDefs, 177 labelers, 178 globalLabelStrings, 179 cause, 180 _, 181 i18n.locale, 182 currentAccount?.did, 183 ]) 184}