fixing client

This commit is contained in:
2025-09-24 00:23:25 +02:00
parent 14d6a95e3a
commit cd2b0796a6
11 changed files with 386 additions and 29 deletions
@@ -1,49 +1,172 @@
package at.mocode
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.safeContentPadding
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.painterResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import at.mocode.ui.PingViewModel
import org.jetbrains.compose.ui.tooling.preview.Preview
import at.mocode.composeapp.generated.resources.Res
import at.mocode.composeapp.generated.resources.compose_multiplatform
@Composable
@Preview
fun App() {
MaterialTheme {
var showContent by remember { mutableStateOf(false) }
val viewModel: PingViewModel = viewModel()
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
Column(
modifier = Modifier
.background(MaterialTheme.colorScheme.primaryContainer)
.safeContentPadding()
.fillMaxSize(),
.background(MaterialTheme.colorScheme.background)
.fillMaxSize()
.padding(16.dp)
.verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
Button(onClick = { showContent = !showContent }) {
Text("Click me!")
}
AnimatedVisibility(showContent) {
val greeting = remember { Greeting().greet() }
// Header
Card(
modifier = Modifier.fillMaxWidth()
) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(painterResource(Res.drawable.compose_multiplatform), null)
Text("Compose: $greeting")
Text(
text = "Meldestelle - Ping Service Client",
style = MaterialTheme.typography.headlineMedium
)
Text(
text = "Trace-Bullet Implementation",
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.secondary
)
}
}
// Action Buttons
Card(
modifier = Modifier.fillMaxWidth()
) {
Column(
modifier = Modifier.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Text(
text = "API Tests",
style = MaterialTheme.typography.titleMedium
)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Button(
onClick = { viewModel.simplePing() },
enabled = !uiState.isLoading,
modifier = Modifier.weight(1f)
) {
Text("Simple Ping")
}
Button(
onClick = { viewModel.enhancedPing() },
enabled = !uiState.isLoading,
modifier = Modifier.weight(1f)
) {
Text("Enhanced Ping")
}
}
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Button(
onClick = { viewModel.healthCheck() },
enabled = !uiState.isLoading,
modifier = Modifier.weight(1f)
) {
Text("Health Check")
}
Button(
onClick = { viewModel.enhancedPing(simulate = true) },
enabled = !uiState.isLoading,
modifier = Modifier.weight(1f),
colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.error
)
) {
Text("Test Failure")
}
}
}
}
// Loading Indicator
if (uiState.isLoading) {
CircularProgressIndicator()
}
// Error Display
uiState.error?.let { error ->
Card(
modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.errorContainer
)
) {
Text(
text = error,
modifier = Modifier.padding(16.dp),
color = MaterialTheme.colorScheme.onErrorContainer
)
}
}
// Results Display
uiState.lastPingResponse?.let { response ->
ResultCard("Simple Ping Result", response)
}
uiState.lastEnhancedResponse?.let { response ->
ResultCard("Enhanced Ping Result", response)
}
uiState.lastHealthResponse?.let { response ->
ResultCard("Health Check Result", response)
}
}
}
}
@Composable
private fun ResultCard(title: String, data: Any) {
Card(
modifier = Modifier.fillMaxWidth()
) {
Column(
modifier = Modifier.padding(16.dp)
) {
Text(
text = title,
style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.primary
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = data.toString(),
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.fillMaxWidth()
)
}
}
}
@@ -0,0 +1,88 @@
package at.mocode.ui
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import at.mocode.model.EnhancedPingResponse
import at.mocode.model.HealthResponse
import at.mocode.model.PingResponse
import at.mocode.service.PingService
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
data class PingUiState(
val isLoading: Boolean = false,
val lastPingResponse: PingResponse? = null,
val lastEnhancedResponse: EnhancedPingResponse? = null,
val lastHealthResponse: HealthResponse? = null,
val error: String? = null
)
class PingViewModel : ViewModel() {
private val pingService = PingService()
private val _uiState = MutableStateFlow(PingUiState())
val uiState: StateFlow<PingUiState> = _uiState.asStateFlow()
fun simplePing() {
viewModelScope.launch {
_uiState.value = _uiState.value.copy(isLoading = true, error = null)
pingService.ping()
.onSuccess { response ->
_uiState.value = _uiState.value.copy(
isLoading = false,
lastPingResponse = response
)
}
.onFailure { exception ->
_uiState.value = _uiState.value.copy(
isLoading = false,
error = "Ping failed: ${exception.message}"
)
}
}
}
fun enhancedPing(simulate: Boolean = false) {
viewModelScope.launch {
_uiState.value = _uiState.value.copy(isLoading = true, error = null)
pingService.enhancedPing(simulate)
.onSuccess { response ->
_uiState.value = _uiState.value.copy(
isLoading = false,
lastEnhancedResponse = response
)
}
.onFailure { exception ->
_uiState.value = _uiState.value.copy(
isLoading = false,
error = "Enhanced ping failed: ${exception.message}"
)
}
}
}
fun healthCheck() {
viewModelScope.launch {
_uiState.value = _uiState.value.copy(isLoading = true, error = null)
pingService.health()
.onSuccess { response ->
_uiState.value = _uiState.value.copy(
isLoading = false,
lastHealthResponse = response
)
}
.onFailure { exception ->
_uiState.value = _uiState.value.copy(
isLoading = false,
error = "Health check failed: ${exception.message}"
)
}
}
}
}