diff --git a/app/build.gradle.kts b/app/build.gradle.kts index baa4f27..9a73f7f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -123,6 +123,12 @@ dependencies { implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0") + + // Ktor + val ktor_version = "2.3.1" + implementation("io.ktor:ktor-client-core:$ktor_version") + implementation("io.ktor:ktor-client-cio:$ktor_version") + implementation(platform("dev.forkhandles:forkhandles-bom:2.6.0.0")) implementation("dev.forkhandles:result4k") @@ -143,5 +149,6 @@ dependencies { implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0") - + // Map Compose library + implementation("ovh.plrapps:mapcompose:2.7.1") } \ No newline at end of file diff --git a/app/src/main/java/ru/nm17/narodmon/ui/elements/AgreementDialog.kt b/app/src/main/java/ru/nm17/narodmon/ui/elements/AgreementDialog.kt index c50a53f..25d8c97 100644 --- a/app/src/main/java/ru/nm17/narodmon/ui/elements/AgreementDialog.kt +++ b/app/src/main/java/ru/nm17/narodmon/ui/elements/AgreementDialog.kt @@ -2,9 +2,6 @@ package ru.nm17.narodmon.ui.elements -import android.content.Context -import android.content.Intent -import android.net.Uri import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding @@ -22,9 +19,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import androidx.activity.ComponentActivity import androidx.compose.ui.platform.LocalUriHandler -import androidx.core.content.ContextCompat.startActivity import ru.nm17.narodmon.R import kotlin.system.exitProcess @@ -40,7 +35,7 @@ fun AgreementDialog(modifier: Modifier = Modifier, onClick: () -> Unit) { Text(text = stringResource(id = R.string.agreement_dialog_text)) Divider(Modifier.padding(vertical = 8.dp)) ListItem( - headlineText = { + headlineContent = { Text( text = stringResource(id = R.string.privacy_policy), style = MaterialTheme.typography.titleSmall @@ -56,7 +51,7 @@ fun AgreementDialog(modifier: Modifier = Modifier, onClick: () -> Unit) { ) ListItem( - headlineText = { + headlineContent = { Text( text = stringResource(id = R.string.user_agreement), style = MaterialTheme.typography.titleSmall diff --git a/app/src/main/java/ru/nm17/narodmon/ui/elements/Scaffolds.kt b/app/src/main/java/ru/nm17/narodmon/ui/elements/Scaffolds.kt index 6fb02c0..016df5f 100644 --- a/app/src/main/java/ru/nm17/narodmon/ui/elements/Scaffolds.kt +++ b/app/src/main/java/ru/nm17/narodmon/ui/elements/Scaffolds.kt @@ -35,7 +35,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp -import androidx.navigation.compose.NavHost import androidx.navigation.compose.rememberNavController import kotlinx.coroutines.delay import kotlinx.coroutines.launch diff --git a/app/src/main/java/ru/nm17/narodmon/ui/pages/Sensors.kt b/app/src/main/java/ru/nm17/narodmon/ui/pages/Sensors.kt index 2c5761b..6bd37c1 100644 --- a/app/src/main/java/ru/nm17/narodmon/ui/pages/Sensors.kt +++ b/app/src/main/java/ru/nm17/narodmon/ui/pages/Sensors.kt @@ -1,46 +1,97 @@ package ru.nm17.narodmon.ui.pages +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FilterChip import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import ru.nm17.narodmon.Greeting +import ovh.plrapps.mapcompose.api.scale +import ovh.plrapps.mapcompose.api.setScroll +import ovh.plrapps.mapcompose.ui.MapUI import ru.nm17.narodmon.R import ru.nm17.narodmon.ui.elements.GenericNavScaffold +import ru.nm17.narodmon.ui.viewmodel.MapViewModel + +enum class SensorsFilter { + All, Thermometer, Camera, +} @ExperimentalMaterial3Api @Composable fun SensorsPage(navController: NavController) { + val mapVM by remember { mutableStateOf(MapViewModel()) } + var filter by remember { mutableStateOf(SensorsFilter.All) } + + val scrConfig = LocalConfiguration.current + val mapHeight = scrConfig.screenHeightDp / 3 + + LaunchedEffect(mapVM) { + // TODO: Подгружать сохранённую позицию + mapVM.state.setScroll(Offset(28702.6F, 14787.6F)) + mapVM.state.scale = 1.4658884F + } + GenericNavScaffold( title = { Text(text = stringResource(R.string.sensors_page_title)) } ) { - Column { - Greeting("Hello sensors") - Row { - FilterChip( - selected = true, - onClick = { }, - label = { Text("Temp") } + Column(modifier = Modifier.padding(it)) { + + MapUI(state = mapVM.state, modifier = Modifier.height(mapHeight.dp)) + + Row( + modifier = Modifier.padding(horizontal = 8.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + SensorsFilterChip( + name = stringResource(R.string.sensors_filter_all), + checkFilter = { filter == SensorsFilter.All }, + updateFilter = { filter = SensorsFilter.All }, ) - FilterChip( - selected = false, - onClick = { }, - label = { Text("Abc") } + SensorsFilterChip( + name = stringResource(R.string.sensors_filter_temp), + checkFilter = { filter == SensorsFilter.Thermometer }, + updateFilter = { filter = SensorsFilter.Thermometer }, ) - FilterChip( - selected = false, - onClick = { }, - label = { Text("Def") } + SensorsFilterChip( + name = stringResource(R.string.sensors_filter_camera), + checkFilter = { filter == SensorsFilter.Camera }, + updateFilter = { filter = SensorsFilter.Camera }, ) } + + //Text(mapVM.state.scroll.toString()) + //Text(mapVM.state.scale.toString()) } } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun SensorsFilterChip( + name: String, + checkFilter: () -> Boolean, + updateFilter: () -> Unit, +) { + FilterChip( + selected = checkFilter(), + onClick = updateFilter, + label = { Text(name) }, + ) } \ No newline at end of file diff --git a/app/src/main/java/ru/nm17/narodmon/ui/viewmodel/MapViewModel.kt b/app/src/main/java/ru/nm17/narodmon/ui/viewmodel/MapViewModel.kt new file mode 100644 index 0000000..4d330ba --- /dev/null +++ b/app/src/main/java/ru/nm17/narodmon/ui/viewmodel/MapViewModel.kt @@ -0,0 +1,39 @@ +package ru.nm17.narodmon.ui.viewmodel + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.ViewModel +import io.ktor.client.HttpClient +import io.ktor.client.engine.cio.CIO +import io.ktor.client.request.get +import io.ktor.client.statement.bodyAsChannel +import io.ktor.utils.io.jvm.javaio.toInputStream +import ovh.plrapps.mapcompose.api.addLayer +import ovh.plrapps.mapcompose.core.TileStreamProvider +import ovh.plrapps.mapcompose.ui.state.MapState +import java.io.InputStream + +class MapViewModel : ViewModel() { + private val client = HttpClient(CIO) + + private val tileStreamProvider = TileStreamProvider { row, col, zoom -> + requestTile(row, col, zoom) + } + + private val mapSize = 32768 + val state: MapState by mutableStateOf( + MapState( + levelCount = 8, + fullWidth = mapSize, + fullHeight = mapSize, + workerCount = 16, + ).apply { + addLayer(tileStreamProvider) + } + ) + + private suspend fun requestTile(row: Int, col: Int, zoom: Int): InputStream { + val response = client.get("https://tile.openstreetmap.org/${zoom}/${col}/${row}.png") + return response.bodyAsChannel().toInputStream() + } +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 50cd33f..e6c67e6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -15,4 +15,7 @@ Примите необходимые соглашения Сенсоры Ожидаю соглашение пользователя + Все + Термометры + Камеры \ No newline at end of file