auth is worked on
This commit is contained in:
parent
9dac68d0db
commit
8c7c61f299
@ -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")
|
||||||
}
|
}
|
@ -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")
|
|
||||||
}
|
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
}
|
}
|
@ -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)
|
@ -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())
|
||||||
}
|
}
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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>()
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user