feat: add AQI/RAD help dialog on map screen

This commit is contained in:
2026-03-16 16:45:48 +01:00
parent 3c41b0d487
commit fee67c35af
5 changed files with 98 additions and 8 deletions

View File

@@ -119,19 +119,17 @@ private fun MapScreenContent(
MapTopControls(
selectedSensor = uiState.selectedTopSensor,
onSensorSelected = { onEvent(Event.TopSensorSelected(it)) },
onHelpClick = {
Toast.makeText(
context,
context.getString(R.string.text_what_does_it_mean_title),
Toast.LENGTH_SHORT
).show()
},
onHelpClick = { onEvent(Event.HelpClicked) },
modifier = Modifier
.align(Alignment.TopEnd)
.statusBarsPadding()
.padding(top = 20.dp, end = 16.dp)
)
if (uiState.showHelpDialog) {
WhatDoesThisMeanDialog(onDismiss = { onEvent(Event.HelpDialogDismissed) })
}
if (uiState.searchPanelState == null && uiState.devicePanelState == null) {
MapFloatingActions(
onSearchClick = { onEvent(Event.SearchButtonClicked) },

View File

@@ -51,7 +51,8 @@ object MapScreenContract {
val selectedTopSensor: SensorType = SensorType.DUST,
val searchPanelState: SearchPanelState? = null,
val devicePanelState: DevicePanelState? = null,
val selectedMarkerId: String? = null
val selectedMarkerId: String? = null,
val showHelpDialog: Boolean = false
)
sealed interface Action {
@@ -67,6 +68,8 @@ object MapScreenContract {
data class SearchResultClicked(val resultId: String) : Event
data object MyLocationClicked : Event
data class TopSensorSelected(val sensor: SensorType) : Event
data object HelpClicked : Event
data object HelpDialogDismissed : Event
data class MarkerClicked(val itemId: String) : Event
data object DevicePanelClosed : Event
data object DeviceOpenClicked : Event

View File

@@ -1,5 +1,6 @@
package org.db3.airmq.features.map
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
@@ -12,10 +13,13 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
@@ -27,6 +31,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandVertically
@@ -38,6 +43,10 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Brush
@@ -220,6 +229,78 @@ fun MapTopControls(
}
}
@Composable
fun WhatDoesThisMeanDialog(
onDismiss: () -> Unit
) {
Dialog(onDismissRequest = onDismiss) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 32.dp, vertical = 128.dp),
shape = RoundedCornerShape(24.dp),
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface)
) {
Column(
modifier = Modifier.padding(24.dp)
) {
Text(
text = stringResource(id = R.string.text_what_does_it_mean_title),
style = MaterialTheme.typography.titleMedium,
fontSize = 16.sp,
fontWeight = FontWeight.Medium,
modifier = Modifier.padding(bottom = 22.dp)
)
Column(
modifier = Modifier
.heightIn(max = 400.dp)
.verticalScroll(rememberScrollState())
.padding(horizontal = 0.dp)
) {
Text(
text = stringResource(id = R.string.text_aqi_title),
style = MaterialTheme.typography.bodyLarge,
fontSize = 16.sp,
fontWeight = FontWeight.Medium
)
Spacer(modifier = Modifier.height(16.dp))
Text(
text = stringResource(id = R.string.text_aqi),
style = MaterialTheme.typography.bodyMedium
)
Spacer(modifier = Modifier.height(8.dp))
Image(
painter = painterResource(id = R.drawable.aqi_table),
contentDescription = null,
contentScale = ContentScale.Fit,
modifier = Modifier
.width(300.dp)
.height(150.dp)
)
Spacer(modifier = Modifier.height(20.dp))
Text(
text = stringResource(id = R.string.text_rad_title),
style = MaterialTheme.typography.bodyLarge,
fontSize = 16.sp,
fontWeight = FontWeight.Medium
)
Spacer(modifier = Modifier.height(16.dp))
Text(
text = stringResource(id = R.string.text_rad),
style = MaterialTheme.typography.bodyMedium
)
}
TextButton(
onClick = onDismiss,
modifier = Modifier.align(Alignment.End)
) {
Text(stringResource(id = R.string.button_ok))
}
}
}
}
}
@Composable
private fun SensorTypeItem(
iconRes: Int,

View File

@@ -96,6 +96,14 @@ class MapViewModel @Inject constructor(
remapMarkers()
}
Event.HelpClicked -> {
_uiState.value = _uiState.value.copy(showHelpDialog = true)
}
Event.HelpDialogDismissed -> {
_uiState.value = _uiState.value.copy(showHelpDialog = false)
}
is Event.MarkerClicked -> {
val selectedItem = _uiState.value.items.firstOrNull { it.id == event.itemId } ?: return
_uiState.value = _uiState.value.copy(

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB