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