feat(dashboard): add DashboardViewModel, metric gauge pager, chart integration
- Add DashboardScreenContract and DashboardViewModel with dummy data - Extend MetricGauge with pager, page indicators, sensor config - Integrate AirMQChart and city selector - ManageScreen: scaffold contentWindowInsets for edge-to-edge header - Add compose-foundation dependency for HorizontalPager Made-with: Cursor
This commit is contained in:
@@ -81,6 +81,7 @@ dependencies {
|
|||||||
implementation(libs.androidx.compose.ui.graphics)
|
implementation(libs.androidx.compose.ui.graphics)
|
||||||
implementation(libs.androidx.compose.ui.tooling.preview)
|
implementation(libs.androidx.compose.ui.tooling.preview)
|
||||||
implementation(libs.androidx.compose.material3)
|
implementation(libs.androidx.compose.material3)
|
||||||
|
implementation(libs.androidx.compose.foundation)
|
||||||
implementation(libs.androidx.navigation.compose)
|
implementation(libs.androidx.navigation.compose)
|
||||||
implementation(libs.hilt.android)
|
implementation(libs.hilt.android)
|
||||||
implementation(libs.androidx.hilt.navigation.compose)
|
implementation(libs.androidx.hilt.navigation.compose)
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ import java.text.SimpleDateFormat
|
|||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
private val ChartPaddingLeftDp = 56.dp
|
private val ChartPaddingLeftDp = 40.dp
|
||||||
private val ChartPaddingRightDp = 40.dp
|
private val ChartPaddingRightDp = 40.dp
|
||||||
private val ChartPaddingTopDp = 8.dp
|
private val ChartPaddingTopDp = 8.dp
|
||||||
private val ChartPaddingBottomDp = 52.dp
|
private val ChartPaddingBottomDp = 52.dp
|
||||||
|
|||||||
@@ -13,9 +13,11 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
|||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
@@ -23,8 +25,15 @@ import androidx.compose.ui.text.font.FontWeight
|
|||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.pager.HorizontalPager
|
||||||
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
import org.db3.airmq.features.common.metric.getColorFromMetrics
|
import org.db3.airmq.features.common.metric.getColorFromMetrics
|
||||||
import org.db3.airmq.features.common.metric.getSensorIconRes
|
import org.db3.airmq.features.common.metric.getSensorIconRes
|
||||||
import org.db3.airmq.ui.theme.AirMQTheme
|
import org.db3.airmq.ui.theme.AirMQTheme
|
||||||
@@ -126,21 +135,20 @@ fun MetricGauge(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Default sensor order for dashboard gauge row. */
|
/** Page 1: dust, radioactivity, temperature. */
|
||||||
private val DashboardGaugeOrder = listOf(
|
private val Page1Sensors = listOf(
|
||||||
SensorType.DUST,
|
SensorType.DUST,
|
||||||
SensorType.RADIOACTIVITY,
|
SensorType.RADIOACTIVITY,
|
||||||
SensorType.TEMPERATURE
|
SensorType.TEMPERATURE
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/** Page 2: humidity, pressure. */
|
||||||
* Horizontal row of metric gauges (dust, radioactivity, temperature).
|
private val Page2Sensors = listOf(
|
||||||
*
|
SensorType.HUMIDITY,
|
||||||
* @param selectedSensor Currently selected sensor; null if none
|
SensorType.PRESSURE
|
||||||
* @param values Map of sensor type to value
|
)
|
||||||
* @param onGaugeSelected Called when a gauge is tapped
|
|
||||||
* @param modifier Modifier
|
/** @deprecated Use MetricGaugePager. Kept for backward compatibility. */
|
||||||
*/
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MetricGaugeRow(
|
fun MetricGaugeRow(
|
||||||
selectedSensor: SensorType?,
|
selectedSensor: SensorType?,
|
||||||
@@ -152,7 +160,7 @@ fun MetricGaugeRow(
|
|||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
horizontalArrangement = Arrangement.SpaceEvenly
|
horizontalArrangement = Arrangement.SpaceEvenly
|
||||||
) {
|
) {
|
||||||
for (sensorType in DashboardGaugeOrder) {
|
for (sensorType in Page1Sensors) {
|
||||||
MetricGauge(
|
MetricGauge(
|
||||||
value = values[sensorType],
|
value = values[sensorType],
|
||||||
sensorType = sensorType,
|
sensorType = sensorType,
|
||||||
@@ -163,6 +171,90 @@ fun MetricGaugeRow(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paged metric gauges: 2 pages, 5 gauges total.
|
||||||
|
* Page 0: dust, radioactivity, temperature.
|
||||||
|
* Page 1: humidity, pressure.
|
||||||
|
*
|
||||||
|
* @param selectedSensor Currently selected sensor
|
||||||
|
* @param values Map of sensor type to value
|
||||||
|
* @param currentPage Current page index (0 or 1)
|
||||||
|
* @param onGaugeSelected Called when a gauge is tapped
|
||||||
|
* @param onPageChanged Called when page changes (e.g. after swipe)
|
||||||
|
* @param modifier Modifier
|
||||||
|
*/
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
|
@Composable
|
||||||
|
fun MetricGaugePager(
|
||||||
|
selectedSensor: SensorType,
|
||||||
|
values: Map<SensorType, Float?>,
|
||||||
|
currentPage: Int,
|
||||||
|
onGaugeSelected: (SensorType) -> Unit,
|
||||||
|
onPageChanged: (Int) -> Unit,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
val pagerState = rememberPagerState(pageCount = { 2 })
|
||||||
|
LaunchedEffect(currentPage) {
|
||||||
|
if (pagerState.currentPage != currentPage) {
|
||||||
|
pagerState.animateScrollToPage(currentPage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LaunchedEffect(pagerState.currentPage) {
|
||||||
|
onPageChanged(pagerState.currentPage)
|
||||||
|
}
|
||||||
|
Column(modifier = modifier) {
|
||||||
|
HorizontalPager(
|
||||||
|
state = pagerState,
|
||||||
|
modifier = Modifier.height(132.dp),
|
||||||
|
userScrollEnabled = true
|
||||||
|
) { page ->
|
||||||
|
val sensors = if (page == 0) Page1Sensors else Page2Sensors
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 16.dp),
|
||||||
|
horizontalArrangement = Arrangement.SpaceEvenly
|
||||||
|
) {
|
||||||
|
for (sensorType in sensors) {
|
||||||
|
MetricGauge(
|
||||||
|
value = values[sensorType],
|
||||||
|
sensorType = sensorType,
|
||||||
|
selected = selectedSensor == sensorType,
|
||||||
|
onClick = { onGaugeSelected(sensorType) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(top = 4.dp, bottom = 12.dp),
|
||||||
|
horizontalArrangement = Arrangement.Center,
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
PageIndicatorDot(selected = pagerState.currentPage == 0)
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
PageIndicatorDot(selected = pagerState.currentPage == 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun PageIndicatorDot(
|
||||||
|
selected: Boolean,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.size(8.dp)
|
||||||
|
.clip(CircleShape)
|
||||||
|
.background(
|
||||||
|
if (selected) Color.White
|
||||||
|
else Color.White.copy(alpha = 0.38f)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Preview(showBackground = true, name = "Dust – value 6")
|
@Preview(showBackground = true, name = "Dust – value 6")
|
||||||
@Composable
|
@Composable
|
||||||
private fun PreviewMetricGaugeDust() {
|
private fun PreviewMetricGaugeDust() {
|
||||||
@@ -301,6 +393,36 @@ private fun PreviewMetricGaugeSelected() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true, name = "Gauge pager – page 1")
|
||||||
|
@Composable
|
||||||
|
private fun PreviewMetricGaugePager() {
|
||||||
|
AirMQTheme {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(
|
||||||
|
androidx.compose.ui.graphics.Brush.verticalGradient(
|
||||||
|
colors = listOf(LegacyNavGradientStart, LegacyNavGradientEnd)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.padding(16.dp)
|
||||||
|
) {
|
||||||
|
MetricGaugePager(
|
||||||
|
selectedSensor = SensorType.DUST,
|
||||||
|
values = mapOf(
|
||||||
|
SensorType.DUST to 6f,
|
||||||
|
SensorType.RADIOACTIVITY to 0f,
|
||||||
|
SensorType.TEMPERATURE to 3f,
|
||||||
|
SensorType.HUMIDITY to 65f,
|
||||||
|
SensorType.PRESSURE to 745f
|
||||||
|
),
|
||||||
|
currentPage = 0,
|
||||||
|
onGaugeSelected = {},
|
||||||
|
onPageChanged = {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Preview(showBackground = true, name = "Gauge row")
|
@Preview(showBackground = true, name = "Gauge row")
|
||||||
@Composable
|
@Composable
|
||||||
private fun PreviewMetricGaugeRow() {
|
private fun PreviewMetricGaugeRow() {
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package org.db3.airmq.features.dashboard
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import org.db3.airmq.R
|
||||||
|
import org.db3.airmq.features.common.chart.ChartConfig
|
||||||
|
import org.db3.airmq.features.common.chart.ChartDataset
|
||||||
|
import org.db3.airmq.features.common.chart.generateSineWaveData
|
||||||
|
import org.db3.airmq.features.common.metric.SensorType
|
||||||
|
import org.db3.airmq.ui.theme.ChartBackground
|
||||||
|
import org.db3.airmq.ui.theme.ChartFill
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
||||||
|
object DashboardScreenContract {
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun previewState(
|
||||||
|
city: String = "Minsk",
|
||||||
|
selectedSensor: SensorType = SensorType.DUST,
|
||||||
|
currentPage: Int = 0
|
||||||
|
): State {
|
||||||
|
val chartData = when (selectedSensor) {
|
||||||
|
SensorType.DUST -> ChartDataset.Single(generateSineWaveData(amplitude = 8f, offset = 10f, periodCount = 1.5f))
|
||||||
|
SensorType.RADIOACTIVITY -> ChartDataset.Single(generateSineWaveData(amplitude = 0.15f, offset = 0.2f, periodCount = 1f))
|
||||||
|
SensorType.TEMPERATURE -> ChartDataset.Single(generateSineWaveData(amplitude = 5f, offset = 15f, periodCount = 2f))
|
||||||
|
SensorType.HUMIDITY -> ChartDataset.Single(generateSineWaveData(amplitude = 15f, offset = 55f, periodCount = 1.2f))
|
||||||
|
SensorType.PRESSURE -> ChartDataset.Single(generateSineWaveData(amplitude = 10f, offset = 740f, periodCount = 0.8f))
|
||||||
|
else -> ChartDataset.Single(generateSineWaveData())
|
||||||
|
}
|
||||||
|
val chartConfig = ChartConfig(
|
||||||
|
lineColor = Color.White,
|
||||||
|
fillColor = ChartFill,
|
||||||
|
backgroundColor = ChartBackground,
|
||||||
|
labelColor = Color.White,
|
||||||
|
leftTimeLabel = "Yesterday",
|
||||||
|
rightTimeLabel = "Now",
|
||||||
|
unit = selectedSensor.units(),
|
||||||
|
centerLabel = LocalContext.current.getString(
|
||||||
|
when (selectedSensor) {
|
||||||
|
SensorType.DUST -> R.string.sensor_dust
|
||||||
|
SensorType.RADIOACTIVITY -> R.string.sensor_radioactivity
|
||||||
|
SensorType.TEMPERATURE -> R.string.sensor_temperature
|
||||||
|
SensorType.HUMIDITY -> R.string.sensor_humidity
|
||||||
|
SensorType.PRESSURE -> R.string.sensor_pressure
|
||||||
|
else -> R.string.sensor_dust
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return State(
|
||||||
|
city = city,
|
||||||
|
gaugeValues = mapOf(
|
||||||
|
SensorType.DUST to 6f,
|
||||||
|
SensorType.RADIOACTIVITY to 0f,
|
||||||
|
SensorType.TEMPERATURE to 3f,
|
||||||
|
SensorType.HUMIDITY to 65f,
|
||||||
|
SensorType.PRESSURE to 745f
|
||||||
|
),
|
||||||
|
selectedSensor = selectedSensor,
|
||||||
|
currentPage = currentPage,
|
||||||
|
chartData = chartData,
|
||||||
|
chartConfig = chartConfig,
|
||||||
|
chartSensorLabel = chartConfig.centerLabel ?: ""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
data class State(
|
||||||
|
val city: String,
|
||||||
|
val gaugeValues: Map<SensorType, Float?>,
|
||||||
|
val selectedSensor: SensorType,
|
||||||
|
val currentPage: Int,
|
||||||
|
val chartData: ChartDataset?,
|
||||||
|
val chartConfig: ChartConfig,
|
||||||
|
val chartSensorLabel: String
|
||||||
|
)
|
||||||
|
|
||||||
|
sealed interface Action {
|
||||||
|
data object OpenCity : Action
|
||||||
|
data object OpenNews : Action
|
||||||
|
data object OpenWidgetConstructor : Action
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface Event {
|
||||||
|
data class GaugeSelected(val sensor: SensorType) : Event
|
||||||
|
data class PageChanged(val page: Int) : Event
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
package org.db3.airmq.features.dashboard
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.SharedFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
|
import javax.inject.Inject
|
||||||
|
import org.db3.airmq.R
|
||||||
|
import org.db3.airmq.features.common.chart.ChartConfig
|
||||||
|
import org.db3.airmq.features.common.chart.ChartDataset
|
||||||
|
import org.db3.airmq.features.common.chart.generateSineWaveData
|
||||||
|
import org.db3.airmq.features.common.metric.SensorType
|
||||||
|
import org.db3.airmq.ui.theme.ChartBackground
|
||||||
|
import org.db3.airmq.ui.theme.ChartFill
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
class DashboardViewModel @Inject constructor(
|
||||||
|
@ApplicationContext private val context: Context
|
||||||
|
) : ViewModel() {
|
||||||
|
|
||||||
|
private val _uiState = MutableStateFlow(initialState())
|
||||||
|
val uiState: StateFlow<DashboardScreenContract.State> = _uiState.asStateFlow()
|
||||||
|
|
||||||
|
private val _actions = MutableSharedFlow<DashboardScreenContract.Action>(extraBufferCapacity = 1)
|
||||||
|
val actions: SharedFlow<DashboardScreenContract.Action> = _actions.asSharedFlow()
|
||||||
|
|
||||||
|
fun onEvent(event: DashboardScreenContract.Event) {
|
||||||
|
when (event) {
|
||||||
|
is DashboardScreenContract.Event.GaugeSelected -> {
|
||||||
|
_uiState.update { state ->
|
||||||
|
state.copy(
|
||||||
|
selectedSensor = event.sensor,
|
||||||
|
chartData = chartDataFor(event.sensor),
|
||||||
|
chartConfig = chartConfigFor(event.sensor),
|
||||||
|
chartSensorLabel = chartLabelFor(event.sensor)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is DashboardScreenContract.Event.PageChanged -> {
|
||||||
|
_uiState.update { it.copy(currentPage = event.page) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initialState(): DashboardScreenContract.State {
|
||||||
|
val selected = SensorType.DUST
|
||||||
|
return DashboardScreenContract.State(
|
||||||
|
city = "Minsk",
|
||||||
|
gaugeValues = dummyGaugeValues(),
|
||||||
|
selectedSensor = selected,
|
||||||
|
currentPage = 0,
|
||||||
|
chartData = chartDataFor(selected),
|
||||||
|
chartConfig = chartConfigFor(selected),
|
||||||
|
chartSensorLabel = chartLabelFor(selected)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun dummyGaugeValues(): Map<SensorType, Float?> = mapOf(
|
||||||
|
SensorType.DUST to 6f,
|
||||||
|
SensorType.RADIOACTIVITY to 0f,
|
||||||
|
SensorType.TEMPERATURE to 3f,
|
||||||
|
SensorType.HUMIDITY to 65f,
|
||||||
|
SensorType.PRESSURE to 745f
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun chartDataFor(sensor: SensorType): ChartDataset = when (sensor) {
|
||||||
|
SensorType.DUST -> ChartDataset.Single(
|
||||||
|
generateSineWaveData(amplitude = 8f, offset = 10f, periodCount = 1.5f)
|
||||||
|
)
|
||||||
|
SensorType.RADIOACTIVITY -> ChartDataset.Single(
|
||||||
|
generateSineWaveData(amplitude = 0.15f, offset = 0.2f, periodCount = 1f)
|
||||||
|
)
|
||||||
|
SensorType.TEMPERATURE -> ChartDataset.Single(
|
||||||
|
generateSineWaveData(amplitude = 5f, offset = 15f, periodCount = 2f)
|
||||||
|
)
|
||||||
|
SensorType.HUMIDITY -> ChartDataset.Single(
|
||||||
|
generateSineWaveData(amplitude = 15f, offset = 55f, periodCount = 1.2f)
|
||||||
|
)
|
||||||
|
SensorType.PRESSURE -> ChartDataset.Single(
|
||||||
|
generateSineWaveData(amplitude = 10f, offset = 740f, periodCount = 0.8f)
|
||||||
|
)
|
||||||
|
else -> ChartDataset.Single(generateSineWaveData())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun chartConfigFor(sensor: SensorType): ChartConfig = ChartConfig(
|
||||||
|
lineColor = Color.White,
|
||||||
|
fillColor = ChartFill,
|
||||||
|
backgroundColor = ChartBackground,
|
||||||
|
labelColor = Color.White,
|
||||||
|
leftTimeLabel = "Yesterday",
|
||||||
|
rightTimeLabel = "Now",
|
||||||
|
unit = sensor.units(),
|
||||||
|
centerLabel = chartLabelFor(sensor)
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun chartLabelFor(sensor: SensorType): String = context.getString(
|
||||||
|
when (sensor) {
|
||||||
|
SensorType.DUST -> R.string.sensor_dust
|
||||||
|
SensorType.RADIOACTIVITY -> R.string.sensor_radioactivity
|
||||||
|
SensorType.TEMPERATURE -> R.string.sensor_temperature
|
||||||
|
SensorType.HUMIDITY -> R.string.sensor_humidity
|
||||||
|
SensorType.PRESSURE -> R.string.sensor_pressure
|
||||||
|
else -> R.string.sensor_dust
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.height
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
import androidx.compose.foundation.layout.statusBarsPadding
|
||||||
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
@@ -85,7 +86,10 @@ private fun ManageScreenContent(
|
|||||||
uiState: State,
|
uiState: State,
|
||||||
onEvent: (Event) -> Unit
|
onEvent: (Event) -> Unit
|
||||||
) {
|
) {
|
||||||
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
|
Scaffold(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentWindowInsets = WindowInsets(0, 0, 0, 0)
|
||||||
|
) { innerPadding ->
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "u
|
|||||||
androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
|
androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
|
||||||
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
|
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
|
||||||
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
|
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
|
||||||
|
androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation" }
|
||||||
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
|
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
|
||||||
firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebaseBom" }
|
firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebaseBom" }
|
||||||
firebase-analytics = { group = "com.google.firebase", name = "firebase-analytics" }
|
firebase-analytics = { group = "com.google.firebase", name = "firebase-analytics" }
|
||||||
|
|||||||
Reference in New Issue
Block a user