Merge branch 'devel' into feature/nextgen

This commit is contained in:
Koitharu
2022-07-12 11:25:19 +03:00
16 changed files with 234 additions and 133 deletions

View File

@@ -17,7 +17,7 @@ class CloudFlareInterceptor : Interceptor {
if (response.code == HTTP_FORBIDDEN || response.code == HTTP_UNAVAILABLE) {
if (response.header(HEADER_SERVER)?.startsWith(SERVER_CLOUDFLARE) == true) {
response.closeQuietly()
throw CloudFlareProtectedException(chain.request().url.toString())
throw CloudFlareProtectedException(response.request.url.toString())
}
}
return response

View File

@@ -24,7 +24,6 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.acra.ktx.sendWithAcra
import org.koin.android.ext.android.get
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
@@ -47,10 +46,7 @@ import org.koitharu.kotatsu.settings.SettingsActivity
import org.koitharu.kotatsu.utils.GridTouchHelper
import org.koitharu.kotatsu.utils.ScreenOrientationHelper
import org.koitharu.kotatsu.utils.ShareHelper
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
import org.koitharu.kotatsu.utils.ext.hasGlobalPoint
import org.koitharu.kotatsu.utils.ext.observeWithPrevious
import org.koitharu.kotatsu.utils.ext.postDelayed
import org.koitharu.kotatsu.utils.ext.*
import java.util.concurrent.TimeUnit
class ReaderActivity :
@@ -375,7 +371,7 @@ class ReaderActivity :
if (ExceptionResolver.canResolve(exception)) {
tryResolve(exception)
} else {
exception.sendWithAcra()
exception.report("ReaderActivity::onError")
}
} else {
onCancel(dialog)

View File

@@ -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
}
}
}

View File

@@ -28,6 +28,7 @@ fun PreferenceFragmentCompat.addPreferencesFromRepository(repository: RemoteMang
EditTextBindListener(
inputType = EditorInfo.TYPE_CLASS_TEXT or EditorInfo.TYPE_TEXT_VARIATION_URI,
hint = key.defaultValue,
validator = DomainValidator(),
)
)
setTitle(R.string.domain)

View File

@@ -2,14 +2,17 @@ package org.koitharu.kotatsu.settings.utils
import android.widget.EditText
import androidx.preference.EditTextPreference
import org.koitharu.kotatsu.utils.EditTextValidator
class EditTextBindListener(
private val inputType: Int,
private val hint: String
private val hint: String,
private val validator: EditTextValidator?,
) : EditTextPreference.OnBindEditTextListener {
override fun onBindEditText(editText: EditText) {
editText.inputType = inputType
editText.hint = hint
validator?.attachToEditText(editText)
}
}

View File

@@ -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
}
}
}
}

View File

@@ -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()
}
}