This commit is contained in:
Moritz 2026-02-15 17:00:55 +01:00
parent 8b7b2c26c0
commit 5ad7c6cee8
2 changed files with 26 additions and 72 deletions

View file

@ -12,7 +12,6 @@ import android.provider.Settings
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@ -60,6 +59,7 @@ import java.util.Calendar
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.example.helios_alarm_clock.data.AlarmEntity
import com.example.helios_alarm_clock.service.KtorService
import com.example.helios_alarm_clock.ui.theme.HeliosTheme
import dagger.hilt.android.AndroidEntryPoint
@ -73,6 +73,7 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestPermissions()
KtorService.start(this)
setContent {
HeliosTheme {
@ -114,7 +115,6 @@ class MainActivity : ComponentActivity() {
@Composable
fun MainScreen(viewModel: MainViewModel = hiltViewModel()) {
val alarms by viewModel.alarms.collectAsStateWithLifecycle()
val serverRunning by viewModel.serverRunning.collectAsStateWithLifecycle()
var showAddDialog by remember { mutableStateOf(false) }
if (showAddDialog) {
@ -154,11 +154,7 @@ fun MainScreen(viewModel: MainViewModel = hiltViewModel()) {
) {
ServerStatusCard(
ipAddress = viewModel.ipAddress,
port = viewModel.port,
isRunning = serverRunning,
onToggle = {
if (serverRunning) viewModel.stopServer() else viewModel.startServer()
}
port = viewModel.port
)
Spacer(modifier = Modifier.height(24.dp))
@ -204,18 +200,8 @@ fun MainScreen(viewModel: MainViewModel = hiltViewModel()) {
@Composable
fun ServerStatusCard(
ipAddress: String,
port: Int,
isRunning: Boolean,
onToggle: () -> Unit
port: Int
) {
val statusColor by animateColorAsState(
targetValue = if (isRunning)
MaterialTheme.colorScheme.primary
else
MaterialTheme.colorScheme.onSurfaceVariant,
label = "statusColor"
)
Card(
modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors(
@ -223,42 +209,28 @@ fun ServerStatusCard(
)
) {
Column(modifier = Modifier.padding(16.dp)) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
Text(
text = "HTTP Server",
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = "$ipAddress:$port",
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.primary
)
Spacer(modifier = Modifier.height(8.dp))
Surface(
shape = MaterialTheme.shapes.small,
color = MaterialTheme.colorScheme.primaryContainer
) {
Column {
Text(
text = "HTTP Server",
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = if (isRunning) "$ipAddress:$port" else "Stopped",
style = MaterialTheme.typography.bodyLarge,
color = statusColor
)
}
FilledTonalButton(onClick = onToggle) {
Text(if (isRunning) "Stop" else "Start")
}
}
if (isRunning) {
Spacer(modifier = Modifier.height(8.dp))
Surface(
shape = MaterialTheme.shapes.small,
color = MaterialTheme.colorScheme.primaryContainer
) {
Text(
text = "Listening for connections",
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onPrimaryContainer
)
}
Text(
text = "Listening for connections",
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onPrimaryContainer
)
}
}
}

View file

@ -1,6 +1,5 @@
package com.example.helios_alarm_clock.ui
import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.helios_alarm_clock.data.AlarmDao
@ -9,11 +8,8 @@ import com.example.helios_alarm_clock.service.KtorService
import com.example.helios_alarm_clock.util.AlarmScheduler
import com.example.helios_alarm_clock.util.getLocalIpAddress
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import java.util.Calendar
@ -23,31 +19,17 @@ import javax.inject.Inject
@HiltViewModel
class MainViewModel @Inject constructor(
private val alarmDao: AlarmDao,
private val alarmScheduler: AlarmScheduler,
@param:ApplicationContext private val context: Context
private val alarmScheduler: AlarmScheduler
) : ViewModel() {
val alarms: StateFlow<List<AlarmEntity>> = alarmDao.observeAll()
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())
private val _serverRunning = MutableStateFlow(false)
val serverRunning: StateFlow<Boolean> = _serverRunning.asStateFlow()
val ipAddress: String
get() = getLocalIpAddress() ?: "No network"
val port: Int = KtorService.PORT
fun startServer() {
KtorService.start(context)
_serverRunning.value = true
}
fun stopServer() {
KtorService.stop(context)
_serverRunning.value = false
}
fun createAlarm(hour: Int, minute: Int, label: String) {
viewModelScope.launch {
val now = Calendar.getInstance()