Add domain validation in source settings
This commit is contained in:
@@ -0,0 +1,20 @@
|
|||||||
|
package org.koitharu.kotatsu.settings
|
||||||
|
|
||||||
|
import okhttp3.internal.toCanonicalHost
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.utils.EditTextValidator
|
||||||
|
|
||||||
|
class DomainValidator : EditTextValidator() {
|
||||||
|
|
||||||
|
override fun validate(text: String): ValidationResult {
|
||||||
|
if (text.isBlank()) {
|
||||||
|
return ValidationResult.Success
|
||||||
|
}
|
||||||
|
val host = text.trim().toCanonicalHost()
|
||||||
|
return if (host == null) {
|
||||||
|
ValidationResult.Failed(context.getString(R.string.invalid_domain_message))
|
||||||
|
} else {
|
||||||
|
ValidationResult.Success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ fun PreferenceFragmentCompat.addPreferencesFromRepository(repository: RemoteMang
|
|||||||
EditTextBindListener(
|
EditTextBindListener(
|
||||||
inputType = EditorInfo.TYPE_CLASS_TEXT or EditorInfo.TYPE_TEXT_VARIATION_URI,
|
inputType = EditorInfo.TYPE_CLASS_TEXT or EditorInfo.TYPE_TEXT_VARIATION_URI,
|
||||||
hint = key.defaultValue,
|
hint = key.defaultValue,
|
||||||
|
validator = DomainValidator(),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
setTitle(R.string.domain)
|
setTitle(R.string.domain)
|
||||||
|
|||||||
@@ -2,14 +2,17 @@ package org.koitharu.kotatsu.settings.utils
|
|||||||
|
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import androidx.preference.EditTextPreference
|
import androidx.preference.EditTextPreference
|
||||||
|
import org.koitharu.kotatsu.utils.EditTextValidator
|
||||||
|
|
||||||
class EditTextBindListener(
|
class EditTextBindListener(
|
||||||
private val inputType: Int,
|
private val inputType: Int,
|
||||||
private val hint: String
|
private val hint: String,
|
||||||
|
private val validator: EditTextValidator?,
|
||||||
) : EditTextPreference.OnBindEditTextListener {
|
) : EditTextPreference.OnBindEditTextListener {
|
||||||
|
|
||||||
override fun onBindEditText(editText: EditText) {
|
override fun onBindEditText(editText: EditText) {
|
||||||
editText.inputType = inputType
|
editText.inputType = inputType
|
||||||
editText.hint = hint
|
editText.hint = hint
|
||||||
|
validator?.attachToEditText(editText)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package org.koitharu.kotatsu.utils
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.text.Editable
|
||||||
|
import android.text.TextWatcher
|
||||||
|
import android.widget.EditText
|
||||||
|
import androidx.annotation.CallSuper
|
||||||
|
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
|
abstract class EditTextValidator : TextWatcher {
|
||||||
|
|
||||||
|
private var editTextRef: WeakReference<EditText>? = null
|
||||||
|
|
||||||
|
protected val context: Context
|
||||||
|
get() = checkNotNull(editTextRef?.get()?.context) {
|
||||||
|
"EditTextValidator is not attached to EditText"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit
|
||||||
|
|
||||||
|
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) = Unit
|
||||||
|
|
||||||
|
@CallSuper
|
||||||
|
override fun afterTextChanged(s: Editable?) {
|
||||||
|
val editText = editTextRef?.get() ?: return
|
||||||
|
val newText = s?.toString().orEmpty()
|
||||||
|
val result = runCatching {
|
||||||
|
validate(newText)
|
||||||
|
}.getOrElse { e ->
|
||||||
|
ValidationResult.Failed(e.getDisplayMessage(editText.resources))
|
||||||
|
}
|
||||||
|
editText.error = when (result) {
|
||||||
|
is ValidationResult.Failed -> result.message
|
||||||
|
ValidationResult.Success -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun attachToEditText(editText: EditText) {
|
||||||
|
editTextRef = WeakReference(editText)
|
||||||
|
editText.removeTextChangedListener(this)
|
||||||
|
editText.addTextChangedListener(this)
|
||||||
|
afterTextChanged(editText.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun validate(text: String): ValidationResult
|
||||||
|
|
||||||
|
sealed class ValidationResult {
|
||||||
|
|
||||||
|
object Success : ValidationResult()
|
||||||
|
|
||||||
|
class Failed(val message: CharSequence) : ValidationResult()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -320,4 +320,5 @@
|
|||||||
<string name="exclude_nsfw_from_history_summary">Manga marked as NSFW will never added to the history and your progress will not be saved</string>
|
<string name="exclude_nsfw_from_history_summary">Manga marked as NSFW will never added to the history and your progress will not be saved</string>
|
||||||
<string name="clear_cookies_summary">Can help in case of some issues. All authorizations will be invalidated</string>
|
<string name="clear_cookies_summary">Can help in case of some issues. All authorizations will be invalidated</string>
|
||||||
<string name="show_all">Show all</string>
|
<string name="show_all">Show all</string>
|
||||||
|
<string name="invalid_domain_message">Invalid domain</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user