Improve message filtering#371
Conversation
…iding (also option to only mask matched word)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis PR introduces Ayu spoiler masking, an alternative content-filtering mechanism that masks messages with visual spoiler effects instead of hiding them. It refactors regex filtering from a boolean model to an action-based approach (hide, mask all, mask matched spans) with configurable colors, and extends it to blocked users. ChangesAyu Spoiler Masking Implementation
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ast-grep (0.42.3)TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.javaTMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.javaThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 9a4744a7-52b2-46cf-9fbb-7cdb46ca2322
📒 Files selected for processing (9)
TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.javaTMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.javaTMessagesProj/src/main/java/org/telegram/ui/ChatActivity.javaTMessagesProj/src/main/java/tw/nekomimi/nekogram/filters/AyuFilter.javaTMessagesProj/src/main/java/tw/nekomimi/nekogram/filters/RegexFilterEditActivity.javaTMessagesProj/src/main/java/tw/nekomimi/nekogram/filters/RegexFiltersSettingActivity.javaTMessagesProj/src/main/java/tw/nekomimi/nekogram/filters/ShadowBanListActivity.javaTMessagesProj/src/main/kotlin/xyz/nextalone/nagram/NaConfig.ktTMessagesProj/src/main/res/values/strings_na.xml
|
hmm, i will work on those suggestion when i get time |
1. make ayu media and text spoiler mask independent from telegram native spoiler reveal setting 2. make sure AnimatedEmojiSpans are also handled and masked 3. move ayuClipPath to class field and rewind instead of allocating new Path each draw frame 4. fix cache issue of blocked user after caching 5. make entire spoiler color row clickable for accessibility 6. change default blocked user mask color from white to gray for visibility on light backgrounds
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java (1)
8391-8416:⚠️ Potential issue | 🟠 Major | ⚡ Quick winMask Telegram spoiler emoji in the shared patched layout too.
This patched layout is reused for both Ayu masks and native Telegram spoilers, but only the Ayu branch strips self-drawing emoji spans. If a block contains both spoiler types, animated/custom emoji inside the Telegram spoiler range can still draw through because the Telegram branch only adds a transparent foreground span.
💡 Suggested fix
if (block.textLayout.getText() instanceof Spanned) { Spanned sp = (Spanned) block.textLayout.getText(); TextStyleSpan[] tgSpans = sp.getSpans(0, sp.length(), TextStyleSpan.class); for (TextStyleSpan span : tgSpans) { if (span.isSpoiler()) { int start = sp.getSpanStart(span); int end = sp.getSpanEnd(span); if (start >= 0 && end > start && end <= sb.length()) { + for (Emoji.EmojiSpan e : sb.getSpans(start, end, Emoji.EmojiSpan.class)) { + final Emoji.EmojiSpan captured = e; + sb.setSpan(new ReplacementSpan() { + `@Override` + public int getSize(`@NonNull` Paint paint, CharSequence text, int s, int e2, `@Nullable` Paint.FontMetricsInt fm) { + return captured.getSize(paint, text, s, e2, fm); + } + `@Override` + public void draw(`@NonNull` Canvas canvas, CharSequence text, int s, int e2, float x, int top, int y, int bottom, `@NonNull` Paint paint) { + } + }, sb.getSpanStart(e), sb.getSpanEnd(e), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + sb.removeSpan(e); + } + for (AnimatedEmojiSpan e : sb.getSpans(start, end, AnimatedEmojiSpan.class)) { + final AnimatedEmojiSpan captured = e; + sb.setSpan(new ReplacementSpan() { + `@Override` + public int getSize(`@NonNull` Paint paint, CharSequence text, int s, int e2, `@Nullable` Paint.FontMetricsInt fm) { + return captured.getSize(paint, text, s, e2, fm); + } + `@Override` + public void draw(`@NonNull` Canvas canvas, CharSequence text, int s, int e2, float x, int top, int y, int bottom, `@NonNull` Paint paint) { + } + }, sb.getSpanStart(e), sb.getSpanEnd(e), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + sb.removeSpan(e); + } sb.setSpan(new ForegroundColorSpan(Color.TRANSPARENT), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } } } }
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 94aae10a-4811-4400-b225-5a0fc0e222ec
📒 Files selected for processing (5)
TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.javaTMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.javaTMessagesProj/src/main/java/tw/nekomimi/nekogram/filters/AyuFilter.javaTMessagesProj/src/main/java/tw/nekomimi/nekogram/filters/RegexFilterEditActivity.javaTMessagesProj/src/main/kotlin/xyz/nextalone/nagram/NaConfig.kt
What is this?
This PR implement a masking feature for message filters, before user can hide messages completely that matches regex flters but now they can mask them with spoiler tag. Not only that but with a different spoiler tag color to identify what filter is hiding it and also know that its not normal telegram spoiler tag.
Additionally, instead of hiding blocked users messages. User can choose to mask them. Similarly for shadow ban list, they can manually change hide to mask and select a color of masking.
Why this?
I have been trying to filter out seeing some particular kind of text but i didnt wanted to hide whole message (what if a word is mentioned in context and filter hides it). So for my use case i worked on this feature
Note
I am not sure how good the code quality is, i am not yet familiar with this codebase and i didn't work on much of android stuff (i did learn basic of android app in past but not much). So for understanding files and getting help with this feature implementation i used chatbot. But i still added some redundant code block (in
checkSpoilerMotionEventmethod)Also, sorry if PR is too messy to review (i should have committed step by step)