Skip to content

Commit

Permalink
Wire in UserMarketContributor
Browse files Browse the repository at this point in the history
  • Loading branch information
matt-ramotar committed Apr 23, 2024
1 parent 8998792 commit 0598289
Show file tree
Hide file tree
Showing 52 changed files with 63,181 additions and 234 deletions.
1 change: 1 addition & 0 deletions experimental/market/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ kotlin {
dependencies {
implementation(libs.kotlin.stdlib)
implementation(libs.kotlinx.coroutines.core)
api(project(":store"))
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.mobilenativefoundation.market

interface MarketContributor<K : Any> {
fun contribute(key: K)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.mobilenativefoundation.market.impl

import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import org.mobilenativefoundation.market.Market
import org.mobilenativefoundation.market.MarketContributor
import org.mobilenativefoundation.store.store5.Store
import org.mobilenativefoundation.store.store5.impl.extensions.fresh

class RealMarketContributor<K : Any, O : Any, A : Market.Action, D : Market.Dispatcher<A>>(
coroutineDispatcher: CoroutineDispatcher,
private val store: Store<K, O>,
private val marketDispatcher: D,
private val marketActionFactory: MarketActionFactory<O, A>
): MarketContributor<K> {
private val coroutineScope = CoroutineScope(coroutineDispatcher)

override fun contribute(key: K) {
coroutineScope.launch {
val storeOutput = store.fresh(key)
val marketAction = marketActionFactory.create(storeOutput)
marketDispatcher.dispatch(marketAction)
}
}
}

fun interface MarketActionFactory<O : Any, A : Market.Action> {
fun create(storeOutput: O): A
}
1 change: 1 addition & 0 deletions experimental/market/warehouse/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ kotlin {
dependencies {
implementation(libs.kotlin.stdlib)
implementation(libs.kotlinx.coroutines.core)
api(project(":experimental:market"))
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,46 @@
package org.mobilenativefoundation.market.warehouse

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.*
import org.mobilenativefoundation.market.Market


interface Warehouse<S : Warehouse.State, A : Warehouse.Action> {

interface Warehouse<S : Warehouse.State, A : Warehouse.Action, AA: Warehouse.Action.Async> {
val state: StateFlow<S>
fun dispatch(action: A)
fun dispatch(worker: Worker<S, A>)
fun dispatch(action: AA)
fun <D : Any> subscribe(selector: Selector<S, D>): Flow<D>

interface Action {
interface Async: Action
interface Async : Action
}

interface State
fun interface Worker<S : State, A : Action> {
fun work(getState: () -> S, dispatch: (action: A) -> Unit)
}

fun interface Selector<S : State, D : Any> {
fun select(state: S): D
}
}

class RealWarehouse<S : Warehouse.State, A : Warehouse.Action, MS : Market.State, M : Market<MS>>(
coroutineDispatcher: CoroutineDispatcher,
private val market: M,
private val extractor: (MS) -> S,
private val actionHandler: (A, MS) -> Unit
) : Warehouse<S, A> {

fun interface Middleware<A: Action> {
fun apply(action: A, next: (action: A) -> Unit)
private val coroutineScope = CoroutineScope(coroutineDispatcher)

override val state: StateFlow<S> = market.state.map {
extractor(it)
}.stateIn(coroutineScope, SharingStarted.Eagerly, extractor(market.state.value))


override fun <D : Any> subscribe(selector: Warehouse.Selector<S, D>): Flow<D> =
state.map { selector.select(it) }

override fun dispatch(action: A) {
actionHandler(action, market.state.value)
}
}
}
5 changes: 5 additions & 0 deletions experimental/sample/octonaut/android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ dependencies {
implementation(project(":experimental:sample:octonaut:xplat:foundation:di:api"))
implementation(project(":experimental:sample:octonaut:xplat:foundation:networking:impl"))
implementation(project(":experimental:sample:octonaut:xplat:common:market"))
implementation(project(":experimental:sample:octonaut:xplat:domain:user:impl"))
implementation(project(":experimental:sample:octonaut:xplat:feat:homeTab:impl"))
implementation(project(":experimental:sample:octonaut:xplat:feat:notificationsTab:impl"))
implementation(project(":experimental:sample:octonaut:xplat:feat:exploreTab:impl"))
implementation(project(":experimental:sample:octonaut:xplat:feat:profileTab:impl"))
}

ksp {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,31 @@ package org.mobilenativefoundation.sample.octonaut.android.app
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Notifications
import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.RectangleShape
import com.slack.circuit.foundation.Circuit
import com.slack.circuit.foundation.CircuitCompositionLocals
import com.slack.circuit.foundation.CircuitContent
import com.slack.circuit.runtime.screen.Screen
import me.tatarka.inject.annotations.Inject
import org.mobilenativefoundation.sample.octonaut.android.app.di.CoreComponent
import org.mobilenativefoundation.sample.octonaut.android.app.di.create
import org.mobilenativefoundation.sample.octonaut.android.app.theme.OctonautTheme
import org.mobilenativefoundation.sample.octonaut.xplat.foundation.networking.api.GetUserQuery


@Inject
Expand All @@ -39,28 +49,42 @@ class MainActivity : ComponentActivity() {

setContent {

OctonautTheme {
Box(
modifier = Modifier.fillMaxSize()
) {
Column(modifier = Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background)) {
CircuitCompositionLocals(circuit) {

Text(
"Octonaut",
style = MaterialTheme.typography.headlineMedium,
color = MaterialTheme.colorScheme.onBackground
)
val homeTab = coreComponent.screenFactory.homeTab()
val activeScreen = remember { mutableStateOf<Screen>(homeTab) }

Button(onClick = {}, shape = RectangleShape) {
Text("Octonaut")
OctonautTheme {
Box(
modifier = Modifier.fillMaxSize()
) {

LaunchedEffect(Unit) {
try {

coreComponent.userMarketContributor.contribute(GetUserQuery("matt-ramotar"))

} catch (error: Throwable) {
println("Error: ${error.stackTraceToString()}")
}
}

Button(
onClick = {},
shape = RectangleShape,
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.surfaceContainer)
) {
Text("Octonaut", color = MaterialTheme.colorScheme.onSurface)

Scaffold(
bottomBar = {
BottomAppBar(containerColor = MaterialTheme.colorScheme.surfaceContainer) {
Icon(Icons.Default.Home, "")
Icon(Icons.Default.Notifications, "")
Icon(Icons.Default.Search, "")
Icon(Icons.Default.Person, "")
}
}
) { innerPadding ->

CircuitContent(
screen = activeScreen.value,
modifier = Modifier.padding(innerPadding)
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ import com.slack.circuit.runtime.Navigator
import com.slack.circuit.runtime.presenter.Presenter
import com.slack.circuit.runtime.screen.Screen
import me.tatarka.inject.annotations.Inject
import org.mobilenativefoundation.sample.octonaut.xplat.feat.homeTab.api.HomeTab
import org.mobilenativefoundation.sample.octonaut.xplat.feat.homeTab.impl.HomeTabPresenter
import org.mobilenativefoundation.sample.octonaut.xplat.foundation.di.api.UserScope

@Inject
@UserScope
class OctonautPresenterFactory : Presenter.Factory {
class OctonautPresenterFactory(
private val homeTabPresenter: HomeTabPresenter
) : Presenter.Factory {
override fun create(screen: Screen, navigator: Navigator, context: CircuitContext): Presenter<*>? {
return when (screen) {
is HomeTab -> homeTabPresenter
else -> null
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package org.mobilenativefoundation.sample.octonaut.android.app.circuit

import me.tatarka.inject.annotations.Inject
import org.mobilenativefoundation.sample.octonaut.xplat.feat.homeTab.api.HomeTab
import org.mobilenativefoundation.sample.octonaut.xplat.foundation.di.api.UserScope

@Inject
@UserScope
class OctonautScreenFactory : ScreenFactory
class OctonautScreenFactory(
private val homeTab: HomeTab
) : ScreenFactory {
override fun homeTab(): HomeTab = homeTab
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@ import com.slack.circuit.runtime.CircuitContext
import com.slack.circuit.runtime.screen.Screen
import com.slack.circuit.runtime.ui.Ui
import me.tatarka.inject.annotations.Inject
import org.mobilenativefoundation.sample.octonaut.xplat.feat.homeTab.api.HomeTab
import org.mobilenativefoundation.sample.octonaut.xplat.feat.homeTab.impl.HomeTabUi
import org.mobilenativefoundation.sample.octonaut.xplat.foundation.di.api.UserScope

@Inject
@UserScope
class OctonautUiFactory : Ui.Factory {
class OctonautUiFactory(
private val homeTabUi: HomeTabUi
) : Ui.Factory {
override fun create(screen: Screen, context: CircuitContext): Ui<*>? {
return when (screen) {
is HomeTab -> homeTabUi
else -> null
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.mobilenativefoundation.sample.octonaut.android.app.circuit

interface ScreenFactory {
import org.mobilenativefoundation.sample.octonaut.xplat.feat.homeTab.api.HomeTab

interface ScreenFactory {
fun homeTab(): HomeTab
}

Loading

0 comments on commit 0598289

Please sign in to comment.