Compare commits

...

7 commits

4 changed files with 143 additions and 38 deletions

View file

@ -41,6 +41,7 @@ import ru.nm17.narodmon.ui.pages.SensorsPage
import ru.nm17.narodmon.ui.theme.NarodMonTheme
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppNavHost() {
val navController = rememberNavController()

View file

@ -8,7 +8,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import io.ktor.client.HttpClient
import io.ktor.client.engine.cio.CIO
import io.ktor.client.engine.okhttp.OkHttp
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsChannel
import io.ktor.utils.io.jvm.javaio.toInputStream
@ -22,7 +22,7 @@ import java.io.InputStream
const val mapSize = 32768
val client = HttpClient(CIO)
val client = HttpClient(OkHttp)
val tileStreamProvider = TileStreamProvider { row, col, zoom ->
requestTile(row, col, zoom)
}

View file

@ -1,35 +1,85 @@
package ru.nm17.narodmon.ui.pages
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.AssistChip
import androidx.compose.material3.Checkbox
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FilterChip
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.SearchBar
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import ru.nm17.narodmon.R
import ru.nm17.narodmon.ui.elements.GenericNavScaffold
import ru.nm17.narodmon.ui.elements.TileMap
enum class SensorsFilter {
All, Thermometer, Camera,
}
data class SensorFilter(
val stringRes: Int,
val code: Int,
var enabled: MutableState<Boolean> = mutableStateOf(false),
)
@ExperimentalMaterial3Api
@Composable
fun SensorsPage(navController: NavController) {
var filter by remember { mutableStateOf(SensorsFilter.All) }
var searchQuery by remember { mutableStateOf("") }
var searchActive by remember { mutableStateOf(false) }
var filterShown by remember { mutableStateOf(false) }
var filterMine by remember { mutableStateOf(false) }
val filterItems = remember {
listOf(
/* TODO:
* Заменить `code` на настоящее значение
* либо динамически его подгружать из ответа АПИ
* (см. /appInit, ключ в жсоне: types.type) */
SensorFilter(R.string.filter_temp, 0),
SensorFilter(R.string.filter_temp_water, 1),
SensorFilter(R.string.filter_temp_ground, 2),
SensorFilter(R.string.filter_temp_dew_point, 3),
SensorFilter(R.string.filter_humidity, 4),
SensorFilter(R.string.filter_pressure, 5),
SensorFilter(R.string.filter_lightness, 6),
SensorFilter(R.string.filter_uv, 7),
SensorFilter(R.string.filter_radiation, 8),
SensorFilter(R.string.filter_rainfall, 9),
SensorFilter(R.string.filter_dust, 10),
SensorFilter(R.string.filter_wind_speed, 11),
SensorFilter(R.string.filter_wind_direction, 12),
SensorFilter(R.string.filter_concentration, 13),
SensorFilter(R.string.filter_power, 14),
SensorFilter(R.string.filter_voltage, 15),
SensorFilter(R.string.filter_amperage, 16),
SensorFilter(R.string.filter_energy, 17),
SensorFilter(R.string.filter_battery, 18),
SensorFilter(R.string.filter_rxtx, 19),
SensorFilter(R.string.filter_signal, 20),
SensorFilter(R.string.filter_water_meter, 21),
SensorFilter(R.string.filter_time, 22),
)
}
val scrConfig = LocalConfiguration.current
val mapHeight = scrConfig.screenHeightDp / 3
@ -41,45 +91,74 @@ fun SensorsPage(navController: NavController) {
TileMap(modifier = Modifier.height(mapHeight.dp))
SearchBar(
query = searchQuery,
active = searchActive,
onActiveChange = { active -> searchActive = active },
onQueryChange = { query -> searchQuery = query },
onSearch = { searchActive = false },
placeholder = { Text(stringResource(R.string.search)) },
modifier = Modifier.fillMaxWidth()
) {}
Row(
modifier = Modifier.padding(horizontal = 8.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.padding(horizontal = 8.dp),
) {
SensorsFilterChip(
name = stringResource(R.string.sensors_filter_all),
checkFilter = { filter == SensorsFilter.All },
updateFilter = { filter = SensorsFilter.All },
AssistChip(
onClick = { filterShown = true },
label = { Text(text = stringResource(R.string.sensors_filter)) },
)
SensorsFilterChip(
name = stringResource(R.string.sensors_filter_temp),
checkFilter = { filter == SensorsFilter.Thermometer },
updateFilter = { filter = SensorsFilter.Thermometer },
AssistChip(
onClick = { },
label = { Text(text = stringResource(R.string.sensors_sorting)) },
)
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) },
selected = filterMine,
onClick = { filterMine = !filterMine },
label = { Text(text = stringResource(R.string.sensors_mine)) },
)
}
}
}
if (filterShown) {
ModalBottomSheet(onDismissRequest = { filterShown = false }) {
Row(
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth(),
) {
Text(
text = stringResource(R.string.sensors_filter_title),
fontSize = 24.sp,
fontWeight = FontWeight(500),
)
}
LazyColumn(
modifier = Modifier.padding(horizontal = 4.dp),
) {
items(filterItems) {
Row(
verticalAlignment = Alignment.CenterVertically,
) {
Checkbox(
checked = it.enabled.value,
onCheckedChange = { checked ->
it.enabled.value = checked
},
)
Text(
text = stringResource(id = it.stringRes),
modifier = Modifier.clickable {
it.enabled.value = !it.enabled.value
}
)
}
}
}
}
}
}

View file

@ -15,7 +15,32 @@
<string name="agreement_dialog_title">Примите необходимые соглашения</string>
<string name="sensors_page_title">Сенсоры</string>
<string name="waiting_for_user_agreement">Ожидаю соглашение пользователя</string>
<string name="sensors_filter_all">Все</string>
<string name="sensors_filter_temp">Термометры</string>
<string name="sensors_filter_camera">Камеры</string>
<string name="search">Поиск</string>
<string name="sensors_filter">Фильтр</string>
<string name="sensors_sorting">Сортировка</string>
<string name="sensors_mine">Мои</string>
<string name="filter_temp_dew_point">Температура точки росы</string>
<string name="filter_temp">Температура воздуха</string>
<string name="filter_temp_water">Температура воды</string>
<string name="filter_temp_ground">Температура почвы</string>
<string name="filter_humidity">Влажность</string>
<string name="filter_pressure">Давление</string>
<string name="filter_lightness">Освещённость</string>
<string name="filter_uv">УФ-индекс</string>
<string name="filter_radiation">Радиация</string>
<string name="filter_rainfall">Осадки</string>
<string name="filter_dust">Запылённость</string>
<string name="filter_wind_speed">Скорость ветра</string>
<string name="filter_wind_direction">Направление ветра</string>
<string name="filter_concentration">Концентрация</string>
<string name="filter_power">Мощность</string>
<string name="filter_voltage">Напряжение</string>
<string name="filter_amperage">Сила тока</string>
<string name="filter_energy">Энергия</string>
<string name="filter_battery">% батареи</string>
<string name="filter_rxtx">Rx/Tx трафик</string>
<string name="filter_signal">Сигнал в dBm</string>
<string name="filter_water_meter">Счётчик воды</string>
<string name="filter_time">Время работы</string>
<string name="sensors_filter_title">Тип датчиков</string>
</resources>