mirror of
https://github.com/Suwayomi/TachideskJUI.git
synced 2025-12-10 14:52:03 +01:00
Update dependencies
This commit is contained in:
@@ -28,7 +28,8 @@ dependencies {
|
|||||||
implementation(libs.accompanist.pagerIndicators)
|
implementation(libs.accompanist.pagerIndicators)
|
||||||
implementation(libs.accompanist.flowLayout)
|
implementation(libs.accompanist.flowLayout)
|
||||||
implementation(libs.accompanist.systemUIController)
|
implementation(libs.accompanist.systemUIController)
|
||||||
implementation(libs.imageloader)
|
implementation(libs.imageloader.core)
|
||||||
|
implementation(libs.imageloader.moko)
|
||||||
implementation(libs.materialDialogs.core)
|
implementation(libs.materialDialogs.core)
|
||||||
|
|
||||||
// Android
|
// Android
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ plugins {
|
|||||||
alias(libs.plugins.ktorfit) apply false
|
alias(libs.plugins.ktorfit) apply false
|
||||||
alias(libs.plugins.aboutLibraries) apply false
|
alias(libs.plugins.aboutLibraries) apply false
|
||||||
alias(libs.plugins.versions)
|
alias(libs.plugins.versions)
|
||||||
id("com.louiscad.complete-kotlin") version "1.1.0"
|
//id("com.louiscad.complete-kotlin") version "1.1.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ package ca.gosyer.jui.core.lang
|
|||||||
|
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.IO
|
||||||
|
|
||||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
val Dispatchers.IO: CoroutineDispatcher
|
||||||
expect val Dispatchers.IO: CoroutineDispatcher
|
get() = IO
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
package ca.gosyer.jui.core.lang
|
package ca.gosyer.jui.core.lang
|
||||||
|
|
||||||
import com.soywiz.kds.PriorityQueue
|
import korlibs.datastructure.PriorityQueue
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
/*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ca.gosyer.jui.core.lang
|
|
||||||
|
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
private val ioDispatcher = Dispatchers.Default.limitedParallelism(64)
|
|
||||||
|
|
||||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
|
||||||
actual val Dispatchers.IO: CoroutineDispatcher
|
|
||||||
get() = ioDispatcher
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
/*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ca.gosyer.jui.core.lang
|
|
||||||
|
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
|
|
||||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
|
||||||
actual val Dispatchers.IO: CoroutineDispatcher
|
|
||||||
get() = IO
|
|
||||||
@@ -26,10 +26,10 @@ import me.tatarka.inject.annotations.Provides
|
|||||||
interface DataComponent {
|
interface DataComponent {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
fun ktorfit(http: Http, serverPreferences: ServerPreferences, flowIOResponseConverter: FlowIOResponseConverter) = Ktorfit
|
fun ktorfit(http: Http, serverPreferences: ServerPreferences) = Ktorfit
|
||||||
.Builder()
|
.Builder()
|
||||||
.httpClient(http)
|
.httpClient(http)
|
||||||
.responseConverter(flowIOResponseConverter)
|
.converterFactories(FlowConverterFactory())
|
||||||
.baseUrl(serverPreferences.serverUrl().get().toString().addSuffix('/'))
|
.baseUrl(serverPreferences.serverUrl().get().toString().addSuffix('/'))
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ca.gosyer.jui.data
|
||||||
|
|
||||||
|
import ca.gosyer.jui.core.lang.IO
|
||||||
|
import de.jensklingenberg.ktorfit.Ktorfit
|
||||||
|
import de.jensklingenberg.ktorfit.converter.Converter
|
||||||
|
import de.jensklingenberg.ktorfit.internal.TypeData
|
||||||
|
import io.ktor.client.call.body
|
||||||
|
import io.ktor.client.statement.HttpResponse
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.flow
|
||||||
|
import kotlinx.coroutines.flow.flowOn
|
||||||
|
|
||||||
|
class FlowConverterFactory : Converter.Factory {
|
||||||
|
|
||||||
|
private class FlowResponseConverter(
|
||||||
|
val typeData: TypeData,
|
||||||
|
val ktorfit: Ktorfit
|
||||||
|
) : Converter.ResponseConverter<HttpResponse, Flow<Any?>> {
|
||||||
|
|
||||||
|
override fun convert(getResponse: suspend () -> HttpResponse): Flow<Any?> {
|
||||||
|
return flow {
|
||||||
|
val response = getResponse()
|
||||||
|
|
||||||
|
val convertedBody = ktorfit.nextSuspendResponseConverter(
|
||||||
|
null,
|
||||||
|
typeData.typeArgs.first()
|
||||||
|
)?.convert(response)
|
||||||
|
?: response.body(typeData.typeArgs.first().typeInfo)
|
||||||
|
emit(convertedBody)
|
||||||
|
}.flowOn(Dispatchers.IO)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun responseConverter(
|
||||||
|
typeData: TypeData,
|
||||||
|
ktorfit: Ktorfit
|
||||||
|
): Converter.ResponseConverter<HttpResponse, *>? {
|
||||||
|
if (typeData.typeInfo.type == Flow::class) {
|
||||||
|
return FlowResponseConverter(typeData, ktorfit)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun suspendResponseConverter(
|
||||||
|
typeData: TypeData,
|
||||||
|
ktorfit: Ktorfit
|
||||||
|
): Converter.SuspendResponseConverter<HttpResponse, *>? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ca.gosyer.jui.data
|
|
||||||
|
|
||||||
import ca.gosyer.jui.core.lang.IO
|
|
||||||
import de.jensklingenberg.ktorfit.Ktorfit
|
|
||||||
import de.jensklingenberg.ktorfit.converter.request.ResponseConverter
|
|
||||||
import de.jensklingenberg.ktorfit.internal.TypeData
|
|
||||||
import io.ktor.client.statement.HttpResponse
|
|
||||||
import io.ktor.util.reflect.TypeInfo
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.flow.flow
|
|
||||||
import kotlinx.coroutines.flow.flowOn
|
|
||||||
import kotlinx.serialization.json.Json
|
|
||||||
import me.tatarka.inject.annotations.Inject
|
|
||||||
|
|
||||||
class FlowIOResponseConverter @Inject constructor(private val json: Json) : ResponseConverter {
|
|
||||||
|
|
||||||
override fun supportedType(typeData: TypeData, isSuspend: Boolean): Boolean {
|
|
||||||
return typeData.qualifiedName == "kotlinx.coroutines.flow.Flow"
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun <RequestType : Any?> wrapResponse(
|
|
||||||
typeData: TypeData,
|
|
||||||
requestFunction: suspend () -> Pair<TypeInfo, HttpResponse?>,
|
|
||||||
ktorfit: Ktorfit,
|
|
||||||
): Any {
|
|
||||||
return flow {
|
|
||||||
try {
|
|
||||||
val (info, response) = requestFunction()
|
|
||||||
if (info.type == HttpResponse::class) {
|
|
||||||
emit(response!!)
|
|
||||||
} else {
|
|
||||||
emit(decodeType(response!!, info, json))
|
|
||||||
}
|
|
||||||
} catch (exception: Exception) {
|
|
||||||
throw exception
|
|
||||||
}
|
|
||||||
}.flowOn(Dispatchers.IO)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
expect suspend fun decodeType(response: HttpResponse, typeInfo: TypeInfo, json: Json): Any
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ca.gosyer.jui.data
|
|
||||||
|
|
||||||
import io.ktor.client.statement.HttpResponse
|
|
||||||
import io.ktor.client.statement.bodyAsText
|
|
||||||
import io.ktor.util.reflect.TypeInfo
|
|
||||||
import kotlinx.serialization.json.Json
|
|
||||||
import kotlinx.serialization.serializer
|
|
||||||
|
|
||||||
actual suspend fun decodeType(response: HttpResponse, typeInfo: TypeInfo, json: Json): Any {
|
|
||||||
return json.decodeFromString(serializer(typeInfo.kotlinType!!), response.bodyAsText())!!
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
/*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ca.gosyer.jui.data
|
|
||||||
|
|
||||||
import io.ktor.client.call.body
|
|
||||||
import io.ktor.client.statement.HttpResponse
|
|
||||||
import io.ktor.util.reflect.TypeInfo
|
|
||||||
import kotlinx.serialization.json.Json
|
|
||||||
|
|
||||||
actual suspend fun decodeType(response: HttpResponse, typeInfo: TypeInfo, json: Json): Any {
|
|
||||||
return response.body(typeInfo)
|
|
||||||
}
|
|
||||||
@@ -35,7 +35,8 @@ dependencies {
|
|||||||
implementation(libs.accompanist.pager)
|
implementation(libs.accompanist.pager)
|
||||||
implementation(libs.accompanist.pagerIndicators)
|
implementation(libs.accompanist.pagerIndicators)
|
||||||
implementation(libs.accompanist.flowLayout)
|
implementation(libs.accompanist.flowLayout)
|
||||||
implementation(libs.imageloader)
|
implementation(libs.imageloader.core)
|
||||||
|
implementation(libs.imageloader.moko)
|
||||||
implementation(libs.materialDialogs.core)
|
implementation(libs.materialDialogs.core)
|
||||||
|
|
||||||
// UI (Swing)
|
// UI (Swing)
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
[versions]
|
[versions]
|
||||||
# Kotlin
|
# Kotlin
|
||||||
kotlin = "1.8.20"
|
kotlin = "1.8.22"
|
||||||
coroutines = "1.7.0"
|
coroutines = "1.7.2"
|
||||||
|
|
||||||
# Serialization
|
# Serialization
|
||||||
json = "1.5.0"
|
json = "1.5.1"
|
||||||
|
|
||||||
# Compose
|
# Compose
|
||||||
composeGradle = "1.4.0"
|
composeGradle = "1.4.1"
|
||||||
composeCompiler = "1.4.5"
|
composeCompiler = "1.4.8"
|
||||||
composeAndroidRuntime = "1.4.3"
|
composeAndroidRuntime = "1.4.3"
|
||||||
composeAndroidFoundation = "1.4.3"
|
composeAndroidFoundation = "1.4.3"
|
||||||
composeAndroidUI = "1.4.3"
|
composeAndroidUI = "1.4.3"
|
||||||
@@ -19,14 +19,14 @@ composeAndroidMaterial = "1.4.3"
|
|||||||
voyager = "1.0.0-rc06"
|
voyager = "1.0.0-rc06"
|
||||||
accompanist = "0.30.1"
|
accompanist = "0.30.1"
|
||||||
googleAccompanist = "0.30.1"
|
googleAccompanist = "0.30.1"
|
||||||
imageloader = "1.4.0"
|
imageloader = "1.5.3"
|
||||||
materialDialogs = "0.9.3"
|
materialDialogs = "0.9.3"
|
||||||
|
|
||||||
# Android
|
# Android
|
||||||
androidGradle = "8.0.1"
|
androidGradle = "8.0.2"
|
||||||
core = "1.9.0"
|
core = "1.9.0"
|
||||||
appCompat = "1.7.0-alpha02"
|
appCompat = "1.7.0-alpha02"
|
||||||
activityCompose = "1.7.1"
|
activityCompose = "1.7.2"
|
||||||
work = "2.8.1"
|
work = "2.8.1"
|
||||||
|
|
||||||
# Android Lifecycle
|
# Android Lifecycle
|
||||||
@@ -36,14 +36,14 @@ lifecycle = "2.6.1"
|
|||||||
darklaf = "3.0.2"
|
darklaf = "3.0.2"
|
||||||
|
|
||||||
# Ksp
|
# Ksp
|
||||||
ksp = "1.8.20-1.0.11"
|
ksp = "1.8.22-1.0.11"
|
||||||
|
|
||||||
# Dependency Injection
|
# Dependency Injection
|
||||||
kotlinInject = "0.6.1"
|
kotlinInject = "0.6.1"
|
||||||
|
|
||||||
# Network
|
# Network
|
||||||
ktor = "2.3.0"
|
ktor = "2.3.2"
|
||||||
ktorfit = "1.2.0"
|
ktorfit = "1.4.2"
|
||||||
ktorfitCompiler = "1.0.0"
|
ktorfitCompiler = "1.0.0"
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
@@ -60,23 +60,23 @@ multiplatformSettings = "1.0.0-alpha01"
|
|||||||
|
|
||||||
# Utility
|
# Utility
|
||||||
desugarJdkLibs = "2.0.3"
|
desugarJdkLibs = "2.0.3"
|
||||||
aboutLibraries = "10.6.3"
|
aboutLibraries = "10.8.0"
|
||||||
dateTime = "0.4.0"
|
dateTime = "0.4.0"
|
||||||
immutableCollections = "0.3.5"
|
immutableCollections = "0.3.5"
|
||||||
kds = "3.4.0"
|
kds = "4.0.7"
|
||||||
|
|
||||||
# Localization
|
# Localization
|
||||||
moko = "0.22.0"
|
moko = "0.23.0"
|
||||||
|
|
||||||
# BuildConfigs
|
# BuildConfigs
|
||||||
buildconfig = "4.0.4"
|
buildconfig = "4.1.1"
|
||||||
buildkonfig = "0.13.3"
|
buildkonfig = "0.13.3"
|
||||||
|
|
||||||
# Linter
|
# Linter
|
||||||
kotlinter = "3.14.0"
|
kotlinter = "3.15.0"
|
||||||
|
|
||||||
# Version updates
|
# Version updates
|
||||||
versions = "0.46.0"
|
versions = "0.47.0"
|
||||||
|
|
||||||
# Optimizer
|
# Optimizer
|
||||||
proguard = "7.2.2"
|
proguard = "7.2.2"
|
||||||
@@ -111,7 +111,8 @@ accompanist-pager = { module = "ca.gosyer:accompanist-pager", version.ref = "acc
|
|||||||
accompanist-pagerIndicators = { module = "ca.gosyer:accompanist-pager-indicators", version.ref = "accompanist" }
|
accompanist-pagerIndicators = { module = "ca.gosyer:accompanist-pager-indicators", version.ref = "accompanist" }
|
||||||
accompanist-flowLayout = { module = "ca.gosyer:accompanist-flowlayout", version.ref = "accompanist" }
|
accompanist-flowLayout = { module = "ca.gosyer:accompanist-flowlayout", version.ref = "accompanist" }
|
||||||
accompanist-systemUIController = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "googleAccompanist" }
|
accompanist-systemUIController = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "googleAccompanist" }
|
||||||
imageloader = { module = "io.github.qdsfdhvh:image-loader", version.ref = "imageloader" }
|
imageloader-core = { module = "io.github.qdsfdhvh:image-loader", version.ref = "imageloader" }
|
||||||
|
imageloader-moko = { module = "io.github.qdsfdhvh:image-loader-extension-moko-resources", version.ref = "imageloader" }
|
||||||
materialDialogs-core = { module = "ca.gosyer:compose-material-dialogs-core", version.ref = "materialDialogs" }
|
materialDialogs-core = { module = "ca.gosyer:compose-material-dialogs-core", version.ref = "materialDialogs" }
|
||||||
|
|
||||||
# Android
|
# Android
|
||||||
|
|||||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
7
gradlew
vendored
7
gradlew
vendored
@@ -85,9 +85,6 @@ done
|
|||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
|
|
||||||
@@ -197,6 +194,10 @@ if "$cygwin" || "$msys" ; then
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Collect all arguments for the java command;
|
# Collect all arguments for the java command;
|
||||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||||
# shell script including quotes and variable substitutions, so put them in
|
# shell script including quotes and variable substitutions, so put them in
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ kotlin {
|
|||||||
implementation(libs.accompanist.pager)
|
implementation(libs.accompanist.pager)
|
||||||
implementation(libs.accompanist.pagerIndicators)
|
implementation(libs.accompanist.pagerIndicators)
|
||||||
implementation(libs.accompanist.flowLayout)
|
implementation(libs.accompanist.flowLayout)
|
||||||
implementation(libs.imageloader)
|
implementation(libs.imageloader.core)
|
||||||
|
implementation(libs.imageloader.moko)
|
||||||
implementation(libs.materialDialogs.core)
|
implementation(libs.materialDialogs.core)
|
||||||
|
|
||||||
// Threading
|
// Threading
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ kotlin {
|
|||||||
languageSettings {
|
languageSettings {
|
||||||
optIn("kotlin.RequiresOptIn")
|
optIn("kotlin.RequiresOptIn")
|
||||||
optIn("kotlinx.coroutines.ExperimentalCoroutinesApi")
|
optIn("kotlinx.coroutines.ExperimentalCoroutinesApi")
|
||||||
optIn("com.google.accompanist.pager.ExperimentalPagerApi")
|
|
||||||
optIn("androidx.compose.animation.ExperimentalAnimationApi")
|
optIn("androidx.compose.animation.ExperimentalAnimationApi")
|
||||||
optIn("androidx.compose.foundation.ExperimentalFoundationApi")
|
optIn("androidx.compose.foundation.ExperimentalFoundationApi")
|
||||||
optIn("androidx.compose.material.ExperimentalMaterialApi")
|
optIn("androidx.compose.material.ExperimentalMaterialApi")
|
||||||
@@ -45,7 +44,8 @@ kotlin {
|
|||||||
dependencies {
|
dependencies {
|
||||||
api(kotlin("stdlib-common"))
|
api(kotlin("stdlib-common"))
|
||||||
api(libs.coroutines.core)
|
api(libs.coroutines.core)
|
||||||
api(libs.imageloader)
|
api(libs.imageloader.core)
|
||||||
|
api(libs.imageloader.moko)
|
||||||
api(libs.voyager.core)
|
api(libs.voyager.core)
|
||||||
api(libs.voyager.navigation)
|
api(libs.voyager.navigation)
|
||||||
api(libs.voyager.transitions)
|
api(libs.voyager.transitions)
|
||||||
|
|||||||
@@ -14,12 +14,17 @@ import com.seiko.imageloader.cache.memory.MemoryCacheBuilder
|
|||||||
import com.seiko.imageloader.component.ComponentRegistryBuilder
|
import com.seiko.imageloader.component.ComponentRegistryBuilder
|
||||||
import com.seiko.imageloader.component.setupDefaultComponents
|
import com.seiko.imageloader.component.setupDefaultComponents
|
||||||
import com.seiko.imageloader.option.Options
|
import com.seiko.imageloader.option.Options
|
||||||
|
import com.seiko.imageloader.option.OptionsBuilder
|
||||||
|
import com.seiko.imageloader.option.androidContext
|
||||||
import okio.Path.Companion.toOkioPath
|
import okio.Path.Companion.toOkioPath
|
||||||
|
|
||||||
actual val imageConfig: Options.ImageConfig = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
actual fun OptionsBuilder.configure(contextWrapper: ContextWrapper) {
|
||||||
Options.ImageConfig.ARGB_8888
|
imageConfig = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||||
} else {
|
Options.ImageConfig.ARGB_8888
|
||||||
Options.ImageConfig.HARDWARE
|
} else {
|
||||||
|
Options.ImageConfig.HARDWARE
|
||||||
|
}
|
||||||
|
androidContext(contextWrapper)
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun ComponentRegistryBuilder.register(contextWrapper: ContextWrapper, http: Http) {
|
actual fun ComponentRegistryBuilder.register(contextWrapper: ContextWrapper, http: Http) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ package ca.gosyer.jui.ui.base
|
|||||||
import androidx.compose.runtime.ProvidedValue
|
import androidx.compose.runtime.ProvidedValue
|
||||||
import androidx.compose.runtime.compositionLocalOf
|
import androidx.compose.runtime.compositionLocalOf
|
||||||
import ca.gosyer.jui.core.di.AppScope
|
import ca.gosyer.jui.core.di.AppScope
|
||||||
|
import ca.gosyer.jui.core.io.SYSTEM
|
||||||
import ca.gosyer.jui.ui.ViewModelComponent
|
import ca.gosyer.jui.ui.ViewModelComponent
|
||||||
import ca.gosyer.jui.ui.base.image.ImageLoaderProvider
|
import ca.gosyer.jui.ui.base.image.ImageLoaderProvider
|
||||||
import ca.gosyer.jui.ui.base.image.configure
|
import ca.gosyer.jui.ui.base.image.configure
|
||||||
@@ -17,6 +18,7 @@ import com.seiko.imageloader.ImageLoader
|
|||||||
import com.seiko.imageloader.LocalImageLoader
|
import com.seiko.imageloader.LocalImageLoader
|
||||||
import com.seiko.imageloader.cache.disk.DiskCache
|
import com.seiko.imageloader.cache.disk.DiskCache
|
||||||
import me.tatarka.inject.annotations.Provides
|
import me.tatarka.inject.annotations.Provides
|
||||||
|
import okio.FileSystem
|
||||||
|
|
||||||
typealias ImageCache = DiskCache
|
typealias ImageCache = DiskCache
|
||||||
|
|
||||||
@@ -35,15 +37,22 @@ interface UiComponent {
|
|||||||
|
|
||||||
@AppScope
|
@AppScope
|
||||||
@Provides
|
@Provides
|
||||||
fun imageLoaderFactory(imageLoaderProvider: ImageLoaderProvider, imageCache: ImageCache): ImageLoader = imageLoaderProvider.get(imageCache)
|
fun imageLoaderFactory(
|
||||||
|
imageLoaderProvider: ImageLoaderProvider,
|
||||||
|
imageCache: ImageCache
|
||||||
|
): ImageLoader = imageLoaderProvider.get(imageCache)
|
||||||
|
|
||||||
@AppScope
|
@AppScope
|
||||||
@Provides
|
@Provides
|
||||||
fun imageCacheFactory(): ImageCache = DiskCache { configure(contextWrapper, "image_cache") }
|
fun imageCacheFactory(): ImageCache = DiskCache(FileSystem.SYSTEM) {
|
||||||
|
configure(contextWrapper, "image_cache")
|
||||||
|
}
|
||||||
|
|
||||||
@AppScope
|
@AppScope
|
||||||
@Provides
|
@Provides
|
||||||
fun chapterCacheFactory(): ChapterCache = DiskCache { configure(contextWrapper, "chapter_cache") }
|
fun chapterCacheFactory(): ChapterCache = DiskCache(FileSystem.SYSTEM) {
|
||||||
|
configure(contextWrapper, "chapter_cache")
|
||||||
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
fun getHooks(viewModelComponent: ViewModelComponent) = arrayOf(
|
fun getHooks(viewModelComponent: ViewModelComponent) = arrayOf(
|
||||||
|
|||||||
@@ -17,9 +17,11 @@ import com.seiko.imageloader.ImageLoader
|
|||||||
import com.seiko.imageloader.cache.disk.DiskCacheBuilder
|
import com.seiko.imageloader.cache.disk.DiskCacheBuilder
|
||||||
import com.seiko.imageloader.cache.memory.MemoryCacheBuilder
|
import com.seiko.imageloader.cache.memory.MemoryCacheBuilder
|
||||||
import com.seiko.imageloader.component.ComponentRegistryBuilder
|
import com.seiko.imageloader.component.ComponentRegistryBuilder
|
||||||
|
import com.seiko.imageloader.component.fetcher.MokoResourceFetcher
|
||||||
import com.seiko.imageloader.component.keyer.Keyer
|
import com.seiko.imageloader.component.keyer.Keyer
|
||||||
import com.seiko.imageloader.component.mapper.Mapper
|
import com.seiko.imageloader.component.mapper.Mapper
|
||||||
import com.seiko.imageloader.option.Options
|
import com.seiko.imageloader.option.Options
|
||||||
|
import com.seiko.imageloader.option.OptionsBuilder
|
||||||
import io.ktor.http.Url
|
import io.ktor.http.Url
|
||||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
@@ -37,6 +39,7 @@ class ImageLoaderProvider @Inject constructor(
|
|||||||
return ImageLoader {
|
return ImageLoader {
|
||||||
components {
|
components {
|
||||||
register(context, http)
|
register(context, http)
|
||||||
|
add(MokoResourceFetcher.Factory())
|
||||||
add(MangaCoverMapper())
|
add(MangaCoverMapper())
|
||||||
add(MangaCoverKeyer())
|
add(MangaCoverKeyer())
|
||||||
add(ExtensionIconMapper())
|
add(ExtensionIconMapper())
|
||||||
@@ -44,7 +47,9 @@ class ImageLoaderProvider @Inject constructor(
|
|||||||
add(SourceIconMapper())
|
add(SourceIconMapper())
|
||||||
add(SourceIconKeyer())
|
add(SourceIconKeyer())
|
||||||
}
|
}
|
||||||
options.config = imageConfig
|
options {
|
||||||
|
configure(context)
|
||||||
|
}
|
||||||
interceptor {
|
interceptor {
|
||||||
diskCache { imageCache }
|
diskCache { imageCache }
|
||||||
memoryCacheConfig { configure(context) }
|
memoryCacheConfig { configure(context) }
|
||||||
@@ -61,7 +66,7 @@ class ImageLoaderProvider @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MangaCoverKeyer : Keyer {
|
class MangaCoverKeyer : Keyer {
|
||||||
override fun key(data: Any, options: Options): String? {
|
override fun key(data: Any, options: Options, type: Keyer.Type): String? {
|
||||||
if (data !is Manga) return null
|
if (data !is Manga) return null
|
||||||
return "${data.sourceId}-${data.thumbnailUrl}-${data.thumbnailUrlLastFetched}"
|
return "${data.sourceId}-${data.thumbnailUrl}-${data.thumbnailUrlLastFetched}"
|
||||||
}
|
}
|
||||||
@@ -76,7 +81,7 @@ class ImageLoaderProvider @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ExtensionIconKeyer : Keyer {
|
class ExtensionIconKeyer : Keyer {
|
||||||
override fun key(data: Any, options: Options): String? {
|
override fun key(data: Any, options: Options, type: Keyer.Type): String? {
|
||||||
if (data !is Extension) return null
|
if (data !is Extension) return null
|
||||||
return data.iconUrl
|
return data.iconUrl
|
||||||
}
|
}
|
||||||
@@ -91,14 +96,14 @@ class ImageLoaderProvider @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SourceIconKeyer : Keyer {
|
class SourceIconKeyer : Keyer {
|
||||||
override fun key(data: Any, options: Options): String? {
|
override fun key(data: Any, options: Options, type: Keyer.Type): String? {
|
||||||
if (data !is Source) return null
|
if (data !is Source) return null
|
||||||
return data.iconUrl
|
return data.iconUrl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expect val imageConfig: Options.ImageConfig
|
expect fun OptionsBuilder.configure(contextWrapper: ContextWrapper)
|
||||||
|
|
||||||
expect fun ComponentRegistryBuilder.register(contextWrapper: ContextWrapper, http: Http)
|
expect fun ComponentRegistryBuilder.register(contextWrapper: ContextWrapper, http: Http)
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
package ca.gosyer.jui.ui.library.components
|
package ca.gosyer.jui.ui.library.components
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.pager.HorizontalPager
|
||||||
|
import androidx.compose.foundation.pager.PagerState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
@@ -16,8 +18,6 @@ import ca.gosyer.jui.domain.library.model.DisplayMode
|
|||||||
import ca.gosyer.jui.ui.library.CategoryState
|
import ca.gosyer.jui.ui.library.CategoryState
|
||||||
import ca.gosyer.jui.uicore.components.ErrorScreen
|
import ca.gosyer.jui.uicore.components.ErrorScreen
|
||||||
import ca.gosyer.jui.uicore.components.LoadingScreen
|
import ca.gosyer.jui.uicore.components.LoadingScreen
|
||||||
import com.google.accompanist.pager.HorizontalPager
|
|
||||||
import com.google.accompanist.pager.PagerState
|
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||||||
import androidx.compose.foundation.layout.only
|
import androidx.compose.foundation.layout.only
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.windowInsetsPadding
|
import androidx.compose.foundation.layout.windowInsetsPadding
|
||||||
|
import androidx.compose.foundation.pager.PagerState
|
||||||
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
import androidx.compose.material.ModalBottomSheetLayout
|
import androidx.compose.material.ModalBottomSheetLayout
|
||||||
import androidx.compose.material.ModalBottomSheetValue
|
import androidx.compose.material.ModalBottomSheetValue
|
||||||
import androidx.compose.material.Scaffold
|
import androidx.compose.material.Scaffold
|
||||||
@@ -53,8 +55,6 @@ import ca.gosyer.jui.uicore.components.LoadingScreen
|
|||||||
import ca.gosyer.jui.uicore.insets.navigationBars
|
import ca.gosyer.jui.uicore.insets.navigationBars
|
||||||
import ca.gosyer.jui.uicore.insets.statusBars
|
import ca.gosyer.jui.uicore.insets.statusBars
|
||||||
import ca.gosyer.jui.uicore.resources.stringResource
|
import ca.gosyer.jui.uicore.resources.stringResource
|
||||||
import com.google.accompanist.pager.PagerState
|
|
||||||
import com.google.accompanist.pager.rememberPagerState
|
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("DEPRECATION")
|
||||||
|
|
||||||
package ca.gosyer.jui.ui.library.components
|
package ca.gosyer.jui.ui.library.components
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
@@ -11,6 +13,7 @@ import androidx.compose.animation.expandVertically
|
|||||||
import androidx.compose.animation.shrinkVertically
|
import androidx.compose.animation.shrinkVertically
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.pager.PagerState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.Divider
|
import androidx.compose.material.Divider
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
@@ -24,10 +27,11 @@ import androidx.compose.ui.draw.clip
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.util.fastForEachIndexed
|
import androidx.compose.ui.util.fastForEachIndexed
|
||||||
import ca.gosyer.jui.domain.category.model.Category
|
import ca.gosyer.jui.domain.category.model.Category
|
||||||
import com.google.accompanist.pager.PagerState
|
import com.google.accompanist.pager.ExperimentalPagerApi
|
||||||
import com.google.accompanist.pager.pagerTabIndicatorOffset
|
import com.google.accompanist.pager.pagerTabIndicatorOffset
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
|
||||||
|
@OptIn(ExperimentalPagerApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun LibraryTabs(
|
fun LibraryTabs(
|
||||||
visible: Boolean,
|
visible: Boolean,
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("DEPRECATION")
|
||||||
|
|
||||||
package ca.gosyer.jui.ui.library.settings
|
package ca.gosyer.jui.ui.library.settings
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
@@ -11,6 +13,8 @@ import androidx.compose.foundation.layout.Column
|
|||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.pager.HorizontalPager
|
||||||
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.Tab
|
import androidx.compose.material.Tab
|
||||||
@@ -27,9 +31,8 @@ import ca.gosyer.jui.uicore.components.VerticalScrollbar
|
|||||||
import ca.gosyer.jui.uicore.components.rememberScrollbarAdapter
|
import ca.gosyer.jui.uicore.components.rememberScrollbarAdapter
|
||||||
import ca.gosyer.jui.uicore.components.scrollbarPadding
|
import ca.gosyer.jui.uicore.components.scrollbarPadding
|
||||||
import ca.gosyer.jui.uicore.resources.stringResource
|
import ca.gosyer.jui.uicore.resources.stringResource
|
||||||
import com.google.accompanist.pager.HorizontalPager
|
import com.google.accompanist.pager.ExperimentalPagerApi
|
||||||
import com.google.accompanist.pager.pagerTabIndicatorOffset
|
import com.google.accompanist.pager.pagerTabIndicatorOffset
|
||||||
import com.google.accompanist.pager.rememberPagerState
|
|
||||||
import dev.icerock.moko.resources.StringResource
|
import dev.icerock.moko.resources.StringResource
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@@ -39,6 +42,7 @@ enum class LibrarySheetTabs(val res: StringResource) {
|
|||||||
DISPLAY(MR.strings.library_display),
|
DISPLAY(MR.strings.library_display),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalPagerApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun LibrarySheet(
|
fun LibrarySheet(
|
||||||
libraryFilters: @Composable () -> Unit,
|
libraryFilters: @Composable () -> Unit,
|
||||||
@@ -68,7 +72,7 @@ fun LibrarySheet(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
HorizontalPager(
|
HorizontalPager(
|
||||||
count = LibrarySheetTabs.values().size,
|
pageCount = LibrarySheetTabs.values().size,
|
||||||
state = pagerState,
|
state = pagerState,
|
||||||
verticalAlignment = Alignment.Top,
|
verticalAlignment = Alignment.Top,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -13,9 +13,10 @@ import com.seiko.imageloader.cache.disk.DiskCacheBuilder
|
|||||||
import com.seiko.imageloader.cache.memory.MemoryCacheBuilder
|
import com.seiko.imageloader.cache.memory.MemoryCacheBuilder
|
||||||
import com.seiko.imageloader.component.ComponentRegistryBuilder
|
import com.seiko.imageloader.component.ComponentRegistryBuilder
|
||||||
import com.seiko.imageloader.component.setupDefaultComponents
|
import com.seiko.imageloader.component.setupDefaultComponents
|
||||||
import com.seiko.imageloader.option.Options
|
import com.seiko.imageloader.option.OptionsBuilder
|
||||||
|
|
||||||
actual val imageConfig: Options.ImageConfig = Options.ImageConfig.ARGB_8888
|
actual fun OptionsBuilder.configure(contextWrapper: ContextWrapper) {
|
||||||
|
}
|
||||||
|
|
||||||
actual fun ComponentRegistryBuilder.register(contextWrapper: ContextWrapper, http: Http) {
|
actual fun ComponentRegistryBuilder.register(contextWrapper: ContextWrapper, http: Http) {
|
||||||
setupDefaultComponents(httpClient = { http })
|
setupDefaultComponents(httpClient = { http })
|
||||||
|
|||||||
@@ -13,13 +13,14 @@ import com.seiko.imageloader.cache.memory.MemoryCacheBuilder
|
|||||||
import com.seiko.imageloader.cache.memory.maxSizePercent
|
import com.seiko.imageloader.cache.memory.maxSizePercent
|
||||||
import com.seiko.imageloader.component.ComponentRegistryBuilder
|
import com.seiko.imageloader.component.ComponentRegistryBuilder
|
||||||
import com.seiko.imageloader.component.setupDefaultComponents
|
import com.seiko.imageloader.component.setupDefaultComponents
|
||||||
import com.seiko.imageloader.option.Options
|
import com.seiko.imageloader.option.OptionsBuilder
|
||||||
import okio.Path.Companion.toPath
|
import okio.Path.Companion.toPath
|
||||||
import platform.Foundation.NSCachesDirectory
|
import platform.Foundation.NSCachesDirectory
|
||||||
import platform.Foundation.NSFileManager
|
import platform.Foundation.NSFileManager
|
||||||
import platform.Foundation.NSUserDomainMask
|
import platform.Foundation.NSUserDomainMask
|
||||||
|
|
||||||
actual val imageConfig: Options.ImageConfig = Options.ImageConfig.ARGB_8888
|
actual fun OptionsBuilder.configure(contextWrapper: ContextWrapper) {
|
||||||
|
}
|
||||||
|
|
||||||
actual fun ComponentRegistryBuilder.register(contextWrapper: ContextWrapper, http: Http) {
|
actual fun ComponentRegistryBuilder.register(contextWrapper: ContextWrapper, http: Http) {
|
||||||
setupDefaultComponents(httpClient = { http })
|
setupDefaultComponents(httpClient = { http })
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ kotlin {
|
|||||||
dependencies {
|
dependencies {
|
||||||
api(kotlin("stdlib-common"))
|
api(kotlin("stdlib-common"))
|
||||||
api(libs.coroutines.core)
|
api(libs.coroutines.core)
|
||||||
api(libs.imageloader)
|
api(libs.imageloader.core)
|
||||||
|
api(libs.imageloader.moko)
|
||||||
api(libs.voyager.core)
|
api(libs.voyager.core)
|
||||||
api(libs.dateTime)
|
api(libs.dateTime)
|
||||||
api(libs.immutableCollections)
|
api(libs.immutableCollections)
|
||||||
|
|||||||
Reference in New Issue
Block a user