diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/SettingsPreferenceFragment.kt b/mobile/src/main/java/be/mygod/vpnhotspot/SettingsPreferenceFragment.kt index 5bcb3bdc..215a91ea 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/SettingsPreferenceFragment.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/SettingsPreferenceFragment.kt @@ -8,14 +8,20 @@ import android.os.Bundle import android.support.customtabs.CustomTabsIntent import android.support.v4.content.ContextCompat import android.support.v4.content.FileProvider +import android.support.v7.preference.Preference import android.widget.Toast import be.mygod.vpnhotspot.App.Companion.app import be.mygod.vpnhotspot.net.Routing +import be.mygod.vpnhotspot.net.UpstreamMonitor +import be.mygod.vpnhotspot.preference.AlwaysAutoCompleteEditTextPreferenceDialogFragmentCompat +import be.mygod.vpnhotspot.preference.SharedPreferenceDataStore import be.mygod.vpnhotspot.util.loggerSuStream +import be.mygod.vpnhotspot.util.put import com.takisoft.fix.support.v7.preference.PreferenceFragmentCompatDividers import java.io.File import java.io.IOException import java.io.PrintWriter +import java.net.NetworkInterface class SettingsPreferenceFragment : PreferenceFragmentCompatDividers() { private val customTabsIntent by lazy { @@ -92,4 +98,14 @@ class SettingsPreferenceFragment : PreferenceFragmentCompatDividers() { true } } + + override fun onDisplayPreferenceDialog(preference: Preference) = when (preference.key) { + UpstreamMonitor.KEY -> displayPreferenceDialog( + AlwaysAutoCompleteEditTextPreferenceDialogFragmentCompat(), UpstreamMonitor.KEY, + Bundle().put(AlwaysAutoCompleteEditTextPreferenceDialogFragmentCompat.KEY_SUGGESTIONS, + NetworkInterface.getNetworkInterfaces().asSequence() + .filter { it.isUp && !it.isLoopback && it.interfaceAddresses.isNotEmpty() } + .map { it.name }.sorted().toList().toTypedArray())) + else -> super.onDisplayPreferenceDialog(preference) + } } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/UpstreamMonitor.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/UpstreamMonitor.kt index 58319afd..708dfc8c 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/UpstreamMonitor.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/UpstreamMonitor.kt @@ -6,7 +6,7 @@ import java.net.InetAddress abstract class UpstreamMonitor { companion object : SharedPreferences.OnSharedPreferenceChangeListener { - private const val KEY = "service.upstream" + const val KEY = "service.upstream" init { app.pref.registerOnSharedPreferenceChangeListener(this) diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/preference/AlwaysAutoCompleteEditTextPreference.kt b/mobile/src/main/java/be/mygod/vpnhotspot/preference/AlwaysAutoCompleteEditTextPreference.kt new file mode 100644 index 00000000..12ed4b23 --- /dev/null +++ b/mobile/src/main/java/be/mygod/vpnhotspot/preference/AlwaysAutoCompleteEditTextPreference.kt @@ -0,0 +1,24 @@ +package be.mygod.vpnhotspot.preference + +import android.content.Context +import android.text.TextUtils +import android.util.AttributeSet +import be.mygod.vpnhotspot.R +import be.mygod.vpnhotspot.widget.AlwaysAutoCompleteEditText +import com.takisoft.fix.support.v7.preference.AutoSummaryEditTextPreference + +open class AlwaysAutoCompleteEditTextPreference @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = R.attr.editTextPreferenceStyle, + defStyleRes: Int = 0) : AutoSummaryEditTextPreference(context, attrs, defStyleAttr, defStyleRes) { + val editText = AlwaysAutoCompleteEditText(context, attrs) + + init { + editText.id = android.R.id.edit + } + + override fun setText(text: String) { + val oldText = getText() + super.setText(text) + if (!TextUtils.equals(text, oldText)) notifyChanged() + } +} diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/preference/AlwaysAutoCompleteEditTextPreferenceDialogFragmentCompat.kt b/mobile/src/main/java/be/mygod/vpnhotspot/preference/AlwaysAutoCompleteEditTextPreferenceDialogFragmentCompat.kt new file mode 100644 index 00000000..d5fae19b --- /dev/null +++ b/mobile/src/main/java/be/mygod/vpnhotspot/preference/AlwaysAutoCompleteEditTextPreferenceDialogFragmentCompat.kt @@ -0,0 +1,59 @@ +package be.mygod.vpnhotspot.preference + +import android.support.v7.preference.PreferenceDialogFragmentCompat +import android.support.v7.widget.AppCompatAutoCompleteTextView +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import android.widget.EditText + +open class AlwaysAutoCompleteEditTextPreferenceDialogFragmentCompat : PreferenceDialogFragmentCompat() { + companion object { + const val KEY_SUGGESTIONS = "suggestions" + } + + private lateinit var editText: AppCompatAutoCompleteTextView + private val editTextPreference get() = this.preference as AlwaysAutoCompleteEditTextPreference + + override fun onBindDialogView(view: View) { + super.onBindDialogView(view) + + editText = editTextPreference.editText + editText.setText(this.editTextPreference.text) + + val text = editText.text + if (text != null) editText.setSelection(text.length, text.length) + + val suggestions = arguments?.getStringArray(KEY_SUGGESTIONS) + if (suggestions != null) + editText.setAdapter(ArrayAdapter(view.context, android.R.layout.select_dialog_item, suggestions)) + + val oldParent = editText.parent as? ViewGroup? + if (oldParent !== view) { + oldParent?.removeView(editText) + onAddEditTextToDialogView(view, editText) + } + } + + override fun needInputMethod(): Boolean = true + + protected fun onAddEditTextToDialogView(dialogView: View, editText: EditText) { + val oldEditText = dialogView.findViewById(android.R.id.edit) + if (oldEditText != null) { + val container = oldEditText.parent as? ViewGroup? + if (container != null) { + container.removeView(oldEditText) + container.addView(editText, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + } + } + } + + override fun onDialogClosed(positiveResult: Boolean) { + if (positiveResult) { + val value = this.editText.text.toString() + if (this.editTextPreference.callChangeListener(value)) { + this.editTextPreference.text = value + } + } + } +} diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/SharedPreferenceDataStore.kt b/mobile/src/main/java/be/mygod/vpnhotspot/preference/SharedPreferenceDataStore.kt similarity index 97% rename from mobile/src/main/java/be/mygod/vpnhotspot/SharedPreferenceDataStore.kt rename to mobile/src/main/java/be/mygod/vpnhotspot/preference/SharedPreferenceDataStore.kt index cb931833..f6a1a69d 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/SharedPreferenceDataStore.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/preference/SharedPreferenceDataStore.kt @@ -1,4 +1,4 @@ -package be.mygod.vpnhotspot +package be.mygod.vpnhotspot.preference import android.content.SharedPreferences import android.support.v7.preference.PreferenceDataStore diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt b/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt index 7c1fe3a6..26b8e119 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt @@ -2,6 +2,7 @@ package be.mygod.vpnhotspot.util import android.content.* import android.databinding.BindingAdapter +import android.os.Bundle import android.support.annotation.DrawableRes import android.util.Log import android.view.View @@ -26,6 +27,11 @@ fun intentFilter(vararg actions: String): IntentFilter { return result } +fun Bundle.put(key: String, map: Array): Bundle { + putStringArray(key, map) + return this +} + @BindingAdapter("android:src") fun setImageResource(imageView: ImageView, @DrawableRes resource: Int) = imageView.setImageResource(resource) diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/widget/AlwaysAutoCompleteEditText.kt b/mobile/src/main/java/be/mygod/vpnhotspot/widget/AlwaysAutoCompleteEditText.kt new file mode 100644 index 00000000..f8f50c4a --- /dev/null +++ b/mobile/src/main/java/be/mygod/vpnhotspot/widget/AlwaysAutoCompleteEditText.kt @@ -0,0 +1,25 @@ +package be.mygod.vpnhotspot.widget + +import android.content.Context +import android.graphics.Rect +import android.support.v7.widget.AppCompatAutoCompleteTextView +import android.util.AttributeSet +import android.view.View +import be.mygod.vpnhotspot.R + +/** + * Based on: https://gist.github.com/furycomptuers/4961368 + */ +class AlwaysAutoCompleteEditText @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, + defStyleAttr: Int = R.attr.autoCompleteTextViewStyle) : + AppCompatAutoCompleteTextView(context, attrs, defStyleAttr) { + override fun enoughToFilter() = true + + override fun onFocusChanged(focused: Boolean, direction: Int, previouslyFocusedRect: Rect?) { + super.onFocusChanged(focused, direction, previouslyFocusedRect) + if (focused && windowVisibility != View.GONE) { + performFiltering(text, 0) + showDropDown() + } + } +} diff --git a/mobile/src/main/res/xml/pref_settings.xml b/mobile/src/main/res/xml/pref_settings.xml index 29460022..23f42f70 100644 --- a/mobile/src/main/res/xml/pref_settings.xml +++ b/mobile/src/main/res/xml/pref_settings.xml @@ -18,7 +18,7 @@ android:title="@string/settings_service_dns" android:singleLine="true" android:defaultValue="8.8.8.8"/> -