android-client/app/src/main/java/com/projects/httpsserverapp/MainActivity.kt
2025-12-23 16:33:10 +03:00

106 lines
3.2 KiB
Kotlin

package com.projects.httpsserverapp
import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED
) {
requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 123)
}
val app = application as HttpsServerApp
setContent {
val state by app.connectionState.collectAsState()
val domains by app.domains.collectAsState()
val domainStates by app.domainStates.collectAsState()
MaterialTheme {
Surface {
TunnelStatusView(
state = state,
domains = domains,
domainStates = domainStates,
onReconnectClick = { reconnectTunnel() }
)
}
}
}
}
private fun reconnectTunnel() {
stopService(Intent(this, TunnelService::class.java))
val intent = Intent(this, TunnelService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startForegroundService(intent)
else
startService(intent)
}
}
@Composable
fun TunnelStatusView(
state: ConnectionState,
domains: List<String>,
domainStates: Map<String, DomainState>,
onReconnectClick: () -> Unit
) {
val (text, color) = when (state) {
ConnectionState.CONNECTED -> "Connected to relay" to Color.Green
ConnectionState.RECONNECTING -> "Reconnecting..." to Color.Gray
ConnectionState.DISCONNECTED -> "Disconnected" to Color.Red
}
val hasInactiveDomains =
domains.any { domain ->
domainStates[domain] != DomainState.ACTIVE
}
Column(modifier = Modifier.padding(16.dp)) {
Text(text = text, color = color, fontSize = 20.sp)
Spacer(Modifier.height(8.dp))
Text("Domains:")
domains.forEach { domain ->
val domainState = domainStates[domain] ?: DomainState.PENDING
val domainColor = when (domainState) {
DomainState.ACTIVE -> Color.Green
DomainState.PENDING -> Color.Gray
DomainState.REJECTED -> Color.Red
}
Text(
text = "$domain (${domainState.name})",
color = domainColor
)
}
if (
state != ConnectionState.CONNECTED ||
hasInactiveDomains
) {
Spacer(Modifier.height(16.dp))
Button(onClick = onReconnectClick) {
Text("Reconnect")
}
}
}
}