mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-14 19:57:04 +05:30
gradle: upgrade dependencies and sync LazyPagingItems from upstream
This commit is contained in:
parent
eeddc3a3e6
commit
b5c2dc9aaf
5 changed files with 124 additions and 80 deletions
|
@ -2,7 +2,7 @@ import org.gradle.api.tasks.compile.JavaCompile
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
val kotlinVersion = "1.5.31"
|
val kotlinVersion = "1.6.10"
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@ -16,13 +16,12 @@ buildscript {
|
||||||
classpath("com.android.tools:r8:3.2.28-dev")
|
classpath("com.android.tools:r8:3.2.28-dev")
|
||||||
classpath(kotlin("gradle-plugin", version = kotlinVersion))
|
classpath(kotlin("gradle-plugin", version = kotlinVersion))
|
||||||
classpath(kotlin("serialization", version = kotlinVersion))
|
classpath(kotlin("serialization", version = kotlinVersion))
|
||||||
classpath("com.android.tools.build:gradle:7.0.3")
|
classpath("com.android.tools.build:gradle:7.0.4")
|
||||||
classpath("com.diffplug.spotless:spotless-plugin-gradle:6.0.0")
|
classpath("com.google.dagger:hilt-android-gradle-plugin:2.40.5")
|
||||||
classpath("com.google.dagger:hilt-android-gradle-plugin:2.40.2")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins { id("com.diffplug.spotless") version "6.0.0" }
|
plugins { id("com.diffplug.spotless") version "6.0.4" }
|
||||||
|
|
||||||
group = "dev.msfjarvis.claw"
|
group = "dev.msfjarvis.claw"
|
||||||
|
|
||||||
|
|
|
@ -18,11 +18,9 @@ import androidx.compose.foundation.lazy.LazyItemScope
|
||||||
import androidx.compose.foundation.lazy.LazyListScope
|
import androidx.compose.foundation.lazy.LazyListScope
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
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.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.paging.CombinedLoadStates
|
import androidx.paging.CombinedLoadStates
|
||||||
import androidx.paging.DifferCallback
|
import androidx.paging.DifferCallback
|
||||||
|
@ -30,7 +28,6 @@ import androidx.paging.ItemSnapshotList
|
||||||
import androidx.paging.LoadState
|
import androidx.paging.LoadState
|
||||||
import androidx.paging.LoadStates
|
import androidx.paging.LoadStates
|
||||||
import androidx.paging.NullPaddedList
|
import androidx.paging.NullPaddedList
|
||||||
import androidx.paging.PagingConfig
|
|
||||||
import androidx.paging.PagingData
|
import androidx.paging.PagingData
|
||||||
import androidx.paging.PagingDataDiffer
|
import androidx.paging.PagingDataDiffer
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -38,46 +35,28 @@ import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.collect
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
|
||||||
@Composable
|
/**
|
||||||
fun <T : Any> Flow<PagingData<T>>.collectAsLazyPagingItems(): LazyPagingItems<T> {
|
* The class responsible for accessing the data from a [Flow] of [PagingData]. In order to obtain an
|
||||||
val lazyPagingItems = remember(this) { LazyPagingItems(this) }
|
* instance of [LazyPagingItems] use the [collectAsLazyPagingItems] extension method of [Flow] with
|
||||||
|
* [PagingData]. This instance can be used by the [items] and [itemsIndexed] methods inside
|
||||||
LaunchedEffect(lazyPagingItems) { lazyPagingItems.collectPagingData() }
|
* [LazyListScope] to display data received from the [Flow] of [PagingData].
|
||||||
LaunchedEffect(lazyPagingItems) { lazyPagingItems.collectLoadState() }
|
*
|
||||||
|
* @param T the type of value used by [PagingData].
|
||||||
return lazyPagingItems
|
*/
|
||||||
}
|
public class LazyPagingItems<T : Any>
|
||||||
|
|
||||||
fun <T : Any> LazyListScope.items(
|
|
||||||
items: LazyPagingItems<T>,
|
|
||||||
key: ((item: T) -> Any)? = null,
|
|
||||||
itemContent: @Composable LazyItemScope.(value: T?) -> Unit
|
|
||||||
) {
|
|
||||||
items(
|
|
||||||
count = items.itemCount,
|
|
||||||
key =
|
|
||||||
if (key == null) null
|
|
||||||
else
|
|
||||||
{ index ->
|
|
||||||
val item = items.peek(index)
|
|
||||||
if (item == null) {
|
|
||||||
PagingPlaceholderKey(index)
|
|
||||||
} else {
|
|
||||||
key(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
) { index -> itemContent(items[index]) }
|
|
||||||
}
|
|
||||||
|
|
||||||
class LazyPagingItems<T : Any>
|
|
||||||
internal constructor(
|
internal constructor(
|
||||||
/** the [Flow] object which contains a stream of [PagingData] elements. */
|
/** the [Flow] object which contains a stream of [PagingData] elements. */
|
||||||
private val flow: Flow<PagingData<T>>
|
private val flow: Flow<PagingData<T>>
|
||||||
) {
|
) {
|
||||||
private val mainDispatcher = Dispatchers.Main
|
private val mainDispatcher = Dispatchers.Main
|
||||||
|
|
||||||
/** Contains the latest items list snapshot collected from the [flow]. */
|
/**
|
||||||
private var itemSnapshotList by mutableStateOf(ItemSnapshotList<T>(0, 0, emptyList()))
|
* Contains the immutable [ItemSnapshotList] of currently presented items, including any
|
||||||
|
* placeholders if they are enabled. Note that similarly to [peek] accessing the items in a list
|
||||||
|
* will not trigger any loads. Use [get] to achieve such behavior.
|
||||||
|
*/
|
||||||
|
var itemSnapshotList by mutableStateOf(ItemSnapshotList<T>(0, 0, emptyList()))
|
||||||
|
private set
|
||||||
|
|
||||||
/** The number of items which can be accessed. */
|
/** The number of items which can be accessed. */
|
||||||
val itemCount: Int
|
val itemCount: Int
|
||||||
|
@ -109,7 +88,6 @@ internal constructor(
|
||||||
override suspend fun presentNewList(
|
override suspend fun presentNewList(
|
||||||
previousList: NullPaddedList<T>,
|
previousList: NullPaddedList<T>,
|
||||||
newList: NullPaddedList<T>,
|
newList: NullPaddedList<T>,
|
||||||
newCombinedLoadStates: CombinedLoadStates,
|
|
||||||
lastAccessedIndex: Int,
|
lastAccessedIndex: Int,
|
||||||
onListPresentable: () -> Unit
|
onListPresentable: () -> Unit
|
||||||
): Int? {
|
): Int? {
|
||||||
|
@ -134,23 +112,6 @@ internal constructor(
|
||||||
return itemSnapshotList[index]
|
return itemSnapshotList[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the state containing the item specified at [index] and notifies Paging of the item
|
|
||||||
* accessed in order to trigger any loads necessary to fulfill [PagingConfig.prefetchDistance].
|
|
||||||
*
|
|
||||||
* @param index the index of the item which should be returned.
|
|
||||||
* @return the state containing the item specified at [index] or null if the item is a placeholder
|
|
||||||
* or [index] is not within the correct bounds.
|
|
||||||
*/
|
|
||||||
@Composable
|
|
||||||
@Deprecated(
|
|
||||||
"Use get() instead. It will return you the value not wrapped into a State",
|
|
||||||
ReplaceWith("this[index]")
|
|
||||||
)
|
|
||||||
fun getAsState(index: Int): State<T?> {
|
|
||||||
return rememberUpdatedState(get(index))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the presented item at the specified position, without notifying Paging of the item
|
* Returns the presented item at the specified position, without notifying Paging of the item
|
||||||
* access that would normally trigger page loads.
|
* access that would normally trigger page loads.
|
||||||
|
@ -162,14 +123,6 @@ internal constructor(
|
||||||
return itemSnapshotList[index]
|
return itemSnapshotList[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a new [ItemSnapshotList] representing the currently presented items, including any
|
|
||||||
* placeholders if they are enabled.
|
|
||||||
*/
|
|
||||||
fun snapshot(): ItemSnapshotList<T> {
|
|
||||||
return itemSnapshotList
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retry any failed load requests that would result in a [LoadState.Error] update to this
|
* Retry any failed load requests that would result in a [LoadState.Error] update to this
|
||||||
* [LazyPagingItems].
|
* [LazyPagingItems].
|
||||||
|
@ -228,4 +181,100 @@ private val IncompleteLoadState = LoadState.NotLoading(false)
|
||||||
private val InitialLoadStates =
|
private val InitialLoadStates =
|
||||||
LoadStates(IncompleteLoadState, IncompleteLoadState, IncompleteLoadState)
|
LoadStates(IncompleteLoadState, IncompleteLoadState, IncompleteLoadState)
|
||||||
|
|
||||||
data class PagingPlaceholderKey(private val index: Int)
|
/**
|
||||||
|
* Collects values from this [Flow] of [PagingData] and represents them inside a [LazyPagingItems]
|
||||||
|
* instance. The [LazyPagingItems] instance can be used by the [items] and [itemsIndexed] methods
|
||||||
|
* from [LazyListScope] in order to display the data obtained from a [Flow] of [PagingData].
|
||||||
|
*
|
||||||
|
* @sample androidx.paging.compose.samples.PagingBackendSample
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
public fun <T : Any> Flow<PagingData<T>>.collectAsLazyPagingItems(): LazyPagingItems<T> {
|
||||||
|
val lazyPagingItems = remember(this) { LazyPagingItems(this) }
|
||||||
|
|
||||||
|
LaunchedEffect(lazyPagingItems) { lazyPagingItems.collectPagingData() }
|
||||||
|
LaunchedEffect(lazyPagingItems) { lazyPagingItems.collectLoadState() }
|
||||||
|
|
||||||
|
return lazyPagingItems
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the [LazyPagingItems] and their content to the scope. The range from 0 (inclusive) to
|
||||||
|
* [LazyPagingItems.itemCount] (exclusive) always represents the full range of presentable items,
|
||||||
|
* because every event from [PagingDataDiffer] will trigger a recomposition.
|
||||||
|
*
|
||||||
|
* @sample androidx.paging.compose.samples.ItemsDemo
|
||||||
|
*
|
||||||
|
* @param items the items received from a [Flow] of [PagingData].
|
||||||
|
* @param key a factory of stable and unique keys representing the item. Using the same key for
|
||||||
|
* multiple items in the list is not allowed. Type of the key should be saveable via Bundle on
|
||||||
|
* Android. If null is passed the position in the list will represent the key. When you specify the
|
||||||
|
* key the scroll position will be maintained based on the key, which means if you add/remove items
|
||||||
|
* before the current visible item the item with the given key will be kept as the first visible
|
||||||
|
* one.
|
||||||
|
* @param itemContent the content displayed by a single item. In case the item is `null`, the
|
||||||
|
* [itemContent] method should handle the logic of displaying a placeholder instead of the main
|
||||||
|
* content displayed by an item which is not `null`.
|
||||||
|
*/
|
||||||
|
public fun <T : Any> LazyListScope.items(
|
||||||
|
items: LazyPagingItems<T>,
|
||||||
|
key: ((item: T) -> Any)? = null,
|
||||||
|
itemContent: @Composable LazyItemScope.(value: T?) -> Unit
|
||||||
|
) {
|
||||||
|
items(
|
||||||
|
count = items.itemCount,
|
||||||
|
key =
|
||||||
|
if (key == null) null
|
||||||
|
else
|
||||||
|
{ index ->
|
||||||
|
val item = items.peek(index)
|
||||||
|
if (item == null) {
|
||||||
|
PagingPlaceholderKey(index)
|
||||||
|
} else {
|
||||||
|
key(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) { index -> itemContent(items[index]) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the [LazyPagingItems] and their content to the scope where the content of an item is aware
|
||||||
|
* of its local index. The range from 0 (inclusive) to [LazyPagingItems.itemCount] (exclusive)
|
||||||
|
* always represents the full range of presentable items, because every event from
|
||||||
|
* [PagingDataDiffer] will trigger a recomposition.
|
||||||
|
*
|
||||||
|
* @sample androidx.paging.compose.samples.ItemsIndexedDemo
|
||||||
|
*
|
||||||
|
* @param items the items received from a [Flow] of [PagingData].
|
||||||
|
* @param key a factory of stable and unique keys representing the item. Using the same key for
|
||||||
|
* multiple items in the list is not allowed. Type of the key should be saveable via Bundle on
|
||||||
|
* Android. If null is passed the position in the list will represent the key. When you specify the
|
||||||
|
* key the scroll position will be maintained based on the key, which means if you add/remove items
|
||||||
|
* before the current visible item the item with the given key will be kept as the first visible
|
||||||
|
* one.
|
||||||
|
* @param itemContent the content displayed by a single item. In case the item is `null`, the
|
||||||
|
* [itemContent] method should handle the logic of displaying a placeholder instead of the main
|
||||||
|
* content displayed by an item which is not `null`.
|
||||||
|
*/
|
||||||
|
public fun <T : Any> LazyListScope.itemsIndexed(
|
||||||
|
items: LazyPagingItems<T>,
|
||||||
|
key: ((index: Int, item: T) -> Any)? = null,
|
||||||
|
itemContent: @Composable LazyItemScope.(index: Int, value: T?) -> Unit
|
||||||
|
) {
|
||||||
|
items(
|
||||||
|
count = items.itemCount,
|
||||||
|
key =
|
||||||
|
if (key == null) null
|
||||||
|
else
|
||||||
|
{ index ->
|
||||||
|
val item = items.peek(index)
|
||||||
|
if (item == null) {
|
||||||
|
PagingPlaceholderKey(index)
|
||||||
|
} else {
|
||||||
|
key(index, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) { index -> itemContent(index, items[index]) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private data class PagingPlaceholderKey(private val index: Int)
|
||||||
|
|
|
@ -3,7 +3,6 @@ android.useAndroidX=true
|
||||||
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
||||||
kotlin.native.enableDependencyPropagation=false
|
kotlin.native.enableDependencyPropagation=false
|
||||||
kotlin.mpp.stability.nowarn=true
|
kotlin.mpp.stability.nowarn=true
|
||||||
kotlin.mpp.hierarchicalStructureSupport=true
|
|
||||||
# Add opens for KAPT
|
# Add opens for KAPT
|
||||||
# https://youtrack.jetbrains.com/issue/KT-45545#focus=Comments-27-4862682.0-0
|
# https://youtrack.jetbrains.com/issue/KT-45545#focus=Comments-27-4862682.0-0
|
||||||
org.gradle.jvmargs=-Dfile.encoding=UTF-8 \
|
org.gradle.jvmargs=-Dfile.encoding=UTF-8 \
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
[versions]
|
[versions]
|
||||||
accompanist = "0.21.3-beta"
|
accompanist = "0.20.3"
|
||||||
aurora = "1.0.0"
|
aurora = "1.0.1"
|
||||||
coroutines = "1.5.2"
|
coroutines = "1.6.0-RC2"
|
||||||
hilt = "2.40.2"
|
hilt = "2.40.5"
|
||||||
richtext = "0.9.0"
|
richtext = "0.9.0"
|
||||||
serialization = "1.3.1"
|
serialization = "1.3.1"
|
||||||
sqldelight = "1.5.3"
|
sqldelight = "1.5.3"
|
||||||
|
@ -32,7 +32,7 @@ aurora-component = { module = "org.pushing-pixels:aurora-component", version.ref
|
||||||
aurora-theming = { module = "org.pushing-pixels:aurora-theming", version.ref = "aurora" }
|
aurora-theming = { module = "org.pushing-pixels:aurora-theming", version.ref = "aurora" }
|
||||||
aurora-window = { module = "org.pushing-pixels:aurora-window", version.ref = "aurora" }
|
aurora-window = { module = "org.pushing-pixels:aurora-window", version.ref = "aurora" }
|
||||||
|
|
||||||
coil-compose = "io.coil-kt:coil-compose:2.0.0-alpha03"
|
coil-compose = "io.coil-kt:coil-compose:2.0.0-alpha05"
|
||||||
kamel-image = "com.alialbaali.kamel:kamel-image:0.3.0"
|
kamel-image = "com.alialbaali.kamel:kamel-image:0.3.0"
|
||||||
|
|
||||||
compose-richtext-ui = { module = "com.halilibo.compose-richtext:richtext-ui", version.ref = "richtext" }
|
compose-richtext-ui = { module = "com.halilibo.compose-richtext:richtext-ui", version.ref = "richtext" }
|
||||||
|
@ -45,7 +45,7 @@ dagger-hilt-core = { module = "com.google.dagger:hilt-core", version.ref = "hilt
|
||||||
|
|
||||||
copydown = "io.github.furstenheim:copy_down:1.0"
|
copydown = "io.github.furstenheim:copy_down:1.0"
|
||||||
|
|
||||||
multiplatform-paging = "io.github.kuuuurt:multiplatform-paging:0.4.5"
|
multiplatform-paging = "io.github.kuuuurt:multiplatform-paging:0.4.6"
|
||||||
|
|
||||||
retrofit-lib = "com.squareup.retrofit2:retrofit:2.9.0"
|
retrofit-lib = "com.squareup.retrofit2:retrofit:2.9.0"
|
||||||
retrofit-kotlinxSerializationConverter = "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0"
|
retrofit-kotlinxSerializationConverter = "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0"
|
||||||
|
|
|
@ -5,7 +5,7 @@ pluginManagement {
|
||||||
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
|
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
|
||||||
google()
|
google()
|
||||||
}
|
}
|
||||||
plugins { id("org.jetbrains.compose") version "1.0.0" apply false }
|
plugins { id("org.jetbrains.compose") version "1.0.1-rc2" apply false }
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencyResolutionManagement {
|
dependencyResolutionManagement {
|
||||||
|
@ -13,9 +13,6 @@ dependencyResolutionManagement {
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
|
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
|
||||||
maven("https://oss.sonatype.org/content/repositories/snapshots") {
|
|
||||||
content { includeGroup("org.pushing-pixels") }
|
|
||||||
}
|
|
||||||
google()
|
google()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue