fixes / feat: some bugs with dto fixed and block / unblock use case done
This commit is contained in:
parent
f81befe9bd
commit
3aa012adf9
app/src/main
java/ru/myitschool/work
data
domain
ui
res
layout-land
layout
navigation
values-en-rUS
values
@ -7,8 +7,12 @@ import ru.myitschool.work.domain.admin.AdminRepository
|
|||||||
class AdminRepositoryImpl(
|
class AdminRepositoryImpl(
|
||||||
private val networkDataSource: AdminNetworkDataSource,
|
private val networkDataSource: AdminNetworkDataSource,
|
||||||
private val localCredentialsLocalDataSource: CredentialsLocalDataSource
|
private val localCredentialsLocalDataSource: CredentialsLocalDataSource
|
||||||
): AdminRepository {
|
) : AdminRepository {
|
||||||
override suspend fun blockUser(login: String): Result<Unit> {
|
override suspend fun blockUser(login: String): Result<Unit> {
|
||||||
return networkDataSource.blockUser(login, localCredentialsLocalDataSource.getToken())
|
return networkDataSource.blockUser(login, localCredentialsLocalDataSource.getToken())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun unblockUser(login: String): Result<Unit> {
|
||||||
|
return networkDataSource.unblockUser(login, localCredentialsLocalDataSource.getToken())
|
||||||
|
}
|
||||||
}
|
}
|
@ -40,8 +40,8 @@ class PassRepositoryImpl(
|
|||||||
return listDto.map { successListDto ->
|
return listDto.map { successListDto ->
|
||||||
successListDto.mapNotNull { dto ->
|
successListDto.mapNotNull { dto ->
|
||||||
PassEntity(
|
PassEntity(
|
||||||
type = dto.type ?: return@mapNotNull null,
|
type = dto.terminal?.type ?: return@mapNotNull null,
|
||||||
name = dto.name ?: return@mapNotNull null,
|
name = dto.terminal.name ?: return@mapNotNull null,
|
||||||
time = dto.time ?: return@mapNotNull null
|
time = dto.time ?: return@mapNotNull null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package ru.myitschool.work.data
|
package ru.myitschool.work.data
|
||||||
|
|
||||||
import ru.myitschool.work.data.local.CredentialsLocalDataSource
|
import ru.myitschool.work.data.local.CredentialsLocalDataSource
|
||||||
|
import ru.myitschool.work.data.network.QrNetworkDataSource
|
||||||
import ru.myitschool.work.domain.entities.QrEntity
|
import ru.myitschool.work.domain.entities.QrEntity
|
||||||
import ru.myitschool.work.domain.qr.QrRepository
|
import ru.myitschool.work.domain.qr.QrRepository
|
||||||
|
|
||||||
|
@ -21,7 +21,9 @@ class UserRepositoryImpl(
|
|||||||
.fold(
|
.fold(
|
||||||
onSuccess = { dto ->
|
onSuccess = { dto ->
|
||||||
map(dto).fold(
|
map(dto).fold(
|
||||||
onSuccess = { userLocalDataSource.cacheData(it) },
|
onSuccess = {
|
||||||
|
userLocalDataSource.cacheData(it)
|
||||||
|
},
|
||||||
onFailure = { error(it) }
|
onFailure = { error(it) }
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -32,8 +34,13 @@ class UserRepositoryImpl(
|
|||||||
|
|
||||||
override suspend fun authorize(token: String): Result<Unit> {
|
override suspend fun authorize(token: String): Result<Unit> {
|
||||||
return networkDataSource.login(token).fold(
|
return networkDataSource.login(token).fold(
|
||||||
onSuccess = { Result.success(Unit) },
|
onSuccess = { dto ->
|
||||||
onFailure = { error -> Result.failure(error) }
|
map(dto).fold(
|
||||||
|
onSuccess = { Result.success(userLocalDataSource.cacheData(it)) },
|
||||||
|
onFailure = { Result.failure(it) }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onFailure = { Result.failure(it) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +61,7 @@ class UserRepositoryImpl(
|
|||||||
return runCatching {
|
return runCatching {
|
||||||
UserEntity(
|
UserEntity(
|
||||||
name = userDto.name ?: error("Null user name"),
|
name = userDto.name ?: error("Null user name"),
|
||||||
lastVisit = userDto.lastVisit ?: error("Null user lastVisit"),
|
lastVisit = userDto.lastVisit ?: "",
|
||||||
photoUrl = userDto.photoUrl ?: error("Null user photoUrl"),
|
photoUrl = userDto.photoUrl ?: error("Null user photoUrl"),
|
||||||
position = userDto.position ?: error("Null user position"),
|
position = userDto.position ?: error("Null user position"),
|
||||||
isAdmin = userDto.roleId?.let { it ->
|
isAdmin = userDto.roleId?.let { it ->
|
||||||
@ -62,7 +69,8 @@ class UserRepositoryImpl(
|
|||||||
it,
|
it,
|
||||||
credentialsLocalDataSource.getToken()
|
credentialsLocalDataSource.getToken()
|
||||||
).fold(onSuccess = { it }, onFailure = { error(it) })
|
).fold(onSuccess = { it }, onFailure = { error(it) })
|
||||||
} ?: error("Null user roleId")
|
} ?: error("Null user roleId"),
|
||||||
|
isCardBlocked = userDto.isCardBlocked ?: error("Null user isCardBlocked")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,16 @@ import kotlinx.serialization.Serializable
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class PassDto(
|
data class PassDto(
|
||||||
|
@SerialName("time")
|
||||||
|
val time: String?,
|
||||||
|
@SerialName("localDateTime")
|
||||||
|
val terminal: TerminalDto?
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class TerminalDto(
|
||||||
@SerialName("type")
|
@SerialName("type")
|
||||||
val type: String?,
|
val type: String?,
|
||||||
@SerialName("name")
|
@SerialName("name")
|
||||||
val name: String?,
|
val name: String?
|
||||||
@SerialName("time")
|
|
||||||
val time: String?
|
|
||||||
)
|
)
|
||||||
|
@ -5,7 +5,7 @@ import kotlinx.serialization.Serializable
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class UserDto(
|
data class UserDto(
|
||||||
@SerialName("roleId")
|
@SerialName("authority_id")
|
||||||
val roleId: Int?,
|
val roleId: Int?,
|
||||||
@SerialName("name")
|
@SerialName("name")
|
||||||
val name: String?,
|
val name: String?,
|
||||||
@ -15,7 +15,7 @@ data class UserDto(
|
|||||||
val photoUrl: String?,
|
val photoUrl: String?,
|
||||||
@SerialName("position")
|
@SerialName("position")
|
||||||
val position: String?,
|
val position: String?,
|
||||||
@SerialName("login")
|
@SerialName("username")
|
||||||
val login: String?,
|
val login: String?,
|
||||||
@SerialName("isCardBlocked")
|
@SerialName("isCardBlocked")
|
||||||
val isCardBlocked: Boolean?
|
val isCardBlocked: Boolean?
|
||||||
|
@ -15,7 +15,7 @@ object AdminNetworkDataSource {
|
|||||||
suspend fun blockUser(login: String, token: String): Result<Unit> =
|
suspend fun blockUser(login: String, token: String): Result<Unit> =
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
runCatching {
|
runCatching {
|
||||||
val response = client.patch("$SERVER_ADDRESS/api/employees/block&login=${login}") {
|
val response = client.patch("$SERVER_ADDRESS/api/employees/block?login=$login") {
|
||||||
headers {
|
headers {
|
||||||
append(HttpHeaders.Authorization, token)
|
append(HttpHeaders.Authorization, token)
|
||||||
}
|
}
|
||||||
@ -27,4 +27,18 @@ object AdminNetworkDataSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun unblockUser(login: String, token: String): Result<Unit> =
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
runCatching {
|
||||||
|
val response = client.patch("$SERVER_ADDRESS/api/employees/unblock?login=$login") {
|
||||||
|
headers {
|
||||||
|
append(HttpHeaders.Authorization, token)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.status != HttpStatusCode.OK)
|
||||||
|
error("Status ${response.status}")
|
||||||
|
Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ object PassNetworkDataSource {
|
|||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
runCatching {
|
runCatching {
|
||||||
val response =
|
val response =
|
||||||
client.get("$SERVER_ADDRESS/api/passes?pageNum=$pageNum&pageSize=$pageSize") {
|
client.get("$SERVER_ADDRESS/api/passes/paginated/?page=$pageNum&size=$pageSize") {
|
||||||
headers {
|
headers {
|
||||||
append(HttpHeaders.Authorization, token)
|
append(HttpHeaders.Authorization, token)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package ru.myitschool.work.data
|
package ru.myitschool.work.data.network
|
||||||
|
|
||||||
import io.ktor.client.request.headers
|
import io.ktor.client.request.headers
|
||||||
import io.ktor.client.request.patch
|
import io.ktor.client.request.patch
|
||||||
@ -11,28 +11,25 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ru.myitschool.work.core.Constants
|
import ru.myitschool.work.core.Constants
|
||||||
import ru.myitschool.work.data.dto.QrDto
|
import ru.myitschool.work.data.dto.QrDto
|
||||||
import ru.myitschool.work.data.network.KtorClient
|
|
||||||
import ru.myitschool.work.domain.entities.QrEntity
|
import ru.myitschool.work.domain.entities.QrEntity
|
||||||
|
|
||||||
object QrNetworkDataSource {
|
object QrNetworkDataSource {
|
||||||
|
|
||||||
suspend fun pushQr(qrEntity: QrEntity, token: String): Result<Unit> = withContext(Dispatchers.IO) {
|
suspend fun pushQr(qrEntity: QrEntity, token: String): Result<Unit> =
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
runCatching {
|
runCatching {
|
||||||
|
|
||||||
val response = KtorClient.client.patch("${Constants.SERVER_ADDRESS}/api/push_qr") {
|
|
||||||
headers {
|
|
||||||
append(HttpHeaders.Authorization, token)
|
|
||||||
}
|
|
||||||
contentType(ContentType.Application.Json)
|
|
||||||
setBody(
|
|
||||||
QrDto(code = qrEntity.code)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
val response =
|
||||||
|
KtorClient.client.patch("${Constants.SERVER_ADDRESS}/api/open") {
|
||||||
|
headers {
|
||||||
|
append(HttpHeaders.Authorization, token)
|
||||||
|
}
|
||||||
|
contentType(ContentType.Application.Json)
|
||||||
|
setBody(QrDto(qrEntity.code))
|
||||||
|
}
|
||||||
|
if (response.status != HttpStatusCode.OK)
|
||||||
|
error("Status ${response.status}")
|
||||||
|
Unit
|
||||||
}
|
}
|
||||||
if (response.status != HttpStatusCode.OK)
|
|
||||||
error("Status ${response.status}")
|
|
||||||
Unit
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
@ -14,7 +14,7 @@ object UserNetworkDataSource {
|
|||||||
|
|
||||||
suspend fun isUserExist(login: String): Result<Boolean> = withContext(Dispatchers.IO) {
|
suspend fun isUserExist(login: String): Result<Boolean> = withContext(Dispatchers.IO) {
|
||||||
runCatching {
|
runCatching {
|
||||||
val result = KtorClient.client.get("${Constants.SERVER_ADDRESS}/api/employees/$login")
|
val result = KtorClient.client.get("${Constants.SERVER_ADDRESS}/api/users/username/$login")
|
||||||
result.status == HttpStatusCode.OK
|
result.status == HttpStatusCode.OK
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -23,7 +23,7 @@ object UserNetworkDataSource {
|
|||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
runCatching {
|
runCatching {
|
||||||
val result =
|
val result =
|
||||||
KtorClient.client.get("${Constants.SERVER_ADDRESS}/api/employees/login") {
|
KtorClient.client.get("${Constants.SERVER_ADDRESS}/api/users/login") {
|
||||||
headers {
|
headers {
|
||||||
append(HttpHeaders.Authorization, token)
|
append(HttpHeaders.Authorization, token)
|
||||||
}
|
}
|
||||||
@ -38,7 +38,7 @@ object UserNetworkDataSource {
|
|||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
runCatching {
|
runCatching {
|
||||||
val response =
|
val response =
|
||||||
KtorClient.client.get("${Constants.SERVER_ADDRESS}/api/roles/info?$roleId") {
|
KtorClient.client.get("${Constants.SERVER_ADDRESS}/api/authority/$roleId") {
|
||||||
headers {
|
headers {
|
||||||
append(HttpHeaders.Authorization, token)
|
append(HttpHeaders.Authorization, token)
|
||||||
}
|
}
|
||||||
|
@ -2,4 +2,5 @@ package ru.myitschool.work.domain.admin
|
|||||||
|
|
||||||
interface AdminRepository {
|
interface AdminRepository {
|
||||||
suspend fun blockUser(login: String): Result<Unit>
|
suspend fun blockUser(login: String): Result<Unit>
|
||||||
|
suspend fun unblockUser(login: String): Result<Unit>
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package ru.myitschool.work.domain.admin
|
||||||
|
|
||||||
|
class UnblockUserUseCase(
|
||||||
|
private val repository: AdminRepository
|
||||||
|
) {
|
||||||
|
|
||||||
|
suspend operator fun invoke(login: String) = repository.unblockUser(login)
|
||||||
|
}
|
@ -6,5 +6,5 @@ data class UserEntity(
|
|||||||
val lastVisit: String,
|
val lastVisit: String,
|
||||||
val photoUrl: String,
|
val photoUrl: String,
|
||||||
val position: String,
|
val position: String,
|
||||||
|
val isCardBlocked: Boolean
|
||||||
)
|
)
|
||||||
|
@ -21,6 +21,7 @@ import ru.myitschool.work.data.network.AdminNetworkDataSource
|
|||||||
import ru.myitschool.work.data.network.PassNetworkDataSource
|
import ru.myitschool.work.data.network.PassNetworkDataSource
|
||||||
import ru.myitschool.work.data.network.UserNetworkDataSource
|
import ru.myitschool.work.data.network.UserNetworkDataSource
|
||||||
import ru.myitschool.work.domain.admin.BlockUserUseCase
|
import ru.myitschool.work.domain.admin.BlockUserUseCase
|
||||||
|
import ru.myitschool.work.domain.admin.UnblockUserUseCase
|
||||||
import ru.myitschool.work.domain.entities.PassEntity
|
import ru.myitschool.work.domain.entities.PassEntity
|
||||||
import ru.myitschool.work.domain.entities.UserEntity
|
import ru.myitschool.work.domain.entities.UserEntity
|
||||||
import ru.myitschool.work.domain.passes.GetUsersPassesUseCase
|
import ru.myitschool.work.domain.passes.GetUsersPassesUseCase
|
||||||
@ -30,6 +31,7 @@ import ru.myitschool.work.ui.admin.view.UsersPassesPagingSource
|
|||||||
class AdminViewModel(
|
class AdminViewModel(
|
||||||
private val getUserByLoginUseCase: GetUserByLoginUseCase,
|
private val getUserByLoginUseCase: GetUserByLoginUseCase,
|
||||||
private val getUsersPassesUseCase: GetUsersPassesUseCase,
|
private val getUsersPassesUseCase: GetUsersPassesUseCase,
|
||||||
|
private val unBlockUserUseCase: UnblockUserUseCase,
|
||||||
private val blockUserUseCase: BlockUserUseCase
|
private val blockUserUseCase: BlockUserUseCase
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
@ -88,6 +90,12 @@ class AdminViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun unblock() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
unBlockUserUseCase(currentLogin!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sealed interface State {
|
sealed interface State {
|
||||||
data class Show(val user: UserEntity) : State
|
data class Show(val user: UserEntity) : State
|
||||||
data object Waiting : State
|
data object Waiting : State
|
||||||
@ -100,6 +108,10 @@ class AdminViewModel(
|
|||||||
val Factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
|
val Factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
override fun <T : ViewModel> create(modelClass: Class<T>, extras: CreationExtras): T {
|
override fun <T : ViewModel> create(modelClass: Class<T>, extras: CreationExtras): T {
|
||||||
|
val adminRepository = AdminRepositoryImpl(
|
||||||
|
networkDataSource = AdminNetworkDataSource,
|
||||||
|
localCredentialsLocalDataSource = CredentialsLocalDataSource.getInstance()
|
||||||
|
)
|
||||||
return AdminViewModel(
|
return AdminViewModel(
|
||||||
getUserByLoginUseCase = GetUserByLoginUseCase(
|
getUserByLoginUseCase = GetUserByLoginUseCase(
|
||||||
repository = UserRepositoryImpl(
|
repository = UserRepositoryImpl(
|
||||||
@ -115,10 +127,10 @@ class AdminViewModel(
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
blockUserUseCase = BlockUserUseCase(
|
blockUserUseCase = BlockUserUseCase(
|
||||||
repository = AdminRepositoryImpl(
|
repository = adminRepository
|
||||||
networkDataSource = AdminNetworkDataSource,
|
),
|
||||||
localCredentialsLocalDataSource = CredentialsLocalDataSource.getInstance()
|
unBlockUserUseCase = UnblockUserUseCase(
|
||||||
)
|
repository = adminRepository
|
||||||
)
|
)
|
||||||
) as T
|
) as T
|
||||||
}
|
}
|
||||||
|
@ -26,20 +26,20 @@ class ViewUserAsAdminFragment : Fragment(R.layout.fragment_user) {
|
|||||||
|
|
||||||
binding.findUser.visibleOrGone(false)
|
binding.findUser.visibleOrGone(false)
|
||||||
binding.logout.visibleOrGone(false)
|
binding.logout.visibleOrGone(false)
|
||||||
binding.block.visibleOrGone(true)
|
|
||||||
|
|
||||||
val adapter = PassesListAdapter()
|
val adapter = PassesListAdapter()
|
||||||
binding.passes.adapter = adapter
|
binding.passes.adapter = adapter
|
||||||
|
|
||||||
viewModel.state.collectWithLifecycle(this) { state ->
|
viewModel.state.collectWithLifecycle(this) { state ->
|
||||||
binding.refresh.isRefreshing = state is AdminViewModel.State.Loading
|
binding.refresh.isRefreshing = state is AdminViewModel.State.Loading
|
||||||
binding.content?.visibleOrGone(state is AdminViewModel.State.Show)
|
binding.content.visibleOrGone(state is AdminViewModel.State.Show)
|
||||||
|
|
||||||
when (state) {
|
when (state) {
|
||||||
is AdminViewModel.State.Loading -> Unit
|
is AdminViewModel.State.Loading -> Unit
|
||||||
is AdminViewModel.State.Show -> {
|
is AdminViewModel.State.Show -> {
|
||||||
val user = state.user
|
val user = state.user
|
||||||
binding.findUser.visibleOrGone(user.isAdmin)
|
binding.block.visibleOrGone(!user.isCardBlocked)
|
||||||
|
binding.unblock.visibleOrGone(user.isCardBlocked)
|
||||||
binding.fullname.text = user.name
|
binding.fullname.text = user.name
|
||||||
binding.position.text = user.position
|
binding.position.text = user.position
|
||||||
binding.lastEntry.text = user.lastVisit
|
binding.lastEntry.text = user.lastVisit
|
||||||
@ -79,6 +79,10 @@ class ViewUserAsAdminFragment : Fragment(R.layout.fragment_user) {
|
|||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.unblock.setOnClickListener {
|
||||||
|
viewModel.unblock()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
@ -9,14 +9,10 @@ import androidx.navigation.fragment.findNavController
|
|||||||
import ru.myitschool.work.R
|
import ru.myitschool.work.R
|
||||||
import ru.myitschool.work.core.Constants
|
import ru.myitschool.work.core.Constants
|
||||||
import ru.myitschool.work.data.local.CredentialsLocalDataSource
|
import ru.myitschool.work.data.local.CredentialsLocalDataSource
|
||||||
import ru.myitschool.work.databinding.FragmentSplashBinding
|
|
||||||
import ru.myitschool.work.utils.collectWithLifecycle
|
import ru.myitschool.work.utils.collectWithLifecycle
|
||||||
|
|
||||||
class SplashFragment : Fragment(R.layout.fragment_splash) {
|
class SplashFragment : Fragment(R.layout.fragment_splash) {
|
||||||
|
|
||||||
private var _binding: FragmentSplashBinding? = null
|
|
||||||
private val binding: FragmentSplashBinding get() = _binding!!
|
|
||||||
|
|
||||||
private val viewModel by viewModels<LoginViewModel> { LoginViewModel.Factory }
|
private val viewModel by viewModels<LoginViewModel> { LoginViewModel.Factory }
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
@ -30,21 +26,15 @@ class SplashFragment : Fragment(R.layout.fragment_splash) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
_binding = FragmentSplashBinding.bind(view)
|
|
||||||
|
|
||||||
viewModel.action.collectWithLifecycle(this) { action ->
|
viewModel.action.collectWithLifecycle(this) { action ->
|
||||||
val navController = findNavController()
|
val navController = findNavController()
|
||||||
when (action) {
|
when (action) {
|
||||||
is LoginViewModel.Action.GoToLogin -> navController.navigate(R.id.loginFragment)
|
is LoginViewModel.Action.GoToLogin -> navController.navigate(R.id.loginFragment)
|
||||||
is LoginViewModel.Action.OpenApp ->
|
is LoginViewModel.Action.OpenApp ->
|
||||||
navController.navigate(R.id.action_loginFragment_to_userFragment)
|
navController.navigate(R.id.action_splashFragment_to_userFragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
_binding = null
|
|
||||||
super.onDestroy()
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -15,7 +15,7 @@ class PassesPagingSource(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, PassEntity> {
|
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, PassEntity> {
|
||||||
val pageNum = params.key ?: 0
|
val pageNum = params.key ?: 1
|
||||||
return request.invoke(pageNum, params.loadSize).fold(
|
return request.invoke(pageNum, params.loadSize).fold(
|
||||||
onSuccess = { value ->
|
onSuccess = { value ->
|
||||||
LoadResult.Page(
|
LoadResult.Page(
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package ru.myitschool.work.ui.profile
|
package ru.myitschool.work.ui.profile
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
@ -10,9 +11,12 @@ import androidx.paging.LoadState
|
|||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
import ru.myitschool.work.R
|
import ru.myitschool.work.R
|
||||||
import ru.myitschool.work.databinding.FragmentUserBinding
|
import ru.myitschool.work.databinding.FragmentUserBinding
|
||||||
|
import ru.myitschool.work.ui.qr.result.RESPONSE_KEY
|
||||||
|
import ru.myitschool.work.ui.qr.scan.QrScanDestination
|
||||||
import ru.myitschool.work.utils.collectWithLifecycle
|
import ru.myitschool.work.utils.collectWithLifecycle
|
||||||
import ru.myitschool.work.utils.visibleOrGone
|
import ru.myitschool.work.utils.visibleOrGone
|
||||||
|
|
||||||
|
|
||||||
class UserFragment : Fragment(R.layout.fragment_user) {
|
class UserFragment : Fragment(R.layout.fragment_user) {
|
||||||
|
|
||||||
private var _binding: FragmentUserBinding? = null
|
private var _binding: FragmentUserBinding? = null
|
||||||
@ -28,11 +32,13 @@ class UserFragment : Fragment(R.layout.fragment_user) {
|
|||||||
|
|
||||||
viewModel.state.collectWithLifecycle(this) { state ->
|
viewModel.state.collectWithLifecycle(this) { state ->
|
||||||
binding.refresh.isRefreshing = state is UserViewModel.State.Loading
|
binding.refresh.isRefreshing = state is UserViewModel.State.Loading
|
||||||
binding.content?.visibleOrGone(state is UserViewModel.State.Show)
|
binding.content.visibleOrGone(state is UserViewModel.State.Show)
|
||||||
|
Log.d("info", state.toString())
|
||||||
when (state) {
|
when (state) {
|
||||||
is UserViewModel.State.Loading -> Unit
|
is UserViewModel.State.Loading -> Unit
|
||||||
is UserViewModel.State.Show -> {
|
is UserViewModel.State.Show -> {
|
||||||
val user = state.userEntity
|
val user = state.userEntity
|
||||||
|
binding.scan.visibleOrGone(!user.isCardBlocked)
|
||||||
binding.findUser.visibleOrGone(user.isAdmin)
|
binding.findUser.visibleOrGone(user.isAdmin)
|
||||||
binding.fullname.text = user.name
|
binding.fullname.text = user.name
|
||||||
binding.position.text = user.position
|
binding.position.text = user.position
|
||||||
@ -65,14 +71,27 @@ class UserFragment : Fragment(R.layout.fragment_user) {
|
|||||||
.setTitle("Выход")
|
.setTitle("Выход")
|
||||||
.setMessage("Вы уверены, что хотите выйти из аккаунта?")
|
.setMessage("Вы уверены, что хотите выйти из аккаунта?")
|
||||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
.setIcon(android.R.drawable.ic_dialog_alert)
|
||||||
.setPositiveButton(android.R.string.ok) { _, _ -> viewModel.onLogout() }
|
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||||
|
viewModel.onLogout()
|
||||||
|
findNavController().navigate(R.id.action_userFragment_to_loginFragment)
|
||||||
|
}
|
||||||
.show()
|
.show()
|
||||||
findNavController().navigate(R.id.action_userFragment_to_loginFragment)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.findUser.setOnClickListener {
|
binding.findUser.setOnClickListener {
|
||||||
findNavController().navigate(R.id.find_user)
|
findNavController().navigate(R.id.find_user)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.scan.setOnClickListener {
|
||||||
|
findNavController().navigate(R.id.action_userFragment_to_qrScanFragment)
|
||||||
|
}
|
||||||
|
|
||||||
|
parentFragmentManager.setFragmentResultListener(
|
||||||
|
QrScanDestination.REQUEST_KEY, this
|
||||||
|
) { _, result ->
|
||||||
|
parentFragmentManager.setFragmentResult(RESPONSE_KEY, result)
|
||||||
|
findNavController().navigate(R.id.action_userFragment_to_qrResultFragment)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,8 @@ class UserViewModel(
|
|||||||
|
|
||||||
private fun updateState() {
|
private fun updateState() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
State.Show(getCurrentUserUseCase())
|
_state.emit(State.Loading)
|
||||||
|
_state.emit(State.Show(getCurrentUserUseCase()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import androidx.fragment.app.viewModels
|
|||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import ru.myitschool.work.R
|
import ru.myitschool.work.R
|
||||||
import ru.myitschool.work.databinding.FragmentQrResultBinding
|
import ru.myitschool.work.databinding.FragmentQrResultBinding
|
||||||
import ru.myitschool.work.ui.qr.scan.QrScanDestination
|
import ru.myitschool.work.domain.entities.QrEntity
|
||||||
import ru.myitschool.work.ui.qr.scan.QrScanDestination.getDataIfExist
|
import ru.myitschool.work.ui.qr.scan.QrScanDestination.getDataIfExist
|
||||||
import ru.myitschool.work.utils.collectWithLifecycle
|
import ru.myitschool.work.utils.collectWithLifecycle
|
||||||
|
|
||||||
@ -20,25 +20,18 @@ class QrResultFragment : Fragment(R.layout.fragment_qr_result) {
|
|||||||
private var _binding: FragmentQrResultBinding? = null
|
private var _binding: FragmentQrResultBinding? = null
|
||||||
private val binding: FragmentQrResultBinding get() = _binding!!
|
private val binding: FragmentQrResultBinding get() = _binding!!
|
||||||
|
|
||||||
private var _resultQr: String? = null
|
|
||||||
private val resultQr: String = _resultQr!!
|
|
||||||
|
|
||||||
private val viewModel by viewModels<QrResultViewModel> { QrResultViewModel.Factory }
|
private val viewModel by viewModels<QrResultViewModel> { QrResultViewModel.Factory }
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
_binding = FragmentQrResultBinding.bind(view)
|
_binding = FragmentQrResultBinding.bind(view)
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
|
||||||
_resultQr = savedInstanceState.getString(QrScanDestination.REQUEST_KEY)
|
|
||||||
}
|
|
||||||
|
|
||||||
parentFragmentManager.setFragmentResultListener(RESPONSE_KEY, this) { _, result ->
|
parentFragmentManager.setFragmentResultListener(RESPONSE_KEY, this) { _, result ->
|
||||||
_resultQr = getDataIfExist(result)
|
getDataIfExist(result)?.let { viewModel.setQr(QrEntity(it)) }
|
||||||
viewModel.update(resultQr)
|
viewModel.update()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.state.collectWithLifecycle(this) { state ->
|
viewModel.state.collectWithLifecycle(this) { state ->
|
||||||
if (_resultQr == null) {
|
if (viewModel._qrEntity == null) {
|
||||||
binding.result.setText(R.string.door_closed)
|
binding.result.setText(R.string.door_closed)
|
||||||
binding.close.background =
|
binding.close.background =
|
||||||
ContextCompat.getDrawable(requireContext(), R.drawable.warn_button)
|
ContextCompat.getDrawable(requireContext(), R.drawable.warn_button)
|
||||||
@ -65,12 +58,6 @@ class QrResultFragment : Fragment(R.layout.fragment_qr_result) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
|
||||||
super.onSaveInstanceState(outState)
|
|
||||||
outState.putString(QrScanDestination.REQUEST_KEY, resultQr)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
_binding = null
|
_binding = null
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
|
@ -7,7 +7,7 @@ import androidx.lifecycle.viewmodel.CreationExtras
|
|||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import ru.myitschool.work.data.QrNetworkDataSource
|
import ru.myitschool.work.data.network.QrNetworkDataSource
|
||||||
import ru.myitschool.work.data.QrRepositoryImpl
|
import ru.myitschool.work.data.QrRepositoryImpl
|
||||||
import ru.myitschool.work.data.local.CredentialsLocalDataSource
|
import ru.myitschool.work.data.local.CredentialsLocalDataSource
|
||||||
import ru.myitschool.work.domain.entities.QrEntity
|
import ru.myitschool.work.domain.entities.QrEntity
|
||||||
@ -20,9 +20,16 @@ class QrResultViewModel(
|
|||||||
private val _state = MutableStateFlow<State>(State.Loading)
|
private val _state = MutableStateFlow<State>(State.Loading)
|
||||||
val state = _state.asStateFlow()
|
val state = _state.asStateFlow()
|
||||||
|
|
||||||
fun update(qrValue: String) {
|
var _qrEntity: QrEntity? = null
|
||||||
|
private val qrEntity: QrEntity get() = _qrEntity!!
|
||||||
|
|
||||||
|
fun setQr(qrEntity: QrEntity) {
|
||||||
|
_qrEntity = qrEntity
|
||||||
|
}
|
||||||
|
|
||||||
|
fun update() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
pushQrUseCase(QrEntity(code = qrValue)).fold(
|
pushQrUseCase(qrEntity).fold(
|
||||||
onSuccess = { _state.emit(State.Show) },
|
onSuccess = { _state.emit(State.Show) },
|
||||||
onFailure = { _state.emit(State.Error(it.message.toString())) }
|
onFailure = { _state.emit(State.Error(it.message.toString())) }
|
||||||
)
|
)
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/content"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginHorizontal="20dp"
|
android:layout_marginHorizontal="20dp"
|
||||||
@ -132,7 +133,21 @@
|
|||||||
android:background="@drawable/warn_button_outline"
|
android:background="@drawable/warn_button_outline"
|
||||||
android:foreground="?attr/selectableItemBackground"
|
android:foreground="?attr/selectableItemBackground"
|
||||||
android:text="@string/block_card_button_text"
|
android:text="@string/block_card_button_text"
|
||||||
android:textColor="@color/warn_button_color" />
|
android:textColor="@color/warn_button_color"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/unblock"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/main_button_outline"
|
||||||
|
android:foreground="?attr/selectableItemBackground"
|
||||||
|
android:text="@string/unblock_card_button_text"
|
||||||
|
android:textColor="@color/main_button_color"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/logout"
|
android:id="@+id/logout"
|
||||||
|
@ -1,9 +1,21 @@
|
|||||||
<?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:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
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">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/error"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:textColor="@color/warn_button_color"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="Some error" />
|
||||||
|
|
||||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
android:id="@+id/refresh"
|
android:id="@+id/refresh"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -95,15 +107,6 @@
|
|||||||
android:foreground="?attr/selectableItemBackground"
|
android:foreground="?attr/selectableItemBackground"
|
||||||
android:text="@string/scan_qr_text"
|
android:text="@string/scan_qr_text"
|
||||||
android:textColor="@color/white" />
|
android:textColor="@color/white" />
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/error"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:textColor="@color/warn_button_color"
|
|
||||||
android:visibility="gone"
|
|
||||||
tools:text="Some error" />
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@ -123,8 +126,20 @@
|
|||||||
android:text="@string/block_card_button_text"
|
android:text="@string/block_card_button_text"
|
||||||
android:textColor="@color/warn_button_color"
|
android:textColor="@color/warn_button_color"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
|
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/unblock"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/main_button_outline"
|
||||||
|
android:foreground="?attr/selectableItemBackground"
|
||||||
|
android:text="@string/unblock_card_button_text"
|
||||||
|
android:textColor="@color/main_button_color"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/logout"
|
android:id="@+id/logout"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -65,6 +65,11 @@
|
|||||||
<action
|
<action
|
||||||
android:id="@+id/action_splashFragment_to_loginFragment"
|
android:id="@+id/action_splashFragment_to_loginFragment"
|
||||||
app:destination="@id/loginFragment" />
|
app:destination="@id/loginFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_splashFragment_to_userFragment"
|
||||||
|
app:destination="@id/userFragment"
|
||||||
|
app:popUpTo="@id/nav_graph"
|
||||||
|
app:popUpToInclusive="true" />
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/adminFragment"
|
android:id="@+id/adminFragment"
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">NTO Pass</string>
|
<string name="app_name">QR Pass</string>
|
||||||
<string name="scan_qr_text">Scan QR</string>
|
<string name="scan_qr_text">Scan QR</string>
|
||||||
<string name="login_hint">Enter login</string>
|
<string name="login_hint">Enter login</string>
|
||||||
<string name="welcome_text">Welcome to NTO Pass app</string>
|
<string name="welcome_text">Welcome to\nQR Pass app</string>
|
||||||
<string name="login">Login</string>
|
<string name="login">Login</string>
|
||||||
<string name="refresh_data">Refresh</string>
|
<string name="refresh_data">Refresh</string>
|
||||||
<string name="to_main_menu">Close</string>
|
<string name="to_main_menu">Close</string>
|
||||||
@ -21,4 +21,5 @@
|
|||||||
<string name="offline_error">Seems you are offline...</string>
|
<string name="offline_error">Seems you are offline...</string>
|
||||||
<string name="no_internet_instructions">Check your internet connection\\nand try again</string>
|
<string name="no_internet_instructions">Check your internet connection\\nand try again</string>
|
||||||
<string name="reload_text">" Reload"</string>
|
<string name="reload_text">" Reload"</string>
|
||||||
|
<string name="unblock_card_button_text">Unblock card</string>
|
||||||
</resources>
|
</resources>
|
@ -1,8 +1,8 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">NTO Pass</string>
|
<string name="app_name">QR Pass</string>
|
||||||
<string name="scan_qr_text">Сканировать QR-код</string>
|
<string name="scan_qr_text">Сканировать QR-код</string>
|
||||||
<string name="login_hint">Введите логин</string>
|
<string name="login_hint">Введите логин</string>
|
||||||
<string name="welcome_text">Добро пожаловать в NTO Pass</string>
|
<string name="welcome_text">Добро пожаловать в\nQR Pass</string>
|
||||||
<string name="login">Войти</string>
|
<string name="login">Войти</string>
|
||||||
<string name="refresh_data">Обновить данные</string>
|
<string name="refresh_data">Обновить данные</string>
|
||||||
<string name="to_main_menu">Закрыть</string>
|
<string name="to_main_menu">Закрыть</string>
|
||||||
@ -19,4 +19,5 @@
|
|||||||
<string name="offline_error">Кажется вы оффлайн...</string>
|
<string name="offline_error">Кажется вы оффлайн...</string>
|
||||||
<string name="no_internet_instructions">Проверьте подключение к сети\nи попробуйте еще раз</string>
|
<string name="no_internet_instructions">Проверьте подключение к сети\nи попробуйте еще раз</string>
|
||||||
<string name="reload_text">Перезагрузить</string>
|
<string name="reload_text">Перезагрузить</string>
|
||||||
|
<string name="unblock_card_button_text">Разблокировать карту</string>
|
||||||
</resources>
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user