auth is worked on

This commit is contained in:
pedro 2025-02-19 18:59:40 +03:00
parent 9dac68d0db
commit 8c7c61f299
8 changed files with 108 additions and 59 deletions

View File

@ -67,4 +67,5 @@ dependencies {
implementation("com.squareup.retrofit2:converter-gson:$retrofitVersion") implementation("com.squareup.retrofit2:converter-gson:$retrofitVersion")
implementation("androidx.datastore:datastore-preferences:1.1.2") implementation("androidx.datastore:datastore-preferences:1.1.2")
implementation("androidx.datastore:datastore:1.1.2") implementation("androidx.datastore:datastore:1.1.2")
implementation("androidx.compose.runtime:runtime-livedata:1.7.8")
} }

View File

@ -1,7 +1,6 @@
package com.example.nto_minipigs package com.example.nto_minipigs
import android.content.Context import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
@ -9,24 +8,26 @@ import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember 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.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore import androidx.datastore.preferences.preferencesDataStore
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController 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 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.flow.map
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
@ -43,6 +44,7 @@ class MainActivity : ComponentActivity() {
val navController = rememberNavController() val navController = rememberNavController()
val loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] val loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java]
val mainViewModel = ViewModelProvider(this)[MainViewModel::class.java]
val token by dataStore.token.collectAsState("") val token by dataStore.token.collectAsState("")
@ -51,10 +53,12 @@ class MainActivity : ComponentActivity() {
NavHost( NavHost(
navController = navController, navController = navController,
startDestination = if(token == null) Login else Main startDestination = if(token == null) Login else Main
// startDestination = Login
) { ) {
composable<Login> { LoginScreen( onNavigateToMain = { navController.popBackStack(); navController.navigate(route = Main) }, viewModel = loginViewModel, dataStore = dataStore ) } composable<Login> { LoginScreen( onNavigateToMain = { navController.popBackStack(); navController.navigate(route = Main) }, viewModel = loginViewModel, dataStore = dataStore ) }
composable<Main> { MainScreen() } composable<Main> { MainScreen( viewModel = mainViewModel, token = token.toString() ) }
}
LaunchedEffect(Unit) {
dataStore.loadToken()
} }
} }
} }
@ -64,8 +68,14 @@ class MainActivity : ComponentActivity() {
class UserData(private val context: Context) { class UserData(private val context: Context) {
val Context.dataStore by preferencesDataStore("user_data") val Context.dataStore by preferencesDataStore("user_data")
val token = context.dataStore.data.map { preferences -> val token = MutableStateFlow(context.dataStore.data.map { preferences ->
preferences[tokenKey] preferences[tokenKey]
})
public fun loadToken() {
runBlocking { token.value = context.dataStore.data.map { preferences ->
preferences[tokenKey]
}}
} }
suspend fun updateToken(data:String) = suspend fun updateToken(data:String) =
@ -83,8 +93,3 @@ object Login
@Serializable @Serializable
object Main object Main
@Composable
fun MainScreen() {
Text("Main")
}

View File

@ -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.Auth
import com.example.nto_minipigs.Retrofit.Models.Data import com.example.nto_minipigs.Retrofit.Models.Data
import com.example.nto_minipigs.Retrofit.Models.User
import okhttp3.ResponseBody import okhttp3.ResponseBody
import retrofit2.Response import retrofit2.Response
import retrofit2.http.Body import retrofit2.http.Body
import retrofit2.http.GET import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.PATCH import retrofit2.http.PATCH
import retrofit2.http.POST import retrofit2.http.POST
import retrofit2.http.Path import retrofit2.http.Path
@ -14,8 +16,8 @@ public interface ApiService {
@GET("/api/{LOGIN}/auth") @GET("/api/{LOGIN}/auth")
suspend fun auth(@Path("LOGIN") login: String): ResponseBody suspend fun auth(@Path("LOGIN") login: String): ResponseBody
@GET("/api/{LOGIN}/info") @GET("/api/info")
suspend fun info(@Path("LOGIN") login: String): ResponseBody suspend fun info(@Header("Authorization") token: String): Response<User>
@PATCH("/api/{LOGIN}/open") @PATCH("/api/{LOGIN}/open")
suspend fun open(@Body data: Data, @Path("LOGIN") login: String): ResponseBody suspend fun open(@Body data: Data, @Path("LOGIN") login: String): ResponseBody

View File

@ -3,5 +3,5 @@ package com.example.nto_minipigs.core
object Constants { object Constants {
const val SHARED_PREFS = "shared_prefs" const val SHARED_PREFS = "shared_prefs"
const val EMAIL_KEY = "email_key" 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"
} }

View File

@ -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.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -20,11 +20,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.datastore.core.DataStore
import com.example.nto_minipigs.LoginViewModel
import com.example.nto_minipigs.UserData import com.example.nto_minipigs.UserData
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
@Composable @Composable
fun LoginScreen(onNavigateToMain: () -> Unit, viewModel: LoginViewModel, dataStore: UserData) { fun LoginScreen(onNavigateToMain: () -> Unit, viewModel: LoginViewModel, dataStore: UserData) {
@ -62,9 +58,7 @@ fun LoginScreen( onNavigateToMain: () -> Unit, viewModel: LoginViewModel, dataSt
) )
Button( Button(
onClick = { onClick = { viewModel.Authenticate(login, password, onNavigateToMain, dataStore) },
viewModel.getData(login, password, onNavigateToMain, dataStore)
},
shape = RoundedCornerShape(12.dp), shape = RoundedCornerShape(12.dp),
) { ) {
Text(text = "Sign In", style = MaterialTheme.typography.bodyLarge) Text(text = "Sign In", style = MaterialTheme.typography.bodyLarge)

View File

@ -1,22 +1,25 @@
package com.example.nto_minipigs package com.example.nto_minipigs.ui.screens.Login
import RetrofitClient import RetrofitClient
import android.util.Log import android.util.Log
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.nto_minipigs.Retrofit.Models.Auth import com.example.nto_minipigs.Retrofit.Models.Auth
import com.example.nto_minipigs.UserData
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class LoginViewModel :ViewModel() { class LoginViewModel :ViewModel() {
private val serviceApi = RetrofitClient.apiService 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 { viewModelScope.launch {
try { try {
val auth = Auth(login, password) val auth = Auth(login, password)
val response = serviceApi.login(auth) val response = serviceApi.login(auth)
if(response.isSuccessful) {
dataStore.updateToken(response.body()?.token.toString()) dataStore.updateToken(response.body()?.token.toString())
func() func()
}
} catch (e: Exception) { } catch (e: Exception) {
Log.d("exception:", e.toString()) Log.d("exception:", e.toString())
} }

View File

@ -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.Arrangement
import androidx.compose.foundation.layout.Column 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.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.rememberDateRangePickerState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import com.example.nto_minipigs.ui.theme.Nto_minipigsTheme import com.example.nto_minipigs.ui.theme.Nto_minipigsTheme
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.example.nto_minipigs.UserData
@Composable @Composable
fun MainScreen( onNavigateToMain: () -> Unit ) { fun MainScreen( viewModel: MainViewModel, token: String?) {
Nto_minipigsTheme { Nto_minipigsTheme {
val data = viewModel.data.observeAsState()
Surface { Surface {
Column( Column(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center, verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Text( when(val result = data.value){
text = "MiniPigs", is NetworkResponse.Error -> {
style = MaterialTheme.typography.titleLarge, Text(text = result.message)
modifier = Modifier.padding(bottom = 36.dp) }
) NetworkResponse.Loading -> {
CircularProgressIndicator()
var login by remember { mutableStateOf("") } }
var password by remember { mutableStateOf("") } is NetworkResponse.Success -> {
Text(text = result.data.toString())
OutlinedTextField( }
value = login, null -> {}
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),
)
Button( Button(
onClick = { onNavigateToMain() }, onClick = { viewModel.Fetch(token) },
shape = RoundedCornerShape(12.dp), shape = RoundedCornerShape(12.dp),
) { ) {
Text(text = "Sign In", style = MaterialTheme.typography.bodyLarge) Text(text = "Sign In", style = MaterialTheme.typography.bodyLarge)
} }
} }
} }
LaunchedEffect(Unit) {
viewModel.Fetch(token)
}
} }
} }

View File

@ -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<NetworkResponse<User>>()
val data : LiveData<NetworkResponse<User>> = _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<out T> {
data class Success<out T>(val data: T) : NetworkResponse<T>()
data class Error(val message: String) : NetworkResponse<Nothing>()
object Loading : NetworkResponse<Nothing>()
}