Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
0ffd6b0ee6
@ -28,6 +28,7 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
val toolbar = findViewById<Toolbar>(R.id.toolbar)
|
||||
setSupportActionBar(toolbar)
|
||||
|
||||
val navHostFragment =
|
||||
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as? NavHostFragment
|
||||
?: throw IllegalStateException("NavHostFragment is null")
|
||||
@ -38,6 +39,7 @@ class MainActivity : AppCompatActivity() {
|
||||
)
|
||||
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration)
|
||||
NavigationUI.setupWithNavController(navView, navController)
|
||||
supportActionBar!!.setDisplayHomeAsUpEnabled(false)
|
||||
|
||||
navController.addOnDestinationChangedListener { _, destination, _ ->
|
||||
Log.d("Navigate", "Navigate to " + destination.label)
|
||||
@ -45,8 +47,8 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
val userDTO = getCachedUser()
|
||||
if (userDTO != null) {
|
||||
if (!userDTO.roles.any { it.name == "ROLE_ADMIN" }) navView.menu.findItem(R.id.nav_admin)
|
||||
.setVisible(false) else navView.menu.findItem(R.id.nav_admin).setVisible(true)
|
||||
val adminButton = navView.menu.findItem(R.id.nav_admin)
|
||||
if (!userDTO.roles.any { it.name == "ROLE_ADMIN" }) adminButton.setVisible(false) else adminButton.setVisible(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
package com.displaynone.acss.components.auth.models.user
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.displaynone.acss.components.auth.internal_utils.AuthTokenManager
|
||||
import com.displaynone.acss.components.auth.internal_utils.UserManager
|
||||
import com.displaynone.acss.components.auth.models.AuthTokenPair
|
||||
import com.displaynone.acss.components.auth.models.user.repository.UserRepository
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.UserDTO
|
||||
import com.displaynone.acss.components.acs.models.visit.repository.dto.VisitDto
|
||||
|
||||
|
||||
class UserServiceST(
|
||||
@ -34,69 +34,64 @@ class UserServiceST(
|
||||
return instance ?: throw RuntimeException("null instance")
|
||||
}
|
||||
}
|
||||
suspend fun login(login: String, password:String): Result<Unit>{
|
||||
|
||||
suspend fun login(login: String, password: String): Result<Unit> {
|
||||
return runCatching {
|
||||
userRepository.login(login = login, password).getOrThrow().let { data ->
|
||||
tokenManager.saveTokens(data)
|
||||
userManager.saveDto(data.user)
|
||||
tokenManager.saveTokens(data.tokens)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getTokenPair(): AuthTokenPair? {
|
||||
return tokenManager.authTokenPair
|
||||
}
|
||||
|
||||
fun hasTokens(): Boolean {
|
||||
return tokenManager.hasTokens()
|
||||
}
|
||||
// suspend fun getMyLastVisits(pageNum: Int,
|
||||
// pageSize: Int): Result<List<VisitDto>> {
|
||||
// if (!tokenManager.hasTokens()) {
|
||||
// throw RuntimeException("access token is null")
|
||||
// }
|
||||
//
|
||||
// return userRepository.getMyLastVisits(
|
||||
// pageNum = pageNum,
|
||||
// pageSize = pageSize,
|
||||
// token = tokenManager.authTokenPair!!.accessToken
|
||||
// ).map { pagingDto -> pagingDto.content }
|
||||
// }
|
||||
// suspend fun getLastVisitsByLogin(pageNum: Int,
|
||||
// pageSize: Int,
|
||||
// login: String): Result<List<VisitDto>> {
|
||||
// if (!tokenManager.hasTokens()) {
|
||||
// throw RuntimeException("access token is null")
|
||||
// }
|
||||
// return userRepository.getLastVisitsByLogin(pageNum, pageSize, tokenManager.authTokenPair!!.accessToken, login).map { pagingDto -> pagingDto.content }
|
||||
// }
|
||||
fun logout(){
|
||||
|
||||
fun logout() {
|
||||
tokenManager.clear()
|
||||
}
|
||||
|
||||
suspend fun changeRights(login: String, isACSBlocked: Boolean): Result<Unit> {
|
||||
return userRepository.changeRightsByLogin(login, tokenManager.authTokenPair!!.accessToken, isACSBlocked)
|
||||
return userRepository.changeRightsByLogin(
|
||||
login,
|
||||
tokenManager.authTokenPair!!.accessToken,
|
||||
isACSBlocked
|
||||
)
|
||||
}
|
||||
suspend fun getInfo(): Result<UserDTO>{
|
||||
|
||||
suspend fun getInfo(): Result<UserDTO> {
|
||||
if (!tokenManager.hasTokens()) {
|
||||
throw RuntimeException("access token is null")
|
||||
}
|
||||
|
||||
val result = userRepository.getInfo(tokenManager.authTokenPair!!.accessToken)
|
||||
result.map { dto ->
|
||||
saveUserDTO(dto)
|
||||
}
|
||||
result.map { dto -> saveUserDTO(dto) }
|
||||
return result
|
||||
}
|
||||
suspend fun getInfoByLogin(login: String): Result<UserDTO>{
|
||||
|
||||
suspend fun getInfoByLogin(login: String): Result<UserDTO> {
|
||||
if (!tokenManager.hasTokens()) {
|
||||
throw RuntimeException("access token is null")
|
||||
}
|
||||
return userRepository.getInfoByLogin(tokenManager.authTokenPair!!.accessToken, login)
|
||||
}
|
||||
|
||||
suspend fun openDoor(code: String): Result<Int> {
|
||||
return userRepository.openDoor(tokenManager.authTokenPair!!.accessToken, code = code)
|
||||
}
|
||||
|
||||
fun getUserDTO(): UserDTO? {
|
||||
return userManager.dto
|
||||
}
|
||||
fun saveUserDTO(userDTO: UserDTO){
|
||||
return userManager.saveDto(userDTO)
|
||||
|
||||
fun saveUserDTO(userDTO: UserDTO) {
|
||||
Log.d("USER", "UPDATE USER")
|
||||
|
||||
return userManager.saveDto(userDTO)
|
||||
}
|
||||
}
|
@ -1,22 +1,18 @@
|
||||
package com.displaynone.acss.components.auth.models.user.repository
|
||||
|
||||
import android.util.Log
|
||||
import com.bumptech.glide.load.HttpException
|
||||
import com.displaynone.acss.components.auth.models.AuthTokenPair
|
||||
import com.displaynone.acss.config.Constants.serverUrl
|
||||
import com.displaynone.acss.config.Network
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.RegisterUserDto
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.LoginDTO
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.LoginResponseDTO
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.UpdateUserDTO
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.UserDTO
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.UserLoginDto
|
||||
import com.displaynone.acss.config.Constants.serverUrl
|
||||
import com.displaynone.acss.config.Network
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.request.headers
|
||||
import io.ktor.client.request.patch
|
||||
import io.ktor.client.request.post
|
||||
import io.ktor.client.request.setBody
|
||||
import io.ktor.client.statement.bodyAsText
|
||||
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.http.HttpHeaders
|
||||
import io.ktor.http.HttpStatusCode
|
||||
@ -24,40 +20,27 @@ import io.ktor.http.contentType
|
||||
import io.ktor.http.encodeURLPath
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
class UserRepository(
|
||||
|
||||
) {
|
||||
suspend fun isUserExist(login: String): Result<Boolean> = withContext(Dispatchers.IO) {
|
||||
runCatching {
|
||||
val encodedLogin = login.encodeURLPath()
|
||||
val result = Network.client.get("$serverUrl/api/$encodedLogin/auth/")
|
||||
result.status != HttpStatusCode.OK
|
||||
}
|
||||
}
|
||||
suspend fun login(login: String, password: String): Result<AuthTokenPair> = withContext(Dispatchers.IO) {
|
||||
runCatching {
|
||||
val result = Network.client.post("$serverUrl/api/auth/login") {
|
||||
headers {
|
||||
append(HttpHeaders.ContentType, ContentType.Application.Json.toString())
|
||||
class UserRepository {
|
||||
suspend fun login(login: String, password: String): Result<LoginResponseDTO> =
|
||||
withContext(Dispatchers.IO) {
|
||||
runCatching {
|
||||
val result = Network.client.post("$serverUrl/api/auth/login") {
|
||||
headers {
|
||||
append(HttpHeaders.ContentType, ContentType.Application.Json.toString())
|
||||
}
|
||||
contentType(ContentType.Application.Json)
|
||||
setBody(LoginDTO(login, password))
|
||||
}
|
||||
contentType(ContentType.Application.Json)
|
||||
setBody(UserLoginDto(login, password))
|
||||
|
||||
if (result.status != HttpStatusCode.OK) error(result.status)
|
||||
|
||||
result.body()
|
||||
}
|
||||
if (result.status != HttpStatusCode.OK) {
|
||||
error(result.status)
|
||||
}
|
||||
// val gson = Gson()
|
||||
// val tokenPair = gson.fromJson(result.bodyAsText(), AuthTokenPair::class.java)
|
||||
Log.d("UserRepository", result.bodyAsText())
|
||||
// result.body()
|
||||
val tokenPair = Json.decodeFromString<AuthTokenPair>(result.bodyAsText())
|
||||
tokenPair
|
||||
}
|
||||
}
|
||||
suspend fun openDoor(token: String, code: String): Result<Int> = withContext(Dispatchers.IO){
|
||||
runCatching{
|
||||
|
||||
suspend fun openDoor(token: String, code: String): Result<Int> = withContext(Dispatchers.IO) {
|
||||
runCatching {
|
||||
val result = Network.client.post("$serverUrl/api/acs/open") {
|
||||
headers {
|
||||
append(HttpHeaders.Authorization, "Bearer $token")
|
||||
@ -65,58 +48,61 @@ class UserRepository(
|
||||
contentType(ContentType.Application.Json)
|
||||
setBody("""{ "code": $code }""")
|
||||
}
|
||||
if (result.status != HttpStatusCode.OK) {
|
||||
error("Status ${result.status}: ${result.body<String>()}")
|
||||
}
|
||||
Log.d("UserRepository", result.bodyAsText())
|
||||
|
||||
if (result.status != HttpStatusCode.OK) error("Status ${result.status}: ${result.body<String>()}")
|
||||
|
||||
result.status.value
|
||||
}
|
||||
}
|
||||
suspend fun getInfo(token: String): Result<UserDTO> = withContext(Dispatchers.IO){
|
||||
|
||||
suspend fun getInfo(token: String): Result<UserDTO> = withContext(Dispatchers.IO) {
|
||||
runCatching {
|
||||
val result = Network.client.get("$serverUrl/api/users/me") {
|
||||
headers {
|
||||
append(HttpHeaders.Authorization, "Bearer $token")
|
||||
}
|
||||
}
|
||||
if (result.status != HttpStatusCode.OK) {
|
||||
error("Status ${result.status}: ${result.body<String>()}")
|
||||
}
|
||||
Log.d("UserRepository", result.bodyAsText())
|
||||
if (result.status != HttpStatusCode.OK) error("Status ${result.status}: ${result.body<String>()}")
|
||||
result.body()
|
||||
}
|
||||
}
|
||||
suspend fun getInfoByLogin(token: String, login: String): Result<UserDTO> = withContext(Dispatchers.IO){
|
||||
runCatching {
|
||||
val encodedLogin = login.encodeURLPath()
|
||||
val result = Network.client.get("$serverUrl/api/users/login/$encodedLogin") {
|
||||
headers {
|
||||
append(HttpHeaders.Authorization, "Bearer $token")
|
||||
|
||||
suspend fun getInfoByLogin(token: String, login: String): Result<UserDTO> =
|
||||
withContext(Dispatchers.IO) {
|
||||
runCatching {
|
||||
val encodedLogin = login.encodeURLPath()
|
||||
val result = Network.client.get("$serverUrl/api/users/login/$encodedLogin") {
|
||||
headers {
|
||||
append(HttpHeaders.Authorization, "Bearer $token")
|
||||
}
|
||||
setBody("""{ "code": "$encodedLogin" }""")
|
||||
}
|
||||
setBody("""{ "code": "$encodedLogin" }""")
|
||||
if (result.status != HttpStatusCode.OK) error("Status ${result.status}: ${result.body<String>()}")
|
||||
result.body()
|
||||
}
|
||||
if (result.status != HttpStatusCode.OK) {
|
||||
error("Status ${result.status}: ${result.body<String>()}")
|
||||
}
|
||||
Log.d("UserRepository", result.bodyAsText())
|
||||
result.body()
|
||||
}
|
||||
}
|
||||
suspend fun changeRightsByLogin(login: String, token: String, isACSBlocked: Boolean): Result<Unit> = withContext(Dispatchers.IO) {
|
||||
|
||||
suspend fun changeRightsByLogin(
|
||||
login: String,
|
||||
token: String,
|
||||
isACSBlocked: Boolean
|
||||
): Result<Unit> = withContext(Dispatchers.IO) {
|
||||
runCatching {
|
||||
val encodedLogin = login.encodeURLPath()
|
||||
val result = Network.client.patch("$serverUrl/api/users/login/$encodedLogin") {
|
||||
headers{
|
||||
headers {
|
||||
append(HttpHeaders.Authorization, "Bearer $token")
|
||||
}
|
||||
contentType(ContentType.Application.Json)
|
||||
setBody(UpdateUserDTO(
|
||||
password = null,
|
||||
name = null,
|
||||
photo = null,
|
||||
position = null,
|
||||
isACSBlocked = isACSBlocked
|
||||
))
|
||||
setBody(
|
||||
UpdateUserDTO(
|
||||
password = null,
|
||||
name = null,
|
||||
photo = null,
|
||||
position = null,
|
||||
isACSBlocked = isACSBlocked
|
||||
)
|
||||
)
|
||||
}
|
||||
if (result.status != HttpStatusCode.OK) {
|
||||
Log.w("UserRepository", "Status: ${result.status}, Body: ${result.body<String>()}")
|
||||
|
@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class UserLoginDto(
|
||||
data class LoginDTO(
|
||||
@SerialName("login")
|
||||
val login: String,
|
||||
@SerialName("password")
|
@ -0,0 +1,13 @@
|
||||
package com.displaynone.acss.components.auth.models.user.repository.dto
|
||||
|
||||
import com.displaynone.acss.components.auth.models.AuthTokenPair
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class LoginResponseDTO(
|
||||
@SerialName("tokens")
|
||||
val tokens: AuthTokenPair,
|
||||
@SerialName("user")
|
||||
val user: UserDTO,
|
||||
)
|
@ -9,18 +9,17 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.displaynone.acss.R
|
||||
import com.displaynone.acss.databinding.FragmentAuthBinding
|
||||
import com.displaynone.acss.ui.auth.AuthViewModel.Action
|
||||
import com.displaynone.acss.util.collectWithLifecycle
|
||||
import com.displaynone.acss.util.navigateTo
|
||||
import com.displaynone.acss.ui.auth.AuthViewModel.Action
|
||||
|
||||
class AuthFragment: Fragment(R.layout.fragment_auth) {
|
||||
class AuthFragment : Fragment(R.layout.fragment_auth) {
|
||||
private var _binding: FragmentAuthBinding? = null
|
||||
private val binding: FragmentAuthBinding get() = _binding!!
|
||||
|
||||
private val viewModel: AuthViewModel by viewModels()
|
||||
|
||||
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentAuthBinding.bind(view)
|
||||
@ -40,22 +39,25 @@ class AuthFragment: Fragment(R.layout.fragment_auth) {
|
||||
binding.errorTitle.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
binding.next.setOnClickListener{
|
||||
binding.next.setOnClickListener {
|
||||
onLoginButtonClicked(view)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("StringFormatMatches")
|
||||
private fun getErrorDescription(errorCode: String): String {
|
||||
return when (errorCode) {
|
||||
401.toString()+' ' -> getString(R.string.error_401)
|
||||
404.toString()+' ' -> getString(R.string.error_404)
|
||||
500.toString()+' ' -> getString(R.string.error_500)
|
||||
401.toString() + ' ' -> getString(R.string.error_401)
|
||||
404.toString() + ' ' -> getString(R.string.error_404)
|
||||
500.toString() + ' ' -> getString(R.string.error_500)
|
||||
else -> getString(R.string.error_unknown, errorCode)
|
||||
}
|
||||
}
|
||||
|
||||
private fun blockLoginButton() {
|
||||
binding.next.isEnabled = false
|
||||
}
|
||||
|
||||
private fun getPasswordValidError(password: String): String {
|
||||
if (password.length < 8) {
|
||||
return "LenError"
|
||||
@ -76,6 +78,7 @@ class AuthFragment: Fragment(R.layout.fragment_auth) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getLoginValidError(username: String): String {
|
||||
val alf = "^[a-zA-Z0-9_]+$".toRegex()
|
||||
if (username.isEmpty()) {
|
||||
@ -97,53 +100,61 @@ class AuthFragment: Fragment(R.layout.fragment_auth) {
|
||||
// password.length >= 8
|
||||
// }
|
||||
|
||||
// private fun subscribe() {
|
||||
// private fun subscribe() {
|
||||
// viewModel.state.collectWhenStarted(this) { state ->
|
||||
// binding.login.setOnClickListener(this::onLoginButtonClicked)
|
||||
// }
|
||||
// }
|
||||
private fun validateLoginAndSetError(username: String) {
|
||||
val errorType = getLoginValidError(username)
|
||||
private fun validateLoginAndSetError(username: String) {
|
||||
val errorType = getLoginValidError(username)
|
||||
|
||||
when (errorType) {
|
||||
"EmptyError" -> {
|
||||
binding.login.error = getString(R.string.error_login_empty)
|
||||
}
|
||||
"LenError" -> {
|
||||
binding.login.error = getString(R.string.error_login_too_short)
|
||||
}
|
||||
"StartsWithDigitError" -> {
|
||||
binding.login.error = getString(R.string.error_login_starts_with_digit)
|
||||
}
|
||||
"InvalidCharactersError" -> {
|
||||
binding.login.error = getString(R.string.error_login_invalid_characters)
|
||||
}
|
||||
"NoErrors" -> {
|
||||
binding.login.error = null
|
||||
when (errorType) {
|
||||
"EmptyError" -> {
|
||||
binding.login.error = getString(R.string.error_login_empty)
|
||||
}
|
||||
|
||||
"LenError" -> {
|
||||
binding.login.error = getString(R.string.error_login_too_short)
|
||||
}
|
||||
|
||||
"StartsWithDigitError" -> {
|
||||
binding.login.error = getString(R.string.error_login_starts_with_digit)
|
||||
}
|
||||
|
||||
"InvalidCharactersError" -> {
|
||||
binding.login.error = getString(R.string.error_login_invalid_characters)
|
||||
}
|
||||
|
||||
"NoErrors" -> {
|
||||
binding.login.error = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onLoginButtonClicked(view: View) {
|
||||
val login = binding.login.text.toString()
|
||||
val password = binding.password.text.toString()
|
||||
|
||||
if (getPasswordValidError(password) != "NoErrors") {
|
||||
|
||||
|
||||
val color = R.color.secondary
|
||||
binding.next.backgroundTintList = ContextCompat.getColorStateList(requireContext(), color)
|
||||
binding.next.backgroundTintList =
|
||||
ContextCompat.getColorStateList(requireContext(), color)
|
||||
validatePasswordAndSetError(password)
|
||||
}else{
|
||||
} else {
|
||||
val color = R.color.primary
|
||||
binding.next.backgroundTintList = ContextCompat.getColorStateList(requireContext(), color)
|
||||
binding.next.backgroundTintList =
|
||||
ContextCompat.getColorStateList(requireContext(), color)
|
||||
}
|
||||
// if (login.isEmpty()) return
|
||||
|
||||
if (getLoginValidError(login) != "NoErrors") {
|
||||
val color = R.color.secondary
|
||||
binding.next.backgroundTintList = ContextCompat.getColorStateList(requireContext(), color)
|
||||
binding.next.backgroundTintList =
|
||||
ContextCompat.getColorStateList(requireContext(), color)
|
||||
validateLoginAndSetError(login)
|
||||
}else{
|
||||
} else {
|
||||
val color = R.color.primary
|
||||
binding.next.backgroundTintList = ContextCompat.getColorStateList(requireContext(), color)
|
||||
binding.next.backgroundTintList =
|
||||
ContextCompat.getColorStateList(requireContext(), color)
|
||||
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@ import android.util.Log
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.displaynone.acss.components.auth.models.user.UserServiceST
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.RegisterUserDto
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@ -12,9 +11,8 @@ import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
class AuthViewModel(): ViewModel() {
|
||||
class AuthViewModel : ViewModel() {
|
||||
private val _action = Channel<Action>(
|
||||
capacity = Channel.BUFFERED,
|
||||
onBufferOverflow = BufferOverflow.DROP_OLDEST,
|
||||
@ -23,7 +21,7 @@ class AuthViewModel(): ViewModel() {
|
||||
private val _errorState = MutableStateFlow<String?>(null)
|
||||
val errorState: StateFlow<String?> = _errorState.asStateFlow()
|
||||
|
||||
fun login(login: String, password:String){
|
||||
fun login(login: String, password: String) {
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
UserServiceST.getInstance().login(login, password).fold(
|
||||
@ -40,6 +38,7 @@ class AuthViewModel(): ViewModel() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun openProfile() {
|
||||
viewModelScope.launch {
|
||||
_action.send(Action.GotoProfile)
|
||||
|
@ -12,7 +12,6 @@ import androidx.navigation.NavController
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.displaynone.acss.R
|
||||
import com.displaynone.acss.components.auth.models.user.UserServiceST
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.UserDTO
|
||||
import com.displaynone.acss.databinding.FragmentInitBinding
|
||||
import com.displaynone.acss.util.collectWithLifecycle
|
||||
import com.displaynone.acss.util.navigateTo
|
||||
@ -29,24 +28,26 @@ class InitFragment : Fragment(R.layout.fragment_init) {
|
||||
_binding = FragmentInitBinding.bind(view)
|
||||
|
||||
if (!checkInternetConnection()) {
|
||||
hideSpinner()
|
||||
handleError(R.string.noInternet)
|
||||
return
|
||||
}
|
||||
|
||||
pingServer()
|
||||
|
||||
}
|
||||
|
||||
private fun pingServer() {
|
||||
viewModel.pingServer()
|
||||
viewModel.state.collectWithLifecycle(this) { state ->
|
||||
if (state is InitFragmentViewModel.State.Show){
|
||||
if(!state.item){
|
||||
if (state is InitFragmentViewModel.State.Show) {
|
||||
if (!state.item) {
|
||||
hideSpinner()
|
||||
handleError(R.string.serverIsUnabailable)
|
||||
} else{
|
||||
} else {
|
||||
val navController: NavController = findNavController()
|
||||
|
||||
if (!isUserAuthenticated()) {
|
||||
hideSpinner()
|
||||
navigateTo(navController, R.id.action_nav_init_to_nav_auth)
|
||||
} else {
|
||||
updateUser(navController)
|
||||
@ -58,15 +59,14 @@ class InitFragment : Fragment(R.layout.fragment_init) {
|
||||
|
||||
private fun updateUser(navController: NavController) {
|
||||
viewModel.updateUserInfo()
|
||||
viewModel.state.collectWithLifecycle(this){ state ->
|
||||
viewModel.state.collectWithLifecycle(this) { state ->
|
||||
hideSpinner()
|
||||
|
||||
if (state is InitFragmentViewModel.State.Update) {
|
||||
if (state.item == null) {
|
||||
navigateTo(navController, R.id.action_nav_init_to_nav_auth)
|
||||
} else{
|
||||
navigateTo(navController, R.id.action_nav_init_to_nav_profile)
|
||||
}
|
||||
navigateTo(navController, R.id.action_nav_init_to_nav_profile)
|
||||
}
|
||||
if (state is InitFragmentViewModel.State.Error){
|
||||
|
||||
if (state is InitFragmentViewModel.State.Error) {
|
||||
navigateTo(navController, R.id.action_nav_init_to_nav_auth)
|
||||
}
|
||||
}
|
||||
@ -95,8 +95,22 @@ class InitFragment : Fragment(R.layout.fragment_init) {
|
||||
return false
|
||||
}
|
||||
|
||||
private fun getCachedUser(): UserDTO? {
|
||||
return UserServiceST.getInstance().getUserDTO();
|
||||
private fun hideSpinner() {
|
||||
binding.spinner.visibility = View.GONE
|
||||
}
|
||||
|
||||
private fun unhideSpinner() {
|
||||
binding.spinner.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
private fun hideError() {
|
||||
binding.errorImage.visibility = View.GONE
|
||||
binding.error.visibility = View.GONE
|
||||
}
|
||||
|
||||
private fun unhideError() {
|
||||
binding.errorImage.visibility = View.VISIBLE
|
||||
binding.error.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
private fun isUserAuthenticated(): Boolean {
|
||||
@ -104,11 +118,9 @@ class InitFragment : Fragment(R.layout.fragment_init) {
|
||||
}
|
||||
|
||||
private fun handleError(string: Int) {
|
||||
unhideError()
|
||||
binding.error.text = requireContext().getString(string)
|
||||
}
|
||||
private fun handleError(errorMessage: String) {
|
||||
binding.error.text = errorMessage
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
|
@ -6,11 +6,10 @@ import androidx.lifecycle.viewModelScope
|
||||
import androidx.paging.Pager
|
||||
import androidx.paging.PagingConfig
|
||||
import androidx.paging.cachedIn
|
||||
import com.displaynone.acss.components.auth.models.user.UserServiceST
|
||||
import com.displaynone.acss.components.acs.models.visit.VisitListPagingSource
|
||||
import com.displaynone.acss.components.acs.models.visit.VisitServiceST
|
||||
import com.displaynone.acss.components.auth.models.user.UserServiceST
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.UserDTO
|
||||
import io.ktor.util.reflect.instanceOf
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@ -18,21 +17,24 @@ import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class ProfileViewModel(): ViewModel() {
|
||||
class ProfileViewModel() : ViewModel() {
|
||||
private val _action = Channel<Action>(
|
||||
capacity = Channel.BUFFERED,
|
||||
onBufferOverflow = BufferOverflow.DROP_OLDEST,
|
||||
)
|
||||
|
||||
private var login: String = ""
|
||||
fun setLogin(login1: String){
|
||||
fun setLogin(login1: String) {
|
||||
login = login1
|
||||
}
|
||||
|
||||
val action = _action.receiveAsFlow()
|
||||
val _state = MutableStateFlow<State>(State.Loading)
|
||||
val state = _state.asStateFlow()
|
||||
|
||||
val visitListState = Pager(
|
||||
config = PagingConfig(pageSize = 20,
|
||||
config = PagingConfig(
|
||||
pageSize = 20,
|
||||
enablePlaceholders = false,
|
||||
maxSize = 100
|
||||
)
|
||||
@ -45,19 +47,19 @@ class ProfileViewModel(): ViewModel() {
|
||||
config = PagingConfig(pageSize = 20, enablePlaceholders = false, maxSize = 100)
|
||||
) {
|
||||
VisitListPagingSource { pageNum, pageSize ->
|
||||
VisitServiceST.getInstance().getLastVisitsByLogin(pageNum,pageSize, login)
|
||||
VisitServiceST.getInstance().getLastVisitsByLogin(pageNum, pageSize, login)
|
||||
}
|
||||
}.flow.cachedIn(viewModelScope)
|
||||
|
||||
fun logout(){
|
||||
fun logout() {
|
||||
UserServiceST.getInstance().logout()
|
||||
}
|
||||
fun getInfo(){
|
||||
|
||||
fun getInfo() {
|
||||
viewModelScope.launch {
|
||||
UserServiceST.getInstance().getInfo().fold(
|
||||
onSuccess = { data ->
|
||||
_state.emit(State.Show(data))
|
||||
UserServiceST.getInstance().saveUserDTO(data)
|
||||
Log.d("Pvm", data.login)
|
||||
},
|
||||
onFailure = { error ->
|
||||
@ -67,7 +69,8 @@ class ProfileViewModel(): ViewModel() {
|
||||
)
|
||||
}
|
||||
}
|
||||
fun changeRights(login: String, isACSBlocked: Boolean){
|
||||
|
||||
fun changeRights(login: String, isACSBlocked: Boolean) {
|
||||
viewModelScope.launch {
|
||||
UserServiceST.getInstance().changeRights(login, isACSBlocked).fold(
|
||||
onSuccess = {
|
||||
@ -80,12 +83,14 @@ class ProfileViewModel(): ViewModel() {
|
||||
)
|
||||
}
|
||||
}
|
||||
fun openAuth(){
|
||||
|
||||
fun openAuth() {
|
||||
viewModelScope.launch {
|
||||
_action.send(Action.GoToAuth)
|
||||
}
|
||||
}
|
||||
fun openScan(){
|
||||
|
||||
fun openScan() {
|
||||
viewModelScope.launch {
|
||||
_action.send(Action.GoToScan)
|
||||
}
|
||||
@ -96,12 +101,14 @@ class ProfileViewModel(): ViewModel() {
|
||||
data class Show(
|
||||
val item: UserDTO
|
||||
) : State
|
||||
|
||||
data class Change(
|
||||
val item: Boolean
|
||||
) : State
|
||||
}
|
||||
|
||||
sealed interface Action {
|
||||
data object GoToAuth: Action
|
||||
data object GoToScan: Action
|
||||
data object GoToAuth : Action
|
||||
data object GoToScan : Action
|
||||
}
|
||||
}
|
@ -1,35 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_horizontal">
|
||||
|
||||
<ImageView
|
||||
android:visibility="gone"
|
||||
android:id="@+id/error_image"
|
||||
android:layout_width="250dp"
|
||||
android:layout_height="250dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_height="250dp"
|
||||
android:src="@drawable/lost_connection"/>
|
||||
android:src="@drawable/dinosaur"
|
||||
android:textAlignment="center"/>
|
||||
|
||||
<TextView
|
||||
android:visibility="gone"
|
||||
android:id="@+id/error"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textSize="24sp"
|
||||
android:layout_margin="15dp"
|
||||
android:letterSpacing="0.05"
|
||||
android:background="?android:attr/colorBackground"
|
||||
android:gravity="center"
|
||||
android:letterSpacing="0.05"
|
||||
android:textColor="?attr/colorOnBackground"
|
||||
tools:text="@string/noInternet"
|
||||
tools:ignore="MissingConstraints" />
|
||||
<ImageView
|
||||
android:layout_width="250dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_height="250dp"
|
||||
android:src="@drawable/dinosaur"/>
|
||||
android:textSize="24sp"
|
||||
tools:ignore="MissingConstraints"
|
||||
tools:text="@string/noInternet" />
|
||||
<ProgressBar
|
||||
android:id="@+id/spinner"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -6,7 +6,7 @@
|
||||
<fragment
|
||||
android:id="@+id/nav_init"
|
||||
android:name="com.displaynone.acss.ui.init.InitFragment"
|
||||
android:label="InitFragment">
|
||||
android:label="@string/app_name">
|
||||
<action
|
||||
android:id="@+id/action_nav_init_to_nav_profile"
|
||||
app:destination="@id/nav_profile" />
|
||||
|
@ -1,5 +1,5 @@
|
||||
<resources>
|
||||
<string name="app_name">AS</string>
|
||||
<string name="app_name">ACSS</string>
|
||||
<string name="login">Enter Login</string>
|
||||
<string name="password">Enter password</string>
|
||||
<string name="hello">Welcome!</string>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">AS</string>
|
||||
<string name="app_name">ACSS</string>
|
||||
<string name="login">Введите логин</string>
|
||||
<string name="password">Введите пароль</string>
|
||||
<string name="hello">Здравствуйте!</string>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<resources>
|
||||
<string name="app_name">AS</string>
|
||||
<string name="app_name">ACSS</string>
|
||||
<string name="login">Enter Login</string>
|
||||
<string name="password">Enter password</string>
|
||||
<string name="hello">Welcome!</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user