From b5c2dc9aaffb23b8c841e7a8c0dc29a52c5b43ba Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Wed, 15 Dec 2021 00:16:32 +0530 Subject: [PATCH] gradle: upgrade dependencies and sync LazyPagingItems from upstream --- build.gradle.kts | 9 +- desktop/src/jvmMain/kotlin/LazyPagingItems.kt | 177 +++++++++++------- gradle.properties | 1 - gradle/libs.versions.toml | 12 +- settings.gradle.kts | 5 +- 5 files changed, 124 insertions(+), 80 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 170cb409..eed16d30 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,7 +2,7 @@ import org.gradle.api.tasks.compile.JavaCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile buildscript { - val kotlinVersion = "1.5.31" + val kotlinVersion = "1.6.10" repositories { google() mavenCentral() @@ -16,13 +16,12 @@ buildscript { classpath("com.android.tools:r8:3.2.28-dev") classpath(kotlin("gradle-plugin", version = kotlinVersion)) classpath(kotlin("serialization", version = kotlinVersion)) - classpath("com.android.tools.build:gradle:7.0.3") - classpath("com.diffplug.spotless:spotless-plugin-gradle:6.0.0") - classpath("com.google.dagger:hilt-android-gradle-plugin:2.40.2") + classpath("com.android.tools.build:gradle:7.0.4") + classpath("com.google.dagger:hilt-android-gradle-plugin:2.40.5") } } -plugins { id("com.diffplug.spotless") version "6.0.0" } +plugins { id("com.diffplug.spotless") version "6.0.4" } group = "dev.msfjarvis.claw" diff --git a/desktop/src/jvmMain/kotlin/LazyPagingItems.kt b/desktop/src/jvmMain/kotlin/LazyPagingItems.kt index ceaf5d89..ca7d35fc 100644 --- a/desktop/src/jvmMain/kotlin/LazyPagingItems.kt +++ b/desktop/src/jvmMain/kotlin/LazyPagingItems.kt @@ -18,11 +18,9 @@ import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.State import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue import androidx.paging.CombinedLoadStates import androidx.paging.DifferCallback @@ -30,7 +28,6 @@ import androidx.paging.ItemSnapshotList import androidx.paging.LoadState import androidx.paging.LoadStates import androidx.paging.NullPaddedList -import androidx.paging.PagingConfig import androidx.paging.PagingData import androidx.paging.PagingDataDiffer import kotlinx.coroutines.Dispatchers @@ -38,46 +35,28 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collectLatest -@Composable -fun Flow>.collectAsLazyPagingItems(): LazyPagingItems { - val lazyPagingItems = remember(this) { LazyPagingItems(this) } - - LaunchedEffect(lazyPagingItems) { lazyPagingItems.collectPagingData() } - LaunchedEffect(lazyPagingItems) { lazyPagingItems.collectLoadState() } - - return lazyPagingItems -} - -fun LazyListScope.items( - items: LazyPagingItems, - 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 +/** + * The class responsible for accessing the data from a [Flow] of [PagingData]. In order to obtain an + * instance of [LazyPagingItems] use the [collectAsLazyPagingItems] extension method of [Flow] with + * [PagingData]. This instance can be used by the [items] and [itemsIndexed] methods inside + * [LazyListScope] to display data received from the [Flow] of [PagingData]. + * + * @param T the type of value used by [PagingData]. + */ +public class LazyPagingItems internal constructor( /** the [Flow] object which contains a stream of [PagingData] elements. */ private val flow: Flow> ) { private val mainDispatcher = Dispatchers.Main - /** Contains the latest items list snapshot collected from the [flow]. */ - private var itemSnapshotList by mutableStateOf(ItemSnapshotList(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(0, 0, emptyList())) + private set /** The number of items which can be accessed. */ val itemCount: Int @@ -109,7 +88,6 @@ internal constructor( override suspend fun presentNewList( previousList: NullPaddedList, newList: NullPaddedList, - newCombinedLoadStates: CombinedLoadStates, lastAccessedIndex: Int, onListPresentable: () -> Unit ): Int? { @@ -134,23 +112,6 @@ internal constructor( 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 { - return rememberUpdatedState(get(index)) - } - /** * Returns the presented item at the specified position, without notifying Paging of the item * access that would normally trigger page loads. @@ -162,14 +123,6 @@ internal constructor( return itemSnapshotList[index] } - /** - * Returns a new [ItemSnapshotList] representing the currently presented items, including any - * placeholders if they are enabled. - */ - fun snapshot(): ItemSnapshotList { - return itemSnapshotList - } - /** * Retry any failed load requests that would result in a [LoadState.Error] update to this * [LazyPagingItems]. @@ -228,4 +181,100 @@ private val IncompleteLoadState = LoadState.NotLoading(false) private val InitialLoadStates = 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 Flow>.collectAsLazyPagingItems(): LazyPagingItems { + 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 LazyListScope.items( + items: LazyPagingItems, + 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 LazyListScope.itemsIndexed( + items: LazyPagingItems, + 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) diff --git a/gradle.properties b/gradle.properties index e44cb380..368e282c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,6 @@ android.useAndroidX=true kotlin.mpp.enableGranularSourceSetsMetadata=true kotlin.native.enableDependencyPropagation=false kotlin.mpp.stability.nowarn=true -kotlin.mpp.hierarchicalStructureSupport=true # Add opens for KAPT # https://youtrack.jetbrains.com/issue/KT-45545#focus=Comments-27-4862682.0-0 org.gradle.jvmargs=-Dfile.encoding=UTF-8 \ diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4ce87ed1..ccbe7af0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,8 +1,8 @@ [versions] -accompanist = "0.21.3-beta" -aurora = "1.0.0" -coroutines = "1.5.2" -hilt = "2.40.2" +accompanist = "0.20.3" +aurora = "1.0.1" +coroutines = "1.6.0-RC2" +hilt = "2.40.5" richtext = "0.9.0" serialization = "1.3.1" 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-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" 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" -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-kotlinxSerializationConverter = "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0" diff --git a/settings.gradle.kts b/settings.gradle.kts index f219a0ab..a6d87079 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,7 +5,7 @@ pluginManagement { maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") 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 { @@ -13,9 +13,6 @@ dependencyResolutionManagement { repositories { mavenCentral() maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") - maven("https://oss.sonatype.org/content/repositories/snapshots") { - content { includeGroup("org.pushing-pixels") } - } google() } }