Update all dependencies

This commit is contained in:
Syer10
2023-12-01 19:21:07 -05:00
parent 30f43412d4
commit 2c088a3a7e
40 changed files with 385 additions and 431 deletions

View File

@@ -11,7 +11,7 @@ plugins {
}
kotlin {
android {
androidTarget {
compilations {
all {
kotlinOptions.jvmTarget = Config.androidJvmTarget.toString()
@@ -29,6 +29,21 @@ kotlin {
iosArm64()
iosSimulatorArm64()
@OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class)
applyHierarchyTemplate {
common {
group("jvm") {
withAndroidTarget()
withJvm()
}
group("ios") {
withIosX64()
withIosArm64()
withIosSimulatorArm64()
}
}
}
sourceSets {
all {
languageSettings {
@@ -78,33 +93,28 @@ kotlin {
}
}
val jvmMain by creating {
dependsOn(commonMain)
val jvmMain by getting {
dependencies {
api(kotlin("stdlib-jdk8"))
api(compose.desktop.currentOs)
}
}
val jvmTest by creating {
dependsOn(commonTest)
val jvmTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
val desktopMain by getting {
dependsOn(jvmMain)
dependencies {
api(libs.coroutines.swing)
}
}
val desktopTest by getting {
dependsOn(jvmTest)
}
val androidMain by getting {
dependsOn(jvmMain)
dependencies {
api(libs.bundles.compose.android)
api(libs.androidx.core)
@@ -114,23 +124,11 @@ kotlin {
}
}
val androidUnitTest by getting {
dependsOn(jvmTest)
}
val iosMain by creating {
dependsOn(commonMain)
val iosMain by getting {
}
val iosTest by creating {
dependsOn(commonTest)
}
listOf(
"iosX64",
"iosArm64",
"iosSimulatorArm64",
).forEach {
getByName(it + "Main").dependsOn(iosMain)
getByName(it + "Test").dependsOn(iosTest)
val iosTest by getting {
}
}
}

View File

@@ -9,20 +9,22 @@ package ca.gosyer.jui.ui.base.image
import android.os.Build
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.uicore.vm.ContextWrapper
import com.seiko.imageloader.Bitmap
import com.seiko.imageloader.BitmapConfig
import com.seiko.imageloader.cache.disk.DiskCacheBuilder
import com.seiko.imageloader.cache.memory.MemoryCacheBuilder
import com.seiko.imageloader.cache.memory.MemoryKey
import com.seiko.imageloader.component.ComponentRegistryBuilder
import com.seiko.imageloader.component.setupDefaultComponents
import com.seiko.imageloader.option.Options
import com.seiko.imageloader.option.OptionsBuilder
import com.seiko.imageloader.option.androidContext
import okio.Path.Companion.toOkioPath
actual fun OptionsBuilder.configure(contextWrapper: ContextWrapper) {
imageConfig = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
Options.ImageConfig.ARGB_8888
bitmapConfig = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
BitmapConfig.ARGB_8888
} else {
Options.ImageConfig.HARDWARE
BitmapConfig.HARDWARE
}
androidContext(contextWrapper)
}
@@ -42,5 +44,5 @@ actual fun DiskCacheBuilder.configure(
maxSizeBytes(1024 * 1024 * 150) // 150 MB
}
actual fun MemoryCacheBuilder.configure(contextWrapper: ContextWrapper) {
actual fun MemoryCacheBuilder<MemoryKey, Bitmap>.configure(contextWrapper: ContextWrapper) {
}

View File

@@ -35,10 +35,10 @@ fun getMaterialDialogProperties(
dismissOnClickOutside = dismissOnClickOutside,
securePolicy = securePolicy,
usePlatformDefaultWidth = usePlatformDefaultWidth,
position = position,
size = size,
title = title,
icon = icon,
resizable = resizable,
windowPosition = position,
windowSize = size,
windowTitle = title,
windowIcon = icon,
windowIsResizable = resizable,
)
}

View File

@@ -13,9 +13,11 @@ import ca.gosyer.jui.domain.server.service.ServerPreferences
import ca.gosyer.jui.domain.source.model.Source
import ca.gosyer.jui.ui.base.ImageCache
import ca.gosyer.jui.uicore.vm.ContextWrapper
import com.seiko.imageloader.Bitmap
import com.seiko.imageloader.ImageLoader
import com.seiko.imageloader.cache.disk.DiskCacheBuilder
import com.seiko.imageloader.cache.memory.MemoryCacheBuilder
import com.seiko.imageloader.cache.memory.MemoryKey
import com.seiko.imageloader.component.ComponentRegistryBuilder
import com.seiko.imageloader.component.fetcher.MokoResourceFetcher
import com.seiko.imageloader.component.keyer.Keyer
@@ -138,4 +140,4 @@ expect fun DiskCacheBuilder.configure(
cacheDir: String,
)
expect fun MemoryCacheBuilder.configure(contextWrapper: ContextWrapper)
expect fun MemoryCacheBuilder<MemoryKey, Bitmap>.configure(contextWrapper: ContextWrapper)

View File

@@ -27,7 +27,6 @@ import ca.gosyer.jui.ui.base.state.getStateFlow
import ca.gosyer.jui.ui.util.lang.CollatorComparator
import ca.gosyer.jui.uicore.vm.ContextWrapper
import ca.gosyer.jui.uicore.vm.ViewModel
import cafe.adriel.voyager.core.model.coroutineScope
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
@@ -198,7 +197,7 @@ class LibraryScreenViewModel
log.warn(it) { "Failed to get manga list from category ${category.name}" }
library.mangaMap.setError(category.id, it)
}
.launchIn(coroutineScope)
.launchIn(scope)
}
}
.catch {

View File

@@ -37,7 +37,7 @@ fun LibraryPager(
) {
if (categories.isEmpty()) return
HorizontalPager(categories.size, state = pagerState) {
HorizontalPager(state = pagerState) {
when (val library = getLibraryForPage(categories[it].id).value) {
CategoryState.Loading -> LoadingScreen()
is CategoryState.Failed -> ErrorScreen(library.e.message)

View File

@@ -12,7 +12,6 @@ import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.gestures.forEachGesture
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
@@ -90,7 +89,9 @@ fun LibraryScreenContent(
}
BoxWithConstraints {
val pagerState = rememberPagerState(selectedCategoryIndex)
val pagerState = rememberPagerState(selectedCategoryIndex) {
(libraryState as? LibraryState.Loaded)?.categories?.size ?: 1
}
LaunchedEffect(pagerState.isScrollInProgress to pagerState.currentPage) {
if (!pagerState.isScrollInProgress && pagerState.currentPage != selectedCategoryIndex) {
onPageChanged(pagerState.currentPage)
@@ -240,11 +241,7 @@ fun WideLibraryScreenContent(
if (showingMenu) {
Box(
Modifier.fillMaxSize().pointerInput(Unit) {
forEachGesture {
detectTapGestures {
setShowingMenu(false)
}
}
detectTapGestures(onTap = { setShowingMenu(false) })
},
)
}
@@ -295,7 +292,7 @@ fun ThinLibraryScreenContent(
) {
val bottomSheetState = rememberModalBottomSheetState(
ModalBottomSheetValue.Hidden,
confirmStateChange = {
confirmValueChange = {
when (it) {
ModalBottomSheetValue.Hidden -> setShowingSheet(false)
ModalBottomSheetValue.Expanded,

View File

@@ -49,7 +49,7 @@ fun LibrarySheet(
librarySort: @Composable () -> Unit,
libraryDisplay: @Composable () -> Unit,
) {
val pagerState = rememberPagerState()
val pagerState = rememberPagerState { LibrarySheetTabs.values().size }
val selectedPage = pagerState.currentPage
val scope = rememberCoroutineScope()
Column(Modifier.fillMaxSize()) {
@@ -72,7 +72,6 @@ fun LibrarySheet(
}
}
HorizontalPager(
pageCount = LibrarySheetTabs.values().size,
state = pagerState,
verticalAlignment = Alignment.Top,
) {

View File

@@ -13,7 +13,7 @@ import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.consumedWindowInsets
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
@@ -110,7 +110,11 @@ fun WideMainMenu(
}
withDisplayController(controller) {
val insets = WindowInsets.navigationBars.only(WindowInsetsSides.Start)
MainWindow(navigator, Modifier.padding(start = startPadding).windowInsetsPadding(insets).consumedWindowInsets(insets))
MainWindow(navigator,
Modifier.padding(start = startPadding)
.windowInsetsPadding(insets)
.consumeWindowInsets(insets)
)
}
}
}

View File

@@ -35,6 +35,7 @@ import ca.gosyer.jui.uicore.insets.statusBars
import ca.gosyer.jui.uicore.resources.stringResource
import com.mikepenz.aboutlibraries.Libs
import com.mikepenz.aboutlibraries.ui.compose.Libraries
import com.mikepenz.aboutlibraries.ui.compose.util.StableLibrary
import kotlinx.collections.immutable.toImmutableList
@Composable
@@ -58,10 +59,10 @@ fun LicensesContent() {
val state = rememberLazyListState()
val uriHandler = LocalUriHandler.current
Libraries(
libraries = remember(libs) { libs.libraries.toImmutableList() },
libraries = remember(libs) { libs.libraries.map { StableLibrary(it) }.toImmutableList() },
lazyListState = state,
onLibraryClick = {
it.website?.let(uriHandler::openUri)
it.library.website?.let(uriHandler::openUri)
},
contentPadding = WindowInsets.bottomNav.add(
WindowInsets.navigationBars.only(

View File

@@ -33,7 +33,6 @@ import ca.gosyer.jui.ui.base.chapter.ChapterDownloadState
import ca.gosyer.jui.ui.base.model.StableHolder
import ca.gosyer.jui.uicore.vm.ContextWrapper
import ca.gosyer.jui.uicore.vm.ViewModel
import cafe.adriel.voyager.core.model.coroutineScope
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
@@ -94,7 +93,7 @@ class MangaScreenViewModel
private val loadingManga = MutableStateFlow(true)
private val loadingChapters = MutableStateFlow(true)
val isLoading = combine(loadingManga, loadingChapters) { a, b -> a || b }
.stateIn(coroutineScope, SharingStarted.Eagerly, true)
.stateIn(scope, SharingStarted.Eagerly, true)
val categories = getCategories.asFlow(true)
.map { it.toImmutableList() }

View File

@@ -6,8 +6,8 @@
package ca.gosyer.jui.ui.reader
import ca.gosyer.jui.domain.chapter.interactor.GetChapterPage
import ca.gosyer.jui.domain.reader.service.ReaderPreferences
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.ui.base.image.BitmapDecoderFactory
import ca.gosyer.jui.ui.reader.loader.PagesState
import ca.gosyer.jui.ui.reader.loader.TachideskPageLoader
@@ -23,7 +23,7 @@ import org.lighthousegames.logging.logging
class ChapterLoader(
private val readerPreferences: ReaderPreferences,
private val getChapterPage: GetChapterPage,
private val http: Http,
private val chapterCache: DiskCache,
private val bitmapDecoderFactory: BitmapDecoderFactory,
) {
@@ -34,7 +34,7 @@ class ChapterLoader(
chapter.state = ReaderChapter.State.Loading
log.debug { "Loading pages for ${chapter.chapter.name}" }
val loader = TachideskPageLoader(chapter, readerPreferences, getChapterPage, chapterCache, bitmapDecoderFactory)
val loader = TachideskPageLoader(chapter, readerPreferences, http, chapterCache, bitmapDecoderFactory)
val pages = loader.getPages()

View File

@@ -22,6 +22,7 @@ import ca.gosyer.jui.domain.manga.model.MangaMeta
import ca.gosyer.jui.domain.reader.ReaderModeWatch
import ca.gosyer.jui.domain.reader.model.Direction
import ca.gosyer.jui.domain.reader.service.ReaderPreferences
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.ui.base.ChapterCache
import ca.gosyer.jui.ui.base.image.BitmapDecoderFactory
import ca.gosyer.jui.ui.base.model.StableHolder
@@ -82,6 +83,7 @@ class ReaderMenuViewModel
private val updateMangaMeta: UpdateMangaMeta,
private val updateChapterMeta: UpdateChapterMeta,
private val chapterCache: ChapterCache,
private val http: Http,
contextWrapper: ContextWrapper,
@Assisted private val params: Params,
) : ViewModel(contextWrapper) {
@@ -152,7 +154,7 @@ class ReaderMenuViewModel
private val loader = ChapterLoader(
readerPreferences = readerPreferences,
getChapterPage = getChapterPage,
http = http,
chapterCache = chapterCache,
bitmapDecoderFactory = BitmapDecoderFactory(contextWrapper),
)

View File

@@ -13,6 +13,7 @@ import ca.gosyer.jui.core.lang.PriorityChannel
import ca.gosyer.jui.core.lang.throwIfCancellation
import ca.gosyer.jui.domain.chapter.interactor.GetChapterPage
import ca.gosyer.jui.domain.reader.service.ReaderPreferences
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.ui.base.image.BitmapDecoderFactory
import ca.gosyer.jui.ui.base.model.StableHolder
import ca.gosyer.jui.ui.reader.model.ReaderChapter
@@ -23,10 +24,10 @@ import com.seiko.imageloader.asImageBitmap
import com.seiko.imageloader.cache.disk.DiskCache
import com.seiko.imageloader.component.decoder.DecodeResult
import com.seiko.imageloader.model.DataSource
import com.seiko.imageloader.model.ImageRequest
import com.seiko.imageloader.model.ImageResult
import com.seiko.imageloader.option.Options
import io.ktor.client.plugins.onDownload
import io.ktor.client.request.get
import io.ktor.client.statement.HttpResponse
import io.ktor.client.statement.bodyAsChannel
import kotlinx.coroutines.CoroutineScope
@@ -39,6 +40,7 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapLatest
@@ -53,7 +55,7 @@ import org.lighthousegames.logging.logging
class TachideskPageLoader(
val chapter: ReaderChapter,
readerPreferences: ReaderPreferences,
private val getChapterPage: GetChapterPage,
private val http: Http,
private val chapterCache: DiskCache,
private val bitmapDecoderFactory: BitmapDecoderFactory,
) : PageLoader() {
@@ -109,10 +111,14 @@ class TachideskPageLoader(
private suspend fun fetchImage(page: ReaderPage) {
log.debug { "Loading page ${page.index}" }
getChapterPage.asFlow(chapter.chapter, page.index) {
onDownload { bytesSentTotal, contentLength ->
page.progress.value = (bytesSentTotal.toFloat() / contentLength).coerceAtMost(1.0F)
flow {
val response = http.get("api/v1/manga/${chapter.chapter.mangaId}/chapter/${chapter.chapter.index}/page/${page.index}") {
onDownload { bytesSentTotal, contentLength ->
page.progress.value = (bytesSentTotal.toFloat() / contentLength).coerceAtMost(1.0F)
}
}
emit(response)
}
.onEach {
putImageInCache(it, page)
@@ -134,7 +140,7 @@ class TachideskPageLoader(
response: HttpResponse,
page: ReaderPage,
) {
val editor = chapterCache.edit(page.cacheKey)
val editor = chapterCache.openEditor(page.cacheKey)
?: throw Exception("Couldn't open cache")
try {
FileSystem.SYSTEM.write(editor.data) {
@@ -150,18 +156,17 @@ class TachideskPageLoader(
}
private suspend fun getImageFromCache(page: ReaderPage): ReaderPage.ImageDecodeState {
return chapterCache[page.cacheKey]?.use {
return chapterCache.openSnapshot(page.cacheKey)?.use {
it.source().use { source ->
val decoder = bitmapDecoderFactory.create(
ImageResult.Source(
ImageRequest(Any()),
ImageResult.OfSource(
source,
DataSource.Engine,
),
Options(),
)
if (decoder != null) {
runCatching { decoder.decode() as DecodeResult.Bitmap }
runCatching { decoder.decode() as DecodeResult.OfBitmap }
.mapCatching {
ReaderPage.ImageDecodeState.Success(
it.bitmap.asImageBitmap().also {

View File

@@ -86,6 +86,7 @@ class SettingsServerScreen : Screen {
expect class SettingsServerHostViewModel : ViewModel
@Composable
expect fun getServerHostItems(viewModel: @Composable () -> SettingsServerHostViewModel): LazyListScope.() -> Unit
class SettingsServerViewModel

View File

@@ -12,7 +12,6 @@ import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.gestures.forEachGesture
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.WindowInsets
@@ -228,11 +227,7 @@ private fun SourceWideScreenContent(
if (showingFilters && !isLatest) {
Box(
Modifier.fillMaxSize().pointerInput(loading) {
forEachGesture {
detectTapGestures {
setShowingFilters(false)
}
}
detectTapGestures(onTap = { setShowingFilters(false) })
},
)
}
@@ -287,7 +282,7 @@ private fun SourceThinScreenContent(
) {
val bottomSheetState = rememberModalBottomSheetState(
ModalBottomSheetValue.Hidden,
confirmStateChange = {
confirmValueChange = {
when (it) {
ModalBottomSheetValue.Hidden -> setShowingFilters(false)
ModalBottomSheetValue.Expanded,
@@ -364,11 +359,7 @@ private fun SourceThinScreenContent(
if (showingFilters && !isLatest) {
Box(
Modifier.fillMaxSize().pointerInput(loading) {
forEachGesture {
detectTapGestures {
setShowingFilters(false)
}
}
detectTapGestures(onTap = { setShowingFilters(false) })
},
)
}

View File

@@ -8,13 +8,35 @@ package ca.gosyer.jui.ui.base.components
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpOffset
@OptIn(ExperimentalFoundationApi::class)
actual typealias TooltipPlacement = androidx.compose.foundation.TooltipPlacement
actual typealias CursorPointImpl = androidx.compose.foundation.TooltipPlacement.CursorPoint
@OptIn(ExperimentalFoundationApi::class)
actual class CursorPointImpl actual constructor(
offset: DpOffset,
alignment: Alignment,
windowMargin: Dp,
) : TooltipPlacement by androidx.compose.foundation.TooltipPlacement.CursorPoint(
offset = offset,
alignment = alignment,
windowMargin = windowMargin
)
actual typealias ComponentRectImpl = androidx.compose.foundation.TooltipPlacement.ComponentRect
@OptIn(ExperimentalFoundationApi::class)
actual class ComponentRectImpl actual constructor(
anchor: Alignment,
alignment: Alignment,
offset: DpOffset,
) : TooltipPlacement by androidx.compose.foundation.TooltipPlacement.ComponentRect(
anchor = anchor,
alignment = alignment,
offset = offset
)
@OptIn(ExperimentalFoundationApi::class)
@Composable

View File

@@ -9,8 +9,10 @@ package ca.gosyer.jui.ui.base.image
import ca.gosyer.jui.core.io.userDataDir
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.uicore.vm.ContextWrapper
import com.seiko.imageloader.Bitmap
import com.seiko.imageloader.cache.disk.DiskCacheBuilder
import com.seiko.imageloader.cache.memory.MemoryCacheBuilder
import com.seiko.imageloader.cache.memory.MemoryKey
import com.seiko.imageloader.component.ComponentRegistryBuilder
import com.seiko.imageloader.component.setupDefaultComponents
import com.seiko.imageloader.option.OptionsBuilder
@@ -33,5 +35,5 @@ actual fun DiskCacheBuilder.configure(
maxSizeBytes(1024 * 1024 * 150) // 150 MB
}
actual fun MemoryCacheBuilder.configure(contextWrapper: ContextWrapper) {
actual fun MemoryCacheBuilder<MemoryKey, Bitmap>.configure(contextWrapper: ContextWrapper) {
}

View File

@@ -8,8 +8,10 @@ package ca.gosyer.jui.ui.base.image
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.uicore.vm.ContextWrapper
import com.seiko.imageloader.Bitmap
import com.seiko.imageloader.cache.disk.DiskCacheBuilder
import com.seiko.imageloader.cache.memory.MemoryCacheBuilder
import com.seiko.imageloader.cache.memory.MemoryKey
import com.seiko.imageloader.cache.memory.maxSizePercent
import com.seiko.imageloader.component.ComponentRegistryBuilder
import com.seiko.imageloader.component.setupDefaultComponents
@@ -47,6 +49,6 @@ private fun getCacheDir(): String {
)!!.path.orEmpty()
}
actual fun MemoryCacheBuilder.configure(contextWrapper: ContextWrapper) {
actual fun MemoryCacheBuilder<MemoryKey, Bitmap>.configure(contextWrapper: ContextWrapper) {
maxSizePercent(0.25)
}