Remove Kamel

This commit is contained in:
Syer10
2022-08-24 20:21:06 -04:00
parent ddbf9d16b8
commit 282a2b0a54
10 changed files with 0 additions and 317 deletions

View File

@@ -26,7 +26,6 @@ dependencies {
implementation(libs.accompanist.pager)
implementation(libs.accompanist.pagerIndicators)
implementation(libs.accompanist.flowLayout)
implementation(libs.kamel)
implementation(libs.imageloader)
implementation(libs.materialDialogs.core)

View File

@@ -36,7 +36,6 @@ dependencies {
implementation(libs.accompanist.pager)
implementation(libs.accompanist.pagerIndicators)
implementation(libs.accompanist.flowLayout)
implementation(libs.kamel)
implementation(libs.imageloader)
implementation(libs.materialDialogs.core)

View File

@@ -12,7 +12,6 @@ composeCompiler = "1.3.0"
composeAndroid = "1.2.1"
voyager = "1.0.0-beta16"
accompanist = "0.25.1"
kamel = "0.4.1"
imageloader = "1.1.3"
materialDialogs = "0.8.0"
@@ -101,7 +100,6 @@ voyager-transitions = { module = "cafe.adriel.voyager:voyager-transitions", vers
accompanist-pager = { module = "ca.gosyer:accompanist-pager", version.ref = "accompanist" }
accompanist-pagerIndicators = { module = "ca.gosyer:accompanist-pager-indicators", version.ref = "accompanist" }
accompanist-flowLayout = { module = "ca.gosyer:accompanist-flowlayout", version.ref = "accompanist" }
kamel = { module = "com.alialbaali.kamel:kamel-image", version.ref = "kamel" }
imageloader = { module = "io.github.qdsfdhvh:image-loader", version.ref = "imageloader" }
materialDialogs-core = { module = "ca.gosyer:compose-material-dialogs-core", version.ref = "materialDialogs" }

View File

@@ -42,7 +42,6 @@ kotlin {
dependencies {
api(kotlin("stdlib-common"))
api(libs.coroutines.core)
api(libs.kamel)
api(libs.imageloader)
api(libs.voyager.core)
api(libs.voyager.navigation)

View File

@@ -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.ui.base
import ca.gosyer.jui.uicore.vm.ContextWrapper
import io.kamel.core.config.KamelConfigBuilder
import io.kamel.image.config.resourcesFetcher
import io.kamel.image.config.resourcesIdMapper
actual fun KamelConfigBuilder.kamelPlatformHandler(contextWrapper: ContextWrapper) {
resourcesIdMapper(contextWrapper)
resourcesFetcher(contextWrapper)
}

View File

@@ -11,30 +11,18 @@ import androidx.compose.runtime.compositionLocalOf
import ca.gosyer.jui.core.di.AppScope
import ca.gosyer.jui.ui.ViewModelComponent
import ca.gosyer.jui.ui.base.image.ImageLoaderProvider
import ca.gosyer.jui.ui.base.image.KamelConfigProvider
import ca.gosyer.jui.uicore.vm.ContextWrapper
import com.seiko.imageloader.ImageLoader
import com.seiko.imageloader.LocalImageLoader
import io.kamel.core.config.KamelConfig
import io.kamel.core.config.KamelConfigBuilder
import io.kamel.image.config.LocalKamelConfig
import me.tatarka.inject.annotations.Provides
interface UiComponent {
val kamelConfigProvider: KamelConfigProvider
val kamelConfig: KamelConfig
val imageLoader: ImageLoader
val contextWrapper: ContextWrapper
val hooks: Array<ProvidedValue<out Any>>
@AppScope
@Provides
fun kamelConfigFactory(contextWrapper: ContextWrapper): KamelConfig = kamelConfigProvider.get { kamelPlatformHandler(contextWrapper) }
@AppScope
@Provides
fun imageLoaderFactory(imageLoaderProvider: ImageLoaderProvider): ImageLoader = imageLoaderProvider.get()
@@ -42,12 +30,9 @@ interface UiComponent {
@Provides
fun getHooks(viewModelComponent: ViewModelComponent) = arrayOf(
LocalViewModels provides viewModelComponent,
LocalKamelConfig provides kamelConfig,
LocalImageLoader provides imageLoader
)
}
expect fun KamelConfigBuilder.kamelPlatformHandler(contextWrapper: ContextWrapper)
val LocalViewModels =
compositionLocalOf<ViewModelComponent> { throw IllegalArgumentException("ViewModelComponent not found") }

View File

@@ -1,112 +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.ui.base.image
import ca.gosyer.jui.domain.extension.model.Extension
import ca.gosyer.jui.domain.manga.model.Manga
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.domain.server.service.ServerPreferences
import ca.gosyer.jui.domain.source.model.Source
import io.kamel.core.DataSource
import io.kamel.core.Resource
import io.kamel.core.config.DefaultCacheSize
import io.kamel.core.config.KamelConfig
import io.kamel.core.config.KamelConfigBuilder
import io.kamel.core.config.ResourceConfig
import io.kamel.core.config.fileFetcher
import io.kamel.core.config.stringMapper
import io.kamel.core.config.uriMapper
import io.kamel.core.config.urlMapper
import io.kamel.core.fetcher.Fetcher
import io.kamel.core.mapper.Mapper
import io.kamel.image.config.imageBitmapDecoder
import io.ktor.client.HttpClient
import io.ktor.client.plugins.expectSuccess
import io.ktor.client.plugins.onDownload
import io.ktor.client.request.request
import io.ktor.client.request.takeFrom
import io.ktor.client.request.url
import io.ktor.client.statement.bodyAsChannel
import io.ktor.http.Url
import io.ktor.utils.io.ByteReadChannel
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.channelFlow
import me.tatarka.inject.annotations.Inject
class KamelConfigProvider @Inject constructor(
private val http: Http,
serverPreferences: ServerPreferences
) {
@OptIn(DelicateCoroutinesApi::class)
val serverUrl = serverPreferences.serverUrl().stateIn(GlobalScope)
fun get(kamelPlatformHandler: KamelConfigBuilder.() -> Unit): KamelConfig {
return KamelConfig {
// Default config
imageBitmapCacheSize = DefaultCacheSize
imageVectorCacheSize = DefaultCacheSize
imageBitmapDecoder()
stringMapper()
urlMapper()
uriMapper()
fileFetcher()
// JUI config
kamelPlatformHandler()
fetcher(HttpFetcher(http))
mapper(MangaCoverMapper(serverUrl))
mapper(ExtensionIconMapper(serverUrl))
mapper(SourceIconMapper(serverUrl))
}
}
class MangaCoverMapper(private val serverUrlStateFlow: StateFlow<Url>) : Mapper<Manga, Url> {
override fun map(input: Manga): Url {
return Url(serverUrlStateFlow.value.toString() + input.thumbnailUrl.orEmpty())
}
}
class ExtensionIconMapper(private val serverUrlStateFlow: StateFlow<Url>) : Mapper<Extension, Url> {
override fun map(input: Extension): Url {
return Url(serverUrlStateFlow.value.toString() + input.iconUrl)
}
}
class SourceIconMapper(private val serverUrlStateFlow: StateFlow<Url>) : Mapper<Source, Url> {
override fun map(input: Source): Url {
return Url(serverUrlStateFlow.value.toString() + input.iconUrl)
}
}
private class HttpFetcher(private val client: HttpClient) : Fetcher<Url> {
override val source: DataSource = DataSource.Network
override val Url.isSupported: Boolean
get() = protocol.name == "https" || protocol.name == "http"
override fun fetch(
data: Url,
resourceConfig: ResourceConfig
): Flow<Resource<ByteReadChannel>> = channelFlow {
val response = client.request {
onDownload { bytesSentTotal, contentLength ->
val progress = (bytesSentTotal.toFloat() / contentLength).coerceAtMost(1.0F)
send(Resource.Loading(progress))
}
takeFrom(resourceConfig.requestData)
url(data)
expectSuccess = true
}
val bytes = response.bodyAsChannel()
send(Resource.Success(bytes))
}
}
}

View File

@@ -1,19 +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.ui.base
import ca.gosyer.jui.uicore.vm.ContextWrapper
import io.kamel.core.config.KamelConfigBuilder
import io.kamel.image.config.imageVectorDecoder
import io.kamel.image.config.resourcesFetcher
import io.kamel.image.config.svgDecoder
actual fun KamelConfigBuilder.kamelPlatformHandler(contextWrapper: ContextWrapper) {
resourcesFetcher()
imageVectorDecoder()
svgDecoder()
}

View File

@@ -38,7 +38,6 @@ kotlin {
dependencies {
api(kotlin("stdlib-common"))
api(libs.coroutines.core)
api(libs.kamel)
api(libs.imageloader)
api(libs.voyager.core)
api(libs.dateTime)

View File

@@ -1,148 +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.uicore.image
import androidx.compose.animation.Crossfade
import androidx.compose.animation.core.FiniteAnimationSpec
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.BrokenImage
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.DefaultAlpha
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import ca.gosyer.jui.uicore.components.LoadingScreen
import io.kamel.core.Resource
import org.lighthousegames.logging.logging
import io.kamel.image.KamelImage as BaseKamelImage
private val log = logging()
private enum class KamelImageState {
Loading,
Success,
Failure,
}
@Composable
fun KamelImage(
resource: Resource<Painter>,
contentDescription: String?,
modifier: Modifier = Modifier,
errorModifier: Modifier = modifier,
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
alpha: Float = DefaultAlpha,
colorFilter: ColorFilter? = null,
onLoading: (@Composable BoxScope.(Float) -> Unit)? = {
LoadingScreen(progress = it.coerceIn(0.0F, 1.0F), modifier = modifier then Modifier.fillMaxSize())
},
onFailure: (@Composable BoxScope.(Throwable) -> Unit)? = {
LaunchedEffect(it) {
log.warn(it) { "Error loading image" }
}
Box(
modifier = errorModifier then Modifier.fillMaxSize()
.background(Color(0x1F888888)),
contentAlignment = Alignment.Center
) {
Icon(
Icons.Rounded.BrokenImage,
contentDescription = null,
tint = Color(0x1F888888),
modifier = Modifier.size(24.dp)
)
}
},
contentAlignment: Alignment = Alignment.Center,
animationSpec: FiniteAnimationSpec<Float>? = tween()
) {
if (animationSpec != null) {
val progress = remember { mutableStateOf(-1F) }
val image = remember { mutableStateOf<Painter?>(null) }
val error = remember { mutableStateOf<Throwable?>(null) }
val state by derivedStateOf {
when (resource) {
is Resource.Failure -> {
progress.value = -1F
error.value = resource.exception
KamelImageState.Failure
}
is Resource.Loading -> {
progress.value = resource.progress
KamelImageState.Loading
}
is Resource.Success -> {
progress.value = 1.0F
image.value = resource.value
KamelImageState.Success
}
}
}
Crossfade(state, animationSpec = animationSpec, modifier = modifier) {
Box(Modifier.fillMaxSize(), contentAlignment) {
when (it) {
KamelImageState.Loading -> if (onLoading != null) {
onLoading(progress.value)
}
KamelImageState.Success -> Box {
val value = image.value
if (value != null) {
Image(
value,
contentDescription,
modifier,
alignment,
contentScale,
alpha,
colorFilter
)
} else if (onLoading != null) {
onLoading(1.0F)
}
}
KamelImageState.Failure -> {
if (onFailure != null) {
onFailure(error.value ?: return@Crossfade)
}
}
}
}
}
} else {
BaseKamelImage(
resource,
contentDescription,
modifier,
alignment,
contentScale,
alpha,
colorFilter,
onLoading,
onFailure,
contentAlignment,
null
)
}
}