mirror of
https://github.com/Suwayomi/TachideskJUI.git
synced 2025-12-19 11:02:31 +01:00
Update some dependencies
This commit is contained in:
@@ -140,3 +140,7 @@ kotlin {
|
|||||||
languageVersion.set(JavaLanguageVersion.of(Config.androidJvmTarget.target))
|
languageVersion.set(JavaLanguageVersion.of(Config.androidJvmTarget.target))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configurations.all {
|
||||||
|
exclude(group = "org.jetbrains.runtime", module = "jbr-api")
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import Config.migrationCode
|
|||||||
import Config.serverCode
|
import Config.serverCode
|
||||||
import Config.tachideskVersion
|
import Config.tachideskVersion
|
||||||
import com.codingfeline.buildkonfig.compiler.FieldSpec.Type
|
import com.codingfeline.buildkonfig.compiler.FieldSpec.Type
|
||||||
|
import com.google.devtools.ksp.gradle.KspAATask
|
||||||
import org.jetbrains.compose.ComposeExtension
|
import org.jetbrains.compose.ComposeExtension
|
||||||
import org.jetbrains.compose.ComposePlugin
|
import org.jetbrains.compose.ComposePlugin
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||||
@@ -77,7 +78,7 @@ subprojects {
|
|||||||
}
|
}
|
||||||
plugins.withType<com.android.build.gradle.BasePlugin> {
|
plugins.withType<com.android.build.gradle.BasePlugin> {
|
||||||
configure<com.android.build.gradle.BaseExtension> {
|
configure<com.android.build.gradle.BaseExtension> {
|
||||||
compileSdkVersion(34)
|
compileSdkVersion(36)
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdk = 21
|
minSdk = 21
|
||||||
targetSdk = 31
|
targetSdk = 31
|
||||||
@@ -103,6 +104,9 @@ subprojects {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
plugins.withType<com.codingfeline.buildkonfig.gradle.BuildKonfigPlugin> {
|
plugins.withType<com.codingfeline.buildkonfig.gradle.BuildKonfigPlugin> {
|
||||||
|
tasks.withType<KspAATask> {
|
||||||
|
mustRunAfter("generateBuildKonfig")
|
||||||
|
}
|
||||||
configure<com.codingfeline.buildkonfig.gradle.BuildKonfigExtension> {
|
configure<com.codingfeline.buildkonfig.gradle.BuildKonfigExtension> {
|
||||||
defaultConfigs {
|
defaultConfigs {
|
||||||
buildConfigField(Type.STRING, "NAME", rootProject.name, const = true)
|
buildConfigField(Type.STRING, "NAME", rootProject.name, const = true)
|
||||||
|
|||||||
@@ -4,11 +4,10 @@ object Config {
|
|||||||
const val migrationCode = 5
|
const val migrationCode = 5
|
||||||
|
|
||||||
// Suwayomi-Server version
|
// Suwayomi-Server version
|
||||||
const val tachideskVersion = "v1.0.0"
|
const val tachideskVersion = "v2.1.1959"
|
||||||
// Match this to the Suwayomi-Server commit count
|
// Match this to the Suwayomi-Server commit count
|
||||||
const val serverCode = 1498
|
const val serverCode = 1959
|
||||||
const val preview = false
|
const val preview = true
|
||||||
const val previewCommit = "54df9d634a1e83143a6cacf6206b6504721b6ca8"
|
|
||||||
|
|
||||||
val desktopJvmTarget = JvmTarget.JVM_17
|
val desktopJvmTarget = JvmTarget.JVM_17
|
||||||
val androidJvmTarget = JvmTarget.JVM_17
|
val androidJvmTarget = JvmTarget.JVM_17
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import Config.preview
|
import Config.preview
|
||||||
import Config.previewCommit
|
|
||||||
import Config.serverCode
|
import Config.serverCode
|
||||||
import Config.tachideskVersion
|
import Config.tachideskVersion
|
||||||
import de.undercouch.gradle.tasks.download.Download
|
import de.undercouch.gradle.tasks.download.Download
|
||||||
@@ -66,7 +65,7 @@ private fun isSigning(properties: Map<String, Any?>) = properties["compose.deskt
|
|||||||
|
|
||||||
private const val tmpPath = "tmp"
|
private const val tmpPath = "tmp"
|
||||||
private val apiUrl = if (preview) {
|
private val apiUrl = if (preview) {
|
||||||
"https://api.github.com/repos/Suwayomi/Suwayomi-Server-preview/releases/tags/$previewCommit"
|
"https://api.github.com/repos/Suwayomi/Suwayomi-Server-preview/releases/tags/$tachideskVersion"
|
||||||
} else {
|
} else {
|
||||||
"https://api.github.com/repos/Suwayomi/Suwayomi-Server/releases/tags/$tachideskVersion"
|
"https://api.github.com/repos/Suwayomi/Suwayomi-Server/releases/tags/$tachideskVersion"
|
||||||
}
|
}
|
||||||
@@ -140,8 +139,8 @@ fun TaskContainerScope.registerTachideskTasks(project: Project) {
|
|||||||
.forEach {
|
.forEach {
|
||||||
val tmpFile = macJarFolder / it.name
|
val tmpFile = macJarFolder / it.name
|
||||||
it.copyTo(tmpFile)
|
it.copyTo(tmpFile)
|
||||||
exec {
|
Runtime.getRuntime().exec(
|
||||||
commandLine(
|
arrayOf(
|
||||||
"/usr/bin/codesign",
|
"/usr/bin/codesign",
|
||||||
"-vvvv",
|
"-vvvv",
|
||||||
"--timestamp",
|
"--timestamp",
|
||||||
@@ -151,7 +150,7 @@ fun TaskContainerScope.registerTachideskTasks(project: Project) {
|
|||||||
"--sign", "Developer ID Application: ${getSigningIdentity()}",
|
"--sign", "Developer ID Application: ${getSigningIdentity()}",
|
||||||
tmpFile.absolutePathString(),
|
tmpFile.absolutePathString(),
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
|
|
||||||
tmpFile.copyTo(it, overwrite = true)
|
tmpFile.copyTo(it, overwrite = true)
|
||||||
tmpFile.deleteExisting()
|
tmpFile.deleteExisting()
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import com.google.devtools.ksp.gradle.KspAATask
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id(libs.plugins.kotlin.multiplatform.get().pluginId)
|
id(libs.plugins.kotlin.multiplatform.get().pluginId)
|
||||||
id(libs.plugins.kotlin.serialization.get().pluginId)
|
id(libs.plugins.kotlin.serialization.get().pluginId)
|
||||||
@@ -141,3 +143,7 @@ apollo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.withType<KspAATask> {
|
||||||
|
mustRunAfter("generateServiceApolloSources")
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import Config.migrationCode
|
import Config.migrationCode
|
||||||
import Config.serverCode
|
import Config.serverCode
|
||||||
import Config.tachideskVersion
|
import Config.tachideskVersion
|
||||||
|
import com.google.devtools.ksp.gradle.KspAATask
|
||||||
import org.gradle.jvm.tasks.Jar
|
import org.gradle.jvm.tasks.Jar
|
||||||
import org.jetbrains.compose.compose
|
import org.jetbrains.compose.compose
|
||||||
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
|
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
|
||||||
@@ -231,3 +232,11 @@ buildConfig {
|
|||||||
buildConfigField("String", "TACHIDESK_SP_VERSION", tachideskVersion.wrap())
|
buildConfigField("String", "TACHIDESK_SP_VERSION", tachideskVersion.wrap())
|
||||||
buildConfigField("int", "SERVER_CODE", serverCode.toString())
|
buildConfigField("int", "SERVER_CODE", serverCode.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.withType<KspAATask> {
|
||||||
|
mustRunAfter(
|
||||||
|
"generateBuildConfig",
|
||||||
|
"generateResourceAccessorsForMain",
|
||||||
|
"generateComposeResClass"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,37 +1,37 @@
|
|||||||
[versions]
|
[versions]
|
||||||
# Kotlin
|
# Kotlin
|
||||||
kotlin = "2.0.20"
|
kotlin = "2.2.20"
|
||||||
coroutines = "1.9.0"
|
coroutines = "1.9.0"
|
||||||
|
|
||||||
# Serialization
|
# Serialization
|
||||||
json = "1.7.3"
|
json = "1.9.0"
|
||||||
|
|
||||||
# Compose
|
# Compose
|
||||||
composeGradle = "1.6.11"
|
composeGradle = "1.9.0"
|
||||||
|
|
||||||
# Compose Libraries
|
# Compose Libraries
|
||||||
parcelize = "0.9.0"
|
parcelize = "0.9.0"
|
||||||
voyager = "1.0.0"
|
voyager = "1.1.0-beta03"
|
||||||
accompanist = "0.30.1"
|
accompanist = "0.30.1"
|
||||||
googleAccompanist = "0.30.1"
|
googleAccompanist = "0.30.1"
|
||||||
imageloader = "1.8.1"
|
imageloader = "1.8.1"
|
||||||
materialDialogs = "0.9.5"
|
materialDialogs = "0.9.5"
|
||||||
|
|
||||||
# Android
|
# Android
|
||||||
androidGradle = "8.6.1"
|
androidGradle = "8.12.0"
|
||||||
core = "1.13.1"
|
core = "1.13.1"
|
||||||
appCompat = "1.7.0"
|
appCompat = "1.7.0"
|
||||||
activityCompose = "1.9.2"
|
activityCompose = "1.9.2"
|
||||||
work = "2.9.1"
|
work = "2.9.1"
|
||||||
|
|
||||||
# Android Lifecycle
|
# Android Lifecycle
|
||||||
lifecycle = "2.8.6"
|
lifecycle = "2.9.4"
|
||||||
|
|
||||||
# Swing
|
# Swing
|
||||||
darklaf = "3.0.2"
|
darklaf = "3.0.2"
|
||||||
|
|
||||||
# Ksp
|
# Ksp
|
||||||
ksp = "2.0.20-1.0.25"
|
ksp = "2.2.20-2.0.3"
|
||||||
|
|
||||||
# Dependency Injection
|
# Dependency Injection
|
||||||
kotlinInject = "0.7.2"
|
kotlinInject = "0.7.2"
|
||||||
@@ -54,7 +54,7 @@ appDirs = "1.2.0"
|
|||||||
multiplatformSettings = "1.2.0"
|
multiplatformSettings = "1.2.0"
|
||||||
|
|
||||||
# Utility
|
# Utility
|
||||||
desugarJdkLibs = "2.1.2"
|
desugarJdkLibs = "2.1.5"
|
||||||
aboutLibraries = "11.2.3"
|
aboutLibraries = "11.2.3"
|
||||||
dateTime = "0.6.1"
|
dateTime = "0.6.1"
|
||||||
immutableCollections = "0.3.8"
|
immutableCollections = "0.3.8"
|
||||||
@@ -62,17 +62,17 @@ korge = "5.4.0"
|
|||||||
gradleDownloadTask = "5.6.0"
|
gradleDownloadTask = "5.6.0"
|
||||||
|
|
||||||
# Localization
|
# Localization
|
||||||
moko = "0.24.3"
|
moko = "0.25.1"
|
||||||
|
|
||||||
# BuildConfigs
|
# BuildConfigs
|
||||||
buildconfig = "5.5.0"
|
buildconfig = "5.6.8"
|
||||||
buildkonfig = "0.15.2"
|
buildkonfig = "0.17.1"
|
||||||
|
|
||||||
# Linter
|
# Linter
|
||||||
kotlinter = "4.4.1"
|
kotlinter = "4.4.1"
|
||||||
|
|
||||||
# Version updates
|
# Version updates
|
||||||
versions = "0.51.0"
|
versions = "0.53.0"
|
||||||
|
|
||||||
# Optimizer
|
# Optimizer
|
||||||
proguard = "7.5.0"
|
proguard = "7.5.0"
|
||||||
|
|||||||
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.9-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import com.google.devtools.ksp.gradle.KspAATask
|
||||||
import org.jetbrains.compose.compose
|
import org.jetbrains.compose.compose
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
@@ -157,3 +158,12 @@ buildkonfig {
|
|||||||
android {
|
android {
|
||||||
namespace = "ca.gosyer.jui.presentation"
|
namespace = "ca.gosyer.jui.presentation"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.withType<KspAATask> {
|
||||||
|
mustRunAfter(
|
||||||
|
"generateResourceAccessorsForDesktopMain",
|
||||||
|
"generateResourceAccessorsForJvmMain",
|
||||||
|
"generateResourceAccessorsForCommonMain",
|
||||||
|
"generateComposeResClass"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ import androidx.compose.material.icons.automirrored.rounded.ArrowBack
|
|||||||
import androidx.compose.material.icons.automirrored.rounded.Sort
|
import androidx.compose.material.icons.automirrored.rounded.Sort
|
||||||
import androidx.compose.material.icons.rounded.Close
|
import androidx.compose.material.icons.rounded.Close
|
||||||
import androidx.compose.material.icons.rounded.Search
|
import androidx.compose.material.icons.rounded.Search
|
||||||
import androidx.compose.material.ripple.rememberRipple
|
import androidx.compose.material.ripple
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
@@ -398,7 +398,7 @@ fun TextActionIcon(
|
|||||||
enabled = enabled,
|
enabled = enabled,
|
||||||
role = Role.Button,
|
role = Role.Button,
|
||||||
interactionSource = interactionSource,
|
interactionSource = interactionSource,
|
||||||
indication = rememberRipple(bounded = false, radius = 32.dp),
|
indication = ripple(bounded = false, radius = 32.dp),
|
||||||
)
|
)
|
||||||
.size(56.dp),
|
.size(56.dp),
|
||||||
verticalArrangement = Arrangement.SpaceAround,
|
verticalArrangement = Arrangement.SpaceAround,
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ fun DownloadsScreenContent(
|
|||||||
) {
|
) {
|
||||||
items(downloadQueue, key = { "${it.mangaId}-${it.chapterIndex}" }) {
|
items(downloadQueue, key = { "${it.mangaId}-${it.chapterIndex}" }) {
|
||||||
DownloadsItem(
|
DownloadsItem(
|
||||||
modifier = Modifier.animateItemPlacement(),
|
modifier = Modifier.animateItem(),
|
||||||
item = it,
|
item = it,
|
||||||
onClickCover = { onMangaClick(it.mangaId) },
|
onClickCover = { onMangaClick(it.mangaId) },
|
||||||
onClickCancel = stopDownload,
|
onClickCancel = stopDownload,
|
||||||
|
|||||||
@@ -145,13 +145,13 @@ fun ExtensionsScreenContent(
|
|||||||
is ExtensionUI.Header -> Text(
|
is ExtensionUI.Header -> Text(
|
||||||
it.header,
|
it.header,
|
||||||
style = MaterialTheme.typography.h6,
|
style = MaterialTheme.typography.h6,
|
||||||
modifier = Modifier.animateItemPlacement()
|
modifier = Modifier.animateItem()
|
||||||
.padding(16.dp, 16.dp, 16.dp, 4.dp),
|
.padding(16.dp, 16.dp, 16.dp, 4.dp),
|
||||||
)
|
)
|
||||||
|
|
||||||
is ExtensionUI.ExtensionItem -> Column {
|
is ExtensionUI.ExtensionItem -> Column {
|
||||||
ExtensionItem(
|
ExtensionItem(
|
||||||
Modifier.animateItemPlacement(),
|
Modifier.animateItem(),
|
||||||
it,
|
it,
|
||||||
onInstallClicked = installExtension,
|
onInstallClicked = installExtension,
|
||||||
onUpdateClicked = updateExtension,
|
onUpdateClicked = updateExtension,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ package ca.gosyer.jui.uicore.components
|
|||||||
|
|
||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.material.ripple.rememberRipple
|
import androidx.compose.material.ripple
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.composed
|
import androidx.compose.ui.composed
|
||||||
@@ -20,7 +20,7 @@ actual fun Modifier.buttonModifier(
|
|||||||
composed {
|
composed {
|
||||||
combinedClickable(
|
combinedClickable(
|
||||||
interactionSource = remember { MutableInteractionSource() },
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
indication = rememberRipple(bounded = false),
|
indication = ripple(bounded = false),
|
||||||
onLongClick = onHintClick,
|
onLongClick = onHintClick,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import androidx.compose.foundation.layout.BoxScope
|
|||||||
import androidx.compose.foundation.layout.ColumnScope
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material.DropdownMenu
|
import androidx.compose.material.DropdownMenu
|
||||||
import androidx.compose.material.ripple.rememberRipple
|
import androidx.compose.material.ripple
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@@ -46,7 +46,7 @@ fun DropdownIconButton(
|
|||||||
.clickable(
|
.clickable(
|
||||||
remember { MutableInteractionSource() },
|
remember { MutableInteractionSource() },
|
||||||
role = Role.Button,
|
role = Role.Button,
|
||||||
indication = rememberRipple(bounded = false, radius = 24.dp),
|
indication = ripple(bounded = false, radius = 24.dp),
|
||||||
) {
|
) {
|
||||||
showMenu = true
|
showMenu = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,10 @@
|
|||||||
|
|
||||||
package ca.gosyer.jui.uicore.pager
|
package ca.gosyer.jui.uicore.pager
|
||||||
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
||||||
import androidx.compose.foundation.gestures.FlingBehavior
|
import androidx.compose.foundation.gestures.FlingBehavior
|
||||||
import androidx.compose.foundation.gestures.Orientation
|
import androidx.compose.foundation.gestures.Orientation
|
||||||
import androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider
|
import androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider
|
||||||
import androidx.compose.foundation.gestures.snapping.SnapPositionInLayout
|
import androidx.compose.foundation.gestures.snapping.SnapPosition
|
||||||
import androidx.compose.foundation.gestures.snapping.SnapPositionInLayout.Companion.CenterToCenter
|
|
||||||
import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
|
import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
@@ -26,9 +24,11 @@ import androidx.compose.foundation.lazy.LazyRow
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberUpdatedState
|
||||||
import androidx.compose.runtime.saveable.Saver
|
import androidx.compose.runtime.saveable.Saver
|
||||||
import androidx.compose.runtime.saveable.listSaver
|
import androidx.compose.runtime.saveable.listSaver
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
@@ -36,10 +36,14 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.runtime.snapshotFlow
|
import androidx.compose.runtime.snapshotFlow
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
|
import androidx.compose.ui.unit.Density
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.util.fastForEach
|
import androidx.compose.ui.util.fastForEach
|
||||||
import androidx.compose.ui.util.fastMaxBy
|
import androidx.compose.ui.util.fastMaxBy
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.absoluteValue
|
||||||
import kotlin.math.sign
|
import kotlin.math.sign
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -234,15 +238,31 @@ class PagerState(
|
|||||||
// https://android.googlesource.com/platform/frameworks/support/+/refs/changes/78/2160778/35/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyListSnapLayoutInfoProvider.kt
|
// https://android.googlesource.com/platform/frameworks/support/+/refs/changes/78/2160778/35/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyListSnapLayoutInfoProvider.kt
|
||||||
private fun lazyListSnapLayoutInfoProvider(
|
private fun lazyListSnapLayoutInfoProvider(
|
||||||
lazyListState: LazyListState,
|
lazyListState: LazyListState,
|
||||||
positionInLayout: SnapPositionInLayout = CenterToCenter,
|
snapPosition: SnapPosition = SnapPosition.Center,
|
||||||
) = object : SnapLayoutInfoProvider {
|
density: State<Density>,
|
||||||
|
): SnapLayoutInfoProvider =
|
||||||
|
object : SnapLayoutInfoProvider {
|
||||||
|
|
||||||
private val layoutInfo: LazyListLayoutInfo
|
private val layoutInfo: LazyListLayoutInfo
|
||||||
get() = lazyListState.layoutInfo
|
get() = lazyListState.layoutInfo
|
||||||
|
|
||||||
// Single page snapping is the default
|
private val averageItemSize: Int
|
||||||
override fun calculateApproachOffset(initialVelocity: Float): Float = 0f
|
get() {
|
||||||
|
val layoutInfo = layoutInfo
|
||||||
|
return if (layoutInfo.visibleItemsInfo.isEmpty()) {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
val numberOfItems = layoutInfo.visibleItemsInfo.size
|
||||||
|
layoutInfo.visibleItemsInfo.sumOf { it.size } / numberOfItems
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun calculateSnappingOffset(currentVelocity: Float): Float {
|
override fun calculateApproachOffset(velocity: Float, decayOffset: Float): Float {
|
||||||
|
return (decayOffset.absoluteValue - averageItemSize).coerceAtLeast(0.0f) *
|
||||||
|
decayOffset.sign
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun calculateSnapOffset(velocity: Float): Float {
|
||||||
var lowerBoundOffset = Float.NEGATIVE_INFINITY
|
var lowerBoundOffset = Float.NEGATIVE_INFINITY
|
||||||
var upperBoundOffset = Float.POSITIVE_INFINITY
|
var upperBoundOffset = Float.POSITIVE_INFINITY
|
||||||
|
|
||||||
@@ -255,7 +275,8 @@ private fun lazyListSnapLayoutInfoProvider(
|
|||||||
itemSize = item.size,
|
itemSize = item.size,
|
||||||
itemOffset = item.offset,
|
itemOffset = item.offset,
|
||||||
itemIndex = item.index,
|
itemIndex = item.index,
|
||||||
snapPositionInLayout = positionInLayout,
|
snapPosition = snapPosition,
|
||||||
|
itemCount = layoutInfo.totalItemsCount,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Find item that is closest to the center
|
// Find item that is closest to the center
|
||||||
@@ -270,51 +291,65 @@ private fun lazyListSnapLayoutInfoProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return calculateFinalOffset(
|
return calculateFinalOffset(
|
||||||
currentVelocity,
|
with(density.value) { calculateFinalSnappingItem(velocity) },
|
||||||
lowerBoundOffset,
|
lowerBoundOffset,
|
||||||
upperBoundOffset,
|
upperBoundOffset,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
|
||||||
private fun calculateDistanceToDesiredSnapPosition(
|
|
||||||
mainAxisViewPortSize: Int,
|
|
||||||
beforeContentPadding: Int,
|
|
||||||
afterContentPadding: Int,
|
|
||||||
itemSize: Int,
|
|
||||||
itemOffset: Int,
|
|
||||||
itemIndex: Int,
|
|
||||||
snapPositionInLayout: SnapPositionInLayout,
|
|
||||||
): Float {
|
|
||||||
val containerSize = mainAxisViewPortSize - beforeContentPadding - afterContentPadding
|
|
||||||
|
|
||||||
val desiredDistance = with(snapPositionInLayout) {
|
|
||||||
position(containerSize, itemSize, beforeContentPadding, afterContentPadding, itemIndex)
|
|
||||||
}.toFloat()
|
|
||||||
|
|
||||||
return itemOffset - desiredDistance
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun calculateFinalOffset(
|
@Composable
|
||||||
velocity: Float,
|
private fun rememberLazyListSnapFlingBehavior(lazyListState: LazyListState): FlingBehavior {
|
||||||
|
// return rememberSnapFlingBehavior(lazyListState)
|
||||||
|
val density = rememberUpdatedState(LocalDensity.current)
|
||||||
|
val snappingLayout = remember(lazyListState) { lazyListSnapLayoutInfoProvider(lazyListState, density = density) }
|
||||||
|
return rememberSnapFlingBehavior(snappingLayout)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val LazyListLayoutInfo.singleAxisViewportSize: Int
|
||||||
|
get() = if (orientation == Orientation.Vertical) viewportSize.height else viewportSize.width
|
||||||
|
|
||||||
|
@kotlin.jvm.JvmInline
|
||||||
|
internal value class FinalSnappingItem
|
||||||
|
internal constructor(@Suppress("unused") private val value: Int) {
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
val ClosestItem: FinalSnappingItem = FinalSnappingItem(0)
|
||||||
|
|
||||||
|
val NextItem: FinalSnappingItem = FinalSnappingItem(1)
|
||||||
|
|
||||||
|
val PreviousItem: FinalSnappingItem = FinalSnappingItem(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun Density.calculateFinalSnappingItem(velocity: Float): FinalSnappingItem {
|
||||||
|
return if (velocity.absoluteValue < 400.dp.toPx()) {
|
||||||
|
FinalSnappingItem.ClosestItem
|
||||||
|
} else {
|
||||||
|
if (velocity > 0) FinalSnappingItem.NextItem else FinalSnappingItem.PreviousItem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun calculateFinalOffset(
|
||||||
|
snappingOffset: FinalSnappingItem,
|
||||||
lowerBound: Float,
|
lowerBound: Float,
|
||||||
upperBound: Float,
|
upperBound: Float,
|
||||||
): Float {
|
): Float {
|
||||||
fun Float.isValidDistance(): Boolean = this != Float.POSITIVE_INFINITY && this != Float.NEGATIVE_INFINITY
|
fun Float.isValidDistance(): Boolean {
|
||||||
|
return this != Float.POSITIVE_INFINITY && this != Float.NEGATIVE_INFINITY
|
||||||
|
}
|
||||||
|
|
||||||
val finalDistance = when (sign(velocity)) {
|
val finalDistance =
|
||||||
0f -> {
|
when (snappingOffset) {
|
||||||
|
FinalSnappingItem.ClosestItem -> {
|
||||||
if (abs(upperBound) <= abs(lowerBound)) {
|
if (abs(upperBound) <= abs(lowerBound)) {
|
||||||
upperBound
|
upperBound
|
||||||
} else {
|
} else {
|
||||||
lowerBound
|
lowerBound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FinalSnappingItem.NextItem -> upperBound
|
||||||
1f -> upperBound
|
FinalSnappingItem.PreviousItem -> lowerBound
|
||||||
|
|
||||||
-1f -> lowerBound
|
|
||||||
|
|
||||||
else -> 0f
|
else -> 0f
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,14 +358,30 @@ private fun lazyListSnapLayoutInfoProvider(
|
|||||||
} else {
|
} else {
|
||||||
0f
|
0f
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun calculateDistanceToDesiredSnapPosition(
|
||||||
|
mainAxisViewPortSize: Int,
|
||||||
|
beforeContentPadding: Int,
|
||||||
|
afterContentPadding: Int,
|
||||||
|
itemSize: Int,
|
||||||
|
itemOffset: Int,
|
||||||
|
itemIndex: Int,
|
||||||
|
snapPosition: SnapPosition,
|
||||||
|
itemCount: Int,
|
||||||
|
): Float {
|
||||||
|
val desiredDistance =
|
||||||
|
with(snapPosition) {
|
||||||
|
position(
|
||||||
|
mainAxisViewPortSize,
|
||||||
|
itemSize,
|
||||||
|
beforeContentPadding,
|
||||||
|
afterContentPadding,
|
||||||
|
itemIndex,
|
||||||
|
itemCount,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
.toFloat()
|
||||||
|
|
||||||
@Composable
|
return itemOffset - desiredDistance
|
||||||
private fun rememberLazyListSnapFlingBehavior(lazyListState: LazyListState): FlingBehavior {
|
|
||||||
val snappingLayout = remember(lazyListState) { lazyListSnapLayoutInfoProvider(lazyListState) }
|
|
||||||
return rememberSnapFlingBehavior(snappingLayout)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val LazyListLayoutInfo.singleAxisViewportSize: Int
|
|
||||||
get() = if (orientation == Orientation.Vertical) viewportSize.height else viewportSize.width
|
|
||||||
|
|||||||
Reference in New Issue
Block a user