fixing(client)
This commit is contained in:
@@ -1,29 +0,0 @@
|
||||
package at.mocode.client.data.api
|
||||
|
||||
import at.mocode.client.data.model.PingResponse
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.call.*
|
||||
import io.ktor.client.plugins.contentnegotiation.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.serialization.kotlinx.json.*
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
class PingApiClient {
|
||||
private val httpClient = HttpClient {
|
||||
install(ContentNegotiation) {
|
||||
json(Json {
|
||||
ignoreUnknownKeys = true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun ping(): String {
|
||||
return try {
|
||||
// HINWEIS: Wir rufen hier Port 8081 an, den Port unseres Gateways.
|
||||
val response = httpClient.get("http://localhost:8081/ping").body<PingResponse>()
|
||||
response.status
|
||||
} catch (e: Exception) {
|
||||
"Fehler: ${e.message}"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package at.mocode.client.data.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class PingResponse(
|
||||
val status: String
|
||||
)
|
||||
@@ -0,0 +1,32 @@
|
||||
package at.mocode.client.data.service
|
||||
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.call.*
|
||||
import io.ktor.client.plugins.contentnegotiation.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.serialization.kotlinx.json.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class PingResponse(val status: String)
|
||||
|
||||
class PingService {
|
||||
private val client = HttpClient {
|
||||
install(ContentNegotiation) {
|
||||
json()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun ping(): Result<PingResponse> = try {
|
||||
val response = client.get("http://localhost:8082/ping").body<PingResponse>()
|
||||
Result.success(response)
|
||||
} catch (e: Exception) {
|
||||
Result.failure(e)
|
||||
}
|
||||
|
||||
fun pingFlow(): Flow<Result<PingResponse>> = flow {
|
||||
emit(ping())
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,90 @@
|
||||
package at.mocode.client.ui
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import at.mocode.client.ui.features.ping.PingScreen
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import at.mocode.client.ui.components.PingTestComponent
|
||||
|
||||
@Composable
|
||||
fun App() {
|
||||
fun App(baseUrl: String = "http://localhost:8080") {
|
||||
MaterialTheme {
|
||||
PingScreen()
|
||||
PingScreen(baseUrl)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun PingScreen(baseUrl: String) {
|
||||
val pingComponent = remember { PingTestComponent() }
|
||||
var pingState by remember { mutableStateOf(pingComponent.state) }
|
||||
|
||||
LaunchedEffect(pingComponent) {
|
||||
pingComponent.onStateChanged = { newState ->
|
||||
pingState = newState
|
||||
}
|
||||
}
|
||||
|
||||
DisposableEffect(pingComponent) {
|
||||
onDispose {
|
||||
pingComponent.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text(
|
||||
text = "Ping Backend Service",
|
||||
style = MaterialTheme.typography.headlineMedium,
|
||||
modifier = Modifier.padding(bottom = 16.dp)
|
||||
)
|
||||
|
||||
when {
|
||||
pingState.isLoading -> {
|
||||
CircularProgressIndicator()
|
||||
Text(
|
||||
text = "Testing connection...",
|
||||
modifier = Modifier.padding(top = 8.dp)
|
||||
)
|
||||
}
|
||||
pingState.error != null -> {
|
||||
Text(
|
||||
text = "Error: ${pingState.error}",
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
modifier = Modifier.padding(bottom = 16.dp)
|
||||
)
|
||||
}
|
||||
pingState.response != null -> {
|
||||
Text(
|
||||
text = "Response: ${pingState.response?.status ?: "Unknown"}",
|
||||
color = if (pingState.isConnected) MaterialTheme.colorScheme.primary
|
||||
else MaterialTheme.colorScheme.error,
|
||||
modifier = Modifier.padding(bottom = 16.dp)
|
||||
)
|
||||
Text(
|
||||
text = if (pingState.isConnected) "✓ Connected" else "✗ Not Connected",
|
||||
color = if (pingState.isConnected) MaterialTheme.colorScheme.primary
|
||||
else MaterialTheme.colorScheme.error
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Button(
|
||||
onClick = { pingComponent.testConnection() },
|
||||
enabled = !pingState.isLoading
|
||||
) {
|
||||
Text("Test Connection")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package at.mocode.client.ui.components
|
||||
|
||||
import at.mocode.client.data.service.PingService
|
||||
import at.mocode.client.data.service.PingResponse
|
||||
import kotlinx.coroutines.*
|
||||
|
||||
data class PingTestState(
|
||||
val isLoading: Boolean = false,
|
||||
val response: PingResponse? = null,
|
||||
val error: String? = null,
|
||||
val isConnected: Boolean = false
|
||||
)
|
||||
|
||||
class PingTestComponent {
|
||||
private val pingService = PingService()
|
||||
private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
|
||||
|
||||
var state: PingTestState = PingTestState()
|
||||
private set
|
||||
|
||||
var onStateChanged: ((PingTestState) -> Unit)? = null
|
||||
|
||||
fun testConnection() {
|
||||
updateState(state.copy(isLoading = true, error = null))
|
||||
|
||||
scope.launch {
|
||||
pingService.ping()
|
||||
.onSuccess { response ->
|
||||
updateState(
|
||||
state.copy(
|
||||
isLoading = false,
|
||||
response = response,
|
||||
isConnected = response.status == "pong"
|
||||
)
|
||||
)
|
||||
}
|
||||
.onFailure { error ->
|
||||
updateState(
|
||||
state.copy(
|
||||
isLoading = false,
|
||||
error = error.message ?: "Unbekannter Fehler",
|
||||
isConnected = false
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateState(newState: PingTestState) {
|
||||
state = newState
|
||||
onStateChanged?.invoke(state)
|
||||
}
|
||||
|
||||
fun dispose() {
|
||||
scope.cancel()
|
||||
}
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
package at.mocode.client.ui.features.ping
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun PingScreen() {
|
||||
val viewModel = remember { PingViewModel() }
|
||||
val responseText by viewModel.responseText.collectAsState()
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize().padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Button(onClick = { viewModel.onPingClicked() }) {
|
||||
Text("Ping Backend")
|
||||
}
|
||||
Text(
|
||||
text = responseText,
|
||||
modifier = Modifier.padding(top = 16.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package at.mocode.client.ui.features.ping
|
||||
|
||||
import at.mocode.client.data.api.PingApiClient
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class PingViewModel {
|
||||
private val apiClient = PingApiClient()
|
||||
private val viewModelScope = CoroutineScope(Dispatchers.Default)
|
||||
|
||||
private val _responseText = MutableStateFlow("Klicke auf den Button, um das Backend zu pingen.")
|
||||
val responseText = _responseText.asStateFlow()
|
||||
|
||||
fun onPingClicked() {
|
||||
_responseText.value = "Pinge Backend..."
|
||||
viewModelScope.launch {
|
||||
val response = apiClient.ping()
|
||||
_responseText.value = "Antwort vom Backend: $response"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user