Merge branch 'feature/sync' into feature/nextgen
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package org.koitharu.kotatsu.utils
|
||||
|
||||
import android.util.ArrayMap
|
||||
import kotlinx.coroutines.CancellableContinuation
|
||||
import kotlinx.coroutines.currentCoroutineContext
|
||||
import kotlinx.coroutines.isActive
|
||||
@@ -11,7 +12,7 @@ import kotlin.coroutines.resume
|
||||
|
||||
class CompositeMutex<T : Any> : Set<T> {
|
||||
|
||||
private val data = HashMap<T, MutableList<CancellableContinuation<Unit>>>()
|
||||
private val data = ArrayMap<T, MutableList<CancellableContinuation<Unit>>>()
|
||||
private val mutex = Mutex()
|
||||
|
||||
override val size: Int
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.koitharu.kotatsu.utils
|
||||
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
import org.koitharu.kotatsu.core.network.CommonHeaders.CONTENT_ENCODING
|
||||
|
||||
class GZipInterceptor : Interceptor {
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val newRequest = chain.request().newBuilder()
|
||||
newRequest.addHeader(CONTENT_ENCODING, "gzip")
|
||||
return chain.proceed(newRequest.build())
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,13 @@ import android.app.ActivityManager
|
||||
import android.app.ActivityOptions
|
||||
import android.content.Context
|
||||
import android.content.Context.ACTIVITY_SERVICE
|
||||
import android.content.OperationApplicationException
|
||||
import android.content.SharedPreferences
|
||||
import android.content.SyncResult
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.database.SQLException
|
||||
import android.graphics.Color
|
||||
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.Network
|
||||
import android.net.NetworkRequest
|
||||
@@ -35,6 +39,9 @@ import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import okio.IOException
|
||||
import org.json.JSONException
|
||||
import org.koitharu.kotatsu.BuildConfig
|
||||
import org.koitharu.kotatsu.utils.InternalResourceHelper
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
@@ -111,6 +118,17 @@ fun Lifecycle.postDelayed(runnable: Runnable, delay: Long) {
|
||||
}
|
||||
}
|
||||
|
||||
fun SyncResult.onError(error: Throwable) {
|
||||
when (error) {
|
||||
is IOException -> stats.numIoExceptions++
|
||||
is OperationApplicationException,
|
||||
is SQLException -> databaseError = true
|
||||
is JSONException -> stats.numParseExceptions++
|
||||
else -> if (BuildConfig.DEBUG) throw error
|
||||
}
|
||||
error.printStackTraceDebug()
|
||||
}
|
||||
|
||||
fun Window.setNavigationBarTransparentCompat(context: Context, elevation: Float = 0F) {
|
||||
navigationBarColor = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q &&
|
||||
!InternalResourceHelper.getBoolean(context, "config_navBarNeedsScrim", true)
|
||||
@@ -150,4 +168,4 @@ fun scaleUpActivityOptionsOf(view: View): ActivityOptions = ActivityOptions.make
|
||||
0,
|
||||
view.width,
|
||||
view.height,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.koitharu.kotatsu.utils.ext
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import org.json.JSONObject
|
||||
|
||||
fun Cursor.toJson(): JSONObject {
|
||||
val jo = JSONObject()
|
||||
for (i in 0 until columnCount) {
|
||||
val name = getColumnName(i)
|
||||
when (getType(i)) {
|
||||
Cursor.FIELD_TYPE_STRING -> jo.put(name, getString(i))
|
||||
Cursor.FIELD_TYPE_FLOAT -> jo.put(name, getDouble(i))
|
||||
Cursor.FIELD_TYPE_INTEGER -> jo.put(name, getLong(i))
|
||||
Cursor.FIELD_TYPE_NULL -> jo.put(name, null)
|
||||
Cursor.FIELD_TYPE_BLOB -> jo.put(name, getBlob(i))
|
||||
}
|
||||
}
|
||||
return jo
|
||||
}
|
||||
|
||||
fun JSONObject.toContentValues(): ContentValues {
|
||||
val cv = ContentValues(length())
|
||||
for (key in keys()) {
|
||||
val name = key.escapeName()
|
||||
when (val value = get(key)) {
|
||||
JSONObject.NULL, "null", null -> cv.putNull(name)
|
||||
is String -> cv.put(name, value)
|
||||
is Float -> cv.put(name, value)
|
||||
is Double -> cv.put(name, value)
|
||||
is Int -> cv.put(name, value)
|
||||
is Long -> cv.put(name, value)
|
||||
else -> throw IllegalArgumentException("Value $value cannot be putted in ContentValues")
|
||||
}
|
||||
}
|
||||
return cv
|
||||
}
|
||||
|
||||
private fun String.escapeName() = "`$this`"
|
||||
@@ -1,10 +1,20 @@
|
||||
|
||||
package org.koitharu.kotatsu.utils.ext
|
||||
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.Response
|
||||
import org.json.JSONObject
|
||||
import org.koitharu.kotatsu.parsers.util.parseJson
|
||||
import java.net.HttpURLConnection
|
||||
|
||||
private val TYPE_JSON = "application/json".toMediaType()
|
||||
|
||||
fun JSONObject.toRequestBody() = toString().toRequestBody(TYPE_JSON)
|
||||
fun JSONObject.toRequestBody() = toString().toRequestBody(TYPE_JSON)
|
||||
|
||||
fun Response.parseJsonOrNull(): JSONObject? {
|
||||
return if (code == HttpURLConnection.HTTP_NO_CONTENT) {
|
||||
null
|
||||
} else {
|
||||
parseJson()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user