Commit f3ddc71b authored by Daniel Wolf's avatar Daniel Wolf
Browse files

Refactor dialogs for more consistent error behavior

Closes #269
parent 1010f64c
......@@ -114,7 +114,9 @@ android {
includeInApk = false
includeInBundle = false
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
}
dependencies {
......@@ -137,6 +139,7 @@ dependencies {
implementation "androidx.preference:preference:1.1.1"
implementation "com.google.android.material:material:1.3.0-alpha02"
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0-alpha01'
implementation "androidx.core:core-ktx:1.3.1"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
......
......@@ -171,19 +171,16 @@ class PinActivity: BaseActivity() {
dialog?.getButton(DialogInterface.BUTTON_POSITIVE)?.setOnClickListener {
if(pinInput.text.toString() == getPreferences().pin || hashMD5(pinInput.text.toString()) == masterPassword) {
view.pinInputTil.error = null
view.pinInput.error = null
onPinPassed()
} else {
(getSystemService(Context.VIBRATOR_SERVICE) as Vibrator).vibrate(200)
view.pinInputTil.error = getString(R.string.error_invalid_pin)
handler.postDelayed( {
view.pinInputTil.error = null
},2000)
view.pinInput.error = getString(R.string.error_invalid_pin)
}
}
pinInput.addTextChangedListener(object:TextWatcher {
override fun afterTextChanged(s: Editable?) {
view.pinInputTil.error = null
view.pinInput.error = null
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
......
......@@ -8,6 +8,7 @@ import android.text.Editable
import android.text.TextWatcher
import android.webkit.URLUtil
import androidx.appcompat.app.AlertDialog
import androidx.core.widget.doOnTextChanged
import com.frostnerd.smokescreen.R
import com.frostnerd.smokescreen.database.entities.HostSource
import com.frostnerd.smokescreen.getPreferences
......@@ -64,6 +65,7 @@ class NewHostSourceDialog(
view.url.setText(it.toString())
}
}
view.name.doOnTextChanged { _, _, _, _ -> view.nameTil.error = null }
setOnShowListener {
if (hostSource != null) {
view.url.setText(hostSource.source)
......@@ -74,6 +76,7 @@ class NewHostSourceDialog(
private var previousText:String = ""
override fun afterTextChanged(s: Editable?) {
view.urlTil.error = null
val alteredString = if(s.isNullOrBlank()) "" else if(s.contains("://")) s.toString() else "https://$s"
if(URLUtil.isValidUrl(alteredString)) {
if(view.name.text.isNullOrBlank() || !userModifiedName) {
......
......@@ -120,23 +120,11 @@ class NewServerDialog(
) { _, _ -> }
setOnShowListener {
addUrlTextWatcher(primaryServerWrap, primaryServer, false)
addUrlTextWatcher(secondaryServerWrap, secondaryServer, true)
serverName.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
serverNameWrap.error = if (s.isNullOrBlank()) context.getString(R.string.error_invalid_servername)
else null
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
serverNameWrap.error = context.getString(R.string.error_invalid_servername)
getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener {
if (inputsValid()) {
val primaryValid = isServerUrlValid(true)
val secondaryValid = isServerUrlValid(false)
val nameValid = serverName.text?.isNotBlank() ?: false
if (primaryValid && secondaryValid && nameValid) {
val name = serverName.text.toString()
var primary = primaryServer.text.toString().trim()
var secondary =
......@@ -147,6 +135,20 @@ class NewServerDialog(
invokeCallback(name, primary, secondary, onServerAdded)
dismiss()
} else {
serverName.error = if(nameValid) null
else context.getString(R.string.error_invalid_servername)
primaryServer.error = when {
primaryValid -> null
dnsOverHttps -> context.getString(R.string.error_invalid_url)
else -> context.getString(R.string.error_invalid_host)
}
secondaryServer.error = when {
secondaryValid -> null
dnsOverHttps -> context.getString(R.string.error_invalid_url)
else -> context.getString(R.string.error_invalid_host)
}
val vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
vibrator.vibrate(250)
}
......@@ -183,15 +185,27 @@ class NewServerDialog(
private fun setHintAndTitle(view:View, dnsOverHttps: Boolean, titleOverride:String?) {
if (dnsOverHttps) {
if(titleOverride == null) setTitle(R.string.dialog_newserver_title_https)
view.primaryServer.setHint(R.string.dialog_newserver_primaryserver_hint)
view.secondaryServer.apply {
if(isFocused || error != null) setHint(R.string.dialog_newserver_secondaryserver_hint)
view.primaryServer.setOnFocusChangeListener { v , hasFocus ->
v as TextInputEditText
if(hasFocus) v.setHint(R.string.dialog_newserver_primaryserver_hint)
else v.setHint(null)
}
view.secondaryServer.setOnFocusChangeListener { v, hasFocus ->
v as TextInputEditText
if(hasFocus) v.setHint(R.string.dialog_newserver_secondaryserver_hint)
else v.setHint(null)
}
}else {
if(titleOverride == null) setTitle(R.string.dialog_newserver_title_tls)
view.primaryServer.setHint(R.string.dialog_newserver_primaryserver_hint_dot)
view.secondaryServer.apply {
if(isFocused || error != null) setHint(R.string.dialog_newserver_secondaryserver_hint_dot)
view.primaryServer.setOnFocusChangeListener { v , hasFocus ->
v as TextInputEditText
if(hasFocus) v.setHint(R.string.dialog_newserver_primaryserver_hint_dot)
else v.hint = null
}
view.secondaryServer.setOnFocusChangeListener { v , hasFocus ->
v as TextInputEditText
if(hasFocus) v.setHint(R.string.dialog_newserver_secondaryserver_hint_dot)
else v.hint = null
}
}
if(titleOverride != null) setTitle(titleOverride)
......@@ -331,34 +345,11 @@ class NewServerDialog(
else HttpsUpstreamAddress(host, port)
}
private fun addUrlTextWatcher(input: TextInputLayout, editText: TextInputEditText, emptyAllowed: Boolean) {
editText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable) {
var valid = (emptyAllowed && s.isBlank())
valid = valid || (!s.isBlank() && dnsOverHttps && isValidDoH(s.toString()))
valid = valid || (!s.isBlank() && !dnsOverHttps && isValidDot(s.toString()))
input.error = when {
valid -> {
null
}
dnsOverHttps -> context.getString(R.string.error_invalid_url)
else -> context.getString(R.string.error_invalid_host)
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
private fun isServerUrlValid(primary:Boolean):Boolean {
val s = (if(primary) primaryServer.text else secondaryServer.text) ?: ""
var valid = (!primary && s.isBlank())
valid = valid || (!s.isBlank() && dnsOverHttps && isValidDoH(s.toString()))
return valid || (!s.isBlank() && !dnsOverHttps && isValidDot(s.toString()))
}
private fun inputsValid(): Boolean = serverNameWrap.error == null &&
primaryServerWrap.error == null &&
secondaryServerWrap.error == null
override fun destroy() {}
}
\ No newline at end of file
......@@ -35,7 +35,6 @@
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:hint="@string/dialog_newserver_name_hint"
android:id="@+id/serverName"
android:inputType="text"
android:imeOptions="actionNext"
......@@ -55,7 +54,6 @@
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:hint="@string/dialog_newserver_name_hint"
android:id="@+id/primaryServer"
android:inputType="textUri"
android:imeOptions="actionNext"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment