Share filters with web client (#956)

* First step toward synchronized content filters

* Add simple filter management UI

* Remove old regex filter UI

* More cleanup

* Escape filter phrases when applying them via regex

* Apply code review feedback

* Fix live timeline update when filters change
This commit is contained in:
Levi Bard 2019-03-20 19:25:26 +01:00 committed by Konrad Pozniak
commit 5135daad2c
13 changed files with 439 additions and 91 deletions

View file

@ -32,6 +32,7 @@ import com.keylesspalace.tusky.appstore.PreferenceChangedEvent
import com.keylesspalace.tusky.db.AccountManager
import com.keylesspalace.tusky.di.Injectable
import com.keylesspalace.tusky.entity.Account
import com.keylesspalace.tusky.entity.Filter
import com.keylesspalace.tusky.entity.Status
import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.util.ThemeUtils
@ -65,6 +66,10 @@ class AccountPreferencesFragment : PreferenceFragmentCompat(),
private lateinit var defaultMediaSensitivityPreference: SwitchPreference
private lateinit var alwaysShowSensitiveMediaPreference: SwitchPreference
private lateinit var mediaPreviewEnabledPreference: SwitchPreference
private lateinit var homeFiltersPreference: Preference
private lateinit var notificationFiltersPreference: Preference
private lateinit var publicFiltersPreference: Preference
private lateinit var threadFiltersPreference: Preference
private val iconSize by lazy {resources.getDimensionPixelSize(R.dimen.preference_icon_size)}
@ -79,6 +84,10 @@ class AccountPreferencesFragment : PreferenceFragmentCompat(),
defaultMediaSensitivityPreference = findPreference("defaultMediaSensitivity") as SwitchPreference
mediaPreviewEnabledPreference = findPreference("mediaPreviewEnabled") as SwitchPreference
alwaysShowSensitiveMediaPreference = findPreference("alwaysShowSensitiveMedia") as SwitchPreference
homeFiltersPreference = findPreference("homeFilters")
notificationFiltersPreference = findPreference("notificationFilters")
publicFiltersPreference = findPreference("publicFilters")
threadFiltersPreference = findPreference("threadFilters")
notificationPreference.icon = IconicsDrawable(notificationPreference.context, GoogleMaterial.Icon.gmd_notifications).sizePx(iconSize).color(ThemeUtils.getColor(notificationPreference.context, R.attr.toolbar_icon_tint))
mutedUsersPreference.icon = getTintedIcon(R.drawable.ic_mute_24dp)
@ -88,12 +97,15 @@ class AccountPreferencesFragment : PreferenceFragmentCompat(),
tabPreference.onPreferenceClickListener = this
mutedUsersPreference.onPreferenceClickListener = this
blockedUsersPreference.onPreferenceClickListener = this
homeFiltersPreference.onPreferenceClickListener = this
notificationFiltersPreference.onPreferenceClickListener = this
publicFiltersPreference.onPreferenceClickListener = this
threadFiltersPreference.onPreferenceClickListener = this
defaultPostPrivacyPreference.onPreferenceChangeListener = this
defaultMediaSensitivityPreference.onPreferenceChangeListener = this
mediaPreviewEnabledPreference.onPreferenceChangeListener = this
alwaysShowSensitiveMediaPreference.onPreferenceChangeListener = this
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -144,7 +156,7 @@ class AccountPreferencesFragment : PreferenceFragmentCompat(),
override fun onPreferenceClick(preference: Preference): Boolean {
when(preference) {
return when(preference) {
notificationPreference -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val intent = Intent()
@ -159,30 +171,42 @@ class AccountPreferencesFragment : PreferenceFragmentCompat(),
}
}
return true
true
}
tabPreference -> {
val intent = Intent(context, TabPreferenceActivity::class.java)
activity?.startActivity(intent)
activity?.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
return true
true
}
mutedUsersPreference -> {
val intent = Intent(context, AccountListActivity::class.java)
intent.putExtra("type", AccountListActivity.Type.MUTES)
activity?.startActivity(intent)
activity?.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
return true
true
}
blockedUsersPreference -> {
val intent = Intent(context, AccountListActivity::class.java)
intent.putExtra("type", AccountListActivity.Type.BLOCKS)
activity?.startActivity(intent)
activity?.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
return true
true
}
homeFiltersPreference -> {
launchFilterActivity(Filter.HOME, R.string.title_home)
}
notificationFiltersPreference -> {
launchFilterActivity(Filter.NOTIFICATIONS, R.string.title_notifications)
}
publicFiltersPreference -> {
launchFilterActivity(Filter.PUBLIC, R.string.pref_title_public_filter_keywords)
}
threadFiltersPreference -> {
launchFilterActivity(Filter.THREAD, R.string.pref_title_thread_filter_keywords)
}
else -> return false
else -> false
}
}
@ -249,6 +273,15 @@ class AccountPreferencesFragment : PreferenceFragmentCompat(),
return drawable
}
fun launchFilterActivity(filterContext: String, titleResource: Int): Boolean {
val intent = Intent(context, FiltersActivity::class.java)
intent.putExtra(FiltersActivity.FILTERS_CONTEXT, filterContext)
intent.putExtra(FiltersActivity.FILTERS_TITLE, getString(titleResource))
activity?.startActivity(intent)
activity?.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
return true
}
companion object {
fun newInstance(): AccountPreferencesFragment {
return AccountPreferencesFragment()

View file

@ -17,14 +17,8 @@ package com.keylesspalace.tusky.fragment.preference
import android.content.SharedPreferences
import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import androidx.preference.PreferenceFragmentCompat
import android.text.Editable
import android.text.TextWatcher
import android.widget.EditText
import androidx.preference.Preference
import com.keylesspalace.tusky.R
import java.util.regex.Pattern
class TabFilterPreferencesFragment : PreferenceFragmentCompat() {
@ -32,50 +26,7 @@ class TabFilterPreferencesFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.timeline_filter_preferences)
sharedPreferences = preferenceManager.sharedPreferences
val regexPref: Preference = findPreference("tabFilterRegex")
regexPref.summary = sharedPreferences.getString("tabFilterRegex", "")
regexPref.setOnPreferenceClickListener {
val editText = EditText(requireContext())
editText.setText(sharedPreferences.getString("tabFilterRegex", ""))
val dialog = AlertDialog.Builder(requireContext())
.setTitle(R.string.pref_title_filter_regex)
.setView(editText)
.setPositiveButton(android.R.string.ok) { _, _ ->
sharedPreferences
.edit()
.putString("tabFilterRegex", editText.text.toString())
.apply()
regexPref.summary = editText.text.toString()
}
.setNegativeButton(android.R.string.cancel, null)
.create()
editText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(newRegex: Editable) {
try {
Pattern.compile(newRegex.toString())
editText.error = null
dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = true
} catch (e: IllegalArgumentException) {
editText.error = getString(R.string.error_invalid_regex)
dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = false
}
}
override fun beforeTextChanged(s1: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s1: CharSequence, start: Int, before: Int, count: Int) {}
})
dialog.show()
true
}
}
companion object {