2021-06-28 09:09:00 +02:00
|
|
|
package jp.juggler.subwaytooter.column
|
2021-05-17 16:13:04 +02:00
|
|
|
|
|
|
|
import android.content.Context
|
2021-06-28 09:09:00 +02:00
|
|
|
import jp.juggler.subwaytooter.App1
|
2021-05-27 04:15:59 +02:00
|
|
|
import jp.juggler.subwaytooter.api.ApiPath
|
|
|
|
import jp.juggler.subwaytooter.api.ApiTask
|
|
|
|
import jp.juggler.subwaytooter.api.TootApiClient
|
2021-05-17 16:13:04 +02:00
|
|
|
import jp.juggler.subwaytooter.api.entity.*
|
2021-05-27 04:15:59 +02:00
|
|
|
import jp.juggler.subwaytooter.api.runApiTask
|
2021-05-17 16:13:04 +02:00
|
|
|
import jp.juggler.subwaytooter.table.FavMute
|
|
|
|
import jp.juggler.subwaytooter.table.HighlightWord
|
|
|
|
import jp.juggler.subwaytooter.table.SavedAccount
|
|
|
|
import jp.juggler.subwaytooter.table.UserRelation
|
2021-06-28 09:35:09 +02:00
|
|
|
import jp.juggler.util.*
|
2023-01-13 13:22:25 +01:00
|
|
|
import jp.juggler.util.coroutine.launchMain
|
|
|
|
import jp.juggler.util.data.WordTrieTree
|
|
|
|
import jp.juggler.util.log.LogCategory
|
|
|
|
import jp.juggler.util.ui.AdapterChange
|
|
|
|
import jp.juggler.util.ui.AdapterChangeType
|
2021-05-17 16:13:04 +02:00
|
|
|
import java.util.regex.Pattern
|
|
|
|
|
2021-06-28 09:35:09 +02:00
|
|
|
private val log = LogCategory("ColumnFilters")
|
|
|
|
|
2021-05-17 21:33:28 +02:00
|
|
|
val Column.isFilterEnabled: Boolean
|
2021-06-20 15:12:25 +02:00
|
|
|
get() = withAttachment ||
|
2022-03-15 12:39:37 +01:00
|
|
|
withHighlight ||
|
|
|
|
regexText.isNotEmpty() ||
|
|
|
|
dontShowNormalToot ||
|
|
|
|
dontShowNonPublicToot ||
|
|
|
|
quickFilter != Column.QUICK_FILTER_ALL ||
|
|
|
|
dontShowBoost ||
|
|
|
|
dontShowFavourite ||
|
|
|
|
dontShowFollow ||
|
|
|
|
dontShowReply ||
|
|
|
|
dontShowReaction ||
|
|
|
|
dontShowVote ||
|
|
|
|
(languageFilter?.isNotEmpty() == true)
|
2021-05-17 21:33:28 +02:00
|
|
|
|
2021-05-17 16:13:04 +02:00
|
|
|
// マストドン2.4.3rcのキーワードフィルタのコンテキスト
|
|
|
|
fun Column.getFilterContext() = when (type) {
|
|
|
|
|
2022-08-02 04:41:05 +02:00
|
|
|
ColumnType.HOME,
|
|
|
|
ColumnType.LIST_TL,
|
|
|
|
ColumnType.MISSKEY_HYBRID,
|
|
|
|
-> TootFilter.CONTEXT_HOME
|
2021-05-17 16:13:04 +02:00
|
|
|
|
2022-08-02 04:41:05 +02:00
|
|
|
ColumnType.NOTIFICATIONS,
|
|
|
|
ColumnType.NOTIFICATION_FROM_ACCT,
|
|
|
|
-> TootFilter.CONTEXT_NOTIFICATIONS
|
2021-05-17 16:13:04 +02:00
|
|
|
|
2022-08-02 04:41:05 +02:00
|
|
|
ColumnType.CONVERSATION,
|
|
|
|
ColumnType.CONVERSATION_WITH_REFERENCE,
|
|
|
|
-> TootFilter.CONTEXT_THREAD
|
2021-05-17 16:13:04 +02:00
|
|
|
|
|
|
|
ColumnType.DIRECT_MESSAGES -> TootFilter.CONTEXT_THREAD
|
|
|
|
|
|
|
|
ColumnType.PROFILE -> TootFilter.CONTEXT_PROFILE
|
|
|
|
|
2022-03-16 05:04:04 +01:00
|
|
|
ColumnType.STATUS_HISTORY -> TootFilter.CONTEXT_NONE
|
|
|
|
|
2021-05-17 16:13:04 +02:00
|
|
|
else -> TootFilter.CONTEXT_PUBLIC
|
|
|
|
// ColumnType.MISSKEY_HYBRID や ColumnType.MISSKEY_ANTENNA_TL はHOMEでもPUBLICでもある…
|
|
|
|
// Misskeyだし関係ないが、NONEにするとアプリ内で完結するフィルタも働かなくなる
|
|
|
|
}
|
|
|
|
|
|
|
|
// カラム設定に正規表現フィルタを含めるなら真
|
2022-03-16 05:04:04 +01:00
|
|
|
fun Column.canStatusFilter() =
|
|
|
|
when (type) {
|
|
|
|
ColumnType.SEARCH_MSP,
|
|
|
|
ColumnType.SEARCH_TS,
|
|
|
|
ColumnType.SEARCH_NOTESTOCK,
|
|
|
|
ColumnType.STATUS_HISTORY,
|
|
|
|
-> true
|
|
|
|
else -> when {
|
|
|
|
getFilterContext() == TootFilter.CONTEXT_NONE -> false
|
|
|
|
else -> true
|
|
|
|
}
|
2021-05-17 16:13:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// カラム設定に「すべての画像を隠す」ボタンを含めるなら真
|
|
|
|
fun Column.canNSFWDefault(): Boolean = canStatusFilter()
|
|
|
|
|
|
|
|
// カラム設定に「ブーストを表示しない」ボタンを含めるなら真
|
|
|
|
fun Column.canFilterBoost(): Boolean = when (type) {
|
|
|
|
ColumnType.HOME, ColumnType.MISSKEY_HYBRID, ColumnType.PROFILE,
|
|
|
|
ColumnType.NOTIFICATIONS, ColumnType.NOTIFICATION_FROM_ACCT,
|
2022-03-15 12:39:37 +01:00
|
|
|
ColumnType.LIST_TL, ColumnType.MISSKEY_ANTENNA_TL,
|
2021-06-28 09:09:00 +02:00
|
|
|
-> true
|
2021-05-17 16:13:04 +02:00
|
|
|
ColumnType.LOCAL, ColumnType.FEDERATE, ColumnType.HASHTAG, ColumnType.SEARCH -> isMisskey
|
|
|
|
ColumnType.HASHTAG_FROM_ACCT -> false
|
2022-08-02 04:41:05 +02:00
|
|
|
ColumnType.CONVERSATION,
|
|
|
|
ColumnType.CONVERSATION_WITH_REFERENCE,
|
|
|
|
ColumnType.DIRECT_MESSAGES,
|
|
|
|
-> isMisskey
|
2021-05-17 16:13:04 +02:00
|
|
|
else -> false
|
|
|
|
}
|
|
|
|
|
|
|
|
// カラム設定に「返信を表示しない」ボタンを含めるなら真
|
|
|
|
fun Column.canFilterReply(): Boolean = when (type) {
|
|
|
|
ColumnType.HOME, ColumnType.MISSKEY_HYBRID, ColumnType.PROFILE,
|
|
|
|
ColumnType.NOTIFICATIONS, ColumnType.NOTIFICATION_FROM_ACCT,
|
2022-03-15 12:39:37 +01:00
|
|
|
ColumnType.LIST_TL, ColumnType.MISSKEY_ANTENNA_TL, ColumnType.DIRECT_MESSAGES,
|
2021-06-28 09:09:00 +02:00
|
|
|
-> true
|
2021-05-17 16:13:04 +02:00
|
|
|
ColumnType.LOCAL, ColumnType.FEDERATE, ColumnType.HASHTAG, ColumnType.SEARCH -> isMisskey
|
|
|
|
ColumnType.HASHTAG_FROM_ACCT -> true
|
|
|
|
else -> false
|
|
|
|
}
|
|
|
|
|
|
|
|
fun Column.canFilterNormalToot(): Boolean = when (type) {
|
|
|
|
ColumnType.NOTIFICATIONS -> true
|
|
|
|
ColumnType.HOME, ColumnType.MISSKEY_HYBRID,
|
2022-03-15 12:39:37 +01:00
|
|
|
ColumnType.LIST_TL, ColumnType.MISSKEY_ANTENNA_TL,
|
2021-06-28 09:09:00 +02:00
|
|
|
-> true
|
2021-05-17 16:13:04 +02:00
|
|
|
ColumnType.LOCAL, ColumnType.FEDERATE, ColumnType.HASHTAG, ColumnType.SEARCH -> isMisskey
|
|
|
|
ColumnType.HASHTAG_FROM_ACCT -> true
|
|
|
|
else -> false
|
|
|
|
}
|
|
|
|
|
|
|
|
fun Column.canFilterNonPublicToot(): Boolean = when (type) {
|
|
|
|
ColumnType.HOME, ColumnType.MISSKEY_HYBRID,
|
2022-03-15 12:39:37 +01:00
|
|
|
ColumnType.LIST_TL, ColumnType.MISSKEY_ANTENNA_TL,
|
2021-06-28 09:09:00 +02:00
|
|
|
-> true
|
2021-05-17 16:13:04 +02:00
|
|
|
ColumnType.LOCAL, ColumnType.FEDERATE, ColumnType.HASHTAG, ColumnType.SEARCH -> isMisskey
|
|
|
|
ColumnType.HASHTAG_FROM_ACCT -> true
|
|
|
|
else -> false
|
|
|
|
}
|
|
|
|
|
|
|
|
fun Column.onFiltersChanged2(filterList: ArrayList<TootFilter>) {
|
|
|
|
val newFilter = encodeFilterTree(filterList) ?: return
|
|
|
|
this.keywordFilterTrees = newFilter
|
|
|
|
checkFiltersForListData(newFilter)
|
|
|
|
}
|
|
|
|
|
|
|
|
fun Column.onFilterDeleted(filter: TootFilter, filterList: ArrayList<TootFilter>) {
|
|
|
|
if (type == ColumnType.KEYWORD_FILTER) {
|
2021-06-20 15:12:25 +02:00
|
|
|
val tmpList = ArrayList<TimelineItem>(listData.size)
|
|
|
|
for (o in listData) {
|
2021-05-17 16:13:04 +02:00
|
|
|
if (o is TootFilter) {
|
|
|
|
if (o.id == filter.id) continue
|
|
|
|
}
|
2021-06-20 15:12:25 +02:00
|
|
|
tmpList.add(o)
|
2021-05-17 16:13:04 +02:00
|
|
|
}
|
2021-06-20 15:12:25 +02:00
|
|
|
if (tmpList.size != listData.size) {
|
|
|
|
listData.clear()
|
|
|
|
listData.addAll(tmpList)
|
2021-05-17 16:13:04 +02:00
|
|
|
fireShowContent(reason = "onFilterDeleted")
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
val context = getFilterContext()
|
|
|
|
if (context != TootFilter.CONTEXT_NONE) {
|
|
|
|
onFiltersChanged2(filterList)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-17 21:33:28 +02:00
|
|
|
@Suppress("unused")
|
2021-05-17 16:13:04 +02:00
|
|
|
fun Column.onLanguageFilterChanged() {
|
|
|
|
// TODO
|
|
|
|
}
|
|
|
|
|
|
|
|
fun Column.initFilter() {
|
2021-06-20 15:12:25 +02:00
|
|
|
columnRegexFilter = Column.COLUMN_REGEX_FILTER_DEFAULT
|
|
|
|
val regexText = this.regexText
|
|
|
|
if (regexText.isNotEmpty()) {
|
2021-05-17 16:13:04 +02:00
|
|
|
try {
|
2021-06-20 15:12:25 +02:00
|
|
|
val re = Pattern.compile(regexText)
|
|
|
|
columnRegexFilter =
|
2021-05-17 16:13:04 +02:00
|
|
|
{ text: CharSequence? ->
|
2021-06-20 15:12:25 +02:00
|
|
|
when {
|
|
|
|
text?.isEmpty() != false -> false
|
|
|
|
else -> re.matcher(text).find()
|
|
|
|
}
|
2021-05-17 16:13:04 +02:00
|
|
|
}
|
|
|
|
} catch (ex: Throwable) {
|
2023-01-13 13:22:25 +01:00
|
|
|
log.e(ex, "initFilter failed.")
|
2021-05-17 16:13:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
favMuteSet = FavMute.acctSet
|
2021-06-20 15:12:25 +02:00
|
|
|
highlightTrie = HighlightWord.nameSet
|
2021-05-17 16:13:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private fun Column.isFilteredByAttachment(status: TootStatus): Boolean {
|
|
|
|
// オプションがどれも設定されていないならフィルタしない(false)
|
2021-06-20 15:12:25 +02:00
|
|
|
if (!(withAttachment || withHighlight)) return false
|
2021-05-17 16:13:04 +02:00
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
val matchMedia = withAttachment && status.reblog?.hasMedia() ?: status.hasMedia()
|
2021-05-17 16:13:04 +02:00
|
|
|
val matchHighlight =
|
2021-06-20 15:12:25 +02:00
|
|
|
withHighlight && null != (status.reblog?.highlightAny ?: status.highlightAny)
|
2021-05-17 16:13:04 +02:00
|
|
|
|
|
|
|
// どれかの条件を満たすならフィルタしない(false)、どれも満たさないならフィルタする(true)
|
|
|
|
return !(matchMedia || matchHighlight)
|
|
|
|
}
|
|
|
|
|
|
|
|
fun Column.isFiltered(status: TootStatus): Boolean {
|
|
|
|
|
|
|
|
val filterTrees = keywordFilterTrees
|
|
|
|
if (filterTrees != null) {
|
2021-06-20 15:12:25 +02:00
|
|
|
if (status.isKeywordFiltered(accessInfo, filterTrees.treeIrreversible)) {
|
2021-06-28 09:35:09 +02:00
|
|
|
log.d("status filtered by treeIrreversible")
|
2021-05-17 16:13:04 +02:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// just update _filtered flag for reversible filter
|
2021-06-20 15:12:25 +02:00
|
|
|
status.updateKeywordFilteredFlag(accessInfo, filterTrees)
|
2021-05-17 16:13:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (isFilteredByAttachment(status)) return true
|
|
|
|
|
|
|
|
val reblog = status.reblog
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
if (dontShowBoost) {
|
2021-05-17 16:13:04 +02:00
|
|
|
if (reblog != null) return true
|
|
|
|
}
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
if (dontShowReply) {
|
2021-05-17 16:13:04 +02:00
|
|
|
if (status.in_reply_to_id != null) return true
|
|
|
|
if (reblog?.in_reply_to_id != null) return true
|
|
|
|
}
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
if (dontShowNormalToot) {
|
2021-05-17 16:13:04 +02:00
|
|
|
if (status.in_reply_to_id == null && reblog == null) return true
|
|
|
|
}
|
2021-06-20 15:12:25 +02:00
|
|
|
if (dontShowNonPublicToot) {
|
2021-05-17 16:13:04 +02:00
|
|
|
if (!status.visibility.isPublic) return true
|
|
|
|
}
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
if (columnRegexFilter(status.decoded_content)) return true
|
|
|
|
if (columnRegexFilter(reblog?.decoded_content)) return true
|
|
|
|
if (columnRegexFilter(status.decoded_spoiler_text)) return true
|
|
|
|
if (columnRegexFilter(reblog?.decoded_spoiler_text)) return true
|
2021-05-17 16:13:04 +02:00
|
|
|
|
|
|
|
if (checkLanguageFilter(status)) return true
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
if (accessInfo.isPseudo) {
|
|
|
|
var r = UserRelation.loadPseudo(accessInfo.getFullAcct(status.account))
|
2021-05-17 16:13:04 +02:00
|
|
|
if (r.muting || r.blocking) return true
|
|
|
|
if (reblog != null) {
|
2021-06-20 15:12:25 +02:00
|
|
|
r = UserRelation.loadPseudo(accessInfo.getFullAcct(reblog.account))
|
2021-05-17 16:13:04 +02:00
|
|
|
if (r.muting || r.blocking) return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return status.checkMuted()
|
|
|
|
}
|
|
|
|
|
|
|
|
// true if the status will be hidden
|
|
|
|
private fun Column.checkLanguageFilter(status: TootStatus?): Boolean {
|
|
|
|
status ?: return false
|
2021-06-20 15:12:25 +02:00
|
|
|
val languageFilter = languageFilter ?: return false
|
2021-05-17 16:13:04 +02:00
|
|
|
|
|
|
|
val allow = languageFilter.boolean(
|
|
|
|
status.language ?: status.reblog?.language ?: TootStatus.LANGUAGE_CODE_UNKNOWN
|
|
|
|
)
|
|
|
|
?: languageFilter.boolean(TootStatus.LANGUAGE_CODE_DEFAULT)
|
|
|
|
?: true
|
|
|
|
|
|
|
|
return !allow
|
|
|
|
}
|
|
|
|
|
|
|
|
fun Column.isFiltered(item: TootNotification): Boolean {
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
if (when (quickFilter) {
|
2021-05-17 16:13:04 +02:00
|
|
|
Column.QUICK_FILTER_ALL -> when (item.type) {
|
2021-06-20 15:12:25 +02:00
|
|
|
TootNotification.TYPE_FAVOURITE -> dontShowFavourite
|
2021-05-17 16:13:04 +02:00
|
|
|
|
|
|
|
TootNotification.TYPE_REBLOG,
|
|
|
|
TootNotification.TYPE_RENOTE,
|
2022-03-15 12:39:37 +01:00
|
|
|
TootNotification.TYPE_QUOTE,
|
|
|
|
-> dontShowBoost
|
2021-05-17 16:13:04 +02:00
|
|
|
|
|
|
|
TootNotification.TYPE_FOLLOW,
|
|
|
|
TootNotification.TYPE_UNFOLLOW,
|
|
|
|
TootNotification.TYPE_FOLLOW_REQUEST,
|
|
|
|
TootNotification.TYPE_FOLLOW_REQUEST_MISSKEY,
|
2022-03-15 12:39:37 +01:00
|
|
|
TootNotification.TYPE_FOLLOW_REQUEST_ACCEPTED_MISSKEY,
|
2022-04-17 07:56:57 +02:00
|
|
|
TootNotification.TYPE_ADMIN_SIGNUP,
|
2022-03-15 12:39:37 +01:00
|
|
|
-> dontShowFollow
|
2021-05-17 16:13:04 +02:00
|
|
|
|
|
|
|
TootNotification.TYPE_MENTION,
|
2022-03-15 12:39:37 +01:00
|
|
|
TootNotification.TYPE_REPLY,
|
|
|
|
-> dontShowReply
|
2021-05-17 16:13:04 +02:00
|
|
|
|
2021-05-27 07:54:04 +02:00
|
|
|
TootNotification.TYPE_EMOJI_REACTION_PLEROMA,
|
2021-05-17 16:13:04 +02:00
|
|
|
TootNotification.TYPE_EMOJI_REACTION,
|
2022-03-15 12:39:37 +01:00
|
|
|
TootNotification.TYPE_REACTION,
|
|
|
|
-> dontShowReaction
|
2021-05-17 16:13:04 +02:00
|
|
|
|
|
|
|
TootNotification.TYPE_VOTE,
|
|
|
|
TootNotification.TYPE_POLL,
|
2022-03-15 12:39:37 +01:00
|
|
|
TootNotification.TYPE_POLL_VOTE_MISSKEY,
|
|
|
|
-> dontShowVote
|
2021-05-17 16:13:04 +02:00
|
|
|
|
2022-03-16 06:08:54 +01:00
|
|
|
TootNotification.TYPE_STATUS,
|
|
|
|
TootNotification.TYPE_UPDATE,
|
2022-03-19 15:42:20 +01:00
|
|
|
TootNotification.TYPE_STATUS_REFERENCE,
|
2022-03-16 06:08:54 +01:00
|
|
|
-> dontShowNormalToot
|
2022-03-15 12:39:37 +01:00
|
|
|
|
2021-05-17 16:13:04 +02:00
|
|
|
else -> false
|
|
|
|
}
|
|
|
|
|
|
|
|
else -> when (item.type) {
|
2021-06-20 15:12:25 +02:00
|
|
|
TootNotification.TYPE_FAVOURITE -> quickFilter != Column.QUICK_FILTER_FAVOURITE
|
2021-05-17 16:13:04 +02:00
|
|
|
TootNotification.TYPE_REBLOG,
|
|
|
|
TootNotification.TYPE_RENOTE,
|
2022-03-15 12:39:37 +01:00
|
|
|
TootNotification.TYPE_QUOTE,
|
|
|
|
-> quickFilter != Column.QUICK_FILTER_BOOST
|
2021-05-17 16:13:04 +02:00
|
|
|
|
|
|
|
TootNotification.TYPE_FOLLOW,
|
|
|
|
TootNotification.TYPE_UNFOLLOW,
|
|
|
|
TootNotification.TYPE_FOLLOW_REQUEST,
|
|
|
|
TootNotification.TYPE_FOLLOW_REQUEST_MISSKEY,
|
2022-03-15 12:39:37 +01:00
|
|
|
TootNotification.TYPE_FOLLOW_REQUEST_ACCEPTED_MISSKEY,
|
2022-04-17 07:56:57 +02:00
|
|
|
TootNotification.TYPE_ADMIN_SIGNUP,
|
2022-03-15 12:39:37 +01:00
|
|
|
-> quickFilter != Column.QUICK_FILTER_FOLLOW
|
2021-05-17 16:13:04 +02:00
|
|
|
|
|
|
|
TootNotification.TYPE_MENTION,
|
2022-03-15 12:39:37 +01:00
|
|
|
TootNotification.TYPE_REPLY,
|
|
|
|
-> quickFilter != Column.QUICK_FILTER_MENTION
|
2021-05-17 16:13:04 +02:00
|
|
|
|
2021-05-27 07:54:04 +02:00
|
|
|
TootNotification.TYPE_EMOJI_REACTION_PLEROMA,
|
2021-05-17 16:13:04 +02:00
|
|
|
TootNotification.TYPE_EMOJI_REACTION,
|
2022-03-15 12:39:37 +01:00
|
|
|
TootNotification.TYPE_REACTION,
|
|
|
|
-> quickFilter != Column.QUICK_FILTER_REACTION
|
2021-05-17 16:13:04 +02:00
|
|
|
|
|
|
|
TootNotification.TYPE_VOTE,
|
|
|
|
TootNotification.TYPE_POLL,
|
2022-03-15 12:39:37 +01:00
|
|
|
TootNotification.TYPE_POLL_VOTE_MISSKEY,
|
|
|
|
-> quickFilter != Column.QUICK_FILTER_VOTE
|
2021-05-17 16:13:04 +02:00
|
|
|
|
2022-03-16 06:08:54 +01:00
|
|
|
TootNotification.TYPE_STATUS,
|
|
|
|
TootNotification.TYPE_UPDATE,
|
2022-03-19 15:42:20 +01:00
|
|
|
TootNotification.TYPE_STATUS_REFERENCE,
|
2022-03-16 06:08:54 +01:00
|
|
|
-> quickFilter != Column.QUICK_FILTER_POST
|
2022-03-15 12:39:37 +01:00
|
|
|
|
2021-05-17 16:13:04 +02:00
|
|
|
else -> true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
) {
|
2021-06-28 09:35:09 +02:00
|
|
|
log.d("isFiltered: ${item.type} notification filtered.")
|
2021-05-17 16:13:04 +02:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
val status = item.status
|
|
|
|
val filterTrees = keywordFilterTrees
|
|
|
|
if (status != null && filterTrees != null) {
|
2021-06-20 15:12:25 +02:00
|
|
|
if (status.isKeywordFiltered(accessInfo, filterTrees.treeIrreversible)) {
|
2021-06-28 09:35:09 +02:00
|
|
|
log.d("isFiltered: status muted by treeIrreversible.")
|
2021-05-17 16:13:04 +02:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// just update _filtered flag for reversible filter
|
2021-06-20 15:12:25 +02:00
|
|
|
status.updateKeywordFilteredFlag(accessInfo, filterTrees)
|
2021-05-17 16:13:04 +02:00
|
|
|
}
|
|
|
|
if (checkLanguageFilter(status)) return true
|
|
|
|
|
|
|
|
if (status?.checkMuted() == true) {
|
2021-06-28 09:35:09 +02:00
|
|
|
log.d("isFiltered: status muted by in-app muted words.")
|
2021-05-17 16:13:04 +02:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// ふぁぼ魔ミュート
|
|
|
|
when (item.type) {
|
|
|
|
TootNotification.TYPE_REBLOG,
|
|
|
|
TootNotification.TYPE_RENOTE,
|
|
|
|
TootNotification.TYPE_QUOTE,
|
|
|
|
TootNotification.TYPE_FAVOURITE,
|
2021-05-27 07:54:04 +02:00
|
|
|
TootNotification.TYPE_EMOJI_REACTION_PLEROMA,
|
2021-05-17 16:13:04 +02:00
|
|
|
TootNotification.TYPE_EMOJI_REACTION,
|
|
|
|
TootNotification.TYPE_REACTION,
|
|
|
|
TootNotification.TYPE_FOLLOW,
|
|
|
|
TootNotification.TYPE_FOLLOW_REQUEST,
|
|
|
|
TootNotification.TYPE_FOLLOW_REQUEST_MISSKEY,
|
2022-03-15 12:39:37 +01:00
|
|
|
TootNotification.TYPE_FOLLOW_REQUEST_ACCEPTED_MISSKEY,
|
2022-04-17 07:56:57 +02:00
|
|
|
TootNotification.TYPE_ADMIN_SIGNUP,
|
2022-03-15 12:39:37 +01:00
|
|
|
-> {
|
2021-05-17 16:13:04 +02:00
|
|
|
val who = item.account
|
2021-06-20 15:12:25 +02:00
|
|
|
if (who != null && favMuteSet?.contains(accessInfo.getFullAcct(who)) == true) {
|
2021-06-28 09:35:09 +02:00
|
|
|
log.d("${accessInfo.getFullAcct(who)} is in favMuteSet.")
|
2021-05-17 16:13:04 +02:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// フィルタを読み直してリストを返す。またはnull
|
|
|
|
suspend fun Column.loadFilter2(client: TootApiClient): ArrayList<TootFilter>? {
|
2021-06-20 15:12:25 +02:00
|
|
|
if (accessInfo.isPseudo || accessInfo.isMisskey) return null
|
|
|
|
val columnContext = getFilterContext()
|
|
|
|
if (columnContext == 0) return null
|
2021-05-17 16:13:04 +02:00
|
|
|
val result = client.request(ApiPath.PATH_FILTERS)
|
|
|
|
|
|
|
|
val jsonArray = result?.jsonArray ?: return null
|
|
|
|
return TootFilter.parseList(jsonArray)
|
|
|
|
}
|
|
|
|
|
|
|
|
fun Column.encodeFilterTree(filterList: ArrayList<TootFilter>?): FilterTrees? {
|
2021-06-20 15:12:25 +02:00
|
|
|
val columnContext = getFilterContext()
|
|
|
|
if (columnContext == 0 || filterList == null) return null
|
2021-05-17 16:13:04 +02:00
|
|
|
val result = FilterTrees()
|
|
|
|
val now = System.currentTimeMillis()
|
|
|
|
for (filter in filterList) {
|
|
|
|
if (filter.time_expires_at > 0L && now >= filter.time_expires_at) continue
|
2021-06-20 15:12:25 +02:00
|
|
|
if ((filter.context and columnContext) != 0) {
|
2021-05-17 16:13:04 +02:00
|
|
|
|
|
|
|
val validator = when (filter.whole_word) {
|
|
|
|
true -> WordTrieTree.WORD_VALIDATOR
|
|
|
|
else -> WordTrieTree.EMPTY_VALIDATOR
|
|
|
|
}
|
|
|
|
|
|
|
|
if (filter.irreversible) {
|
|
|
|
result.treeIrreversible
|
|
|
|
} else {
|
|
|
|
result.treeReversible
|
|
|
|
}.add(filter.phrase, validator = validator)
|
|
|
|
|
|
|
|
result.treeAll.add(filter.phrase, validator = validator)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
fun Column.checkFiltersForListData(trees: FilterTrees?) {
|
|
|
|
trees ?: return
|
|
|
|
val changeList = ArrayList<AdapterChange>()
|
2021-06-20 15:12:25 +02:00
|
|
|
listData.forEachIndexed { idx, item ->
|
2021-05-17 16:13:04 +02:00
|
|
|
when (item) {
|
|
|
|
is TootStatus -> {
|
2021-06-20 15:12:25 +02:00
|
|
|
val oldFiltered = item.filtered
|
|
|
|
item.updateKeywordFilteredFlag(accessInfo, trees, checkIrreversible = true)
|
|
|
|
if (oldFiltered != item.filtered) {
|
2021-05-17 16:13:04 +02:00
|
|
|
changeList.add(AdapterChange(AdapterChangeType.RangeChange, idx))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
is TootNotification -> {
|
|
|
|
val s = item.status
|
|
|
|
if (s != null) {
|
2021-06-20 15:12:25 +02:00
|
|
|
val oldFiltered = s.filtered
|
|
|
|
s.updateKeywordFilteredFlag(accessInfo, trees, checkIrreversible = true)
|
|
|
|
if (oldFiltered != s.filtered) {
|
2021-05-17 16:13:04 +02:00
|
|
|
changeList.add(AdapterChange(AdapterChangeType.RangeChange, idx))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fireShowContent(reason = "filter updated", changeList = changeList)
|
|
|
|
}
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
fun reloadFilter(context: Context, accessInfo: SavedAccount) {
|
2021-06-13 13:48:48 +02:00
|
|
|
launchMain {
|
2021-05-27 04:15:59 +02:00
|
|
|
var resultList: ArrayList<TootFilter>? = null
|
|
|
|
|
|
|
|
context.runApiTask(
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo,
|
2021-05-27 04:15:59 +02:00
|
|
|
progressStyle = ApiTask.PROGRESS_NONE
|
2021-06-13 13:48:48 +02:00
|
|
|
) { client ->
|
|
|
|
client.request(ApiPath.PATH_FILTERS)?.also { result ->
|
|
|
|
result.jsonArray?.let {
|
2021-05-27 04:15:59 +02:00
|
|
|
resultList = TootFilter.parseList(it)
|
2021-05-17 16:13:04 +02:00
|
|
|
}
|
|
|
|
}
|
2021-05-27 04:15:59 +02:00
|
|
|
}
|
2021-05-17 16:13:04 +02:00
|
|
|
|
2021-06-13 13:48:48 +02:00
|
|
|
resultList?.let {
|
2021-06-28 09:35:09 +02:00
|
|
|
log.d("update filters for ${accessInfo.acct.pretty}")
|
2021-05-27 04:15:59 +02:00
|
|
|
for (column in App1.getAppState(context).columnList) {
|
2021-06-20 15:12:25 +02:00
|
|
|
if (column.accessInfo == accessInfo) {
|
2021-05-27 04:15:59 +02:00
|
|
|
column.onFiltersChanged2(it)
|
2021-05-17 16:13:04 +02:00
|
|
|
}
|
|
|
|
}
|
2021-05-27 04:15:59 +02:00
|
|
|
}
|
|
|
|
}
|
2021-05-17 16:13:04 +02:00
|
|
|
}
|