Twidere-App-Android-Twitter.../twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AddStatusFilterDialogFragme...

226 lines
9.7 KiB
Kotlin
Raw Normal View History

2016-07-08 09:52:32 +02:00
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.fragment
import android.app.Dialog
import android.content.ContentValues
import android.os.Bundle
2020-01-26 08:35:15 +01:00
import androidx.fragment.app.FragmentManager
import androidx.appcompat.app.AlertDialog
2020-06-27 22:43:38 +02:00
import com.twitter.twittertext.Extractor
2017-04-17 15:10:14 +02:00
import org.mariotaku.kpreferences.get
2016-07-08 09:52:32 +02:00
import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_STATUS
2017-04-17 15:10:14 +02:00
import org.mariotaku.twidere.constant.nameFirstKey
2017-02-05 14:42:20 +01:00
import org.mariotaku.twidere.extension.applyTheme
2017-06-19 15:45:41 +02:00
import org.mariotaku.twidere.extension.onShow
2016-07-08 09:52:32 +02:00
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.ParcelableUserMention
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.provider.TwidereDataStore.Filters
import org.mariotaku.twidere.util.ContentValuesCreator
import org.mariotaku.twidere.util.HtmlEscapeHelper
import org.mariotaku.twidere.util.ParseUtils
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.content.ContentResolverUtils
import java.util.*
class AddStatusFilterDialogFragment : BaseDialogFragment() {
private val extractor = Extractor()
private var filterItems: Array<FilterItemInfo>? = null
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(requireContext())
2016-07-08 09:52:32 +02:00
filterItems = filterItemsInfo
val entries = arrayOfNulls<String>(filterItems!!.size)
2017-04-17 15:10:14 +02:00
val nameFirst = preferences[nameFirstKey]
2020-06-08 23:07:20 +02:00
for (i in entries.indices) {
val info = filterItems!![i]
when (info.type) {
FilterItemInfo.FILTER_TYPE_USER -> {
entries[i] = getString(R.string.user_filter_name, getName(userColorNameManager,
info.value, nameFirst))
}
FilterItemInfo.FILTER_TYPE_KEYWORD -> {
entries[i] = getString(R.string.keyword_filter_name, getName(userColorNameManager,
info.value, nameFirst))
}
FilterItemInfo.FILTER_TYPE_SOURCE -> {
entries[i] = getString(R.string.source_filter_name, getName(userColorNameManager,
info.value, nameFirst))
2016-07-08 09:52:32 +02:00
}
}
}
builder.setTitle(R.string.action_add_to_filter)
2016-07-08 09:52:32 +02:00
builder.setMultiChoiceItems(entries, null, null)
builder.setPositiveButton(android.R.string.ok) { dialog, _ ->
2016-07-08 09:52:32 +02:00
val alertDialog = dialog as AlertDialog
val checkPositions = alertDialog.listView.checkedItemPositions
val userKeys = HashSet<UserKey>()
val keywords = HashSet<String>()
val sources = HashSet<String>()
val userValues = ArrayList<ContentValues>()
val keywordValues = ArrayList<ContentValues>()
val sourceValues = ArrayList<ContentValues>()
loop@ for (i in 0 until checkPositions.size()) {
2016-07-08 09:52:32 +02:00
if (!checkPositions.valueAt(i)) {
continue@loop
2016-07-08 09:52:32 +02:00
}
val info = filterItems!![checkPositions.keyAt(i)]
val value = info.value
2020-06-09 02:21:48 +02:00
when {
value is ParcelableUserMention -> {
userKeys.add(value.key)
userValues.add(ContentValuesCreator.createFilteredUser(value))
}
value is UserItem -> {
userKeys.add(value.key)
userValues.add(createFilteredUser(value))
}
info.type == FilterItemInfo.FILTER_TYPE_KEYWORD -> {
val keyword = ParseUtils.parseString(value)
keywords.add(keyword)
val values = ContentValues()
values.put(Filters.Keywords.VALUE, "#$keyword")
keywordValues.add(values)
}
info.type == FilterItemInfo.FILTER_TYPE_SOURCE -> {
val source = ParseUtils.parseString(value)
sources.add(source)
val values = ContentValues()
values.put(Filters.Sources.VALUE, source)
sourceValues.add(values)
}
2016-07-08 09:52:32 +02:00
}
}
2020-01-26 08:35:15 +01:00
context?.contentResolver?.let { resolver ->
ContentResolverUtils.bulkDelete(resolver, Filters.Users.CONTENT_URI,
Filters.Users.USER_KEY, false, userKeys, null, null)
ContentResolverUtils.bulkDelete(resolver, Filters.Keywords.CONTENT_URI,
Filters.Keywords.VALUE, false, keywords, null, null)
ContentResolverUtils.bulkDelete(resolver, Filters.Sources.CONTENT_URI,
Filters.Sources.VALUE, false, sources, null, null)
ContentResolverUtils.bulkInsert(resolver, Filters.Users.CONTENT_URI, userValues)
ContentResolverUtils.bulkInsert(resolver, Filters.Keywords.CONTENT_URI, keywordValues)
ContentResolverUtils.bulkInsert(resolver, Filters.Sources.CONTENT_URI, sourceValues)
}
2016-07-08 09:52:32 +02:00
}
builder.setNegativeButton(android.R.string.cancel, null)
2017-02-05 14:42:20 +01:00
val dialog = builder.create()
2017-06-19 15:45:41 +02:00
dialog.onShow { it.applyTheme() }
2017-02-05 14:42:20 +01:00
return dialog
2016-07-08 09:52:32 +02:00
}
private val filterItemsInfo: Array<FilterItemInfo>
get() {
val args = arguments
if (args == null || !args.containsKey(EXTRA_STATUS)) return emptyArray()
val status = args.getParcelable<ParcelableStatus>(EXTRA_STATUS) ?: return emptyArray()
val list = ArrayList<FilterItemInfo>()
if (status.is_retweet && status.retweeted_by_user_key != null) {
list.add(FilterItemInfo(FilterItemInfo.FILTER_TYPE_USER,
UserItem(status.retweeted_by_user_key!!, status.retweeted_by_user_name,
status.retweeted_by_user_screen_name)))
}
if (status.is_quote && status.quoted_user_key != null) {
list.add(FilterItemInfo(FilterItemInfo.FILTER_TYPE_USER,
UserItem(status.quoted_user_key!!, status.quoted_user_name,
status.quoted_user_screen_name)))
}
list.add(FilterItemInfo(FilterItemInfo.FILTER_TYPE_USER, UserItem(status.user_key,
status.user_name, status.user_screen_name)))
val mentions = status.mentions
if (mentions != null) {
for (mention in mentions) {
if (mention.key != status.user_key) {
list.add(FilterItemInfo(FilterItemInfo.FILTER_TYPE_USER, mention))
}
}
}
val hashtags = HashSet<String>()
hashtags.addAll(extractor.extractHashtags(status.text_plain))
for (hashtag in hashtags) {
list.add(FilterItemInfo(FilterItemInfo.FILTER_TYPE_KEYWORD, hashtag))
}
2017-04-23 09:15:46 +02:00
val source = status.source?.let(HtmlEscapeHelper::toPlainText)
2017-04-23 08:39:49 +02:00
if (source != null) {
list.add(FilterItemInfo(FilterItemInfo.FILTER_TYPE_SOURCE, source))
}
2016-07-08 09:52:32 +02:00
return list.toTypedArray()
}
private fun getName(manager: UserColorNameManager, value: Any, nameFirst: Boolean): String {
2020-06-09 02:21:48 +02:00
return when (value) {
is ParcelableUserMention -> {
manager.getDisplayName(value.key, value.name, value.screen_name, nameFirst)
}
is UserItem -> {
manager.getDisplayName(value.key, value.name, value.screen_name, nameFirst)
}
else -> ParseUtils.parseString(value)
}
2016-07-08 09:52:32 +02:00
}
internal data class FilterItemInfo(
val type: Int,
val value: Any
) {
companion object {
internal const val FILTER_TYPE_USER = 1
internal const val FILTER_TYPE_KEYWORD = 2
internal const val FILTER_TYPE_SOURCE = 3
}
}
internal data class UserItem(
val key: UserKey,
val name: String,
val screen_name: String
)
companion object {
2020-06-08 23:11:06 +02:00
const val FRAGMENT_TAG = "add_status_filter"
2016-07-08 09:52:32 +02:00
private fun createFilteredUser(item: UserItem): ContentValues {
val values = ContentValues()
values.put(Filters.Users.USER_KEY, item.key.toString())
values.put(Filters.Users.NAME, item.name)
values.put(Filters.Users.SCREEN_NAME, item.screen_name)
return values
}
fun show(fm: FragmentManager, status: ParcelableStatus): AddStatusFilterDialogFragment {
val args = Bundle()
args.putParcelable(EXTRA_STATUS, status)
val f = AddStatusFilterDialogFragment()
f.arguments = args
f.show(fm, FRAGMENT_TAG)
return f
}
}
}