Started Login Process

This commit is contained in:
2026-02-20 21:30:57 +01:00
parent 534f844196
commit 89c8a4b985
4 changed files with 110 additions and 19 deletions

View File

@@ -40,6 +40,8 @@ android {
}
dependencies {
//Android Studio Auto-Gen
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
@@ -55,4 +57,7 @@ dependencies {
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
debugImplementation(libs.androidx.compose.ui.tooling)
debugImplementation(libs.androidx.compose.ui.test.manifest)
//Manually added
implementation("androidx.datastore:datastore-preferences:1.2.0")
}

View File

@@ -0,0 +1,39 @@
package de.miaurizius.shap_planner
import android.content.Context
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
val Context.dataStore by preferencesDataStore(name = "user_prefs")
object UserPreferencesKeys {
val IS_LOGGED_IN = booleanPreferencesKey("is_logged_in")
val LAST_USER_ID = stringPreferencesKey("last_user_id")
}
class UserPreferences(private val context: Context) {
//Stave status
suspend fun saveLogin(userId: String) {
context.dataStore.edit { prefs ->
prefs[UserPreferencesKeys.IS_LOGGED_IN] = true
prefs[UserPreferencesKeys.LAST_USER_ID] = userId;
}
}
//Logout
suspend fun clearLogin() {
context.dataStore.edit { prefs ->
prefs[UserPreferencesKeys.IS_LOGGED_IN] = false
prefs[UserPreferencesKeys.LAST_USER_ID] = ""
}
}
//Get state
val isLoggedInFlow: Flow<Boolean> = context.dataStore.data.map { prefs -> prefs[UserPreferencesKeys.IS_LOGGED_IN] ?: false }
val lastUserLoginFlow: Flow<String?> = context.dataStore.data.map { prefs -> prefs[UserPreferencesKeys.LAST_USER_ID] }
}

View File

@@ -4,44 +4,68 @@ import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import de.miaurizius.shap_planner.UserPreferences
import de.miaurizius.shap_planner.ui.theme.ShapPlannerTheme
import de.miaurizius.shap_planner.viewmodels.LoginViewModel
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
// enableEdgeToEdge()
val prefs = UserPreferences(this)
val viewModel = LoginViewModel(prefs)
setContent {
ShapPlannerTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
val isLoggedIn by viewModel.isLoggedIn.collectAsState()
if(isLoggedIn) MainScreen()
else LoginScreen { userId -> viewModel.login(userId) }
}
}
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "Hello $name!",
modifier = modifier
)
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
ShapPlannerTheme {
Greeting("Android")
fun MainScreen() {
Column(modifier = Modifier.padding(16.dp)) {
Text("Willkommen zurück!")
Button(onClick = { /* TODO: Logout */ }) {
Text("Logout")
}
}
}
@Composable
fun LoginScreen(onLogin: (String) -> Unit) {
var userId by remember { mutableStateOf("") }
Column(modifier = Modifier.padding(16.dp)) {
Text("Bitte anmelden")
Spacer(modifier = Modifier.height(8.dp))
TextField(
value = userId,
onValueChange = { userId = it },
label = { Text("User ID") }
)
Spacer(modifier = Modifier.height(8.dp))
Button(onClick = { if(userId.isNotEmpty()) onLogin(userId) }) {
Text("Login")
}
}
}

View File

@@ -0,0 +1,23 @@
package de.miaurizius.shap_planner.viewmodels
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import de.miaurizius.shap_planner.UserPreferences
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
class LoginViewModel(private val prefs: UserPreferences) : ViewModel() {
val isLoggedIn = prefs.isLoggedInFlow.stateIn(viewModelScope, SharingStarted.Lazily, false)
val lastUserId = prefs.lastUserLoginFlow.stateIn(viewModelScope, SharingStarted.Lazily, null)
fun login(userId: String) {
viewModelScope.launch { prefs.saveLogin(userId) }
}
fun logout() {
viewModelScope.launch { prefs.clearLogin() }
}
}