From 8c7c61f299649bfb533452254dfab88a24763bfc Mon Sep 17 00:00:00 2001 From: pedro Date: Wed, 19 Feb 2025 18:59:40 +0300 Subject: [PATCH] auth is worked on --- app/build.gradle.kts | 1 + .../com/example/nto_minipigs/MainActivity.kt | 35 ++++++------ .../nto_minipigs/Retrofit/ApiService.kt | 6 ++- .../example/nto_minipigs/core/Constants.kt | 2 +- .../ui/screens/{ => Login}/LoginScreen.kt | 12 ++--- .../{ => ui/screens/Login}/LoginViewModel.kt | 11 ++-- .../ui/screens/{ => Main}/MainScreen.kt | 54 +++++++++---------- .../ui/screens/Main/MainViewModel.kt | 46 ++++++++++++++++ 8 files changed, 108 insertions(+), 59 deletions(-) rename app/src/main/java/com/example/nto_minipigs/ui/screens/{ => Login}/LoginScreen.kt (84%) rename app/src/main/java/com/example/nto_minipigs/{ => ui/screens/Login}/LoginViewModel.kt (62%) rename app/src/main/java/com/example/nto_minipigs/ui/screens/{ => Main}/MainScreen.kt (54%) create mode 100644 app/src/main/java/com/example/nto_minipigs/ui/screens/Main/MainViewModel.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4df0e42..563378f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -67,4 +67,5 @@ dependencies { implementation("com.squareup.retrofit2:converter-gson:$retrofitVersion") implementation("androidx.datastore:datastore-preferences:1.1.2") implementation("androidx.datastore:datastore:1.1.2") + implementation("androidx.compose.runtime:runtime-livedata:1.7.8") } \ No newline at end of file diff --git a/app/src/main/java/com/example/nto_minipigs/MainActivity.kt b/app/src/main/java/com/example/nto_minipigs/MainActivity.kt index d42445e..3e3c873 100644 --- a/app/src/main/java/com/example/nto_minipigs/MainActivity.kt +++ b/app/src/main/java/com/example/nto_minipigs/MainActivity.kt @@ -1,7 +1,6 @@ package com.example.nto_minipigs import android.content.Context -import android.content.SharedPreferences import android.os.Bundle import android.util.Log import androidx.activity.ComponentActivity @@ -9,24 +8,26 @@ import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.remember -import androidx.datastore.core.DataStore -import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.edit -import androidx.datastore.preferences.core.intPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.preferencesDataStore import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController -import com.example.nto_minipigs.ui.screens.LoginScreen +import com.example.nto_minipigs.ui.screens.Login.LoginScreen +import com.example.nto_minipigs.ui.screens.Login.LoginViewModel +import com.example.nto_minipigs.ui.screens.Main.MainScreen +import com.example.nto_minipigs.ui.screens.Main.MainViewModel import com.example.nto_minipigs.ui.theme.Nto_minipigsTheme -import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.map +import kotlinx.coroutines.runBlocking import kotlinx.serialization.Serializable class MainActivity : ComponentActivity() { @@ -43,6 +44,7 @@ class MainActivity : ComponentActivity() { val navController = rememberNavController() val loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] + val mainViewModel = ViewModelProvider(this)[MainViewModel::class.java] val token by dataStore.token.collectAsState("") @@ -51,10 +53,12 @@ class MainActivity : ComponentActivity() { NavHost( navController = navController, startDestination = if(token == null) Login else Main -// startDestination = Login ) { composable { LoginScreen( onNavigateToMain = { navController.popBackStack(); navController.navigate(route = Main) }, viewModel = loginViewModel, dataStore = dataStore ) } - composable
{ MainScreen() } + composable
{ MainScreen( viewModel = mainViewModel, token = token.toString() ) } + } + LaunchedEffect(Unit) { + dataStore.loadToken() } } } @@ -64,8 +68,14 @@ class MainActivity : ComponentActivity() { class UserData(private val context: Context) { val Context.dataStore by preferencesDataStore("user_data") - val token = context.dataStore.data.map { preferences -> + val token = MutableStateFlow(context.dataStore.data.map { preferences -> preferences[tokenKey] + }) + + public fun loadToken() { + runBlocking { token.value = context.dataStore.data.map { preferences -> + preferences[tokenKey] + }} } suspend fun updateToken(data:String) = @@ -83,8 +93,3 @@ object Login @Serializable object Main - -@Composable -fun MainScreen() { - Text("Main") -} diff --git a/app/src/main/java/com/example/nto_minipigs/Retrofit/ApiService.kt b/app/src/main/java/com/example/nto_minipigs/Retrofit/ApiService.kt index 70078f3..43a3601 100644 --- a/app/src/main/java/com/example/nto_minipigs/Retrofit/ApiService.kt +++ b/app/src/main/java/com/example/nto_minipigs/Retrofit/ApiService.kt @@ -2,10 +2,12 @@ package com.example.nto_minipigs.Retrofit import com.example.nto_minipigs.Retrofit.Models.Auth import com.example.nto_minipigs.Retrofit.Models.Data +import com.example.nto_minipigs.Retrofit.Models.User import okhttp3.ResponseBody import retrofit2.Response import retrofit2.http.Body import retrofit2.http.GET +import retrofit2.http.Header import retrofit2.http.PATCH import retrofit2.http.POST import retrofit2.http.Path @@ -14,8 +16,8 @@ public interface ApiService { @GET("/api/{LOGIN}/auth") suspend fun auth(@Path("LOGIN") login: String): ResponseBody - @GET("/api/{LOGIN}/info") - suspend fun info(@Path("LOGIN") login: String): ResponseBody + @GET("/api/info") + suspend fun info(@Header("Authorization") token: String): Response @PATCH("/api/{LOGIN}/open") suspend fun open(@Body data: Data, @Path("LOGIN") login: String): ResponseBody diff --git a/app/src/main/java/com/example/nto_minipigs/core/Constants.kt b/app/src/main/java/com/example/nto_minipigs/core/Constants.kt index 6bda110..f7d4211 100644 --- a/app/src/main/java/com/example/nto_minipigs/core/Constants.kt +++ b/app/src/main/java/com/example/nto_minipigs/core/Constants.kt @@ -3,5 +3,5 @@ package com.example.nto_minipigs.core object Constants { const val SHARED_PREFS = "shared_prefs" const val EMAIL_KEY = "email_key" - const val SERVER_ADDRESS = "http://192.168.1.127:5000" + const val SERVER_ADDRESS = "http://10.6.66.120:5000" } \ No newline at end of file diff --git a/app/src/main/java/com/example/nto_minipigs/ui/screens/LoginScreen.kt b/app/src/main/java/com/example/nto_minipigs/ui/screens/Login/LoginScreen.kt similarity index 84% rename from app/src/main/java/com/example/nto_minipigs/ui/screens/LoginScreen.kt rename to app/src/main/java/com/example/nto_minipigs/ui/screens/Login/LoginScreen.kt index 5e3465a..4d27ddf 100644 --- a/app/src/main/java/com/example/nto_minipigs/ui/screens/LoginScreen.kt +++ b/app/src/main/java/com/example/nto_minipigs/ui/screens/Login/LoginScreen.kt @@ -1,4 +1,4 @@ -package com.example.nto_minipigs.ui.screens +package com.example.nto_minipigs.ui.screens.Login import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -20,14 +20,10 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.unit.dp -import androidx.datastore.core.DataStore -import com.example.nto_minipigs.LoginViewModel import com.example.nto_minipigs.UserData -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch @Composable -fun LoginScreen( onNavigateToMain: () -> Unit, viewModel: LoginViewModel, dataStore: UserData) { +fun LoginScreen(onNavigateToMain: () -> Unit, viewModel: LoginViewModel, dataStore: UserData) { Nto_minipigsTheme { val cor = rememberCoroutineScope() Surface { @@ -62,9 +58,7 @@ fun LoginScreen( onNavigateToMain: () -> Unit, viewModel: LoginViewModel, dataSt ) Button( - onClick = { - viewModel.getData(login, password, onNavigateToMain, dataStore) - }, + onClick = { viewModel.Authenticate(login, password, onNavigateToMain, dataStore) }, shape = RoundedCornerShape(12.dp), ) { Text(text = "Sign In", style = MaterialTheme.typography.bodyLarge) diff --git a/app/src/main/java/com/example/nto_minipigs/LoginViewModel.kt b/app/src/main/java/com/example/nto_minipigs/ui/screens/Login/LoginViewModel.kt similarity index 62% rename from app/src/main/java/com/example/nto_minipigs/LoginViewModel.kt rename to app/src/main/java/com/example/nto_minipigs/ui/screens/Login/LoginViewModel.kt index ba49d65..cfc20e1 100644 --- a/app/src/main/java/com/example/nto_minipigs/LoginViewModel.kt +++ b/app/src/main/java/com/example/nto_minipigs/ui/screens/Login/LoginViewModel.kt @@ -1,22 +1,25 @@ -package com.example.nto_minipigs +package com.example.nto_minipigs.ui.screens.Login import RetrofitClient import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.example.nto_minipigs.Retrofit.Models.Auth +import com.example.nto_minipigs.UserData import kotlinx.coroutines.launch class LoginViewModel :ViewModel() { private val serviceApi = RetrofitClient.apiService - fun getData(login: String, password: String, func: () -> Unit, dataStore: UserData) { + fun Authenticate(login: String, password: String, func: () -> Unit, dataStore: UserData) { viewModelScope.launch { try { val auth = Auth(login, password) val response = serviceApi.login(auth) - dataStore.updateToken(response.body()?.token.toString()) - func() + if(response.isSuccessful) { + dataStore.updateToken(response.body()?.token.toString()) + func() + } } catch (e: Exception) { Log.d("exception:", e.toString()) } diff --git a/app/src/main/java/com/example/nto_minipigs/ui/screens/MainScreen.kt b/app/src/main/java/com/example/nto_minipigs/ui/screens/Main/MainScreen.kt similarity index 54% rename from app/src/main/java/com/example/nto_minipigs/ui/screens/MainScreen.kt rename to app/src/main/java/com/example/nto_minipigs/ui/screens/Main/MainScreen.kt index d0605ef..a0f2999 100644 --- a/app/src/main/java/com/example/nto_minipigs/ui/screens/MainScreen.kt +++ b/app/src/main/java/com/example/nto_minipigs/ui/screens/Main/MainScreen.kt @@ -1,4 +1,4 @@ -package com.example.nto_minipigs.ui.screens +package com.example.nto_minipigs.ui.screens.Main import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -6,61 +6,59 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Button +import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Surface import androidx.compose.material3.Text +import androidx.compose.material3.rememberDateRangePickerState import androidx.compose.runtime.Composable +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 com.example.nto_minipigs.ui.theme.Nto_minipigsTheme import androidx.compose.runtime.getValue +import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.setValue import androidx.compose.ui.unit.dp +import com.example.nto_minipigs.UserData @Composable -fun MainScreen( onNavigateToMain: () -> Unit ) { +fun MainScreen( viewModel: MainViewModel, token: String?) { Nto_minipigsTheme { + val data = viewModel.data.observeAsState() Surface { Column( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, ) { - Text( - text = "MiniPigs", - style = MaterialTheme.typography.titleLarge, - modifier = Modifier.padding(bottom = 36.dp) - ) - - var login by remember { mutableStateOf("") } - var password by remember { mutableStateOf("") } - - OutlinedTextField( - value = login, - onValueChange = { login = it }, - label = { Text("Login") }, - modifier = Modifier.padding(bottom = 4.dp), - shape = RoundedCornerShape(12.dp) - ) - - OutlinedTextField( - value = password, - onValueChange = { password = it }, - label = { Text("Password") }, - modifier = Modifier.padding(bottom = 12.dp), - shape = RoundedCornerShape(12.dp), - ) + when(val result = data.value){ + is NetworkResponse.Error -> { + Text(text = result.message) + } + NetworkResponse.Loading -> { + CircularProgressIndicator() + } + is NetworkResponse.Success -> { + Text(text = result.data.toString()) + } + null -> {} + } Button( - onClick = { onNavigateToMain() }, + onClick = { viewModel.Fetch(token) }, shape = RoundedCornerShape(12.dp), - ) { + ) { Text(text = "Sign In", style = MaterialTheme.typography.bodyLarge) } } } + + LaunchedEffect(Unit) { + viewModel.Fetch(token) + } } } diff --git a/app/src/main/java/com/example/nto_minipigs/ui/screens/Main/MainViewModel.kt b/app/src/main/java/com/example/nto_minipigs/ui/screens/Main/MainViewModel.kt new file mode 100644 index 0000000..d9155e5 --- /dev/null +++ b/app/src/main/java/com/example/nto_minipigs/ui/screens/Main/MainViewModel.kt @@ -0,0 +1,46 @@ +package com.example.nto_minipigs.ui.screens.Main + +import android.util.Log +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.example.nto_minipigs.Retrofit.Models.Auth +import com.example.nto_minipigs.Retrofit.Models.User +import com.example.nto_minipigs.UserData +import kotlinx.coroutines.launch + +class MainViewModel: ViewModel() { + private val serviceApi = RetrofitClient.apiService + + private val _data = MutableLiveData>() + val data : LiveData> = _data + + fun Fetch(token: String?) { + Log.d("penis", token.toString()) + _data.value = NetworkResponse.Loading + + viewModelScope.launch { + if(token != null) { + try { + val response = serviceApi.info(token) + if(response.isSuccessful) { + response.body()?.let { + _data.value = NetworkResponse.Success(it) + } + } else { + _data.value = NetworkResponse.Error(response.message()) + } + } catch(e: Exception) { + _data.value = NetworkResponse.Error(e.toString()) + } + } + } + } +} + +sealed class NetworkResponse { + data class Success(val data: T) : NetworkResponse() + data class Error(val message: String) : NetworkResponse() + object Loading : NetworkResponse() +} \ No newline at end of file