Labeling & moderation updates [DRAFT] (#1057)
* First pass moving to the new labeling sdk (it compiles) * Correct behaviors around interpreting label moderation * Improve moderation state rendering * Improve hiders and alerts * Improve handling of mutes * Improve profile warnings * Add profile blurring to profile header * Add blocks to test cases * Render labels on profile cards, do not filter * Filter profiles from suggestions using moderation * Apply profile blurring to ProfileCard * Handle blocked and deleted quote posts * Temporarily translate content filtering settings to new labels * Fix types * Tune ContentHider & PostHider click targets * Put a warning on profilecard label pills * Fix screenhider learnmore link on mobile * Enforce no-override on user avatar * Dont enumerate profile blur-media labels in alerts * Fixes to muted posts (esp quotes of muted users) * Fixes to account/profile warnings * Bump @atproto/api@0.5.0 * Bump @atproto/api@0.5.1 * Fix tests * 1.43 * Remove log * Bump @atproto/api@0.5.2
This commit is contained in:
parent
3ae5a6b631
commit
b154d3ea21
43 changed files with 1193 additions and 717 deletions
24
src/lib/api/hack-add-deleted-embed.ts
Normal file
24
src/lib/api/hack-add-deleted-embed.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import {
|
||||
AppBskyFeedDefs,
|
||||
AppBskyFeedPost,
|
||||
ComAtprotoRepoStrongRef,
|
||||
} from '@atproto/api'
|
||||
|
||||
/**
|
||||
* HACK
|
||||
* The server doesnt seem to be correctly giving the notFound view yet
|
||||
* so I'm adding it manually for now
|
||||
* -prf
|
||||
*/
|
||||
export function hackAddDeletedEmbed(post: AppBskyFeedDefs.PostView) {
|
||||
const record = post.record as AppBskyFeedPost.Record
|
||||
if (record.embed?.$type === 'app.bsky.embed.record' && !post.embed) {
|
||||
post.embed = {
|
||||
$type: 'app.bsky.embed.record#view',
|
||||
record: {
|
||||
$type: 'app.bsky.embed.record#viewNotFound',
|
||||
uri: (record.embed.record as ComAtprotoRepoStrongRef.Main).uri,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
77
src/lib/moderation.ts
Normal file
77
src/lib/moderation.ts
Normal file
|
@ -0,0 +1,77 @@
|
|||
import {ModerationCause, ProfileModeration} from '@atproto/api'
|
||||
|
||||
export interface ModerationCauseDescription {
|
||||
name: string
|
||||
description: string
|
||||
}
|
||||
|
||||
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') {
|
||||
return {
|
||||
name: 'Blocked User',
|
||||
description: 'You have blocked this user. You cannot view their content.',
|
||||
}
|
||||
}
|
||||
if (cause.type === 'blocked-by') {
|
||||
return {
|
||||
name: 'Blocking You',
|
||||
description: 'This user has blocked you. You cannot view their content.',
|
||||
}
|
||||
}
|
||||
if (cause.type === 'muted') {
|
||||
if (cause.source.type === 'user') {
|
||||
return {
|
||||
name: context === 'account' ? 'Muted User' : 'Post by muted user',
|
||||
description: 'You have muted this user',
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
name:
|
||||
context === 'account'
|
||||
? `Muted by "${cause.source.list.name}"`
|
||||
: `Post by muted user ("${cause.source.list.name}")`,
|
||||
description: 'You have muted this user',
|
||||
}
|
||||
}
|
||||
}
|
||||
return cause.labelDef.strings[context].en
|
||||
}
|
||||
|
||||
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[]
|
||||
}
|
|
@ -1,10 +1,19 @@
|
|||
import {ModerationUI} from '@atproto/api'
|
||||
import {describeModerationCause} from '../moderation'
|
||||
|
||||
// \u2705 = ✅
|
||||
// \u2713 = ✓
|
||||
// \u2714 = ✔
|
||||
// \u2611 = ☑
|
||||
const CHECK_MARKS_RE = /[\u2705\u2713\u2714\u2611]/gu
|
||||
|
||||
export function sanitizeDisplayName(str: string): string {
|
||||
export function sanitizeDisplayName(
|
||||
str: string,
|
||||
moderation?: ModerationUI,
|
||||
): string {
|
||||
if (moderation?.blur) {
|
||||
return `⚠${describeModerationCause(moderation.cause, 'account').name}`
|
||||
}
|
||||
if (typeof str === 'string') {
|
||||
return str.replace(CHECK_MARKS_RE, '').trim()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue