Skip to content

Commit

Permalink
Merge pull request #62 from stslex/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
stslex authored Oct 29, 2023
2 parents 3bcac81 + 2f871e1 commit 2e7dd3e
Show file tree
Hide file tree
Showing 65 changed files with 444 additions and 501 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package st.slex.csplashscreen.di.main

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.stslex93.notes.core.ui.base.ViewModelFactory
import st.slex.csplashscreen.core.ui.base.ViewModelFactory
import dagger.Binds
import dagger.Module
import dagger.multibindings.IntoMap
Expand Down
4 changes: 2 additions & 2 deletions build-logic/dependencies/src/main/kotlin/AppVersions.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
object AppVersions {
const val versionName = "1.63"
const val versionCode = 9
const val versionName = "1.64"
const val versionCode = 10
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import st.slex.csplashscreen.core.ui.mvi.Store.Event
import st.slex.csplashscreen.core.ui.mvi.Store.State

open class BaseViewModel<out S : State, out E : Event, in A : Action>(
private val store: Store<S, E, A>
private val store: Store<S, E, A>,
) : ViewModel() {

val state: StateFlow<S> = store.state
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package st.slex.csplashscreen.core.ui.base

import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.compose.viewModel
import st.slex.csplashscreen.core.ui.di.builder.Feature
import st.slex.csplashscreen.core.ui.di.builder.FeatureBuilder

@Composable
inline fun <reified T : ViewModel> daggerViewModel(
Expand All @@ -13,4 +17,25 @@ inline fun <reified T : ViewModel> daggerViewModel(
modelClass = T::class.java,
key = key,
factory = factory()
)
)

@Composable
inline fun <reified VM : ViewModel, F : Feature> setupComponent(
builder: FeatureBuilder<F>,
key: String? = null,
): VM {
val context = LocalContext.current

DisposableEffect(Unit) {
builder.create(context)
onDispose {
builder.clear()
}
}

return daggerViewModel(key) {
builder
.build(context)
.viewModelFactory
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.stslex93.notes.core.ui.base
package st.slex.csplashscreen.core.ui.base

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package st.slex.csplashscreen.core.ui.di.builder

import androidx.lifecycle.ViewModelProvider

interface Feature {

val viewModelFactory: ViewModelProvider.Factory
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package st.slex.csplashscreen.core.ui.di.builder

import android.content.Context

interface FeatureBuilder<F : Feature> {

var feature: F?

fun create(context: Context): F

fun build(
context: Context
): F = feature ?: create(context)
.also { createdFeature ->
feature = createdFeature
}

fun clear() {
feature = null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,38 @@ import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import st.slex.csplashscreen.core.ui.mvi.Store.Action
import st.slex.csplashscreen.core.ui.mvi.Store.Event
import st.slex.csplashscreen.core.ui.mvi.Store.Navigation
import st.slex.csplashscreen.core.ui.mvi.Store.State

abstract class BaseStoreImpl<S : State, E : Event, A : Action> :
Store<S, E, A>,
StoreImpl<S, E, A> {
abstract class BaseStore<S : State, E : Event, A : Action, N : Navigation>(
private val router: Router<N>
) : Store<S, E, A> {

abstract val initialState: S

private var _scope: CoroutineScope? = null
val scope: CoroutineScope
get() = requireNotNull(_scope)

@Suppress("LeakingThis")
override val state: MutableStateFlow<S> = MutableStateFlow(initialState)
override val state: MutableStateFlow<S>
get() = MutableStateFlow(initialState)

override val event: MutableSharedFlow<E> = MutableSharedFlow()

override fun updateState(update: (S) -> S) {
fun updateState(update: (S) -> S) {
state.update(update)
}

override fun sendEvent(event: E) {
fun sendEvent(event: E) {
scope.launch {
this@BaseStoreImpl.event.emit(event)
this@BaseStore.event.emit(event)
}
}

fun navigate(event: N) {
router(event)
}

override fun init(scope: CoroutineScope) {
_scope = scope
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package st.slex.csplashscreen.core.ui.mvi

fun interface Router<in E : Store.Navigation> {
operator fun invoke(event: E)
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ interface Store<out S : State, out E : Event, in A : Action> {
fun destroy()

interface State

interface Event

interface Navigation

interface Action
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,36 +1,23 @@
package st.slex.csplashscreen.feature.collection.di

import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import android.content.Context
import st.slex.csplashscreen.core.network.di.NetworkApiBuilder
import st.slex.csplashscreen.core.ui.base.daggerViewModel
import st.slex.csplashscreen.core.ui.di.NavigationApi
import st.slex.csplashscreen.core.ui.di.builder.FeatureBuilder
import st.slex.csplashscreen.core.ui.di.navigationApi
import st.slex.csplashscreen.feature.collection.ui.SingleCollectionViewModel

object SingleCollectionBuilder {
object SingleCollectionBuilder : FeatureBuilder<SingleCollectionComponent> {

fun build(
navigationApi: NavigationApi
): SingleCollectionComponent = DaggerSingleCollectionComponent
.factory()
.create(
dependencies = DaggerSingleCollectionComponent_SingleCollectionDependenciesComponent
.factory()
.create(
networkClientApi = NetworkApiBuilder.build(),
navigationApi = navigationApi
)
override var feature: SingleCollectionComponent? = null

)
}

@Composable
fun setupComponent(key: String): SingleCollectionViewModel {
val context = LocalContext.current
return daggerViewModel(key) {
SingleCollectionBuilder
.build(context.navigationApi)
.viewModelFactory
}
override fun create(context: Context): SingleCollectionComponent =
DaggerSingleCollectionComponent
.factory()
.create(
dependencies = DaggerSingleCollectionComponent_SingleCollectionDependenciesComponent
.factory()
.create(
networkClientApi = NetworkApiBuilder.build(),
navigationApi = context.navigationApi
)
)
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package st.slex.csplashscreen.feature.collection.di

import androidx.lifecycle.ViewModelProvider
import dagger.Component
import st.slex.csplashscreen.core.network.di.NetworkClientApi
import st.slex.csplashscreen.core.ui.di.NavigationApi
import st.slex.csplashscreen.core.ui.di.builder.Feature

@Component(
dependencies = [SingleCollectionDependencies::class],
modules = [SingleCollectionModule::class]
)
@SingleCollectionScope
interface SingleCollectionComponent {
interface SingleCollectionComponent : Feature {

@Component.Factory
interface Factory {
Expand All @@ -32,6 +32,4 @@ interface SingleCollectionComponent {
): SingleCollectionDependencies
}
}

val viewModelFactory: ViewModelProvider.Factory
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package st.slex.csplashscreen.feature.collection.di

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.stslex93.notes.core.ui.base.ViewModelFactory
import st.slex.csplashscreen.core.ui.base.ViewModelFactory
import dagger.Binds
import dagger.Module
import dagger.multibindings.IntoMap
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ import st.slex.csplashscreen.core.navigation.AppArguments
import st.slex.csplashscreen.core.navigation.AppDestination
import st.slex.csplashscreen.core.navigation.NavExt.composableArguments
import st.slex.csplashscreen.core.navigation.NavExt.parseArguments
import st.slex.csplashscreen.core.ui.base.setupComponent
import st.slex.csplashscreen.core.ui.utils.CollectAsEvent
import st.slex.csplashscreen.feature.collection.di.setupComponent
import st.slex.csplashscreen.feature.collection.di.SingleCollectionBuilder
import st.slex.csplashscreen.feature.collection.ui.CollectionScreen
import st.slex.csplashscreen.feature.collection.ui.SingleCollectionViewModel
import st.slex.csplashscreen.feature.collection.ui.store.SingleCollectionStore.Action
import st.slex.csplashscreen.feature.collection.ui.store.SingleCollectionStore.Event

fun NavGraphBuilder.singleCollectionGraph(
modifier: Modifier = Modifier,
Expand All @@ -28,7 +29,10 @@ fun NavGraphBuilder.singleCollectionGraph(
val arguments = AppDestination.COLLECTION.parseArguments(navBackStackEntry).let { args ->
AppArguments.CollectionScreen(args[0])
}
val viewModel = setupComponent(key = arguments.collectionId)
val viewModel: SingleCollectionViewModel = setupComponent(
key = arguments.collectionId,
builder = SingleCollectionBuilder
)

val state by remember {
viewModel.state
Expand All @@ -43,9 +47,7 @@ fun NavGraphBuilder.singleCollectionGraph(
}

viewModel.event.CollectAsEvent { event ->
when (event) {
is Event.Navigation -> viewModel.processNavigation(event)
}
// TODO NOT IMPLEMENTED YET
}

CollectionScreen(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package st.slex.csplashscreen.feature.collection.navigation

interface SingleCollectionRouter {
import st.slex.csplashscreen.core.ui.mvi.Router
import st.slex.csplashscreen.feature.collection.ui.store.SingleCollectionStore.Navigation

fun navToImage(uuid: String)

fun navToProfile(username: String)
}
interface SingleCollectionRouter : Router<Navigation>
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,25 @@ package st.slex.csplashscreen.feature.collection.navigation

import st.slex.csplashscreen.core.navigation.NavigationScreen
import st.slex.csplashscreen.core.ui.di.Navigator
import st.slex.csplashscreen.feature.collection.ui.store.SingleCollectionStore.Navigation
import javax.inject.Inject

class SingleCollectionRouterImpl @Inject constructor(
private val navigator: Navigator
) : SingleCollectionRouter {

override fun navToImage(uuid: String) {
navigator(NavigationScreen.ImageDetailScreen(uuid))
override fun invoke(event: Navigation) {
when (event) {
is Navigation.ImageDetail -> navToImage(event)
is Navigation.Profile -> navToProfile(event)
}
}

override fun navToProfile(username: String) {
navigator(NavigationScreen.UserScreen(username))
private fun navToImage(event: Navigation.ImageDetail) {
navigator(NavigationScreen.ImageDetailScreen(event.uuid))
}

private fun navToProfile(event: Navigation.Profile) {
navigator(NavigationScreen.UserScreen(event.username))
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,12 @@
package st.slex.csplashscreen.feature.collection.ui

import st.slex.csplashscreen.core.ui.base.BaseViewModel
import st.slex.csplashscreen.feature.collection.navigation.SingleCollectionRouter
import st.slex.csplashscreen.feature.collection.ui.store.SingleCollectionStore
import st.slex.csplashscreen.feature.collection.ui.store.SingleCollectionStore.Action
import st.slex.csplashscreen.feature.collection.ui.store.SingleCollectionStore.Event
import st.slex.csplashscreen.feature.collection.ui.store.SingleCollectionStore.Event.Navigation
import st.slex.csplashscreen.feature.collection.ui.store.SingleCollectionStore.State
import javax.inject.Inject

class SingleCollectionViewModel @Inject constructor(
store: SingleCollectionStore,
private val router: SingleCollectionRouter
) : BaseViewModel<State, Event, Action>(store) {

fun processNavigation(event: Navigation) {
when (event) {
is Navigation.ImageDetail -> router.navToImage(event.uuid)
is Navigation.Profile -> router.navToProfile(event.username)
}
}
}
) : BaseViewModel<State, Event, Action>(store)
Loading

0 comments on commit 2e7dd3e

Please sign in to comment.