Skip to content

Commit

Permalink
Second stab
Browse files Browse the repository at this point in the history
  • Loading branch information
matt-ramotar committed Oct 18, 2023
1 parent ebde3bb commit 7492b1f
Show file tree
Hide file tree
Showing 26 changed files with 1,043 additions and 446 deletions.
3 changes: 3 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ ktlintGradle = "10.2.1"
jacocoGradlePlugin = "0.8.7"
mavenPublishPlugin = "0.22.0"
moleculeGradlePlugin = "1.2.1"
pagingCompose = "3.3.0-alpha02"
pagingRuntime = "3.2.1"
spotlessPluginGradle = "6.4.1"
junit = "4.13.2"
Expand All @@ -25,6 +26,7 @@ truth = "1.1.3"

[libraries]
android-gradle-plugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" }
androidx-paging-compose = { module = "androidx.paging:paging-compose", version.ref = "pagingCompose" }
androidx-paging-runtime = { module = "androidx.paging:paging-runtime", version.ref = "pagingRuntime" }
kotlin-gradle-plugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "baseKotlin" }
kotlin-serialization-plugin = { group = "org.jetbrains.kotlin", name = "kotlin-serialization", version.ref = "baseKotlin" }
Expand All @@ -51,3 +53,4 @@ kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-cor
junit = { group = "junit", name = "junit", version.ref = "junit" }
google-truth = { group = "com.google.truth", name = "truth", version.ref = "truth" }
touchlab-kermit = { group = "co.touchlab", name = "kermit", version.ref = "kermit" }
turbine = "app.cash.turbine:turbine:0.12.3"
15 changes: 13 additions & 2 deletions paging/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ plugins {
}

kotlin {
android()
jvm()
androidTarget()

sourceSets {
val commonMain by getting {
Expand All @@ -25,6 +24,7 @@ kotlin {
implementation(libs.molecule.runtime)
implementation(compose.ui)
implementation(compose.foundation)
implementation(compose.material)


}
Expand All @@ -33,6 +33,17 @@ kotlin {
val androidMain by getting {
dependencies {
implementation(libs.androidx.paging.runtime)
implementation(libs.androidx.paging.compose)
}
}
@OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
implementation(libs.turbine)
implementation(libs.kotlinx.coroutines.test)
implementation(compose.uiTestJUnit4)
implementation(compose.ui)
}
}
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.mobilenativefoundation.store.paging5


/**
* An interface that defines items that can be uniquely identified.
* Every item that implements the [Identifiable] interface must have a means of identification.
* This is useful in scenarios when data can be represented as singles or collections.
*/

interface Identifiable<out Id : Any> {

/**
* Represents a single identifiable item.
*/
interface Single<Id : Any> : Identifiable<Id> {
val id: Id
}

/**
* Represents a collection of identifiable items.
*/
interface Collection<Id : Any, S : Single<Id>> : Identifiable<Id> {
val items: List<S>

/**
* Returns a new collection with the updated items.
*/
fun copyWith(items: List<S>): Collection<Id, S>

/**
* Inserts items to the existing collection and returns the updated collection.
*/
fun insertItems(type: StoreKey.LoadType, items: List<S>): Collection<Id, S>
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package org.mobilenativefoundation.store.paging5

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import org.mobilenativefoundation.store.store5.ExperimentalStoreApi
import org.mobilenativefoundation.store.store5.MutableStore
import org.mobilenativefoundation.store.store5.Store


/**
* Initializes and returns a [StateFlow] that reflects the state of the Store, updating by a flow of provided keys.
* @param scope A [CoroutineScope].
* @param keys A flow of keys that dictate how the Store should be updated.
* @param updateStoreState A lambda that defines how the Store's state should be updated based on the current state and a key.
* @return A read-only [StateFlow] reflecting the state of the Store.
*/
private fun <Id : Any, Key : StoreKey<Id>, Output : Identifiable<Id>> initStoreStateFlow(
scope: CoroutineScope,
keys: Flow<Key>,
updateStoreState: suspend (currentState: StoreState<Id, Output>, key: Key) -> StoreState<Id, Output>
): StateFlow<StoreState<Id, Output>> {
val stateFlow = MutableStateFlow<StoreState<Id, Output>>(StoreState.Loading)

scope.launch {
keys.collect { key ->
println("KEY = $key")
println("CURRENT STATE = ${stateFlow.value}")
val updatedState = updateStoreState(stateFlow.value, key)
stateFlow.emit(updatedState)
}
}

return stateFlow.asStateFlow()
}

/**
* Initializes and returns a [StateFlow] that reflects the state of the [Store], updating by a flow of provided keys.
* @see [initStoreStateFlow].
*/
fun <Id : Any, Key : StoreKey<Id>, Output : Identifiable<Id>> Store<Key, Output>.initStoreStateFlow(
scope: CoroutineScope,
keys: Flow<Key>,
): StateFlow<StoreState<Id, Output>> {
return initStoreStateFlow(scope, keys) { currentState, key ->
this.updateStoreState(currentState, key)
}
}

/**
* Initializes and returns a [StateFlow] that reflects the state of the [Store], updating by a flow of provided keys.
* @see [initStoreStateFlow].
*/
@OptIn(ExperimentalStoreApi::class)
fun <Id : Any, Key : StoreKey<Id>, Output : Identifiable<Id>> MutableStore<Key, Output>.initStoreStateFlow(
scope: CoroutineScope,
keys: Flow<Key>,
): StateFlow<StoreState<Id, Output>> {
return initStoreStateFlow(scope, keys) { currentState, key ->
this.updateStoreState(currentState, key)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.mobilenativefoundation.store.paging5

interface KeyProvider<Id : Any, Single : Identifiable.Single<Id>> {
fun from(key: StoreKey.Collection<Id>, value: Single): StoreKey.Single<Id>
fun from(key: StoreKey.Single<Id>, value: Single): StoreKey.Collection<Id>
}
Loading

0 comments on commit 7492b1f

Please sign in to comment.