106 lines
3.2 KiB
Kotlin
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")
|
|
}
|
|
}
|
|
}
|
|
}
|