Support filter comments

Resolve #516
This commit is contained in:
小白-白 authored and tarsin committed 2022-12-31 16:47:02 +08:00
1 parent b549acc1de
commit f0f79a52b8
8 files changed
+197 -47

No files matched your search

@@ -24,6 +24,8 @@ import com.hippo.ehviewer.dao.Filter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class EhFilter {
@@ -31,36 +33,38 @@ public final class EhFilter {
public static final int MODE_UPLOADER = 1;
public static final int MODE_TAG = 2;
public static final int MODE_TAG_NAMESPACE = 3;
public static final int MODE_COMMENTER = 4;
public static final int MODE_COMMENT = 5;
private static final String TAG = EhFilter.class.getSimpleName();
private static EhFilter sInstance;
private final List<Filter> mTitleFilterList = new ArrayList<>();
private final List<Filter> mUploaderFilterList = new ArrayList<>();
private final List<Filter> mTagFilterList = new ArrayList<>();
private final List<Filter> mTagNamespaceFilterList = new ArrayList<>();
private final List<Filter> mCommenterFilterList = new ArrayList<>();
private final List<Filter> mCommentFilterList = new ArrayList<>();
private EhFilter() {
List<Filter> list = EhDB.getAllFilter();
for (int i = 0, n = list.size(); i < n; i++) {
Filter filter = list.get(i);
switch (filter.mode) {
case MODE_TITLE:
case MODE_TITLE -> {
filter.text = filter.text.toLowerCase();
mTitleFilterList.add(filter);
break;
case MODE_UPLOADER:
mUploaderFilterList.add(filter);
break;
case MODE_TAG:
}
case MODE_TAG -> {
filter.text = filter.text.toLowerCase();
mTagFilterList.add(filter);
break;
case MODE_TAG_NAMESPACE:
}
case MODE_TAG_NAMESPACE -> {
filter.text = filter.text.toLowerCase();
mTagNamespaceFilterList.add(filter);
break;
default:
Log.d(TAG, "Unknown mode: " + filter.mode);
break;
}
case MODE_UPLOADER -> mUploaderFilterList.add(filter);
case MODE_COMMENTER -> mCommenterFilterList.add(filter);
case MODE_COMMENT -> mCommentFilterList.add(filter);
default -> Log.d(TAG, "Unknown mode: " + filter.mode);
}
}
}
@@ -88,30 +92,36 @@ public final class EhFilter {
return mTagNamespaceFilterList;
}
public List<Filter> getCommenterFilterList() {
return mCommenterFilterList;
}
public List<Filter> getCommentFilterList() {
return mCommentFilterList;
}
public synchronized boolean addFilter(Filter filter) {
// enable filter by default before it is added to database
filter.enable = true;
if (!EhDB.addFilter(filter)) return false;
switch (filter.mode) {
case MODE_TITLE:
case MODE_TITLE -> {
filter.text = filter.text.toLowerCase();
mTitleFilterList.add(filter);
break;
case MODE_UPLOADER:
mUploaderFilterList.add(filter);
break;
case MODE_TAG:
}
case MODE_TAG -> {
filter.text = filter.text.toLowerCase();
mTagFilterList.add(filter);
break;
case MODE_TAG_NAMESPACE:
}
case MODE_TAG_NAMESPACE -> {
filter.text = filter.text.toLowerCase();
mTagNamespaceFilterList.add(filter);
break;
default:
Log.d(TAG, "Unknown mode: " + filter.mode);
break;
}
case MODE_UPLOADER -> mUploaderFilterList.add(filter);
case MODE_COMMENTER -> mCommenterFilterList.add(filter);
case MODE_COMMENT -> mCommentFilterList.add(filter);
default -> Log.d(TAG, "Unknown mode: " + filter.mode);
}
return true;
}
@@ -124,21 +134,13 @@ public final class EhFilter {
EhDB.deleteFilter(filter);
switch (filter.mode) {
case MODE_TITLE:
mTitleFilterList.remove(filter);
break;
case MODE_UPLOADER:
mUploaderFilterList.remove(filter);
break;
case MODE_TAG:
mTagFilterList.remove(filter);
break;
case MODE_TAG_NAMESPACE:
mTagNamespaceFilterList.remove(filter);
break;
default:
Log.d(TAG, "Unknown mode: " + filter.mode);
break;
case MODE_TITLE -> mTitleFilterList.remove(filter);
case MODE_TAG -> mTagFilterList.remove(filter);
case MODE_TAG_NAMESPACE -> mTagNamespaceFilterList.remove(filter);
case MODE_UPLOADER -> mUploaderFilterList.remove(filter);
case MODE_COMMENTER -> mCommenterFilterList.remove(filter);
case MODE_COMMENT -> mCommentFilterList.remove(filter);
default -> Log.d(TAG, "Unknown mode: " + filter.mode);
}
}
@@ -272,4 +274,40 @@ public final class EhFilter {
return true;
}
public synchronized boolean filterCommenter(String commenter) {
if (null == commenter) {
return false;
}
List<Filter> filters = mCommenterFilterList;
if (filters.size() > 0) {
for (int i = 0, n = filters.size(); i < n; i++) {
if (filters.get(i).enable && commenter.equals(filters.get(i).text)) {
return false;
}
}
}
return true;
}
public synchronized boolean filterComment(String comment) {
if (null == comment) {
return false;
}
List<Filter> filters = mCommentFilterList;
if (filters.size() > 0) {
for (int i = 0, n = filters.size(); i < n; i++) {
if (filters.get(i).enable) {
Pattern p = Pattern.compile(filters.get(i).text);
Matcher m = p.matcher(comment);
if (m.find()) return false;
}
}
}
return true;
}
}
@@ -20,6 +20,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.hippo.ehviewer.EhDB;
import com.hippo.ehviewer.client.EhFilter;
import com.hippo.ehviewer.client.EhUtils;
import com.hippo.ehviewer.client.data.GalleryComment;
import com.hippo.ehviewer.client.data.GalleryCommentList;
@@ -473,6 +474,13 @@ public class GalleryDetailParser {
comment.user = c3.child(0).text();
// comment
comment.comment = JsoupUtils.getElementByClass(element, "c6").html();
// filter comment
if (!comment.uploader) {
EhFilter sEhFilter = EhFilter.getInstance();
if (!sEhFilter.filterCommenter(comment.user) || !sEhFilter.filterComment(comment.comment)) {
return null;
}
}
// last edited
Element c8 = JsoupUtils.getElementByClass(element, "c8");
if (c8 != null) {
@@ -264,10 +264,14 @@ class FilterFragment : BaseFragment() {
private val mUploaderFilterList: List<Filter> = mEhFilter.uploaderFilterList
private val mTagFilterList: List<Filter> = mEhFilter.tagFilterList
private val mTagNamespaceFilterList: List<Filter> = mEhFilter.tagNamespaceFilterList
private val mCommenterFilterList: List<Filter> = mEhFilter.commenterFilterList
private val mCommentFilterList: List<Filter> = mEhFilter.commentFilterList
private var mTitleHeader: Filter? = null
private var mUploaderHeader: Filter? = null
private var mTagHeader: Filter? = null
private var mTagNamespaceHeader: Filter? = null
private var mCommenterHeader: Filter? = null
private var mCommentHeader: Filter? = null
fun size(): Int {
var count = 0
var size = mTitleFilterList.size
@@ -278,6 +282,10 @@ class FilterFragment : BaseFragment() {
count += if (0 == size) 0 else size + 1
size = mTagNamespaceFilterList.size
count += if (0 == size) 0 else size + 1
size = mCommenterFilterList.size;
count += if (0 == size) 0 else size + 1
size = mCommentFilterList.size;
count += if (0 == size) 0 else size + 1
return count
}
@@ -317,6 +325,24 @@ class FilterFragment : BaseFragment() {
}
return mTagNamespaceHeader!!
}
private val commenterHeader: Filter
get() {
if (null == mCommenterHeader) {
mCommenterHeader = Filter()
mCommenterHeader!!.mode = MODE_HEADER
mCommenterHeader!!.text = getString(R.string.filter_commenter)
}
return mCommenterHeader!!
}
private val commentHeader: Filter
get() {
if (null == mCommentHeader) {
mCommentHeader = Filter()
mCommentHeader!!.mode = MODE_HEADER
mCommentHeader!!.text = getString(R.string.filter_comment)
}
return mCommentHeader!!
}
operator fun get(index: Int): Filter {
var index1 = index
@@ -356,6 +382,26 @@ class FilterFragment : BaseFragment() {
return tagNamespaceHeader
} else if (index1 <= size) {
return mTagNamespaceFilterList[index1 - 1]
} else {
size + 1
}
}
size = mCommenterFilterList.size
if (0 != size) {
index1 -= if (index1 == 0) {
return commenterHeader
} else if (index1 <= size) {
return mCommenterFilterList[index1 - 1]
} else {
size + 1
}
}
size = mCommentFilterList.size
if (0 != size) {
if (index1 == 0) {
return commentHeader
} else if (index1 <= size) {
return mCommentFilterList[index1 - 1]
}
}
throw IndexOutOfBoundsException()
@@ -62,6 +62,7 @@ import com.hippo.ehviewer.R;
import com.hippo.ehviewer.UrlOpener;
import com.hippo.ehviewer.WindowInsetsAnimationHelper;
import com.hippo.ehviewer.client.EhClient;
import com.hippo.ehviewer.client.EhFilter;
import com.hippo.ehviewer.client.EhRequest;
import com.hippo.ehviewer.client.EhUrl;
import com.hippo.ehviewer.client.data.GalleryComment;
@@ -69,6 +70,7 @@ import com.hippo.ehviewer.client.data.GalleryCommentList;
import com.hippo.ehviewer.client.data.GalleryDetail;
import com.hippo.ehviewer.client.data.ListUrlBuilder;
import com.hippo.ehviewer.client.parser.VoteCommentParser;
import com.hippo.ehviewer.dao.Filter;
import com.hippo.ehviewer.ui.MainActivity;
import com.hippo.scene.SceneFragment;
import com.hippo.text.URLImageGetter;
@@ -265,6 +267,45 @@ public final class GalleryCommentsScene extends ToolbarScene
onBackPressed();
}
private void showFilterCommenterDialog(String commenter, int position) {
Context context = getContext();
if (context == null || commenter == null) {
return;
}
new BaseDialogBuilder(context)
.setMessage(getString(R.string.filter_the_commenter, commenter))
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
Filter filter = new Filter();
filter.mode = EhFilter.MODE_COMMENTER;
filter.text = commenter;
EhFilter.getInstance().addFilter(filter);
hideComment(position);
showTip(R.string.filter_added, LENGTH_SHORT);
})
.setNegativeButton(android.R.string.cancel, null)
.show();
}
private void hideComment(int position) {
if (mGalleryDetail == null || mGalleryDetail.comments == null || mGalleryDetail.comments.comments == null) {
return;
}
GalleryComment[] oldCommentsList = mGalleryDetail.comments.comments;
GalleryComment[] newCommentsList = new GalleryComment[oldCommentsList.length - 1];
for (int i = 0, j = 0; i < oldCommentsList.length; i++) {
if (i != position) {
newCommentsList[j] = oldCommentsList[i];
j++;
}
}
mGalleryDetail.comments.comments = newCommentsList;
mAdapter.notifyDataSetChanged();
updateView(true);
}
private void voteComment(long id, int vote) {
Context context = getContext();
MainActivity activity = getMainActivity();
@@ -339,6 +380,10 @@ public final class GalleryCommentsScene extends ToolbarScene
menu.add(resources.getString(R.string.copy_comment_text));
menuId.add(R.id.copy);
if (!comment.uploader && !comment.editable) {
menu.add(resources.getString(R.string.block_commenter));
menuId.add(R.id.block_commenter);
}
if (comment.editable) {
menu.add(resources.getString(R.string.edit_comment));
menuId.add(R.id.edit_comment);
@@ -364,6 +409,8 @@ public final class GalleryCommentsScene extends ToolbarScene
int id = menuId.get(which);
if (id == R.id.copy) {
ClipboardUtilKt.addTextToClipboard(requireActivity(), comment.comment, false);
} else if (id == R.id.block_commenter) {
showFilterCommenterDialog(comment.user, position);
} else if (id == R.id.vote_up) {
voteComment(comment.id, 1);
} else if (id == R.id.vote_down) {
+8 -4
View File
@@ -238,6 +238,8 @@
<string name="comment_successfully">评论成功</string>
<string name="comment_failed">评论失败</string>
<string name="copy_comment_text">复制评论文字</string>
<string name="block_commenter">屏蔽评论者</string>
<string name="filter_the_commenter">屏蔽评论者“%s”?</string>
<string name="edit_comment">修改评论</string>
<string name="edit_comment_successfully">评论已被修改</string>
<string name="edit_comment_failed">修改评论失败</string>
@@ -309,17 +311,19 @@
<string name="clear_all_history">清除所有阅读历史?</string>
<!-- Filter -->
<string name="filter">屏蔽画廊</string>
<string name="filter">屏蔽列表</string>
<string name="filter_title">标题</string>
<string name="filter_uploader">上传者</string>
<string name="filter_tag">标签</string>
<string name="filter_tag_namespace">标签组</string>
<string name="filter_commenter">评论者</string>
<string name="filter_comment">评论</string>
<string name="delete_filter">删除屏蔽项“%s”?</string>
<string name="tip">提示</string>
<string name="add_filter">添加屏蔽项</string>
<string name="show_definition">查看定义</string>
<string name="filter_text">屏蔽项文本</string>
<string name="filter_tip">该屏蔽系统会在 EHentai 网站屏蔽系统的基础上继续屏蔽画廊。\n\n标题屏蔽项:排除标题含有该关键字的画廊。\n\n上传者屏蔽项:排除该上传者上传的画廊。\n\n标签屏蔽项:排除包含该标签的画廊,这会使获取画廊列表花费更多时间。\n\n标签组屏蔽项:排除包含该标签组的画廊,这会使获取画廊列表花费更多时间。</string>
<string name="filter_tip">该屏蔽系统会在 EHentai 网站屏蔽系统的基础上继续屏蔽画廊。\n\n标题屏蔽项:排除标题含有该关键字的画廊。\n\n上传者屏蔽项:排除该上传者上传的画廊。\n\n标签屏蔽项:排除包含该标签的画廊,这会使获取画廊列表花费更多时间。\n\n标签组屏蔽项:排除包含该标签组的画廊,这会使获取画廊列表花费更多时间。\n\n评论者屏蔽项:排除该评论者发布的评论。\n\n评论屏蔽项:排除匹配该正则表达式的评论。</string>
<!-- Set Security -->
@@ -382,8 +386,8 @@
<string name="settings_eh_tag_translations_source_url">https://github.com/EhTagTranslation/Editor/wiki</string>
<string name="settings_eh_preview_num">画廊详情页预览图最大数量</string>
<string name="settings_eh_preview_num_summary">由于历史因素,此值过大会导致卡顿</string>
<string name="settings_eh_filter">屏蔽画廊</string>
<string name="settings_eh_filter_summary">根据标题、上传者、标签屏蔽画廊</string>
<string name="settings_eh_filter">屏蔽列表</string>
<string name="settings_eh_filter_summary">根据标题、上传者、标签、评论者屏蔽画廊或评论</string>
<string name="settings_read_volume_page">使用音量键翻页</string>
<string name="settings_read_reverse_volume">翻转音量键</string>
+2
View File
@@ -178,6 +178,8 @@
<item>@string/filter_uploader</item>
<item>@string/filter_tag</item>
<item>@string/filter_tag_namespace</item>
<item>@string/filter_commenter</item>
<item>@string/filter_comment</item>
</string-array>
<string-array name="app_language_entries">
+1
View File
@@ -22,6 +22,7 @@
<item name="fragment_tag" type="id" />
<item name="copy" type="id" />
<item name="block_commenter" type="id" />
<item name="vote_up" type="id" />
<item name="vote_down" type="id" />
<item name="check_vote_status" type="id" />
+8 -4
View File
@@ -284,6 +284,8 @@
<string name="comment_successfully">Comment post successfully</string>
<string name="comment_failed">Failed to post the comment</string>
<string name="copy_comment_text">Copy comment text</string>
<string name="block_commenter">Block the commenter</string>
<string name="filter_the_commenter">Block the commenter \"%s\"?</string>
<string name="edit_comment">Edit comment</string>
<string name="edit_comment_successfully">The comment has been edited</string>
<string name="edit_comment_failed">Failed to edit the comment</string>
@@ -355,17 +357,19 @@
<string name="clear_all_history">Clear all history?</string>
<!-- Filter -->
<string name="filter">Block gallery</string>
<string name="filter">Blockers</string>
<string name="filter_title">Title</string>
<string name="filter_uploader">Uploader</string>
<string name="filter_tag">Tag</string>
<string name="filter_tag_namespace">Tag namespace</string>
<string name="filter_commenter">Commenter</string>
<string name="filter_comment">Comment Regex</string>
<string name="delete_filter">Delete blocker \"%s\"?</string>
<string name="tip">Tip</string>
<string name="add_filter">Add blocker</string>
<string name="show_definition">Show definition</string>
<string name="filter_text">Blocker text</string>
<string name="filter_tip">This blocking system filters the result of EHentai website blocking system.\n\nTitle Blocker: exclude the gallery whose title contains the word.\n\nUploader Blocker: exclude the gallery which was uploaded by the uploader.\n\nTag Blocker: exclude the gallery which contain the tag, it takes more time to get gallery list.\n\nTag Namespace Blocker: exclude the gallery which contain the tag namespace, it takes more time to get gallery list.</string>
<string name="filter_tip">This blocking system filters the result of EHentai website blocking system.\n\nTitle Blocker: exclude the gallery whose title contains the word.\n\nUploader Blocker: exclude the gallery which was uploaded by the uploader.\n\nTag Blocker: exclude the gallery which contain the tag, it takes more time to get gallery list.\n\nTag Namespace Blocker: exclude the gallery which contain the tag namespace, it takes more time to get gallery list.\n\nCommenter Blocker: exclude the comments posted by the commenter.\n\nComment Blocker: exclude the comments matching the regex.</string>
<!-- Set Security -->
@@ -427,8 +431,8 @@
<string name="settings_eh_tag_translations_source_url">https://placeholder</string>
<string name="settings_eh_preview_num">The maximum number of previews on the gallery details page</string>
<string name="settings_eh_preview_num_summary">For historical reasons, large value could cause lag</string>
<string name="settings_eh_filter">Block gallery</string>
<string name="settings_eh_filter_summary">Block gallery by title, uploader and tags</string>
<string name="settings_eh_filter">Blockers</string>
<string name="settings_eh_filter_summary">Block gallery or comment by title, uploader, tags and commenter</string>
<string name="settings_read_volume_page">Use volume key to turn pages</string>
<string name="settings_read_reverse_volume">Reverse volume key</string>