initial commit - source
This commit is contained in:
1 parent
003b5501f0
commit
e89bb29070
45 files changed
+5997
No files matched your search
@@ -0,0 +1,166 @@
|
||||
package net.keinekekse.app
|
||||
|
||||
//import org.koin.plugin.module.dsl.startKoin
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import net.keinekekse.app.auth.AuthResult
|
||||
import net.keinekekse.app.auth.Authenticator
|
||||
import net.keinekekse.app.books.di.KoinApp
|
||||
import net.keinekekse.app.ui.ProgressIndicator
|
||||
import org.koin.compose.koinInject
|
||||
import org.koin.plugin.module.dsl.startKoin
|
||||
|
||||
//@PropertyValue("kc_server")
|
||||
//var keycloakServer: String = ""
|
||||
//
|
||||
//@PropertyValue("kc_realm")
|
||||
//var keycloakRealm: String = ""
|
||||
//
|
||||
//@PropertyValue("kc_client")
|
||||
//var keycloakClient: String = ""
|
||||
|
||||
fun main() = application {
|
||||
|
||||
startKoin<KoinApp>()
|
||||
|
||||
// keycloakServer = "kec.keinekekse.net"
|
||||
// keycloakRealm = "app-server-realm"
|
||||
// keycloakClient = "pkce-book-app"
|
||||
|
||||
// val inj = koinInject<String>(named("AppString"))
|
||||
|
||||
val authResultState = remember { mutableStateOf<AuthResult?>(null) }
|
||||
|
||||
val authenticator: Authenticator = koinInject()
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
authResultState.value = withContext(Dispatchers.IO) {
|
||||
// TODO - (~) Verständnis für App-Aufbau und DI
|
||||
// - (x) das object muss global angelegt werden -> DI singleton
|
||||
// - (x) globale Speicherung der Tokens
|
||||
// - Tokens persistieren? Multiplatform! (evtl. library)
|
||||
// - (x) globaler httpClient mit Konfig für Tokens -> DI
|
||||
// - (x) Error-Handling: 401 -> refresh -> 401 -> reauth [implizit]
|
||||
// Authenticator(
|
||||
// "kec.keinekekse.net",
|
||||
// "app-server-realm",
|
||||
// "pkce-book-app",
|
||||
// ).use {
|
||||
|
||||
val result = authenticator.authenticate()
|
||||
|
||||
when (result) {
|
||||
is AuthResult.Success -> {
|
||||
// println("Access Token: ${result.tokens?.accessToken}")
|
||||
// println("Refresh Token: ${result.tokens?.refreshToken}")
|
||||
|
||||
// delay(3000)
|
||||
/*
|
||||
// klappt, gibt aber nicht mehr her, als ohnehin im Token steht
|
||||
it.requestUserInfo(result.tokens!!.accessToken)
|
||||
*/
|
||||
/*
|
||||
// funktioniert -> jetzt fehlt die DI-Mimik für die compose app
|
||||
when (val res = it.requestRefreshToken(result.tokens)) {
|
||||
is AuthResult.Success -> {
|
||||
println("Access Token: ${res.tokens?.accessToken}")
|
||||
println("Refresh Token: ${res.tokens?.refreshToken}")
|
||||
}
|
||||
|
||||
is AuthResult.Error -> {
|
||||
println("Refresh Token fehlgeschlagen ${res.code}: ${res.details ?: ""}")
|
||||
}
|
||||
|
||||
is AuthResult.Fatal -> {
|
||||
println("Refresh Token fehlgeschlagen ${res.code}: ${res.details ?: ""}")
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
|
||||
result
|
||||
// }
|
||||
}
|
||||
}
|
||||
Window(
|
||||
onCloseRequest = ::exitApplication,
|
||||
title = "app",
|
||||
) {
|
||||
when (val result = authResultState.value) {
|
||||
null -> {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text("Warten auf Anmeldung...")
|
||||
|
||||
// Icon(
|
||||
// imageVector = Icons.Default.HourglassTop,
|
||||
// contentDescription = "Home",
|
||||
// modifier = Modifier.padding(top = 16.dp).size(32.dp)
|
||||
// )
|
||||
ProgressIndicator()
|
||||
}
|
||||
}
|
||||
|
||||
is AuthResult.Error -> {
|
||||
// TODO show an error UI (and maybe a retry button)
|
||||
Text("Fehler bei der Anmeldung: ${result.message} (${result.code})")
|
||||
Text("Fehlerbeschreibung: ${result.details ?: ""}")
|
||||
// App()
|
||||
}
|
||||
|
||||
is AuthResult.Fatal -> {
|
||||
Text("Fataler Fehler bei der Anmeldung: ${result.message} (${result.code})")
|
||||
Text("Fehlerbeschreibung: ${result.details ?: ""}")
|
||||
}
|
||||
|
||||
is AuthResult.Success -> {
|
||||
val test = koinInject<TestAuth>()
|
||||
CoroutineScope(Dispatchers.Default).launch {
|
||||
println("requesting '/'")
|
||||
test.request("/")
|
||||
}
|
||||
App()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
//@Composable
|
||||
//fun ProgressIndicator(animationSize: Int = 48, paddingTop: Int = 16, strokeWidth: Int = 5) {
|
||||
// val primaryColor = MaterialTheme.colorScheme.primary
|
||||
// val backgroundColor = MaterialTheme.colorScheme.background
|
||||
// val strokewidth = strokeWidth.dp
|
||||
// CircularProgressIndicator(
|
||||
// modifier =
|
||||
// Modifier.padding(top = paddingTop.dp).size(animationSize.dp).drawBehind {
|
||||
// drawCircle(
|
||||
// primaryColor,
|
||||
// radius = size.width / 2 - strokewidth.toPx() / 2,
|
||||
// style = Stroke(strokewidth.toPx()),
|
||||
//
|
||||
// )
|
||||
// },
|
||||
// color = backgroundColor,
|
||||
// strokeWidth = strokewidth
|
||||
// )
|
||||
//}
|
||||
Reference in new issue
Block a user