Merge branch 'devel' into feature/nextgen
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package org.koitharu.kotatsu.utils
|
||||
|
||||
import kotlinx.coroutines.CancellableContinuation
|
||||
import kotlinx.coroutines.currentCoroutineContext
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
@@ -32,11 +34,13 @@ class CompositeMutex<T : Any> : Set<T> {
|
||||
}
|
||||
|
||||
suspend fun lock(element: T) {
|
||||
waitForRemoval(element)
|
||||
mutex.withLock {
|
||||
val lastValue = data.put(element, LinkedList<CancellableContinuation<Unit>>())
|
||||
check(lastValue == null) {
|
||||
"CompositeMutex is double-locked for $element"
|
||||
while (currentCoroutineContext().isActive) {
|
||||
waitForRemoval(element)
|
||||
mutex.withLock {
|
||||
if (data[element] == null) {
|
||||
data[element] = LinkedList<CancellableContinuation<Unit>>()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user