From aa96d02923748e3fd2852f7a172c71d4ff5fb199 Mon Sep 17 00:00:00 2001 From: Nik Clayton Date: Fri, 13 Jan 2023 19:28:46 +0100 Subject: [PATCH] Implement HTTP proxy summary as a SummaryProvider (#3091) * Handle preference fragments using the framework The previous code started new preference "screens" as activities, even though each one hosted a single fragment. Modify this to use the framework's support for swapping in/out different preference fragments. PreferencesActivity: - Remove the code for launching tab and proxy preferences - Remove the code for setting titles, each fragment is responsible for that - Implement OnPreferenceStartFragmentCallback to swap fragments in/out with the correct animation PreferencesFragment: - Use `fragment` property instead of `setOnPreferenceClickListener` - Set the activity title when resuming Everything else: - Set the activity title when resuming * Implement HTTP proxy summary as a SummaryProvider Uses the frameworks's support for setting summaries instead of rolling our own. Also fix a tiny bug -- the minimum port number to connect to should be 1, not 0. * Lint --- .../preference/PreferencesFragment.kt | 31 +++---------------- .../preference/ProxyPreferencesFragment.kt | 31 +++++++++++++++++++ .../tusky/settings/ProxyConfiguration.kt | 2 +- app/src/main/res/values/strings.xml | 3 ++ 4 files changed, 39 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesFragment.kt index 807b0429..5d6c1ea2 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesFragment.kt @@ -32,7 +32,6 @@ import com.keylesspalace.tusky.settings.preferenceCategory import com.keylesspalace.tusky.settings.switchPreference import com.keylesspalace.tusky.util.LocaleManager import com.keylesspalace.tusky.util.deserialize -import com.keylesspalace.tusky.util.getNonNullString import com.keylesspalace.tusky.util.makeIcon import com.keylesspalace.tusky.util.serialize import com.mikepenz.iconics.IconicsDrawable @@ -49,7 +48,6 @@ class PreferencesFragment : PreferenceFragmentCompat(), Injectable { lateinit var localeManager: LocaleManager private val iconSize by lazy { resources.getDimensionPixelSize(R.dimen.preference_icon_size) } - private var httpProxyPref: Preference? = null enum class ReadingOrder { /** User scrolls up, reading statuses oldest to newest */ @@ -236,7 +234,7 @@ class PreferencesFragment : PreferenceFragmentCompat(), Injectable { preferenceCategory(R.string.pref_title_timeline_filters) { preference { setTitle(R.string.pref_title_post_tabs) - fragment = "com.keylesspalace.tusky.components.preference.TabFilterPreferencesFragment" + fragment = TabFilterPreferencesFragment::class.qualifiedName } } @@ -280,9 +278,10 @@ class PreferencesFragment : PreferenceFragmentCompat(), Injectable { } preferenceCategory(R.string.pref_title_proxy_settings) { - httpProxyPref = preference { + preference { setTitle(R.string.pref_title_http_proxy_settings) - fragment = "com.keylesspalace.tusky.components.preference.ProxyPreferencesFragment" + fragment = ProxyPreferencesFragment::class.qualifiedName + summaryProvider = ProxyPreferencesFragment.SummaryProvider } } } @@ -295,28 +294,6 @@ class PreferencesFragment : PreferenceFragmentCompat(), Injectable { override fun onResume() { super.onResume() requireActivity().setTitle(R.string.action_view_preferences) - updateHttpProxySummary() - } - - private fun updateHttpProxySummary() { - preferenceManager.sharedPreferences?.let { sharedPreferences -> - val httpProxyEnabled = sharedPreferences.getBoolean(PrefKeys.HTTP_PROXY_ENABLED, false) - val httpServer = sharedPreferences.getNonNullString(PrefKeys.HTTP_PROXY_SERVER, "") - - try { - val httpPort = sharedPreferences.getNonNullString(PrefKeys.HTTP_PROXY_PORT, "-1") - .toInt() - - if (httpProxyEnabled && httpServer.isNotBlank() && httpPort > 0 && httpPort < 65535) { - httpProxyPref?.summary = "$httpServer:$httpPort" - return - } - } catch (e: NumberFormatException) { - // user has entered wrong port, fall back to empty summary - } - - httpProxyPref?.summary = "" - } } override fun onDisplayPreferenceDialog(preference: Preference) { diff --git a/app/src/main/java/com/keylesspalace/tusky/components/preference/ProxyPreferencesFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/preference/ProxyPreferencesFragment.kt index 12a22271..22318440 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/preference/ProxyPreferencesFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/preference/ProxyPreferencesFragment.kt @@ -16,14 +16,18 @@ package com.keylesspalace.tusky.components.preference import android.os.Bundle +import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import com.keylesspalace.tusky.R import com.keylesspalace.tusky.settings.PrefKeys import com.keylesspalace.tusky.settings.ProxyConfiguration +import com.keylesspalace.tusky.settings.ProxyConfiguration.Companion.MAX_PROXY_PORT +import com.keylesspalace.tusky.settings.ProxyConfiguration.Companion.MIN_PROXY_PORT import com.keylesspalace.tusky.settings.makePreferenceScreen import com.keylesspalace.tusky.settings.preferenceCategory import com.keylesspalace.tusky.settings.switchPreference import com.keylesspalace.tusky.settings.validatedEditTextPreference +import com.keylesspalace.tusky.util.getNonNullString import kotlin.system.exitProcess class ProxyPreferencesFragment : PreferenceFragmentCompat() { @@ -78,6 +82,33 @@ class ProxyPreferencesFragment : PreferenceFragmentCompat() { } } + object SummaryProvider : Preference.SummaryProvider { + override fun provideSummary(preference: Preference): CharSequence { + val sharedPreferences = preference.sharedPreferences + sharedPreferences ?: return "" + + if (!sharedPreferences.getBoolean(PrefKeys.HTTP_PROXY_ENABLED, false)) { + return preference.context.getString(R.string.pref_summary_http_proxy_disabled) + } + + val missing = preference.context.getString(R.string.pref_summary_http_proxy_missing) + + val server = sharedPreferences.getNonNullString(PrefKeys.HTTP_PROXY_SERVER, missing) + val port = try { + sharedPreferences.getNonNullString(PrefKeys.HTTP_PROXY_PORT, "-1").toInt() + } catch (e: NumberFormatException) { + -1 + } + + if (port < MIN_PROXY_PORT || port > MAX_PROXY_PORT) { + val invalid = preference.context.getString(R.string.pref_summary_http_proxy_invalid) + return "$server:$invalid" + } + + return "$server:$port" + } + } + companion object { fun newInstance(): ProxyPreferencesFragment { return ProxyPreferencesFragment() diff --git a/app/src/main/java/com/keylesspalace/tusky/settings/ProxyConfiguration.kt b/app/src/main/java/com/keylesspalace/tusky/settings/ProxyConfiguration.kt index 903a2c6a..f1e04bd5 100644 --- a/app/src/main/java/com/keylesspalace/tusky/settings/ProxyConfiguration.kt +++ b/app/src/main/java/com/keylesspalace/tusky/settings/ProxyConfiguration.kt @@ -22,7 +22,7 @@ class ProxyConfiguration private constructor( } fun isValidHostname(hostname: String): Boolean = IP_ADDRESS_REGEX.matches(hostname) || HOSTNAME_REGEX.matches(hostname) - const val MIN_PROXY_PORT = 0 + const val MIN_PROXY_PORT = 1 const val MAX_PROXY_PORT = 65535 } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 73813b31..2d9e2ce5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -291,6 +291,9 @@ HTTP proxy server HTTP proxy port Port should be between %d and %d + Disabled + <not set> + <invalid> Default post privacy Default posting language