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, domainStates: Map, 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") } } } }