Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ plugins {
alias(libs.plugins.kotlinAndroid)
alias(libs.plugins.kotlinxSerialization)
alias(libs.plugins.kapt)
alias(libs.plugins.composeCompiler)
}

composeCompiler {
reportsDestination.set(layout.buildDirectory.dir("compose_compiler/reports"))
metricsDestination.set(layout.buildDirectory.dir("compose_compiler/metrics"))
}

android {
Expand Down Expand Up @@ -33,17 +39,39 @@ android {
jvmTarget = '17'
}
buildFeatures {
compose true
viewBinding true
}
}

dependencies {

implementation project(":common:di")
implementation project(":common:formatters")
implementation project(":common:ui")
implementation project(":common:data:products")
implementation project(":common:data:promo")


implementation(platform(libs.androidx.compose.bom))

implementation(libs.compose.activity)
implementation(libs.compose.foundation)
implementation(libs.compose.lifecicle.viewmodel)
implementation(libs.compose.material3)
implementation(libs.compose.ui)
implementation(libs.compose.ui.tooling)
implementation(libs.compose.ui.tooling.preview)
implementation(libs.compose.coil)
implementation(libs.compose.coil.http)

implementation(libs.androidx.navigation3.ui)
implementation(libs.androidx.navigation3.runtime)
implementation(libs.androidx.lifecycle.viewmodel.navigation3)
implementation(libs.androidx.material3.adaptive.navigation3)

implementation(libs.kotlinx.serialization.core)

implementation libs.core.ktx
implementation libs.appcompat
implementation libs.material
Expand Down
20 changes: 9 additions & 11 deletions app/src/main/java/ru/otus/marketsample/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
package ru.otus.marketsample

import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import ru.otus.marketsample.databinding.ActivityMainBinding
import javax.inject.Inject

class MainActivity : AppCompatActivity() {

private lateinit var binding: ActivityMainBinding
@Inject
lateinit var viewModelsFactory: ViewModelsFactory

override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)

ViewCompat.setOnApplyWindowInsetsListener(binding.container) { view, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
view.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets

application.getAppComponent()?.inject(this)

setContent {
MainScreen(viewModelsFactory)
}
}
}
49 changes: 0 additions & 49 deletions app/src/main/java/ru/otus/marketsample/MainFragment.kt

This file was deleted.

146 changes: 146 additions & 0 deletions app/src/main/java/ru/otus/marketsample/MainScreen.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package ru.otus.marketsample

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarDefaults
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModelProvider
import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.ui.NavDisplay
import ru.otus.marketsample.details.feature.compose.DetailsContent
import ru.otus.marketsample.products.feature.ProductListViewModel
import ru.otus.marketsample.products.feature.compose.ProductsContent
import ru.otus.marketsample.promo.feature.PromoListViewModel
import ru.otus.marketsample.promo.feature.compose.PromoContent
import ru.otus.common.ui.R

private const val PRODUCTS_NAV_INDEX = 0
private const val PROMO_NAV_INDEX = 1

private const val UNKNOWN_INDEX = 2

private const val NAV_ICON_SIZE = 24

@Composable
fun MainScreen(viewModelsFactory: ViewModelProvider.Factory) {
val backStack = remember { mutableStateListOf<ScreenKey>(ProductsScreen) }

Scaffold(
modifier = Modifier
.fillMaxSize()
.background(color = Color.White),
bottomBar = {
NavBar(
selectedItem = when (backStack.lastOrNull()) {
ProductsScreen -> PRODUCTS_NAV_INDEX
PromoScreen -> PROMO_NAV_INDEX
else -> UNKNOWN_INDEX
},
onPromoListClick = {
if (backStack.lastOrNull() != PromoScreen) backStack.add(PromoScreen)
},
onProductListClick = {
if (backStack.lastOrNull() != ProductsScreen) backStack.add(ProductsScreen)
}
)
}) { paddingValues ->

NavDisplay(
modifier = Modifier.padding(paddingValues),
onBack = { backStack.removeLastOrNull() },
backStack = backStack,
entryProvider = entryProvider {
entry<ProductsScreen> {
ProductsContent(
viewModelsFactory.create(ProductListViewModel::class.java)
)
}
entry<PromoScreen> {
PromoContent(
viewModelsFactory.create(PromoListViewModel::class.java)
)
}
entry<DetailsScreen> { DetailsContent(it.id) }
}
)
}
}

@Composable
private fun NavBar(
selectedItem: Int,
onProductListClick: () -> Unit,
onPromoListClick: () -> Unit
) {

NavigationBar(
modifier = Modifier.fillMaxWidth(),
windowInsets = NavigationBarDefaults.windowInsets
) {
NavigationBarItem(
selected = selectedItem == PRODUCTS_NAV_INDEX,
onClick = {
onProductListClick()
},
label = {
Text(
text = stringResource(ru.otus.marketsample.R.string.title_products),
color = colorResource(R.color.purple_500)
)
},
icon = {
Icon(
modifier = Modifier.size(NAV_ICON_SIZE.dp),
painter = painterResource(R.drawable.ic_list),
tint = colorResource(R.color.purple_500),
contentDescription = null
)
})
NavigationBarItem(
selected = selectedItem == PROMO_NAV_INDEX,
onClick = {
onPromoListClick()

},
label = {
Text(
text = stringResource(ru.otus.marketsample.R.string.title_promo),
color = colorResource(R.color.purple_500)
)
},
icon = {
Icon(
modifier = Modifier.size(NAV_ICON_SIZE.dp),
painter = painterResource(R.drawable.ic_discount),
tint = colorResource(R.color.purple_500),
contentDescription = null
)
})
}
}

sealed interface ScreenKey

data object PromoScreen : ScreenKey

data object ProductsScreen : ScreenKey

data class DetailsScreen(val id: String) : ScreenKey


13 changes: 7 additions & 6 deletions app/src/main/java/ru/otus/marketsample/MarketSampleApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package ru.otus.marketsample
import android.app.Application
import ru.otus.marketsample.di.AppComponent
import ru.otus.marketsample.di.DaggerAppComponent
import ru.otus.common.di.Dependencies
import ru.otus.common.di.DependenciesProvider

class MarketSampleApp: Application(), DependenciesProvider {
val appComponent: AppComponent = DaggerAppComponent.factory().create(this)
class MarketSampleApp: Application() {
lateinit var appComponent: AppComponent

override fun getDependencies(): Dependencies {
return appComponent
override fun onCreate() {
super.onCreate()
appComponent = DaggerAppComponent.factory().create(this)
}
}

fun Application.getAppComponent() = (this as? MarketSampleApp)?.appComponent
14 changes: 14 additions & 0 deletions app/src/main/java/ru/otus/marketsample/ViewModelsFactory.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package ru.otus.marketsample

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import javax.inject.Inject
import javax.inject.Provider

class ViewModelsFactory @Inject constructor(private val vmMap: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>) :
ViewModelProvider.Factory {

override fun <T : ViewModel> create(modelClass: Class<T>): T {
return vmMap.getValue(modelClass).get() as T
}
}
Loading