Skip to content

Commit 5df5851

Browse files
Add Messages Filter feature
Adds ability to filter messages in chats: - Hide messages from blocked senders in groups - Hide mentions of blocked chats - Filter Telegram/external links per-channel - Manage filtered channels list - Settings UI in Settings > Interface Cherry-picked from PR TGX-Android#516 by Arseny271. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent dae27e4 commit 5df5851

18 files changed

Lines changed: 1287 additions & 2 deletions

app/src/main/java/org/thunderdog/challegram/component/chat/MessageView.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,14 @@ public static Object fillMessageOptions (MessagesController m, TGMessage msg, @N
630630
boolean isSent = !msg.isNotSent();
631631
Object tag = null;
632632

633+
final boolean isHiddenByMessagesFilter = msg.isHiddenByMessagesFilter();
634+
635+
if (!isMore && (isHiddenByMessagesFilter /*|| BuildConfig.DEBUG*/)) {
636+
ids.append(R.id.btn_messageChangeMessageFilterVisibility);
637+
strings.append(Lang.getString(R.string.MessagesFilterShowMessage));
638+
icons.append(R.drawable.baseline_visibility_24);
639+
}
640+
633641
// Promotion
634642

635643
if (msg.isSponsoredMessage()) {
@@ -1551,7 +1559,7 @@ public boolean onTouchEvent (MotionEvent e) {
15511559
} else {
15521560
preventLongPress();
15531561
}
1554-
if (c.inSelectMode() || !msg.onTouchEvent(this, e)) {
1562+
if (c.inSelectMode() || msg.isHiddenByMessagesFilter() || !msg.onTouchEvent(this, e)) {
15551563
flags |= FLAG_CAUGHT_CLICK;
15561564
} else {
15571565
flags |= FLAG_CAUGHT_MESSAGE_TOUCH;
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* This file is a part of Telegram X
3+
* Copyright © 2014 (tgx-android@pm.me)
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* You should have received a copy of the GNU General Public License
11+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
12+
*
13+
* File created on 17/11/2023
14+
*/
15+
package org.thunderdog.challegram.component.chat.filter;
16+
17+
import android.net.Uri;
18+
19+
import org.drinkless.tdlib.TdApi;
20+
import org.thunderdog.challegram.data.TD;
21+
22+
import java.util.HashSet;
23+
import java.util.Set;
24+
25+
import me.vkryl.td.ChatId;
26+
import me.vkryl.td.Td;
27+
28+
class Content {
29+
public final Set<String> mentionsUsername = new HashSet<>();
30+
public final Set<Long> mentionsId = new HashSet<>();
31+
public final Set<String> internalLinks = new HashSet<>();
32+
public final Set<String> externalLinks = new HashSet<>();
33+
34+
public Content () {}
35+
36+
public void add (TdApi.MessageContent content) {
37+
final TdApi.FormattedText textOrCaption = Td.textOrCaption(content);
38+
if (textOrCaption == null || textOrCaption.text == null) return;
39+
40+
if (textOrCaption.entities != null) {
41+
for (TdApi.TextEntity entity : textOrCaption.entities) {
42+
switch (entity.type.getConstructor()) {
43+
case TdApi.TextEntityTypeMention.CONSTRUCTOR: {
44+
mentionsUsername.add(Td.substring(textOrCaption.text, entity));
45+
break;
46+
}
47+
case TdApi.TextEntityTypeMentionName.CONSTRUCTOR: {
48+
mentionsId.add(ChatId.fromUserId(((TdApi.TextEntityTypeMentionName) entity.type).userId));
49+
break;
50+
}
51+
case TdApi.TextEntityTypeUrl.CONSTRUCTOR: {
52+
addLink(Td.substring(textOrCaption.text, entity));
53+
break;
54+
}
55+
case TdApi.TextEntityTypeTextUrl.CONSTRUCTOR: {
56+
addLink(((TdApi.TextEntityTypeTextUrl) entity.type).url);
57+
break;
58+
}
59+
default: {
60+
break;
61+
}
62+
}
63+
}
64+
}
65+
}
66+
67+
private void addLink (String link) {
68+
if (TD.isTelegramOwnedHost(Uri.parse(link), false)) {
69+
internalLinks.add(link);
70+
} else {
71+
externalLinks.add(link);
72+
}
73+
}
74+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* This file is a part of Telegram X
3+
* Copyright © 2014 (tgx-android@pm.me)
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* You should have received a copy of the GNU General Public License
11+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
12+
*
13+
* File created on 16/11/2023
14+
*/
15+
package org.thunderdog.challegram.component.chat.filter;
16+
17+
import androidx.annotation.IntDef;
18+
19+
import java.lang.annotation.Retention;
20+
import java.lang.annotation.RetentionPolicy;
21+
22+
@Retention(RetentionPolicy.SOURCE)
23+
@IntDef({
24+
FilterReason.PENDING,
25+
FilterReason.NONE,
26+
FilterReason.BLOCKED_SENDER,
27+
FilterReason.BLOCKED_SENDER_MENTION,
28+
FilterReason.CONTAINS_INTERNAL_LINK,
29+
FilterReason.CONTAINS_EXTERNAL_LINK
30+
})
31+
public @interface FilterReason {
32+
int
33+
PENDING = -1,
34+
NONE = 0,
35+
BLOCKED_SENDER = 1,
36+
BLOCKED_SENDER_MENTION = 2,
37+
CONTAINS_INTERNAL_LINK = 3,
38+
CONTAINS_EXTERNAL_LINK = 4;
39+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* This file is a part of Telegram X
3+
* Copyright © 2014 (tgx-android@pm.me)
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* You should have received a copy of the GNU General Public License
11+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
12+
*
13+
* File created on 16/11/2023
14+
*/
15+
package org.thunderdog.challegram.component.chat.filter;
16+
17+
import androidx.annotation.IntDef;
18+
19+
import java.lang.annotation.Retention;
20+
import java.lang.annotation.RetentionPolicy;
21+
22+
@Retention(RetentionPolicy.SOURCE)
23+
@IntDef({
24+
FilterState.VISIBLE,
25+
FilterState.HIDDEN,
26+
FilterState.LAST_STATE_VISIBLE,
27+
FilterState.LAST_STATE_HIDDEN
28+
})
29+
public @interface FilterState {
30+
int
31+
VISIBLE = 0,
32+
HIDDEN = 1,
33+
LAST_STATE_VISIBLE = 2,
34+
LAST_STATE_HIDDEN = 3;
35+
}

0 commit comments

Comments
 (0)