1
0

199 lines
6.7 KiB
Kotlin
Raw Normal View History

2025-04-21 17:44:40 +03:00
/*
* Created by sweetbread
* Copyright (c) 2025. All rights reserved.
*/
2025-04-21 15:48:45 +03:00
package ru.risdeveau.geotracker
2025-05-03 17:19:54 +03:00
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
2025-04-21 15:48:45 +03:00
import android.os.Bundle
import androidx.activity.ComponentActivity
2025-05-03 17:19:54 +03:00
import androidx.activity.compose.rememberLauncherForActivityResult
2025-04-21 15:48:45 +03:00
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
2025-05-03 17:19:54 +03:00
import androidx.activity.result.contract.ActivityResultContracts
2025-04-21 15:48:45 +03:00
import androidx.compose.foundation.layout.Box
2025-04-21 22:32:36 +03:00
import androidx.compose.foundation.layout.Column
2025-04-21 15:48:45 +03:00
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
2025-05-03 17:19:54 +03:00
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Done
import androidx.compose.material3.Button
2025-04-21 17:44:40 +03:00
import androidx.compose.material3.CircularProgressIndicator
2025-05-03 17:19:54 +03:00
import androidx.compose.material3.Icon
2025-04-22 03:11:25 +03:00
import androidx.compose.material3.MaterialTheme
2025-04-21 17:44:40 +03:00
import androidx.compose.material3.OutlinedTextField
2025-04-21 15:48:45 +03:00
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
2025-04-21 17:44:40 +03:00
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.Alignment
2025-04-21 15:48:45 +03:00
import androidx.compose.ui.Modifier
2025-05-03 17:19:54 +03:00
import androidx.compose.ui.platform.LocalContext
2025-04-22 03:11:25 +03:00
import androidx.compose.ui.text.TextStyle
2025-05-03 17:19:54 +03:00
import androidx.core.content.ContextCompat
import kotlinx.coroutines.delay
2025-04-21 17:44:40 +03:00
import kotlinx.coroutines.launch
2025-04-21 15:48:45 +03:00
import ru.risdeveau.geotracker.ui.theme.GeoTrackerTheme
2025-05-03 17:19:54 +03:00
import splitties.experimental.ExperimentalSplittiesApi
import splitties.init.appCtx
2025-04-22 03:11:25 +03:00
import splitties.resources.appStr
2025-04-21 15:48:45 +03:00
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
GeoTrackerTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
2025-04-21 17:44:40 +03:00
Box(
Modifier
.padding(innerPadding)
.fillMaxSize()) {
2025-04-21 22:32:36 +03:00
var screen by remember { mutableStateOf<Screen>(Screen.Loading) }
2025-04-21 15:48:45 +03:00
2025-04-21 22:32:36 +03:00
when (screen) {
2025-05-03 17:19:54 +03:00
Screen.Main -> {
Text("Hello world")
}
2025-04-21 22:32:36 +03:00
Screen.Settings -> {
2025-05-03 17:19:54 +03:00
Settings(Modifier.align(Alignment.Center)) {
screen = Screen.Main
}
2025-04-21 22:32:36 +03:00
}
Screen.Loading -> {
var loading by remember { mutableStateOf(true) }
if (loading) {
CircularProgressIndicator(Modifier.align(Alignment.Center))
LaunchedEffect(true) {
launch {
screen = if (health(SettingsPreferences.url))
Screen.Main
else
Screen.Settings
}
2025-04-21 17:44:40 +03:00
}
}
}
}
2025-04-21 15:48:45 +03:00
}
}
}
}
}
}
2025-04-21 17:44:40 +03:00
sealed class Screen {
object Main : Screen()
object Settings : Screen()
2025-04-21 22:32:36 +03:00
object Loading : Screen()
2025-04-21 15:48:45 +03:00
}
2025-05-03 17:19:54 +03:00
@OptIn(ExperimentalSplittiesApi::class)
2025-04-21 15:48:45 +03:00
@Composable
2025-05-03 17:19:54 +03:00
fun Settings(modifier: Modifier = Modifier, onConfirm: () -> Unit) {
2025-04-21 17:44:40 +03:00
var username by remember { mutableStateOf("") }
var url by remember { mutableStateOf("") }
var urlIsValid by remember { mutableStateOf(false) }
var loading by remember { mutableStateOf(false) }
2025-04-21 17:44:40 +03:00
LaunchedEffect(url) {
if (url.isNotEmpty()) {
delay(1000)
loading = true
urlIsValid = health(url)
loading = false
}
}
2025-04-21 17:44:40 +03:00
Column (modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) {
2025-04-21 17:44:40 +03:00
OutlinedTextField(
value = username,
onValueChange = { username = it },
2025-04-22 03:11:25 +03:00
label = { Text(appStr(R.string.username)) }
2025-04-21 17:44:40 +03:00
)
OutlinedTextField(
value = url,
onValueChange = { url = it },
2025-05-03 17:19:54 +03:00
placeholder = {
Text("https://geo.example.com",
style = TextStyle(color = MaterialTheme.colorScheme.onSurfaceVariant)
)
},
label = { Text(appStr(R.string.server_url)) },
2025-05-03 17:19:54 +03:00
trailingIcon = {
if (loading) CircularProgressIndicator()
else if (urlIsValid) Icon(Icons.Outlined.Done, "Done")
}
2025-04-21 17:44:40 +03:00
)
2025-05-03 17:19:54 +03:00
LocationPermissionScreen()
Button({
SettingsPreferences.username = username.trim()
SettingsPreferences.url = url
onConfirm()
}, enabled = urlIsValid
&& !loading
&& username.trim().isNotEmpty()
&& hasLocationPermissions(appCtx)
) {
Text(appStr(R.string.apply))
}
2025-04-21 15:48:45 +03:00
}
2025-05-03 17:19:54 +03:00
}
@Composable
fun LocationPermissionScreen() {
val context = LocalContext.current
val locationPermissions = arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION
)
val hasLocationPermissions = remember {
mutableStateOf(
locationPermissions.all {
ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
}
)
}
val permissionLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
hasLocationPermissions.value = permissions.all { it.value }
}
if (hasLocationPermissions.value) {
Button({}, enabled = false) {
Icon(Icons.Outlined.Done, "Done")
Text("Разрешения получены")
}
} else {
Button(onClick = {
permissionLauncher.launch(locationPermissions)
}) {
Text("Получить разрешения")
}
}
}
fun hasLocationPermissions(context: Context): Boolean {
return ContextCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_COARSE_LOCATION
) == PackageManager.PERMISSION_GRANTED
2025-04-21 15:48:45 +03:00
}