-
Notifications
You must be signed in to change notification settings - Fork 75
Take the content moderation rules from the SDK #3503
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,44 +1,14 @@ | ||
| import { get } from 'lodash'; | ||
| import { Platform } from 'react-native'; | ||
| import { postBodySummary, renderPostBody, catchPostImage } from '@ecency/render-helper'; | ||
| import { getContentModerationReason } from '@ecency/sdk'; | ||
|
qodo-code-review[bot] marked this conversation as resolved.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Every clean install remains locked to Useful? React with 👍 / 👎.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, and resolved in 32e2e6e before merge: @ecency/sdk 2.3.87 (published from ecency/vision-web#1493 under the |
||
| import { Image as ExpoImage } from 'expo-image'; | ||
|
|
||
| // Utils | ||
| import parseAsset from './parseAsset'; | ||
| import { getResizedAvatar, shouldPrefetchImages } from './image'; | ||
| import { parseReputation } from './user'; | ||
| import { calculateVoteReward } from './vote'; | ||
| import { MutedReason } from '../providers/hive/hive.types'; | ||
|
|
||
| // Reputation below this (human-readable 0-100 scale) collapses the content. New Hive | ||
| // accounts start at 25. Account age is NOT an input, so a years-old account that never | ||
| // gained reputation trips this exactly like a fresh one, and the copy must say | ||
| // "low reputation" rather than "new account". | ||
| export const LOW_REPUTATION_THRESHOLD = 25; | ||
|
|
||
| // Heavily downvoted: strongly negative rshares from more than a handful of voters. | ||
| const DOWNVOTED_RSHARES_THRESHOLD = -7000000000; | ||
| const DOWNVOTED_MIN_VOTES = 3; | ||
|
|
||
| /** | ||
| * First matching reason wins, most authoritative first: an explicit moderator action | ||
| * outranks the heuristics. Returns null when the content is not muted. | ||
| */ | ||
| export const getMutedReason = (content: any): MutedReason | null => { | ||
| if (content?.stats?.gray || content?.stats?.hide) { | ||
| return MutedReason.MODERATED; | ||
| } | ||
| if (content?.author_reputation < LOW_REPUTATION_THRESHOLD) { | ||
| return MutedReason.LOW_REPUTATION; | ||
| } | ||
| if ( | ||
| content?.net_rshares < DOWNVOTED_RSHARES_THRESHOLD && | ||
| content?.active_votes?.length > DOWNVOTED_MIN_VOTES | ||
| ) { | ||
| return MutedReason.DOWNVOTED; | ||
| } | ||
| return null; | ||
| }; | ||
|
|
||
| export const parsePost = ( | ||
| post: any, | ||
|
|
@@ -164,8 +134,9 @@ export const parsePost = ( | |
|
|
||
| post.total_payout = totalPayout; | ||
|
|
||
| // set mute status | ||
| post.mutedReason = getMutedReason(post); | ||
| // set mute status. The rules live in the SDK so this app and the website flag | ||
| // the same content for the same reason. | ||
| post.mutedReason = getContentModerationReason(post); | ||
| post.isMuted = !!post.mutedReason; | ||
|
|
||
| // determine vote status | ||
|
|
@@ -354,7 +325,7 @@ export const parseComment = (comment: any, currentUsername?: string, currentTime | |
| ); | ||
|
|
||
| // set mute status | ||
| comment.mutedReason = getMutedReason(comment); | ||
| comment.mutedReason = getContentModerationReason(comment); | ||
| comment.isMuted = !!comment.mutedReason; | ||
|
|
||
| // set user vote status on comment | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1. Author check ordered wrongly
🐞 Bug☼ ReliabilityAgent Prompt
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation toolsThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Half right, and worth fixing, though not for the stated reason.
isAuthorMutedis null-safe on its own:so an entry with a missing or empty author cannot throw there or be misclassified; it returns false and the
!!item?.authorcheck then drops the item.What is real is the ordering:
item.authoris dereferenced twice before the?.that exists to tolerate a nullish item, so a null entry would take the feed down at the dereference rather than being filtered out. That predates this PR (the previous line was!isMuted && !!item?.author), but it reads as the opposite of what the code means.Fixed in #3504, guard first in both the main filter and the promoted one.