Compare commits
2 commits
Author | SHA1 | Date | |
---|---|---|---|
86338e6e1f | |||
525f840ce8 |
75 changed files with 345 additions and 976 deletions
|
@ -74,43 +74,62 @@ dependencies {
|
||||||
debugImplementation(libs.ui.tooling)
|
debugImplementation(libs.ui.tooling)
|
||||||
debugImplementation(libs.ui.test.manifest)
|
debugImplementation(libs.ui.test.manifest)
|
||||||
|
|
||||||
|
|
||||||
//-- Navigation
|
|
||||||
val nav_version = "2.5.3"
|
val nav_version = "2.5.3"
|
||||||
|
|
||||||
|
// Java language implementation
|
||||||
|
implementation("androidx.navigation:navigation-fragment:$nav_version")
|
||||||
|
implementation("androidx.navigation:navigation-ui:$nav_version")
|
||||||
|
|
||||||
|
// Kotlin
|
||||||
implementation("androidx.navigation:navigation-fragment-ktx:$nav_version")
|
implementation("androidx.navigation:navigation-fragment-ktx:$nav_version")
|
||||||
implementation("androidx.navigation:navigation-ui-ktx:$nav_version")
|
implementation("androidx.navigation:navigation-ui-ktx:$nav_version")
|
||||||
|
|
||||||
|
// Feature module Support
|
||||||
implementation("androidx.navigation:navigation-dynamic-features-fragment:$nav_version")
|
implementation("androidx.navigation:navigation-dynamic-features-fragment:$nav_version")
|
||||||
|
|
||||||
|
// Testing Navigation
|
||||||
androidTestImplementation("androidx.navigation:navigation-testing:$nav_version")
|
androidTestImplementation("androidx.navigation:navigation-testing:$nav_version")
|
||||||
|
|
||||||
|
// Jetpack Compose Integration
|
||||||
implementation("androidx.navigation:navigation-compose:$nav_version")
|
implementation("androidx.navigation:navigation-compose:$nav_version")
|
||||||
|
|
||||||
|
val room_version = "2.5.1"
|
||||||
|
|
||||||
|
implementation("androidx.room:room-runtime:$room_version")
|
||||||
|
annotationProcessor("androidx.room:room-compiler:$room_version")
|
||||||
|
|
||||||
//-- Room
|
|
||||||
// To use Kotlin annotation processing tool (kapt)
|
// To use Kotlin annotation processing tool (kapt)
|
||||||
//kapt("androidx.room:room-compiler:$room_version")
|
//kapt("androidx.room:room-compiler:$room_version")
|
||||||
// To use Kotlin Symbol Processing (KSP)
|
// To use Kotlin Symbol Processing (KSP)
|
||||||
val room_version = "2.5.1"
|
|
||||||
|
|
||||||
ksp("androidx.room:room-compiler:$room_version")
|
ksp("androidx.room:room-compiler:$room_version")
|
||||||
annotationProcessor("androidx.room:room-compiler:$room_version")
|
|
||||||
implementation("androidx.room:room-runtime:$room_version")
|
// optional - Kotlin Extensions and Coroutines support for Room
|
||||||
implementation("androidx.room:room-ktx:$room_version")
|
implementation("androidx.room:room-ktx:$room_version")
|
||||||
|
|
||||||
|
// optional - Guava support for Room, including Optional and ListenableFuture
|
||||||
implementation("androidx.room:room-guava:$room_version")
|
implementation("androidx.room:room-guava:$room_version")
|
||||||
|
|
||||||
|
// optional - Test helpers
|
||||||
testImplementation("androidx.room:room-testing:$room_version")
|
testImplementation("androidx.room:room-testing:$room_version")
|
||||||
|
|
||||||
|
// optional - Paging 3 Integration
|
||||||
implementation("androidx.room:room-paging:$room_version")
|
implementation("androidx.room:room-paging:$room_version")
|
||||||
|
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0")
|
||||||
|
|
||||||
//-- Ktor
|
|
||||||
|
// Ktor
|
||||||
val ktor_version = "2.3.1"
|
val ktor_version = "2.3.1"
|
||||||
implementation("io.ktor:ktor-client-core:$ktor_version")
|
implementation("io.ktor:ktor-client-core:$ktor_version")
|
||||||
implementation("io.ktor:ktor-client-cio:$ktor_version")
|
implementation("io.ktor:ktor-client-cio:$ktor_version")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0")
|
|
||||||
implementation(platform("dev.forkhandles:forkhandles-bom:2.6.0.0"))
|
implementation(platform("dev.forkhandles:forkhandles-bom:2.6.0.0"))
|
||||||
implementation("dev.forkhandles:result4k")
|
implementation("dev.forkhandles:result4k")
|
||||||
|
|
||||||
implementation("io.ktor:ktor-client-core:2.3.1")
|
implementation("io.ktor:ktor-client-core:2.3.1")
|
||||||
implementation("io.ktor:ktor-client-okhttp:2.3.1")
|
implementation("io.ktor:ktor-client-okhttp:2.3.1")
|
||||||
implementation("androidx.security:security-crypto-ktx:1.1.0-alpha06")
|
|
||||||
|
|
||||||
|
implementation("androidx.security:security-crypto-ktx:1.1.0-alpha06")
|
||||||
|
|
||||||
// For Identity Credential APIs
|
// For Identity Credential APIs
|
||||||
implementation("androidx.security:security-identity-credential:1.0.0-alpha03")
|
implementation("androidx.security:security-identity-credential:1.0.0-alpha03")
|
||||||
|
@ -124,14 +143,10 @@ dependencies {
|
||||||
|
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
|
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
|
||||||
|
|
||||||
|
// Map Compose library
|
||||||
//-- Map Compose library
|
|
||||||
implementation("ovh.plrapps:mapcompose:2.7.1")
|
implementation("ovh.plrapps:mapcompose:2.7.1")
|
||||||
|
|
||||||
|
// Glide
|
||||||
//-- Glide
|
implementation ("com.github.bumptech.glide:glide:4.14.2")
|
||||||
implementation("com.github.bumptech.glide:glide:4.14.2")
|
|
||||||
implementation("com.github.bumptech.glide:compose:1.0.0-alpha.1")
|
implementation("com.github.bumptech.glide:compose:1.0.0-alpha.1")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
|
@ -1,16 +1,28 @@
|
||||||
|
@file:OptIn(
|
||||||
|
ExperimentalMaterial3Api::class, ExperimentalMaterial3Api::class,
|
||||||
|
ExperimentalMaterial3Api::class
|
||||||
|
)
|
||||||
|
|
||||||
package ru.nm17.narodmon
|
package ru.nm17.narodmon
|
||||||
|
|
||||||
|
import android.content.pm.ApplicationInfo
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Person
|
||||||
|
import androidx.compose.material.icons.rounded.Add
|
||||||
|
import androidx.compose.material.icons.rounded.Menu
|
||||||
|
import androidx.compose.material3.BottomAppBar
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.FloatingActionButton
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
@ -22,17 +34,65 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.navigation.compose.NavHost
|
||||||
|
import androidx.navigation.compose.composable
|
||||||
|
import androidx.navigation.compose.rememberNavController
|
||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
|
import androidx.security.crypto.EncryptedSharedPreferences
|
||||||
|
import androidx.security.crypto.MasterKeys
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import ru.nm17.narodmon.db.AppDatabase
|
import ru.nm17.narodmon.db.AppDatabase
|
||||||
import ru.nm17.narodmon.db.entities.KVSetting
|
import ru.nm17.narodmon.db.entities.KVSetting
|
||||||
import ru.nm17.narodmon.ui.dialogs.AgreementDialog
|
import ru.nm17.narodmon.ui.dialogs.AgreementDialog
|
||||||
import ru.nm17.narodmon.ui.navHost.AppNavHost
|
import ru.nm17.narodmon.ui.dialogs.UuidDialog
|
||||||
|
import ru.nm17.narodmon.ui.sensorsScreen.SensorsScreen
|
||||||
import ru.nm17.narodmon.ui.theme.NarodMonTheme
|
import ru.nm17.narodmon.ui.theme.NarodMonTheme
|
||||||
|
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun AppNavHost() {
|
||||||
|
val navController = rememberNavController()
|
||||||
|
val coScope = rememberCoroutineScope()
|
||||||
|
NavHost(navController = navController, startDestination = "sensors") {
|
||||||
|
composable("agreement") {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
composable("sensors") {
|
||||||
|
Scaffold(bottomBar = {
|
||||||
|
BottomAppBar(actions = {
|
||||||
|
Image(
|
||||||
|
Icons.Rounded.Menu,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
}, floatingActionButton = {
|
||||||
|
FloatingActionButton(onClick = { /*TODO*/ }) {
|
||||||
|
Image(
|
||||||
|
Icons.Rounded.Add,
|
||||||
|
contentDescription = ""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
contentPadding = PaddingValues(start = 16.dp)
|
||||||
|
)
|
||||||
|
}) {
|
||||||
|
Column(modifier = Modifier.padding(it)) {
|
||||||
|
SensorsScreen(navController)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*...*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -65,6 +125,10 @@ class MainActivity : ComponentActivity() {
|
||||||
|
|
||||||
NarodMonTheme {
|
NarodMonTheme {
|
||||||
var agreed by remember { mutableStateOf(true) }
|
var agreed by remember { mutableStateOf(true) }
|
||||||
|
var uuid: String? by remember { mutableStateOf(null) }
|
||||||
|
val debug = remember {
|
||||||
|
0 != applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE
|
||||||
|
}
|
||||||
|
|
||||||
LaunchedEffect(key1 = Unit, block = {
|
LaunchedEffect(key1 = Unit, block = {
|
||||||
coScope.launch(Dispatchers.IO) {
|
coScope.launch(Dispatchers.IO) {
|
||||||
|
@ -74,7 +138,7 @@ class MainActivity : ComponentActivity() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!agreed) {
|
if (!agreed && !debug) {
|
||||||
Scaffold {
|
Scaffold {
|
||||||
AgreementDialog {
|
AgreementDialog {
|
||||||
coScope.launch(Dispatchers.IO) {
|
coScope.launch(Dispatchers.IO) {
|
||||||
|
@ -93,9 +157,30 @@ class MainActivity : ComponentActivity() {
|
||||||
Text(text = stringResource(R.string.waiting_for_user_agreement))
|
Text(text = stringResource(R.string.waiting_for_user_agreement))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else if (debug && uuid == null) {
|
||||||
|
Scaffold {
|
||||||
|
UuidDialog { uuidNew ->
|
||||||
|
uuid = uuidNew
|
||||||
|
}
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(it)
|
||||||
|
) {
|
||||||
|
CircularProgressIndicator()
|
||||||
|
Text(text = "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
AppNavHost()
|
AppNavHost()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A surface container using the 'background' color from the theme
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities
|
|
||||||
|
|
||||||
|
|
||||||
data class SensorEntity(
|
|
||||||
val changed: Int,
|
|
||||||
val fav: Int,
|
|
||||||
val id: Int,
|
|
||||||
val mac: String,
|
|
||||||
val name: String,
|
|
||||||
val pub: Int,
|
|
||||||
val time: Int,
|
|
||||||
val trend: Int,
|
|
||||||
val type: Int,
|
|
||||||
val unit: String,
|
|
||||||
val value: Double
|
|
||||||
)
|
|
|
@ -1,8 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.addLike
|
|
||||||
|
|
||||||
data class AddLikeRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val id: Int,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,7 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.addLike
|
|
||||||
|
|
||||||
data class AddLikeResponseEntity(
|
|
||||||
val id: Int,
|
|
||||||
val liked: Int,
|
|
||||||
val time: Int
|
|
||||||
)
|
|
|
@ -1,11 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.appInit
|
|
||||||
|
|
||||||
data class AppInitRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val lang: String,
|
|
||||||
val platform: String,
|
|
||||||
val utc: Int,
|
|
||||||
val uuid: String,
|
|
||||||
val version: String
|
|
||||||
)
|
|
|
@ -1,14 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.appInit
|
|
||||||
|
|
||||||
data class AppInitResponseEntity(
|
|
||||||
val addr: String,
|
|
||||||
val favorites: List<Any>,
|
|
||||||
val lat: Double,
|
|
||||||
val latest: String,
|
|
||||||
val login: String,
|
|
||||||
val lon: Double,
|
|
||||||
val timestamp: Int,
|
|
||||||
val types: List<AppInitTypeEntity>,
|
|
||||||
val url: String,
|
|
||||||
val vip: Int
|
|
||||||
)
|
|
|
@ -1,7 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.appInit
|
|
||||||
|
|
||||||
data class AppInitTypeEntity(
|
|
||||||
val name: String,
|
|
||||||
val type: Int,
|
|
||||||
val unit: String
|
|
||||||
)
|
|
|
@ -1,12 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.bugReport
|
|
||||||
|
|
||||||
data class BugReportRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val email: String,
|
|
||||||
val logs: String,
|
|
||||||
val mess: String,
|
|
||||||
val name: String,
|
|
||||||
val time: Int,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,8 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.disLike
|
|
||||||
|
|
||||||
data class DisLikeRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val id: Int,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,7 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.disLike
|
|
||||||
|
|
||||||
data class DisLikeResponseEntity(
|
|
||||||
val id: Int,
|
|
||||||
val liked: Int,
|
|
||||||
val time: Int
|
|
||||||
)
|
|
|
@ -1,12 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.mapBounds
|
|
||||||
|
|
||||||
data class MapBoundsDeviceEntity(
|
|
||||||
val id: Int,
|
|
||||||
val lat: Double,
|
|
||||||
val lon: Double,
|
|
||||||
val name: String,
|
|
||||||
val time: Int,
|
|
||||||
val type: Int,
|
|
||||||
val unit: String,
|
|
||||||
val value: Double
|
|
||||||
)
|
|
|
@ -1,10 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.mapBounds
|
|
||||||
|
|
||||||
data class MapBoundsRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val bounds: List<Int>,
|
|
||||||
val cmd: String,
|
|
||||||
val lang: String,
|
|
||||||
val limit: Int,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,6 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.mapBounds
|
|
||||||
|
|
||||||
data class MapBoundsResponseEntity(
|
|
||||||
val devices: List<MapBoundsDeviceEntity>,
|
|
||||||
val webcams: List<MapBoundsWebcamEntity>
|
|
||||||
)
|
|
|
@ -1,10 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.mapBounds
|
|
||||||
|
|
||||||
data class MapBoundsWebcamEntity(
|
|
||||||
val id: Int,
|
|
||||||
val image: String,
|
|
||||||
val lat: Double,
|
|
||||||
val lon: Double,
|
|
||||||
val name: String,
|
|
||||||
val time: Int
|
|
||||||
)
|
|
|
@ -1,9 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.nameSensor
|
|
||||||
|
|
||||||
data class NameSensorRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val id: Int,
|
|
||||||
val name: String,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,8 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.pubSensor
|
|
||||||
|
|
||||||
data class PubSensorRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val id: Int,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,6 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.pubSensor
|
|
||||||
|
|
||||||
data class PubSensorResponseEntity(
|
|
||||||
val code: Int,
|
|
||||||
val id: Int
|
|
||||||
)
|
|
|
@ -1,9 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.sendCommand
|
|
||||||
|
|
||||||
data class SendCommandRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val command: String,
|
|
||||||
val id: Int,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,13 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.sendComplaint
|
|
||||||
|
|
||||||
data class SendComplaintRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val email: String,
|
|
||||||
val id: Int,
|
|
||||||
val name: String,
|
|
||||||
val problem: String,
|
|
||||||
val time: Int,
|
|
||||||
val uuid: String,
|
|
||||||
val value: Int
|
|
||||||
)
|
|
|
@ -1,12 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.sendMessage
|
|
||||||
|
|
||||||
data class SendMessageRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val email: String,
|
|
||||||
val mess: String,
|
|
||||||
val name: String,
|
|
||||||
val subj: String,
|
|
||||||
val uid: Int,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,7 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.sensorsHistory
|
|
||||||
|
|
||||||
data class HistoryDataEntity(
|
|
||||||
val id: Int,
|
|
||||||
val time: Int,
|
|
||||||
val value: Double
|
|
||||||
)
|
|
|
@ -1,8 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.sensorsHistory
|
|
||||||
|
|
||||||
data class HistorySensorEntity(
|
|
||||||
val id: Int,
|
|
||||||
val name: String,
|
|
||||||
val type: Int,
|
|
||||||
val unit: String
|
|
||||||
)
|
|
|
@ -1,10 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.sensorsHistory
|
|
||||||
|
|
||||||
data class SensorsHistoryRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val id: Int,
|
|
||||||
val offset: Int,
|
|
||||||
val period: String,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,6 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.sensorsHistory
|
|
||||||
|
|
||||||
data class SensorsHistoryResponseEntity(
|
|
||||||
val `data`: List<HistoryDataEntity>,
|
|
||||||
val sensors: List<HistorySensorEntity>
|
|
||||||
)
|
|
|
@ -1,19 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.sensorsNearby
|
|
||||||
|
|
||||||
import ru.nm17.narodmon.appNarodMonApiClient.entities.SensorEntity
|
|
||||||
|
|
||||||
|
|
||||||
data class NearbyDeviceEntity(
|
|
||||||
val cmd: Int,
|
|
||||||
val distance: Double,
|
|
||||||
val id: Int,
|
|
||||||
val lat: Double,
|
|
||||||
val location: String,
|
|
||||||
val lon: Double,
|
|
||||||
val mac: String,
|
|
||||||
val my: Int,
|
|
||||||
val name: String,
|
|
||||||
val owner: String,
|
|
||||||
val sensors: List<SensorEntity>,
|
|
||||||
val time: Int
|
|
||||||
)
|
|
|
@ -1,12 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.sensorsNearby
|
|
||||||
|
|
||||||
data class SensorsNearbyRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val lang: String,
|
|
||||||
val lat: Double,
|
|
||||||
val lon: Double,
|
|
||||||
val radius: Int,
|
|
||||||
val types: List<Int>,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,5 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.sensorsNearby
|
|
||||||
|
|
||||||
data class SensorsNearbyResponseEntity(
|
|
||||||
val devices: List<NearbyDeviceEntity>
|
|
||||||
)
|
|
|
@ -1,19 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.sensorsOnDevice
|
|
||||||
|
|
||||||
import ru.nm17.narodmon.ui.entities.SensorEntity
|
|
||||||
|
|
||||||
data class SensorOnDeviceEntity(
|
|
||||||
val cmd: Int,
|
|
||||||
val distance: Double,
|
|
||||||
val id: Int,
|
|
||||||
val info: String,
|
|
||||||
val location: String,
|
|
||||||
val mac: String,
|
|
||||||
val my: Int,
|
|
||||||
val name: String,
|
|
||||||
val owner: String,
|
|
||||||
val photo: String,
|
|
||||||
val sensors: List<SensorEntity>,
|
|
||||||
val site: String,
|
|
||||||
val time: Int
|
|
||||||
)
|
|
|
@ -1,9 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.sensorsOnDevice
|
|
||||||
|
|
||||||
data class SensorsOnDeviceRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val devices: List<Int>,
|
|
||||||
val lang: String,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,5 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.sensorsOnDevice
|
|
||||||
|
|
||||||
data class SensorsOnDeviceResponseEntity(
|
|
||||||
val devices: List<SensorOnDeviceEntity>
|
|
||||||
)
|
|
|
@ -1,10 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.sensorsValues
|
|
||||||
|
|
||||||
data class SensorValueEntity(
|
|
||||||
val changed: Int,
|
|
||||||
val id: Int,
|
|
||||||
val time: Int,
|
|
||||||
val trend: Int,
|
|
||||||
val type: Int,
|
|
||||||
val value: Int
|
|
||||||
)
|
|
|
@ -1,8 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.sensorsValues
|
|
||||||
|
|
||||||
data class SensorsValuesRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val sensors: List<Int>,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,5 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.sensorsValues
|
|
||||||
|
|
||||||
data class SensorsValuesResponseEntity(
|
|
||||||
val sensors: List<SensorValueEntity>
|
|
||||||
)
|
|
|
@ -1,9 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.userFavorites
|
|
||||||
|
|
||||||
data class FavoriteSensorEntity(
|
|
||||||
val id: Int,
|
|
||||||
val name: String,
|
|
||||||
val time: Int,
|
|
||||||
val type: Int,
|
|
||||||
val value: Double
|
|
||||||
)
|
|
|
@ -1,8 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.userFavorites
|
|
||||||
|
|
||||||
data class FavoriteWebcamEntity(
|
|
||||||
val id: Int,
|
|
||||||
val image: String,
|
|
||||||
val name: String,
|
|
||||||
val time: Int
|
|
||||||
)
|
|
|
@ -1,10 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.userFavorites
|
|
||||||
|
|
||||||
data class UserFavoritesRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val lang: String,
|
|
||||||
val sensors: List<Int>,
|
|
||||||
val uuid: String,
|
|
||||||
val webcams: List<Int>
|
|
||||||
)
|
|
|
@ -1,6 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.userFavorites
|
|
||||||
|
|
||||||
data class UserFavoritesResponseEntity(
|
|
||||||
val sensors: List<FavoriteSensorEntity>,
|
|
||||||
val webcams: List<FavoriteWebcamEntity>
|
|
||||||
)
|
|
|
@ -1,6 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.userLocation
|
|
||||||
|
|
||||||
data class CellEntity(
|
|
||||||
val bssid: String,
|
|
||||||
val rssi: Int
|
|
||||||
)
|
|
|
@ -1,9 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.userLocation
|
|
||||||
|
|
||||||
data class UserLocationByAddrRequestEntity(
|
|
||||||
val addr: String,
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val lang: String,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,9 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.userLocation
|
|
||||||
|
|
||||||
data class UserLocationByCellRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cells: List<CellEntity>,
|
|
||||||
val cmd: String,
|
|
||||||
val lang: String,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,10 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.userLocation
|
|
||||||
|
|
||||||
data class UserLocationByCoordRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val lang: String,
|
|
||||||
val lat: Double,
|
|
||||||
val lon: Double,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,9 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.userLocation
|
|
||||||
|
|
||||||
data class UserLocationByWifiRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val lang: String,
|
|
||||||
val uuid: String,
|
|
||||||
val wifi: List<WifiEntity>
|
|
||||||
)
|
|
|
@ -1,7 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.userLocation
|
|
||||||
|
|
||||||
data class UserLocationResponseEntity(
|
|
||||||
val addr: String,
|
|
||||||
val lat: Double,
|
|
||||||
val lon: Double
|
|
||||||
)
|
|
|
@ -1,6 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.userLocation
|
|
||||||
|
|
||||||
data class WifiEntity(
|
|
||||||
val bssid: String,
|
|
||||||
val rssi: Int
|
|
||||||
)
|
|
|
@ -1,10 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.userLogon
|
|
||||||
|
|
||||||
data class UserLogonRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val hash: String,
|
|
||||||
val lang: String,
|
|
||||||
val login: String,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,8 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.userLogon
|
|
||||||
|
|
||||||
data class UserLogonResponseEntity(
|
|
||||||
val login: String,
|
|
||||||
val tz: Int,
|
|
||||||
val uid: Int,
|
|
||||||
val vip: Int
|
|
||||||
)
|
|
|
@ -1,7 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.userLogout
|
|
||||||
|
|
||||||
data class UserLogoutRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,6 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.userLogout
|
|
||||||
|
|
||||||
data class UserLogoutResponseEntity(
|
|
||||||
val login: String,
|
|
||||||
val uid: Int
|
|
||||||
)
|
|
|
@ -1,14 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.weatherReport
|
|
||||||
|
|
||||||
data class WeatherReportRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val humid: String,
|
|
||||||
val lang: String,
|
|
||||||
val lat: Double,
|
|
||||||
val lon: Double,
|
|
||||||
val press: String,
|
|
||||||
val temp: String,
|
|
||||||
val uuid: String,
|
|
||||||
val wind: String
|
|
||||||
)
|
|
|
@ -1,5 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.weatherReport
|
|
||||||
|
|
||||||
data class WeatherReportResponseEntity(
|
|
||||||
val result: String
|
|
||||||
)
|
|
|
@ -1,6 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.webcamImages
|
|
||||||
|
|
||||||
data class WebcamImageEntity(
|
|
||||||
val image: String,
|
|
||||||
val time: Int
|
|
||||||
)
|
|
|
@ -1,9 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.webcamImages
|
|
||||||
|
|
||||||
data class WebcamImagesRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val id: Int,
|
|
||||||
val limit: Int,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,9 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.webcamImages
|
|
||||||
|
|
||||||
data class WebcamImagesResponseEntity(
|
|
||||||
val distance: Double,
|
|
||||||
val id: Int,
|
|
||||||
val images: List<WebcamImageEntity>,
|
|
||||||
val location: String,
|
|
||||||
val name: String
|
|
||||||
)
|
|
|
@ -1,15 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.webcamsNearby
|
|
||||||
|
|
||||||
data class WebcamNearbyEntity(
|
|
||||||
val distance: Double,
|
|
||||||
val fav: Int,
|
|
||||||
val id: Int,
|
|
||||||
val image: String,
|
|
||||||
val lat: Double,
|
|
||||||
val location: String,
|
|
||||||
val lon: Double,
|
|
||||||
val my: Int,
|
|
||||||
val name: String,
|
|
||||||
val owner: String,
|
|
||||||
val time: Int
|
|
||||||
)
|
|
|
@ -1,11 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.webcamsNearby
|
|
||||||
|
|
||||||
data class WebcamsNearbyRequestEntity(
|
|
||||||
val api_key: String,
|
|
||||||
val cmd: String,
|
|
||||||
val lang: String,
|
|
||||||
val lat: Double,
|
|
||||||
val lon: Double,
|
|
||||||
val radius: Int,
|
|
||||||
val uuid: String
|
|
||||||
)
|
|
|
@ -1,5 +0,0 @@
|
||||||
package ru.nm17.narodmon.appNarodMonApiClient.entities.webcamsNearby
|
|
||||||
|
|
||||||
data class WebcamsResponseEntity(
|
|
||||||
val webcams: List<WebcamNearbyEntity>
|
|
||||||
)
|
|
59
app/src/main/java/ru/nm17/narodmon/ui/dialogs/UuidDialog.kt
Normal file
59
app/src/main/java/ru/nm17/narodmon/ui/dialogs/UuidDialog.kt
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package ru.nm17.narodmon.ui.dialogs
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.KeyboardArrowRight
|
||||||
|
import androidx.compose.material3.AlertDialog
|
||||||
|
import androidx.compose.material3.Divider
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.ListItem
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.material3.TextField
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
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.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import ru.nm17.narodmon.R
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
@ExperimentalMaterial3Api
|
||||||
|
@Composable
|
||||||
|
fun UuidDialog(modifier: Modifier = Modifier, onUuidInput: (uuid: String) -> Unit) {
|
||||||
|
var uuid by remember { mutableStateOf("") }
|
||||||
|
|
||||||
|
AlertDialog(
|
||||||
|
onDismissRequest = { },
|
||||||
|
title = { Text(text = stringResource(id = R.string.uuid_dialog_title)) },
|
||||||
|
text = {
|
||||||
|
TextField(
|
||||||
|
value = uuid,
|
||||||
|
onValueChange = { uuid = it },
|
||||||
|
placeholder = { Text(text = "UUID") }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(
|
||||||
|
onClick = { onUuidInput(uuid) }
|
||||||
|
) {
|
||||||
|
Text(text = stringResource(id = R.string.uuid_confirm))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dismissButton = {
|
||||||
|
TextButton(
|
||||||
|
onClick = { onUuidInput("") }) {
|
||||||
|
Text(text = stringResource(id = R.string.uuid_generate))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier = modifier
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,50 +0,0 @@
|
||||||
package ru.nm17.narodmon.ui.elements
|
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
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.Switch
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import ru.nm17.narodmon.R
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Кнопка, которая нужна для настроек.
|
|
||||||
* @param titleId Id заголовка кнопки
|
|
||||||
* @param leadingItem Заполнить, когда нужно вставить Composable перед заголовком(например [Icon], [FilterCheckbox] или [Switch]
|
|
||||||
*/
|
|
||||||
@Composable
|
|
||||||
fun SettingsItem(
|
|
||||||
@StringRes titleId: Int,
|
|
||||||
leadingItem: @Composable (() -> Unit)? = null,
|
|
||||||
onClick: () -> Unit = {}
|
|
||||||
) {
|
|
||||||
Row(modifier = Modifier.padding(16.dp)) {
|
|
||||||
if (leadingItem != null) {
|
|
||||||
leadingItem.invoke()
|
|
||||||
Spacer(modifier = Modifier.size(16.dp))
|
|
||||||
}
|
|
||||||
Column(modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.clickable { onClick.invoke() }) {
|
|
||||||
Text(text = stringResource(id = titleId))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview(showBackground = true)
|
|
||||||
@Composable
|
|
||||||
fun PreviewSettingsItem() {
|
|
||||||
SettingsItem(R.string.about_app) {}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package ru.nm17.narodmon.ui.messagesScreen
|
|
||||||
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun MessagesScreen() {
|
|
||||||
Text(text = "todo")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
fun PreviewMessagesScreen() {
|
|
||||||
MessagesScreen()
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
package ru.nm17.narodmon.ui.navHost
|
|
||||||
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.navigation.compose.NavHost
|
|
||||||
import androidx.navigation.compose.composable
|
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import ru.nm17.narodmon.ui.settings.SettingsNavigation
|
|
||||||
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
fun AppNavHost() {
|
|
||||||
val navController = rememberNavController()
|
|
||||||
NavHost(navController = navController, startDestination = "main") {
|
|
||||||
composable("main") {
|
|
||||||
MainScreen(navController)
|
|
||||||
}
|
|
||||||
composable("settings") {
|
|
||||||
SettingsNavigation()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
fun PreviewAppNavHost() {
|
|
||||||
AppNavHost()
|
|
||||||
}
|
|
|
@ -1,83 +0,0 @@
|
||||||
package ru.nm17.narodmon.ui.navHost
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.NavigationBar
|
|
||||||
import androidx.compose.material3.NavigationBarItem
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.navigation.NavController
|
|
||||||
import androidx.navigation.NavGraph.Companion.findStartDestination
|
|
||||||
import androidx.navigation.compose.NavHost
|
|
||||||
import androidx.navigation.compose.composable
|
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import ru.nm17.narodmon.ui.sensorsScreen.SensorsScreen
|
|
||||||
import ru.nm17.narodmon.ui.theme.NarodMonTheme
|
|
||||||
import ru.nm17.narodmon.ui.webCamsScreen.WebCamsScreen
|
|
||||||
|
|
||||||
|
|
||||||
val items = listOf(
|
|
||||||
MainScreenSealed.Sensors,
|
|
||||||
MainScreenSealed.Webcams,
|
|
||||||
MainScreenSealed.Messages
|
|
||||||
)
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun MainScreen(outerNavController: NavController) {
|
|
||||||
val navController = rememberNavController()
|
|
||||||
|
|
||||||
Scaffold(
|
|
||||||
bottomBar = {
|
|
||||||
NavigationBar {
|
|
||||||
|
|
||||||
items.forEach { screen ->
|
|
||||||
NavigationBarItem(
|
|
||||||
selected = navController.currentDestination?.route == screen.route,
|
|
||||||
onClick = {
|
|
||||||
navController.navigate(screen.route) {
|
|
||||||
popUpTo(navController.graph.findStartDestination().id) {
|
|
||||||
saveState = true
|
|
||||||
}
|
|
||||||
launchSingleTop = true
|
|
||||||
restoreState = true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
label = { Text(text = stringResource(id = screen.resourceId)) },
|
|
||||||
icon = {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(id = screen.iconId),
|
|
||||||
contentDescription = ""
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
modifier = Modifier.fillMaxSize()
|
|
||||||
) {
|
|
||||||
NavHost(
|
|
||||||
navController,
|
|
||||||
startDestination = MainScreenSealed.Sensors.route,
|
|
||||||
Modifier.padding(it)
|
|
||||||
) {
|
|
||||||
composable(MainScreenSealed.Sensors.route) {
|
|
||||||
SensorsScreen(outerNavController)
|
|
||||||
}
|
|
||||||
composable(MainScreenSealed.Webcams.route) { WebCamsScreen(navController) }
|
|
||||||
composable(MainScreenSealed.Messages.route) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
fun PreviewMainScreen() {
|
|
||||||
NarodMonTheme {
|
|
||||||
MainScreen(rememberNavController())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package ru.nm17.narodmon.ui.navHost
|
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import ru.nm17.narodmon.R
|
|
||||||
|
|
||||||
sealed class MainScreenSealed(
|
|
||||||
val route: String,
|
|
||||||
@StringRes val resourceId: Int,
|
|
||||||
@DrawableRes val iconId: Int
|
|
||||||
) {
|
|
||||||
object Sensors : MainScreenSealed("sensors", R.string.sensors_page_title, R.drawable.ic_home)
|
|
||||||
object Webcams : MainScreenSealed("webcams", R.string.webcams, R.drawable.ic_webcam)
|
|
||||||
|
|
||||||
object Messages : MainScreenSealed("messages", R.string.messages, R.drawable.ic_message)
|
|
||||||
|
|
||||||
object Settings : MainScreenSealed("settings", R.string.settings, R.drawable.ic_settings)
|
|
||||||
}
|
|
|
@ -1,6 +1,8 @@
|
||||||
package ru.nm17.narodmon.ui.sensorsScreen
|
package ru.nm17.narodmon.ui.sensorsScreen
|
||||||
|
|
||||||
|
import androidx.compose.animation.AnimatedContent
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.ExperimentalAnimationApi
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
|
@ -11,23 +13,29 @@ import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.LazyRow
|
import androidx.compose.foundation.lazy.LazyRow
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.Settings
|
import androidx.compose.material.icons.filled.ArrowDropDown
|
||||||
|
import androidx.compose.material.icons.rounded.ArrowDropDown
|
||||||
import androidx.compose.material.icons.rounded.Check
|
import androidx.compose.material.icons.rounded.Check
|
||||||
|
import androidx.compose.material.icons.rounded.Person
|
||||||
import androidx.compose.material3.BottomSheetScaffold
|
import androidx.compose.material3.BottomSheetScaffold
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.FilterChip
|
import androidx.compose.material3.FilterChip
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.SearchBar
|
import androidx.compose.material3.SearchBar
|
||||||
import androidx.compose.material3.SearchBarDefaults
|
import androidx.compose.material3.SearchBarDefaults
|
||||||
import androidx.compose.material3.SheetValue
|
import androidx.compose.material3.SheetValue
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextField
|
||||||
|
import androidx.compose.material3.TextFieldColors
|
||||||
|
import androidx.compose.material3.TextFieldDefaults
|
||||||
import androidx.compose.material3.rememberBottomSheetScaffoldState
|
import androidx.compose.material3.rememberBottomSheetScaffoldState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
@ -37,23 +45,28 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import ovh.plrapps.mapcompose.core.debounce
|
||||||
import ru.nm17.narodmon.R
|
import ru.nm17.narodmon.R
|
||||||
import ru.nm17.narodmon.db.entities.SensorType
|
import ru.nm17.narodmon.db.entities.SensorType
|
||||||
import ru.nm17.narodmon.ui.dialogs.FilterSensorsDialog
|
import ru.nm17.narodmon.ui.dialogs.FilterSensorsDialog
|
||||||
import ru.nm17.narodmon.ui.dialogs.SortSensorsDialog
|
|
||||||
import ru.nm17.narodmon.ui.elements.SensorItem
|
import ru.nm17.narodmon.ui.elements.SensorItem
|
||||||
|
import ru.nm17.narodmon.ui.dialogs.SortSensorsDialog
|
||||||
import ru.nm17.narodmon.ui.elements.TileMap
|
import ru.nm17.narodmon.ui.elements.TileMap
|
||||||
import ru.nm17.narodmon.ui.entities.SensorEntity
|
import ru.nm17.narodmon.ui.entities.SensorEntity
|
||||||
import ru.nm17.narodmon.ui.entities.SensorSortingUiEntity
|
import ru.nm17.narodmon.ui.entities.SensorSortingUiEntity
|
||||||
import ru.nm17.narodmon.ui.entities.SortingTypes
|
import ru.nm17.narodmon.ui.entities.SortingTypes
|
||||||
import ru.nm17.narodmon.ui.navHost.MainScreenSealed
|
|
||||||
import ru.nm17.narodmon.ui.theme.NarodMonTheme
|
import ru.nm17.narodmon.ui.theme.NarodMonTheme
|
||||||
import ru.nm17.narodmon.ui.toChipTitle
|
import ru.nm17.narodmon.ui.toChipTitle
|
||||||
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalAnimationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun SensorsScreen(outerNavController: NavController) {
|
fun SensorsScreen(navController: NavController) {
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
var searchQuery by remember { mutableStateOf("") }
|
var searchQuery by remember { mutableStateOf("") }
|
||||||
var searchActive by remember { mutableStateOf(false) }
|
var searchActive by remember { mutableStateOf(false) }
|
||||||
|
@ -106,100 +119,108 @@ fun SensorsScreen(outerNavController: NavController) {
|
||||||
mutableStateOf(SheetHeight.ExtraExpanded)
|
mutableStateOf(SheetHeight.ExtraExpanded)
|
||||||
}
|
}
|
||||||
|
|
||||||
BottomSheetScaffold(modifier = Modifier.fillMaxSize(), sheetPeekHeight = when (sheetHeight) {
|
BottomSheetScaffold(
|
||||||
SheetHeight.ExtraExpanded -> 256.dp
|
modifier = Modifier.fillMaxSize(),
|
||||||
SheetHeight.Expanded -> 128.dp
|
sheetPeekHeight = when (sheetHeight) {
|
||||||
SheetHeight.Hidden -> 0.dp
|
SheetHeight.ExtraExpanded -> 256.dp
|
||||||
}, scaffoldState = scaffoldState, sheetContent = {
|
SheetHeight.Expanded -> 128.dp
|
||||||
AnimatedVisibility(visible = scaffoldState.bottomSheetState.currentValue == SheetValue.Expanded) {
|
SheetHeight.Hidden -> 0.dp
|
||||||
OutlinedTextField(
|
},
|
||||||
value = searchQuery,
|
scaffoldState = scaffoldState,
|
||||||
onValueChange = { searchQuery = it },
|
sheetContent = {
|
||||||
placeholder = { Text(stringResource(R.string.search)) },
|
AnimatedVisibility(visible = scaffoldState.bottomSheetState.currentValue == SheetValue.Expanded) {
|
||||||
shape = SearchBarDefaults.inputFieldShape,
|
OutlinedTextField(
|
||||||
|
value = searchQuery,
|
||||||
|
onValueChange = { searchQuery = it },
|
||||||
|
placeholder = { Text(stringResource(R.string.search)) },
|
||||||
|
shape = SearchBarDefaults.inputFieldShape,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 8.dp, vertical = 8.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
LazyRow(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterHorizontally),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = 8.dp, vertical = 8.dp)
|
.padding(horizontal = 16.dp),
|
||||||
)
|
) {
|
||||||
}
|
item {
|
||||||
|
FilterChip(
|
||||||
LazyRow(
|
selected = false,
|
||||||
horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterHorizontally),
|
onClick = { filterShow = true },
|
||||||
modifier = Modifier
|
leadingIcon = {
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = 16.dp),
|
|
||||||
) {
|
|
||||||
item {
|
|
||||||
FilterChip(
|
|
||||||
selected = false,
|
|
||||||
onClick = { filterShow = true },
|
|
||||||
leadingIcon = {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(id = R.drawable.ic_filter),
|
|
||||||
contentDescription = stringResource(id = R.string.sensors_filter)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
trailingIcon = {
|
|
||||||
// Icon(
|
|
||||||
// Icons.Filled.ArrowDropDown,
|
|
||||||
// "",
|
|
||||||
// tint = MaterialTheme.colorScheme.onBackground
|
|
||||||
// )
|
|
||||||
},
|
|
||||||
|
|
||||||
label = { Text(text = stringResource(R.string.sensors_filter)) },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
item {
|
|
||||||
FilterChip(selected = sortingType.sortingType != SortingTypes.DISTANCE,
|
|
||||||
onClick = { sortingShow = true },
|
|
||||||
leadingIcon = {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(id = R.drawable.ic_sort),
|
|
||||||
contentDescription = stringResource(id = R.string.sensors_sorting)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
trailingIcon = {
|
|
||||||
// Icon(
|
|
||||||
// Icons.Filled.ArrowDropDown,
|
|
||||||
// "",
|
|
||||||
// tint = MaterialTheme.colorScheme.onBackground
|
|
||||||
// )
|
|
||||||
},
|
|
||||||
label = {
|
|
||||||
Text(
|
|
||||||
text = stringResource(
|
|
||||||
if (sortingType.sortingType == SortingTypes.DISTANCE) R.string.sensors_sorting
|
|
||||||
else sortingType.stringRes
|
|
||||||
).toChipTitle(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
item {
|
|
||||||
FilterChip(
|
|
||||||
selected = filterMine,
|
|
||||||
onClick = { filterMine = !filterMine },
|
|
||||||
leadingIcon = {
|
|
||||||
if (filterMine) {
|
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Rounded.Check, contentDescription = ""
|
painter = painterResource(id = R.drawable.ic_filter),
|
||||||
|
contentDescription = stringResource(id = R.string.sensors_filter)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
trailingIcon = {
|
||||||
|
// Icon(
|
||||||
|
// Icons.Filled.ArrowDropDown,
|
||||||
|
// "",
|
||||||
|
// tint = MaterialTheme.colorScheme.onBackground
|
||||||
|
// )
|
||||||
|
},
|
||||||
|
|
||||||
|
label = { Text(text = stringResource(R.string.sensors_filter)) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
FilterChip(
|
||||||
|
selected = sortingType.sortingType != SortingTypes.DISTANCE,
|
||||||
|
onClick = { sortingShow = true },
|
||||||
|
leadingIcon = {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.drawable.ic_sort),
|
||||||
|
contentDescription = stringResource(id = R.string.sensors_sorting)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
trailingIcon = {
|
||||||
|
// Icon(
|
||||||
|
// Icons.Filled.ArrowDropDown,
|
||||||
|
// "",
|
||||||
|
// tint = MaterialTheme.colorScheme.onBackground
|
||||||
|
// )
|
||||||
|
},
|
||||||
|
label = {
|
||||||
|
Text(
|
||||||
|
text = stringResource(
|
||||||
|
if (sortingType.sortingType == SortingTypes.DISTANCE) R.string.sensors_sorting
|
||||||
|
else sortingType.stringRes
|
||||||
|
).toChipTitle(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
)
|
||||||
label = { Text(text = stringResource(R.string.sensors_mine)) },
|
}
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyColumn(
|
item {
|
||||||
modifier = Modifier.fillMaxHeight(),
|
FilterChip(
|
||||||
) {
|
selected = filterMine,
|
||||||
items(sensorEntities) { sensor ->
|
onClick = { filterMine = !filterMine },
|
||||||
SensorItem(sensor)
|
leadingIcon = {
|
||||||
|
if (filterMine) {
|
||||||
|
Icon(
|
||||||
|
Icons.Rounded.Check,
|
||||||
|
contentDescription = ""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
label = { Text(text = stringResource(R.string.sensors_mine)) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier.fillMaxHeight(),
|
||||||
|
) {
|
||||||
|
items(sensorEntities) { sensor ->
|
||||||
|
SensorItem(sensor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}) {
|
) {
|
||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
SearchBar(
|
SearchBar(
|
||||||
query = searchQuery,
|
query = searchQuery,
|
||||||
|
@ -210,24 +231,18 @@ fun SensorsScreen(outerNavController: NavController) {
|
||||||
},
|
},
|
||||||
onQueryChange = { query -> searchQuery = query },
|
onQueryChange = { query -> searchQuery = query },
|
||||||
onSearch = { searchActive = false },
|
onSearch = { searchActive = false },
|
||||||
placeholder = { Text(stringResource(R.string.search_sensors)) },
|
placeholder = { Text(stringResource(R.string.search)) },
|
||||||
trailingIcon = {
|
|
||||||
IconButton(onClick = { outerNavController.navigate(MainScreenSealed.Settings.route) }) {
|
|
||||||
Icon(
|
|
||||||
Icons.Outlined.Settings,
|
|
||||||
contentDescription = stringResource(R.string.settings)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(
|
.padding(
|
||||||
horizontal = if (!searchActive) 8.dp else 0.dp,
|
horizontal = if (!searchActive) 8.dp else 0.dp,
|
||||||
|
vertical = if (!searchActive) 16.dp else 0.dp
|
||||||
)
|
)
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
TileMap(
|
TileMap(
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
sheetHeight =
|
sheetHeight =
|
||||||
SheetHeight.Expanded // TODO придумать, чтобы менялось на SheetHeight.ExtraExpanded после взаимодействия с картой
|
SheetHeight.Expanded // TODO придумать, чтобы менялось на SheetHeight.ExtraExpanded после взаимодействия с картой
|
||||||
|
@ -236,18 +251,25 @@ fun SensorsScreen(outerNavController: NavController) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sortingShow) {
|
if (sortingShow) {
|
||||||
SortSensorsDialog(sortingType, onApply = {
|
SortSensorsDialog(
|
||||||
sortingType = it
|
sortingType,
|
||||||
sortingShow = false
|
onApply = {
|
||||||
}, onDismissRequest = {
|
sortingType = it
|
||||||
sortingShow = false
|
sortingShow = false
|
||||||
})
|
},
|
||||||
|
onDismissRequest = {
|
||||||
|
sortingShow = false
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if (filterShow) {
|
if (filterShow) {
|
||||||
FilterSensorsDialog(onApply = {
|
FilterSensorsDialog(
|
||||||
// TODO применение фильтров
|
onApply = {
|
||||||
filterShow = false
|
// TODO применение фильтров
|
||||||
}, onDismissRequest = { filterShow = false })
|
filterShow = false
|
||||||
|
},
|
||||||
|
onDismissRequest = { filterShow = false }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
package ru.nm17.narodmon.ui.settings
|
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import ru.nm17.narodmon.R
|
|
||||||
|
|
||||||
sealed class Settings(val route: String, @StringRes val resourceId: Int) {
|
|
||||||
|
|
||||||
object Main : Settings("settings_main", R.string.settings)
|
|
||||||
object AboutApp : Settings("settings_about_app", R.string.about_app)
|
|
||||||
|
|
||||||
object Debug : Settings("settings_debug_menu", R.string.debug_menu)
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
package ru.nm17.narodmon.ui.settings
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.material3.TopAppBar
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.navigation.compose.NavHost
|
|
||||||
import androidx.navigation.compose.composable
|
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
fun SettingsNavigation() {
|
|
||||||
val navController = rememberNavController()
|
|
||||||
Scaffold(topBar = {
|
|
||||||
TopAppBar(title = { Text(text = navController.currentDestination?.route ?: "") })
|
|
||||||
}) {
|
|
||||||
NavHost(
|
|
||||||
navController = navController,
|
|
||||||
startDestination = Settings.Main.route,
|
|
||||||
modifier = Modifier.padding(it)
|
|
||||||
) {
|
|
||||||
composable(Settings.Main.route) { SettingsScreen(navController) }
|
|
||||||
composable(Settings.AboutApp.route) { }
|
|
||||||
composable(Settings.Debug.route) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
fun PreviewSettingsNavigation() {
|
|
||||||
SettingsNavigation()
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package ru.nm17.narodmon.ui.settings
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.navigation.NavController
|
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import ru.nm17.narodmon.R
|
|
||||||
import ru.nm17.narodmon.ui.elements.SettingsItem
|
|
||||||
import ru.nm17.narodmon.ui.theme.NarodMonTheme
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SettingsScreen(navController: NavController) {
|
|
||||||
LazyColumn(modifier = Modifier.fillMaxSize()) {
|
|
||||||
item {
|
|
||||||
SettingsItem(titleId = R.string.debug_menu) {
|
|
||||||
navController.navigate(Settings.Debug.route)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
item {
|
|
||||||
SettingsItem(R.string.about_app) {
|
|
||||||
navController.navigate(Settings.AboutApp.route)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview(showBackground = true, showSystemUi = false)
|
|
||||||
@Composable
|
|
||||||
fun PreviewSettingsScreen() {
|
|
||||||
NarodMonTheme {
|
|
||||||
SettingsScreen(rememberNavController())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,16 +10,15 @@ import androidx.compose.material3.dynamicLightColorScheme
|
||||||
import androidx.compose.material3.lightColorScheme
|
import androidx.compose.material3.lightColorScheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.SideEffect
|
import androidx.compose.runtime.SideEffect
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.graphics.toArgb
|
import androidx.compose.ui.graphics.toArgb
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalView
|
import androidx.compose.ui.platform.LocalView
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
|
|
||||||
private val DarkColorScheme = darkColorScheme(
|
private val DarkColorScheme = darkColorScheme(
|
||||||
primary = Purple80,
|
primary = Purple80,
|
||||||
secondary = PurpleGrey80,
|
secondary = PurpleGrey80,
|
||||||
tertiary = Pink80
|
tertiary = Pink80
|
||||||
)
|
)
|
||||||
|
|
||||||
private val LightColorScheme = lightColorScheme(
|
private val LightColorScheme = lightColorScheme(
|
||||||
|
@ -27,23 +26,23 @@ private val LightColorScheme = lightColorScheme(
|
||||||
secondary = PurpleGrey80,
|
secondary = PurpleGrey80,
|
||||||
tertiary = Pink80
|
tertiary = Pink80
|
||||||
|
|
||||||
/* Other default colors to override
|
/* Other default colors to override
|
||||||
background = Color(0xFFFFFBFE),
|
background = Color(0xFFFFFBFE),
|
||||||
surface = Color(0xFFFFFBFE),
|
surface = Color(0xFFFFFBFE),
|
||||||
onPrimary = Color.White,
|
onPrimary = Color.White,
|
||||||
onSecondary = Color.White,
|
onSecondary = Color.White,
|
||||||
onTertiary = Color.White,
|
onTertiary = Color.White,
|
||||||
onBackground = Color(0xFF1C1B1F),
|
onBackground = Color(0xFF1C1B1F),
|
||||||
onSurface = Color(0xFF1C1B1F),
|
onSurface = Color(0xFF1C1B1F),
|
||||||
*/
|
*/
|
||||||
)
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun NarodMonTheme(
|
fun NarodMonTheme(
|
||||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||||
// Dynamic color is available on Android 12+
|
// Dynamic color is available on Android 12+
|
||||||
dynamicColor: Boolean = true,
|
dynamicColor: Boolean = true,
|
||||||
content: @Composable () -> Unit
|
content: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
val colorScheme = when {
|
val colorScheme = when {
|
||||||
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
||||||
|
@ -58,16 +57,14 @@ fun NarodMonTheme(
|
||||||
if (!view.isInEditMode) {
|
if (!view.isInEditMode) {
|
||||||
SideEffect {
|
SideEffect {
|
||||||
val window = (view.context as Activity).window
|
val window = (view.context as Activity).window
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
window.statusBarColor = colorScheme.primary.toArgb()
|
||||||
window.statusBarColor = Color.Transparent.toArgb()
|
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme
|
||||||
|
|
||||||
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialTheme(
|
MaterialTheme(
|
||||||
colorScheme = colorScheme,
|
colorScheme = colorScheme,
|
||||||
typography = Typography,
|
typography = Typography,
|
||||||
content = content
|
content = content
|
||||||
)
|
)
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package ru.nm17.narodmon.ui.webCamsScreen
|
package ru.nm17.narodmon.ui.webCamsScreen
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
@ -7,13 +8,13 @@ import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.navigation.NavController
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import ru.nm17.narodmon.ui.theme.NarodMonTheme
|
import ru.nm17.narodmon.ui.theme.NarodMonTheme
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun WebCamsScreen(navController: NavController) {
|
fun WebCamsScreen() {
|
||||||
|
|
||||||
var webCams by remember {
|
var webCams by remember {
|
||||||
mutableStateOf(
|
mutableStateOf(
|
||||||
|
@ -57,6 +58,6 @@ fun WebCamsScreen(navController: NavController) {
|
||||||
@Composable
|
@Composable
|
||||||
fun PreviewWebCams() {
|
fun PreviewWebCams() {
|
||||||
NarodMonTheme {
|
NarodMonTheme {
|
||||||
WebCamsScreen(rememberNavController())
|
WebCamsScreen()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +0,0 @@
|
||||||
<vector android:height="24dp" android:tint="#000000"
|
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M12,5.69l5,4.5V18h-2v-6H9v6H7v-7.81l5,-4.5M12,3L2,12h3v8h6v-6h2v6h6v-8h3L12,3z"/>
|
|
||||||
</vector>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<vector android:autoMirrored="true" android:height="24dp"
|
|
||||||
android:tint="#000000" android:viewportHeight="24"
|
|
||||||
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M4,4h16v12L5.17,16L4,17.17L4,4m0,-2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2L4,2zM6,12h12v2L6,14v-2zM6,9h12v2L6,11L6,9zM6,6h12v2L6,8L6,6z"/>
|
|
||||||
</vector>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<vector android:height="24dp" android:tint="#000000"
|
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98 0,-0.34 -0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.09,-0.16 -0.26,-0.25 -0.44,-0.25 -0.06,0 -0.12,0.01 -0.17,0.03l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.06,-0.02 -0.12,-0.03 -0.18,-0.03 -0.17,0 -0.34,0.09 -0.43,0.25l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98 0,0.33 0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.09,0.16 0.26,0.25 0.44,0.25 0.06,0 0.12,-0.01 0.17,-0.03l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.06,0.02 0.12,0.03 0.18,0.03 0.17,0 0.34,-0.09 0.43,-0.25l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM17.45,11.27c0.04,0.31 0.05,0.52 0.05,0.73 0,0.21 -0.02,0.43 -0.05,0.73l-0.14,1.13 0.89,0.7 1.08,0.84 -0.7,1.21 -1.27,-0.51 -1.04,-0.42 -0.9,0.68c-0.43,0.32 -0.84,0.56 -1.25,0.73l-1.06,0.43 -0.16,1.13 -0.2,1.35h-1.4l-0.19,-1.35 -0.16,-1.13 -1.06,-0.43c-0.43,-0.18 -0.83,-0.41 -1.23,-0.71l-0.91,-0.7 -1.06,0.43 -1.27,0.51 -0.7,-1.21 1.08,-0.84 0.89,-0.7 -0.14,-1.13c-0.03,-0.31 -0.05,-0.54 -0.05,-0.74s0.02,-0.43 0.05,-0.73l0.14,-1.13 -0.89,-0.7 -1.08,-0.84 0.7,-1.21 1.27,0.51 1.04,0.42 0.9,-0.68c0.43,-0.32 0.84,-0.56 1.25,-0.73l1.06,-0.43 0.16,-1.13 0.2,-1.35h1.39l0.19,1.35 0.16,1.13 1.06,0.43c0.43,0.18 0.83,0.41 1.23,0.71l0.91,0.7 1.06,-0.43 1.27,-0.51 0.7,1.21 -1.07,0.85 -0.89,0.7 0.14,1.13zM12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM12,14c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z"/>
|
|
||||||
</vector>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<vector android:height="24dp" android:tint="#000000"
|
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M15,8v8H5V8h10m1,-2H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1v-3.5l4,4v-11l-4,4V7c0,-0.55 -0.45,-1 -1,-1z"/>
|
|
||||||
</vector>
|
|
|
@ -52,10 +52,7 @@
|
||||||
<string name="apply">Применить</string>
|
<string name="apply">Применить</string>
|
||||||
<string name="sort_by_distance_desc">От дальних к ближним</string>
|
<string name="sort_by_distance_desc">От дальних к ближним</string>
|
||||||
<string name="cancel1">Отменить</string>
|
<string name="cancel1">Отменить</string>
|
||||||
<string name="webcams">Веб-камеры</string>
|
<string name="uuid_dialog_title">Введите UUID приложения</string>
|
||||||
<string name="messages">Сообщения</string>
|
<string name="uuid_confirm">Сохранить</string>
|
||||||
<string name="settings">Настройки</string>
|
<string name="uuid_generate">Сгенерировать</string>
|
||||||
<string name="search_sensors">Поиск датчиков</string>
|
|
||||||
<string name="about_app">О приложении</string>
|
|
||||||
<string name="debug_menu">Debug-меню</string>
|
|
||||||
</resources>
|
</resources>
|
|
@ -1,5 +1,5 @@
|
||||||
[versions]
|
[versions]
|
||||||
agp = "8.2.0-alpha07"
|
agp = "8.2.0-alpha08"
|
||||||
kotlin = "1.8.10"
|
kotlin = "1.8.10"
|
||||||
core-ktx = "1.9.0"
|
core-ktx = "1.9.0"
|
||||||
junit = "4.13.2"
|
junit = "4.13.2"
|
||||||
|
|
Loading…
Add table
Reference in a new issue