Skip to content

Commit

Permalink
Normalize Market
Browse files Browse the repository at this point in the history
  • Loading branch information
matt-ramotar committed Apr 25, 2024
1 parent 2abcee2 commit 7ab3b74
Show file tree
Hide file tree
Showing 44 changed files with 1,023 additions and 64 deletions.
3 changes: 3 additions & 0 deletions experimental/sample/octonaut/android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,16 @@ 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:foundation:webview"))
implementation(project(":experimental:sample:octonaut:xplat:common:market"))
implementation(project(":experimental:sample:octonaut:xplat:domain:user:impl"))
implementation(project(":experimental:sample:octonaut:xplat:domain:feed:impl"))
implementation(project(":experimental:sample:octonaut:xplat:domain:notifications: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"))
implementation(libs.compose.webview.multiplatform)
}

ksp {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,27 @@ 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.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
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.*
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import coil3.annotation.ExperimentalCoilApi
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 com.multiplatform.webview.web.WebView
import com.multiplatform.webview.web.WebViewNavigator
import com.multiplatform.webview.web.rememberWebViewState
import com.slack.circuit.backstack.rememberSaveableBackStack
import com.slack.circuit.foundation.*
import me.tatarka.inject.annotations.Inject
import org.mobilenativefoundation.sample.octonaut.android.app.di.CoreComponent
import org.mobilenativefoundation.sample.octonaut.android.app.di.create
Expand All @@ -31,7 +35,7 @@ import org.mobilenativefoundation.sample.octonaut.xplat.foundation.networking.ap
import kotlin.time.Duration.Companion.minutes


@OptIn(ExperimentalCoilApi::class)
@OptIn(ExperimentalCoilApi::class, ExperimentalMaterial3Api::class)
@Inject
class MainActivity : ComponentActivity() {

Expand All @@ -51,27 +55,33 @@ class MainActivity : ComponentActivity() {

setContent {

val homeTab = remember { coreComponent.screenFactory.homeTab() }
val exploreTab = remember { coreComponent.screenFactory.exploreTab() }
val notificationsTab = remember { coreComponent.screenFactory.notificationsTab() }

val webViewUrlState = coreComponent.webViewUrlStateHolder.url.collectAsState()

val webViewState = webViewUrlState.value?.let { rememberWebViewState(it) }


val backStack = rememberSaveableBackStack(root = homeTab)
val navigator = rememberCircuitNavigator(backStack)

CircuitCompositionLocals(circuit) {

val homeTab = remember { coreComponent.screenFactory.homeTab() }
val exploreTab = remember { coreComponent.screenFactory.exploreTab() }
val notificationsTab = remember { coreComponent.screenFactory.notificationsTab()}
val activeScreen = remember { mutableStateOf<Screen>(homeTab) }

OctonautTheme {
Box(
modifier = Modifier.fillMaxSize()
) {

LaunchedEffect(Unit) {
try {

coreComponent.userSupplier.supply(GetUserQuery("matt-ramotar"))

coreComponent.currentUserSupplier.supply(GetUserQuery("matt-ramotar"))
coreComponent.scheduledNotificationsSupplier.supply(
ListNotificationsQueryParams(),
5.minutes
)
coreComponent.feedSupplier.supply(Unit)

} catch (error: Throwable) {
println("Error: ${error.stackTraceToString()}")
Expand All @@ -84,23 +94,23 @@ class MainActivity : ComponentActivity() {
BottomAppBar(containerColor = MaterialTheme.colorScheme.surfaceContainer) {
IconButton(
onClick = {
activeScreen.value = homeTab
navigator.goTo(homeTab)
}
) {
Icon(Icons.Default.Home, "")
}

IconButton(
onClick = {
activeScreen.value = notificationsTab
navigator.goTo(notificationsTab)
}
) {
Icon(Icons.Default.Notifications, "")
}

IconButton(
onClick = {
activeScreen.value = exploreTab
navigator.goTo(exploreTab)
}
) {
Icon(Icons.Default.Search, "")
Expand All @@ -115,12 +125,49 @@ class MainActivity : ComponentActivity() {
}
) { innerPadding ->

CircuitContent(
screen = activeScreen.value,
NavigableCircuitContent(
navigator,
backStack,
modifier = Modifier.padding(innerPadding)
.background(MaterialTheme.colorScheme.background)
.background(MaterialTheme.colorScheme.background),
decoration = NavigatorDefaults.EmptyDecoration
)
}

webViewState?.let {
val webViewNavigator = WebViewNavigator(rememberCoroutineScope())

Box(modifier = Modifier.fillMaxSize()) {
Column {
TopAppBar(
title = {
Text(webViewState.pageTitle?.let { "${it}..." } ?: "",
style = MaterialTheme.typography.labelLarge,
maxLines = 1)
},
navigationIcon = {
IconButton(onClick = {
if (webViewNavigator.canGoBack) {
webViewNavigator.navigateBack()
} else {
coreComponent.webViewUrlStateHolder.url.value = null
}

}) {
Icon(Icons.AutoMirrored.Default.ArrowBack, "")
}
}
)
WebView(
it,
modifier = Modifier.fillMaxSize(),
captureBackPresses = true,
navigator = webViewNavigator
)
}

}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.slack.circuit.runtime.ui.Ui
import io.ktor.client.*
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import me.tatarka.inject.annotations.Component
import me.tatarka.inject.annotations.Provides
import org.mobilenativefoundation.market.impl.MarketActionFactory
Expand All @@ -19,9 +20,13 @@ import org.mobilenativefoundation.sample.octonaut.android.app.market.MutableOcto
import org.mobilenativefoundation.sample.octonaut.android.app.market.RealMutableOctonautMarket
import org.mobilenativefoundation.sample.octonaut.android.app.market.RealOctonautMarketDispatcher
import org.mobilenativefoundation.sample.octonaut.xplat.common.market.*
import org.mobilenativefoundation.sample.octonaut.xplat.domain.feed.api.FeedStore
import org.mobilenativefoundation.sample.octonaut.xplat.domain.feed.api.FeedSupplier
import org.mobilenativefoundation.sample.octonaut.xplat.domain.feed.impl.FeedStoreFactory
import org.mobilenativefoundation.sample.octonaut.xplat.domain.notifications.api.NotificationsStore
import org.mobilenativefoundation.sample.octonaut.xplat.domain.notifications.api.NotificationsSupplier
import org.mobilenativefoundation.sample.octonaut.xplat.domain.notifications.impl.NotificationsStoreFactory
import org.mobilenativefoundation.sample.octonaut.xplat.domain.user.api.CurrentUserSupplier
import org.mobilenativefoundation.sample.octonaut.xplat.domain.user.api.UserStore
import org.mobilenativefoundation.sample.octonaut.xplat.domain.user.api.UserSupplier
import org.mobilenativefoundation.sample.octonaut.xplat.domain.user.impl.UserStoreFactory
Expand All @@ -32,13 +37,11 @@ import org.mobilenativefoundation.sample.octonaut.xplat.feat.homeTab.api.HomeTab
import org.mobilenativefoundation.sample.octonaut.xplat.feat.homeTab.impl.*
import org.mobilenativefoundation.sample.octonaut.xplat.feat.notificationsTab.api.NotificationsTab
import org.mobilenativefoundation.sample.octonaut.xplat.foundation.di.api.UserScope
import org.mobilenativefoundation.sample.octonaut.xplat.foundation.networking.api.GetUserQuery
import org.mobilenativefoundation.sample.octonaut.xplat.foundation.networking.api.ListNotificationsResponse
import org.mobilenativefoundation.sample.octonaut.xplat.foundation.networking.api.NetworkingClient
import org.mobilenativefoundation.sample.octonaut.xplat.foundation.networking.api.NetworkingComponent
import org.mobilenativefoundation.sample.octonaut.xplat.foundation.networking.api.*
import org.mobilenativefoundation.sample.octonaut.xplat.foundation.networking.impl.Env
import org.mobilenativefoundation.sample.octonaut.xplat.foundation.networking.impl.RealNetworkingClient
import org.mobilenativefoundation.sample.octonaut.xplat.foundation.networking.impl.httpClient
import org.mobilenativefoundation.sample.octonaut.xplat.foundation.webview.WebViewUrlStateHolder

@UserScope
@Component
Expand All @@ -51,8 +54,10 @@ abstract class CoreComponent : NetworkingComponent {
abstract val mutableMarket: MutableOctonautMarket
abstract val marketDispatcher: OctonautMarketDispatcher
abstract val coroutineDispatcher: CoroutineDispatcher
abstract val userSupplier: UserSupplier
abstract val currentUserSupplier: CurrentUserSupplier
abstract val scheduledNotificationsSupplier: NotificationsSupplier
abstract val feedSupplier: FeedSupplier
abstract val webViewUrlStateHolder: WebViewUrlStateHolder

@UserScope
@Provides
Expand Down Expand Up @@ -113,6 +118,17 @@ abstract class CoreComponent : NetworkingComponent {
return notificationsStoreFactory.create()
}

@Provides
fun provideFeedStoreFactory(networkingClient: NetworkingClient): FeedStoreFactory {
return FeedStoreFactory(networkingClient)
}

@Provides
@UserScope
fun provideFeedStore(notificationsStoreFactory: FeedStoreFactory): FeedStore {
return notificationsStoreFactory.create()
}


@Provides
@UserScope
Expand All @@ -123,7 +139,48 @@ abstract class CoreComponent : NetworkingComponent {
): UserSupplier {

val marketActionFactory = MarketActionFactory<GetUserQuery.User, OctonautMarketAction> { storeOutput ->
OctonautMarketAction.UpdateUser(storeOutput)
OctonautMarketAction.AddUser(storeOutput)
}

return RealMarketSupplier(
coroutineDispatcher,
userStore,
marketDispatcher,
marketActionFactory
)
}

@Provides
@UserScope
fun provideCurrentUserSupplier(
coroutineDispatcher: CoroutineDispatcher,
userStore: UserStore,
marketDispatcher: OctonautMarketDispatcher,
): CurrentUserSupplier {

val marketActionFactory = MarketActionFactory<GetUserQuery.User, OctonautMarketAction> { storeOutput ->
OctonautMarketAction.UpdateCurrentUser(storeOutput)
}

return RealMarketSupplier(
coroutineDispatcher,
userStore,
marketDispatcher,
marketActionFactory
)
}

@Provides
@UserScope
fun provideFeedSupplier(
coroutineDispatcher: CoroutineDispatcher,
userStore: FeedStore,
marketDispatcher: OctonautMarketDispatcher,
): FeedSupplier {

val marketActionFactory = MarketActionFactory<Feed, OctonautMarketAction> { storeOutput ->
println("STORE OUTPUT = $storeOutput")
OctonautMarketAction.UpdateFeed(storeOutput)
}

return RealMarketSupplier(
Expand Down Expand Up @@ -182,9 +239,10 @@ abstract class CoreComponent : NetworkingComponent {

@Provides
fun provideHomeTabPresenter(
warehouse: HomeTabWarehouse
warehouse: HomeTabWarehouse,
webViewUrlStateHolder: WebViewUrlStateHolder
): HomeTabPresenter {
return HomeTabPresenter(warehouse)
return HomeTabPresenter(warehouse, webViewUrlStateHolder)
}

@Provides
Expand Down Expand Up @@ -253,6 +311,14 @@ abstract class CoreComponent : NetworkingComponent {
@Provides
fun provideNotificationsTab(): NotificationsTab = RealNotificationsTab

@Provides
@UserScope
fun provideWebViewUrlStateHolder(): WebViewUrlStateHolder {
return object : WebViewUrlStateHolder {
override val url = MutableStateFlow<String?>(null)
}
}


companion object
}
Expand Down
Loading

0 comments on commit 7ab3b74

Please sign in to comment.