単語フィルタのエンティティのv2対応
This commit is contained in:
parent
d391a1ab8f
commit
301905c016
|
@ -9,9 +9,11 @@ import androidx.appcompat.app.AppCompatActivity
|
|||
import jp.juggler.subwaytooter.api.ApiPath
|
||||
import jp.juggler.subwaytooter.api.entity.EntityId
|
||||
import jp.juggler.subwaytooter.api.entity.TootFilter
|
||||
import jp.juggler.subwaytooter.api.entity.TootFilterContext
|
||||
import jp.juggler.subwaytooter.api.entity.TootStatus
|
||||
import jp.juggler.subwaytooter.api.runApiTask
|
||||
import jp.juggler.subwaytooter.column.ColumnType
|
||||
import jp.juggler.subwaytooter.databinding.ActKeywordFilterBinding
|
||||
import jp.juggler.subwaytooter.table.AcctColor
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.util.coroutine.launchMain
|
||||
|
@ -65,18 +67,22 @@ class ActKeywordFilter
|
|||
|
||||
private lateinit var account: SavedAccount
|
||||
|
||||
private lateinit var tvAccount: TextView
|
||||
private lateinit var etPhrase: EditText
|
||||
private lateinit var cbContextHome: CheckBox
|
||||
private lateinit var cbContextNotification: CheckBox
|
||||
private lateinit var cbContextPublic: CheckBox
|
||||
private lateinit var cbContextThread: CheckBox
|
||||
private lateinit var cbContextProfile: CheckBox
|
||||
private val views by lazy {
|
||||
ActKeywordFilterBinding.inflate(layoutInflater)
|
||||
}
|
||||
|
||||
private lateinit var cbFilterIrreversible: CheckBox
|
||||
private lateinit var cbFilterWordMatch: CheckBox
|
||||
private lateinit var tvExpire: TextView
|
||||
private lateinit var spExpire: Spinner
|
||||
// private lateinit var tvAccount: TextView
|
||||
// private lateinit var etPhrase: EditText
|
||||
// private lateinit var cbContextHome: CheckBox
|
||||
// private lateinit var cbContextNotification: CheckBox
|
||||
// private lateinit var cbContextPublic: CheckBox
|
||||
// private lateinit var cbContextThread: CheckBox
|
||||
// private lateinit var cbContextProfile: CheckBox
|
||||
//
|
||||
// private lateinit var cbFilterIrreversible: CheckBox
|
||||
// private lateinit var cbFilterWordMatch: CheckBox
|
||||
// private lateinit var tvExpire: TextView
|
||||
// private lateinit var spExpire: Spinner
|
||||
|
||||
private var loading = false
|
||||
private var density: Float = 1f
|
||||
|
@ -109,13 +115,13 @@ class ActKeywordFilter
|
|||
if (filterId != null) {
|
||||
startLoading()
|
||||
} else {
|
||||
spExpire.setSelection(1)
|
||||
etPhrase.setText(intent.getStringExtra(EXTRA_INITIAL_PHRASE) ?: "")
|
||||
views. spExpire.setSelection(1)
|
||||
views. etPhrase.setText(intent.getStringExtra(EXTRA_INITIAL_PHRASE) ?: "")
|
||||
}
|
||||
} else {
|
||||
val iv = savedInstanceState.getInt(STATE_EXPIRE_SPINNER, -1)
|
||||
if (iv != -1) {
|
||||
spExpire.setSelection(iv)
|
||||
views. spExpire.setSelection(iv)
|
||||
}
|
||||
filterExpire = savedInstanceState.getLong(STATE_EXPIRE_AT, filterExpire)
|
||||
}
|
||||
|
@ -124,7 +130,7 @@ class ActKeywordFilter
|
|||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
if (!loading) {
|
||||
outState.putInt(STATE_EXPIRE_SPINNER, spExpire.selectedItemPosition)
|
||||
outState.putInt(STATE_EXPIRE_SPINNER, views.spExpire.selectedItemPosition)
|
||||
outState.putLong(STATE_EXPIRE_AT, filterExpire)
|
||||
}
|
||||
}
|
||||
|
@ -138,24 +144,24 @@ class ActKeywordFilter
|
|||
)
|
||||
|
||||
this.density = resources.displayMetrics.density
|
||||
setContentView(R.layout.act_keyword_filter)
|
||||
setContentView(views.root)
|
||||
App1.initEdgeToEdge(this)
|
||||
|
||||
fixHorizontalPadding(findViewById(R.id.svContent))
|
||||
|
||||
tvAccount = findViewById(R.id.tvAccount)
|
||||
etPhrase = findViewById(R.id.etPhrase)
|
||||
cbContextHome = findViewById(R.id.cbContextHome)
|
||||
cbContextNotification = findViewById(R.id.cbContextNotification)
|
||||
cbContextPublic = findViewById(R.id.cbContextPublic)
|
||||
cbContextThread = findViewById(R.id.cbContextThread)
|
||||
cbContextProfile = findViewById(R.id.cbContextProfile)
|
||||
cbFilterIrreversible = findViewById(R.id.cbFilterIrreversible)
|
||||
cbFilterWordMatch = findViewById(R.id.cbFilterWordMatch)
|
||||
tvExpire = findViewById(R.id.tvExpire)
|
||||
spExpire = findViewById(R.id.spExpire)
|
||||
// tvAccount = findViewById(R.id.tvAccount)
|
||||
// etPhrase = findViewById(R.id.etPhrase)
|
||||
// cbContextHome = findViewById(R.id.cbContextHome)
|
||||
// cbContextNotification = findViewById(R.id.cbContextNotification)
|
||||
// cbContextPublic = findViewById(R.id.cbContextPublic)
|
||||
// cbContextThread = findViewById(R.id.cbContextThread)
|
||||
// cbContextProfile = findViewById(R.id.cbContextProfile)
|
||||
// cbFilterIrreversible = findViewById(R.id.cbFilterIrreversible)
|
||||
// cbFilterWordMatch = findViewById(R.id.cbFilterWordMatch)
|
||||
// tvExpire = findViewById(R.id.tvExpire)
|
||||
// spExpire = findViewById(R.id.spExpire)
|
||||
|
||||
findViewById<View>(R.id.btnSave).setOnClickListener(this)
|
||||
views.btnSave.setOnClickListener(this)
|
||||
|
||||
val captionList = arrayOf(
|
||||
getString(R.string.dont_change),
|
||||
|
@ -169,11 +175,11 @@ class ActKeywordFilter
|
|||
)
|
||||
val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, captionList)
|
||||
adapter.setDropDownViewResource(R.layout.lv_spinner_dropdown)
|
||||
spExpire.adapter = adapter
|
||||
views.spExpire.adapter = adapter
|
||||
}
|
||||
|
||||
private fun showAccount() {
|
||||
tvAccount.text = AcctColor.getNicknameWithColor(account.acct)
|
||||
views.tvAccount.text = AcctColor.getNicknameWithColor(account.acct)
|
||||
}
|
||||
|
||||
private fun startLoading() {
|
||||
|
@ -207,17 +213,17 @@ class ActKeywordFilter
|
|||
|
||||
filterExpire = filter.time_expires_at
|
||||
|
||||
etPhrase.setText(filter.phrase)
|
||||
setContextChecked(filter, cbContextHome, TootFilter.CONTEXT_HOME)
|
||||
setContextChecked(filter, cbContextNotification, TootFilter.CONTEXT_NOTIFICATIONS)
|
||||
setContextChecked(filter, cbContextPublic, TootFilter.CONTEXT_PUBLIC)
|
||||
setContextChecked(filter, cbContextThread, TootFilter.CONTEXT_THREAD)
|
||||
setContextChecked(filter, cbContextProfile, TootFilter.CONTEXT_PROFILE)
|
||||
setContextChecked(filter, views.cbContextHome, TootFilterContext.Home)
|
||||
setContextChecked(filter, views.cbContextNotification, TootFilterContext.Notifications)
|
||||
setContextChecked(filter, views.cbContextPublic, TootFilterContext.Public)
|
||||
setContextChecked(filter, views.cbContextThread, TootFilterContext.Thread)
|
||||
setContextChecked(filter, views.cbContextProfile, TootFilterContext.Account)
|
||||
|
||||
cbFilterIrreversible.isChecked = filter.irreversible
|
||||
cbFilterWordMatch.isChecked = filter.whole_word
|
||||
views.etPhrase.setText(filter.phrase)
|
||||
views.cbFilterIrreversible.isChecked = filter.irreversible
|
||||
views.cbFilterWordMatch.isChecked = filter.whole_word
|
||||
|
||||
tvExpire.text = if (filter.time_expires_at == 0L) {
|
||||
views.tvExpire.text = if (filter.time_expires_at == 0L) {
|
||||
getString(R.string.filter_expire_unlimited)
|
||||
} else {
|
||||
TootStatus.formatTime(this, filter.time_expires_at, false)
|
||||
|
@ -230,12 +236,12 @@ class ActKeywordFilter
|
|||
}
|
||||
}
|
||||
|
||||
private fun setContextChecked(filter: TootFilter, cb: CheckBox, bit: Int) {
|
||||
cb.isChecked = ((filter.context and bit) != 0)
|
||||
private fun setContextChecked(filter: TootFilter, cb: CheckBox, fc: TootFilterContext) {
|
||||
cb.isChecked = filter.hasContext(fc)
|
||||
}
|
||||
|
||||
private fun JsonArray.putContextChecked(cb: CheckBox, key: String) {
|
||||
if (cb.isChecked) add(key)
|
||||
private fun JsonArray.putContextChecked(cb: CheckBox, fc:TootFilterContext) {
|
||||
if (cb.isChecked) add(fc.apiName)
|
||||
}
|
||||
|
||||
private fun save() {
|
||||
|
@ -243,22 +249,22 @@ class ActKeywordFilter
|
|||
|
||||
val params = buildJsonObject {
|
||||
|
||||
put("phrase", etPhrase.text.toString())
|
||||
|
||||
put("context", JsonArray().apply {
|
||||
putContextChecked(cbContextHome, "home")
|
||||
putContextChecked(cbContextNotification, "notifications")
|
||||
putContextChecked(cbContextPublic, "public")
|
||||
putContextChecked(cbContextThread, "thread")
|
||||
putContextChecked(cbContextProfile, "account")
|
||||
putContextChecked(views.cbContextHome, TootFilterContext.Home)
|
||||
putContextChecked(views.cbContextNotification, TootFilterContext.Notifications)
|
||||
putContextChecked(views.cbContextPublic, TootFilterContext.Public)
|
||||
putContextChecked(views.cbContextThread, TootFilterContext.Thread)
|
||||
putContextChecked(views.cbContextProfile, TootFilterContext.Account)
|
||||
})
|
||||
|
||||
put("irreversible", cbFilterIrreversible.isChecked)
|
||||
put("whole_word", cbFilterWordMatch.isChecked)
|
||||
put("phrase", views.etPhrase.text.toString())
|
||||
|
||||
put("irreversible",views. cbFilterIrreversible.isChecked)
|
||||
put("whole_word", views.cbFilterWordMatch.isChecked)
|
||||
|
||||
var seconds = -1
|
||||
|
||||
val i = spExpire.selectedItemPosition
|
||||
val i = views.spExpire.selectedItemPosition
|
||||
if (i >= 0 && i < expire_duration_list.size) {
|
||||
seconds = expire_duration_list[i]
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ fun ActMain.filterDelete(
|
|||
confirm(R.string.filter_delete_confirm, filter.phrase)
|
||||
}
|
||||
|
||||
var resultFilterList: ArrayList<TootFilter>? = null
|
||||
var resultFilterList: List<TootFilter>? = null
|
||||
runApiTask(accessInfo) { client ->
|
||||
var result =
|
||||
client.request("/api/v1/filters/${filter.id}", Request.Builder().delete())
|
||||
|
|
|
@ -1,82 +1,78 @@
|
|||
package jp.juggler.subwaytooter.api.entity
|
||||
|
||||
import android.content.Context
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.util.*
|
||||
import jp.juggler.util.data.JsonArray
|
||||
import jp.juggler.util.data.JsonObject
|
||||
import jp.juggler.util.data.notBlank
|
||||
import jp.juggler.util.log.LogCategory
|
||||
|
||||
// https://docs.joinmastodon.org/entities/Filter/
|
||||
// https://docs.joinmastodon.org/entities/V1_Filter/
|
||||
class TootFilter(src: JsonObject) : TimelineItem() {
|
||||
|
||||
class FilterContext(val name: String, val bit: Int, val caption_id: Int)
|
||||
|
||||
companion object {
|
||||
val log = LogCategory("TootFilter")
|
||||
|
||||
@Suppress("unused")
|
||||
const val CONTEXT_ALL = 31
|
||||
const val CONTEXT_NONE = 0
|
||||
const val CONTEXT_HOME = 1
|
||||
const val CONTEXT_NOTIFICATIONS = 2
|
||||
const val CONTEXT_PUBLIC = 4
|
||||
const val CONTEXT_THREAD = 8
|
||||
const val CONTEXT_PROFILE = 16
|
||||
|
||||
private val CONTEXT_LIST = arrayOf(
|
||||
FilterContext("home", CONTEXT_HOME, R.string.filter_home),
|
||||
FilterContext("notifications", CONTEXT_NOTIFICATIONS, R.string.filter_notification),
|
||||
FilterContext("public", CONTEXT_PUBLIC, R.string.filter_public),
|
||||
FilterContext("thread", CONTEXT_THREAD, R.string.filter_thread),
|
||||
FilterContext("account", CONTEXT_PROFILE, R.string.filter_profile)
|
||||
)
|
||||
|
||||
private val CONTEXT_MAP = CONTEXT_LIST.associateBy { it.name }
|
||||
|
||||
private fun parseFilterContext(src: JsonArray?): Int {
|
||||
var n = 0
|
||||
src?.stringList()?.forEach { key ->
|
||||
val v = CONTEXT_MAP[key]
|
||||
if (v != null) n += v.bit
|
||||
}
|
||||
return n
|
||||
}
|
||||
private val log = LogCategory("TootFilter")
|
||||
|
||||
fun parseList(src: JsonArray?) =
|
||||
ArrayList<TootFilter>().also { result ->
|
||||
src?.objectList()?.forEach {
|
||||
try {
|
||||
result.add(TootFilter(it))
|
||||
} catch (ex: Throwable) {
|
||||
log.e(ex, "TootFilter parse failed.")
|
||||
}
|
||||
src?.objectList()?.mapNotNull {
|
||||
try {
|
||||
TootFilter(it)
|
||||
} catch (ex: Throwable) {
|
||||
log.e(ex, "TootFilter parse failed.")
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val id: EntityId
|
||||
val phrase: String
|
||||
val context: Int
|
||||
private val expires_at: String? // null is not specified, or "2018-07-06T00:59:13.161Z"
|
||||
val time_expires_at: Long // 0L if not specified
|
||||
val irreversible: Boolean
|
||||
val whole_word: Boolean
|
||||
|
||||
init {
|
||||
id = EntityId.mayDefault(src.string("id"))
|
||||
phrase = src.string("phrase") ?: error("missing phrase")
|
||||
context = parseFilterContext(src.jsonArray("context"))
|
||||
expires_at = src.string("expires_at") // may null
|
||||
time_expires_at = TootStatus.parseTime(expires_at)
|
||||
irreversible = src.optBoolean("irreversible")
|
||||
whole_word = src.optBoolean("whole_word")
|
||||
}
|
||||
|
||||
fun getContextNames(context: Context): ArrayList<String> {
|
||||
val result = ArrayList<String>()
|
||||
for (item in CONTEXT_LIST) {
|
||||
if ((item.bit and this.context) != 0) result.add(context.getString(item.caption_id))
|
||||
fun parse1(src: JsonObject?) = try {
|
||||
src?.let { TootFilter(it) }
|
||||
} catch (ex: Throwable) {
|
||||
log.e(ex, "TootFilter parse failed.")
|
||||
null
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
val id: EntityId = EntityId.mayDefault(src.string("id"))
|
||||
|
||||
// v2
|
||||
val title: String? = src.string("title")
|
||||
|
||||
private val contextBits: Int = TootFilterContext.parseBits(src.jsonArray("context"))
|
||||
|
||||
// フィルタの適用先の名前の文字列IDのリスト
|
||||
val contextNames
|
||||
get() = TootFilterContext.bitsToNames(contextBits)
|
||||
|
||||
// null is not specified, or "2018-07-06T00:59:13.161Z"
|
||||
private val expires_at: String? = src.string("expires_at")
|
||||
|
||||
// 0L if not specified
|
||||
val time_expires_at: Long = TootStatus.parseTime(expires_at)
|
||||
|
||||
// v2: filter_action is "warn" or "hide".
|
||||
// v1: irreversible boolean flag.
|
||||
val filter_action: String = src.string("filter_action") ?: run {
|
||||
// v1
|
||||
when (src.boolean("irreversible")) {
|
||||
true -> "hide"
|
||||
else -> "warn"
|
||||
}
|
||||
}
|
||||
|
||||
val keywords: List<TootFilterKeyword>? =
|
||||
src.jsonArray("keywords")?.let { a ->
|
||||
/* v2 */ a.objectList().map { TootFilterKeyword(it) }
|
||||
} ?: src.string("phrase").notBlank()?.let {
|
||||
listOf(
|
||||
/* v1 */
|
||||
TootFilterKeyword(
|
||||
keyword = it,
|
||||
whole_word = src.boolean("whole_word") ?: false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// フィルタにマッチしたステータスのIDのリスト
|
||||
val statuses = src.jsonArray("statuses")?.objectList()?.map { TootFilterStatus(it) }
|
||||
|
||||
fun hasContext(fc: TootFilterContext) =
|
||||
contextBits.and(fc.bit) != 0
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package jp.juggler.subwaytooter.api.entity
|
||||
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.util.data.JsonArray
|
||||
import jp.juggler.util.log.LogCategory
|
||||
|
||||
enum class TootFilterContext(
|
||||
// アプリ内で管理するビット
|
||||
val bit: Int,
|
||||
// API中の識別子
|
||||
val apiName: String,
|
||||
// アプリに表示する文字列のID
|
||||
val caption_id: Int
|
||||
) {
|
||||
Home(1, "home", R.string.filter_home),
|
||||
Notifications(2, "notifications", R.string.filter_notification),
|
||||
Public(4, "public", R.string.filter_public),
|
||||
Thread(8, "thread", R.string.filter_thread),
|
||||
Account(16, "account", R.string.filter_profile),
|
||||
|
||||
;
|
||||
|
||||
companion object {
|
||||
private val log = LogCategory("TootFilterContext")
|
||||
|
||||
private val valuesCache = values()
|
||||
private val apiNameMap = values().associateBy { it.name }
|
||||
|
||||
fun parseBits(src: JsonArray?): Int =
|
||||
src?.stringList()?.mapNotNull { apiNameMap[it]?.bit }?.sum() ?: 0
|
||||
|
||||
fun bitsToNames(mask: Int) =
|
||||
valuesCache.filter { it.bit.and(mask) != 0 }.map { it.caption_id }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package jp.juggler.subwaytooter.api.entity
|
||||
|
||||
import jp.juggler.util.data.JsonArray
|
||||
import jp.juggler.util.data.JsonObject
|
||||
|
||||
class TootFilterKeyword(
|
||||
var id: EntityId? = null,// v1 has no id
|
||||
var keyword: String?,
|
||||
var whole_word: Boolean,
|
||||
) {
|
||||
// from Mastodon api/v2/filter
|
||||
constructor(src: JsonObject) : this(
|
||||
id = EntityId.mayNull(src.string("id")),
|
||||
keyword = src.string("keyword"),
|
||||
whole_word = src.boolean("whole_word") ?: true,
|
||||
)
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package jp.juggler.subwaytooter.api.entity
|
||||
|
||||
import jp.juggler.util.data.JsonObject
|
||||
|
||||
class TootFilterResult(src: JsonObject) {
|
||||
|
||||
val filter: TootFilter? =
|
||||
TootFilter.parse1(src.jsonObject("filter"))
|
||||
|
||||
val keyword_matches: List<String>? =
|
||||
src.jsonArray("keyword_matches")?.stringList()
|
||||
|
||||
val status_matches: EntityId? =
|
||||
EntityId.mayNull(src.string("status_matches"))
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package jp.juggler.subwaytooter.api.entity
|
||||
|
||||
import jp.juggler.util.data.JsonObject
|
||||
|
||||
// https://docs.joinmastodon.org/entities/FilterStatus/
|
||||
// Represents a status ID that, if matched, should cause the filter action to be taken.
|
||||
class TootFilterStatus(src: JsonObject) {
|
||||
val id = EntityId.mayDefault(src.string("id"))
|
||||
val status_id = EntityId.mayDefault(src.string("status_id"))
|
||||
}
|
|
@ -39,26 +39,25 @@ val Column.isFilterEnabled: Boolean
|
|||
// マストドン2.4.3rcのキーワードフィルタのコンテキスト
|
||||
fun Column.getFilterContext() = when (type) {
|
||||
|
||||
ColumnType.STATUS_HISTORY -> null
|
||||
|
||||
ColumnType.HOME,
|
||||
ColumnType.LIST_TL,
|
||||
ColumnType.MISSKEY_HYBRID,
|
||||
-> TootFilter.CONTEXT_HOME
|
||||
-> TootFilterContext.Home
|
||||
|
||||
ColumnType.NOTIFICATIONS,
|
||||
ColumnType.NOTIFICATION_FROM_ACCT,
|
||||
-> TootFilter.CONTEXT_NOTIFICATIONS
|
||||
-> TootFilterContext.Notifications
|
||||
|
||||
ColumnType.CONVERSATION,
|
||||
ColumnType.CONVERSATION_WITH_REFERENCE,
|
||||
-> TootFilter.CONTEXT_THREAD
|
||||
ColumnType.DIRECT_MESSAGES,
|
||||
-> TootFilterContext.Thread
|
||||
|
||||
ColumnType.DIRECT_MESSAGES -> TootFilter.CONTEXT_THREAD
|
||||
ColumnType.PROFILE -> TootFilterContext.Account
|
||||
|
||||
ColumnType.PROFILE -> TootFilter.CONTEXT_PROFILE
|
||||
|
||||
ColumnType.STATUS_HISTORY -> TootFilter.CONTEXT_NONE
|
||||
|
||||
else -> TootFilter.CONTEXT_PUBLIC
|
||||
else -> TootFilterContext.Public
|
||||
// ColumnType.MISSKEY_HYBRID や ColumnType.MISSKEY_ANTENNA_TL はHOMEでもPUBLICでもある…
|
||||
// Misskeyだし関係ないが、NONEにするとアプリ内で完結するフィルタも働かなくなる
|
||||
}
|
||||
|
@ -71,10 +70,7 @@ fun Column.canStatusFilter() =
|
|||
ColumnType.SEARCH_NOTESTOCK,
|
||||
ColumnType.STATUS_HISTORY,
|
||||
-> true
|
||||
else -> when {
|
||||
getFilterContext() == TootFilter.CONTEXT_NONE -> false
|
||||
else -> true
|
||||
}
|
||||
else -> getFilterContext() !=null
|
||||
}
|
||||
|
||||
// カラム設定に「すべての画像を隠す」ボタンを含めるなら真
|
||||
|
@ -125,13 +121,13 @@ fun Column.canFilterNonPublicToot(): Boolean = when (type) {
|
|||
else -> false
|
||||
}
|
||||
|
||||
fun Column.onFiltersChanged2(filterList: ArrayList<TootFilter>) {
|
||||
fun Column.onFiltersChanged2(filterList: List<TootFilter>) {
|
||||
val newFilter = encodeFilterTree(filterList) ?: return
|
||||
this.keywordFilterTrees = newFilter
|
||||
checkFiltersForListData(newFilter)
|
||||
}
|
||||
|
||||
fun Column.onFilterDeleted(filter: TootFilter, filterList: ArrayList<TootFilter>) {
|
||||
fun Column.onFilterDeleted(filter: TootFilter, filterList: List<TootFilter>) {
|
||||
if (type == ColumnType.KEYWORD_FILTER) {
|
||||
val tmpList = ArrayList<TimelineItem>(listData.size)
|
||||
for (o in listData) {
|
||||
|
@ -146,8 +142,7 @@ fun Column.onFilterDeleted(filter: TootFilter, filterList: ArrayList<TootFilter>
|
|||
fireShowContent(reason = "onFilterDeleted")
|
||||
}
|
||||
} else {
|
||||
val context = getFilterContext()
|
||||
if (context != TootFilter.CONTEXT_NONE) {
|
||||
if( getFilterContext() != null){
|
||||
onFiltersChanged2(filterList)
|
||||
}
|
||||
}
|
||||
|
@ -386,38 +381,36 @@ fun Column.isFiltered(item: TootNotification): Boolean {
|
|||
}
|
||||
|
||||
// フィルタを読み直してリストを返す。またはnull
|
||||
suspend fun Column.loadFilter2(client: TootApiClient): ArrayList<TootFilter>? {
|
||||
suspend fun Column.loadFilter2(client: TootApiClient): List<TootFilter>? {
|
||||
if (accessInfo.isPseudo || accessInfo.isMisskey) return null
|
||||
val columnContext = getFilterContext()
|
||||
if (columnContext == 0) return null
|
||||
if (getFilterContext() ==null) return null
|
||||
val result = client.request(ApiPath.PATH_FILTERS)
|
||||
|
||||
val jsonArray = result?.jsonArray ?: return null
|
||||
return TootFilter.parseList(jsonArray)
|
||||
}
|
||||
|
||||
fun Column.encodeFilterTree(filterList: ArrayList<TootFilter>?): FilterTrees? {
|
||||
fun Column.encodeFilterTree(filterList: List<TootFilter>?): FilterTrees? {
|
||||
val columnContext = getFilterContext()
|
||||
if (columnContext == 0 || filterList == null) return null
|
||||
if (columnContext == null || filterList == null) return null
|
||||
val result = FilterTrees()
|
||||
val now = System.currentTimeMillis()
|
||||
for (filter in filterList) {
|
||||
if (filter.time_expires_at > 0L && now >= filter.time_expires_at) continue
|
||||
if ((filter.context and columnContext) != 0) {
|
||||
if (!filter.hasContext(columnContext)) continue
|
||||
|
||||
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)
|
||||
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
|
||||
}
|
||||
|
@ -452,7 +445,7 @@ fun Column.checkFiltersForListData(trees: FilterTrees?) {
|
|||
|
||||
fun reloadFilter(context: Context, accessInfo: SavedAccount) {
|
||||
launchMain {
|
||||
var resultList: ArrayList<TootFilter>? = null
|
||||
var resultList: List<TootFilter>? = null
|
||||
|
||||
context.runApiTask(
|
||||
accessInfo,
|
||||
|
|
|
@ -905,7 +905,7 @@ class ColumnTask_Loading(
|
|||
val result = client.request(pathBase)
|
||||
if (result != null) {
|
||||
val src = TootFilter.parseList(result.jsonArray)
|
||||
this.listTmp = addAll(null, src)
|
||||
this.listTmp = addAll(null, src?: emptyList())
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -400,7 +400,7 @@ fun ItemViewHolder.showFilter(filter: TootFilter) {
|
|||
//
|
||||
sb.append(activity.getString(R.string.filter_context))
|
||||
.append(": ")
|
||||
.append(filter.getContextNames(activity).joinToString("/"))
|
||||
.append(filter.contextNames.joinToString("/") { activity.getString(it) })
|
||||
//
|
||||
val flags = ArrayList<String>()
|
||||
if (filter.irreversible) flags.add(activity.getString(R.string.filter_irreversible))
|
||||
|
|
Loading…
Reference in New Issue