Added start logic for visits pagination, changed visits logic, changed Dto objects, added password in login, bug fixes,
This commit is contained in:
parent
12c6b6e1c2
commit
961c37d265
@ -39,7 +39,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation("androidx.paging:paging-runtime:3.3.2")
|
||||
val cameraX = "1.3.4"
|
||||
implementation("androidx.camera:camera-core:$cameraX")
|
||||
implementation("androidx.camera:camera-camera2:$cameraX")
|
||||
|
@ -6,5 +6,5 @@ data class UserEntity(
|
||||
val name: String,
|
||||
val photo: String,
|
||||
val position: String,
|
||||
val lastVisit: String,
|
||||
// val lastVisit: String,
|
||||
)
|
@ -10,7 +10,7 @@ class UserMapper {
|
||||
login = userDTO.login,
|
||||
position = userDTO.position,
|
||||
name = userDTO.name,
|
||||
lastVisit = userDTO.lastVisit,
|
||||
// lastVisit = userDTO.lastVisit,
|
||||
photo = userDTO.photo
|
||||
)
|
||||
return userEntity
|
||||
@ -22,7 +22,7 @@ class UserMapper {
|
||||
name = userEntity.name,
|
||||
photo = userEntity.photo,
|
||||
position = userEntity.position,
|
||||
lastVisit = userEntity.lastVisit,
|
||||
// lastVisit = userEntity.lastVisit,
|
||||
)
|
||||
return userDto
|
||||
}
|
||||
|
@ -3,7 +3,9 @@ package com.displaynone.acss.components.auth.models.user
|
||||
import android.content.Context
|
||||
import com.displaynone.acss.components.auth.internal_utils.AuthTokenManager
|
||||
import com.displaynone.acss.components.auth.models.user.repository.UserRepository
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.LastVisitsDto
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.UserDTO
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.VisitDto
|
||||
|
||||
|
||||
class UserServiceST(
|
||||
@ -28,13 +30,34 @@ class UserServiceST(
|
||||
return instance ?: throw RuntimeException("null instance")
|
||||
}
|
||||
}
|
||||
suspend fun login(login: String): Result<Unit>{
|
||||
suspend fun login(login: String, password:String): Result<Unit>{
|
||||
return runCatching {
|
||||
userRepository.login(login = login).getOrThrow().let { data ->
|
||||
userRepository.login(login = login, password).getOrThrow().let { data ->
|
||||
tokenManager.saveTokens(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
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(){
|
||||
tokenManager.clear()
|
||||
}
|
||||
|
@ -2,10 +2,12 @@ package com.displaynone.acss.components.auth.models.user.repository
|
||||
|
||||
import android.util.Log
|
||||
import com.displaynone.acss.components.auth.models.AuthTokenPair
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.LastVisitsDto
|
||||
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.UserDTO
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.UserLoginDto
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.request.headers
|
||||
@ -33,13 +35,14 @@ class UserRepository(
|
||||
result.status != HttpStatusCode.OK
|
||||
}
|
||||
}
|
||||
suspend fun login(login: String): Result<AuthTokenPair> = withContext(Dispatchers.IO) {
|
||||
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())
|
||||
}
|
||||
setBody("""{ "login": "$login" }""")
|
||||
contentType(ContentType.Application.Json)
|
||||
setBody(UserLoginDto(login, password))
|
||||
}
|
||||
if (result.status != HttpStatusCode.OK) {
|
||||
error("Status ${result.status}: ${result.body<String>()}")
|
||||
@ -99,6 +102,57 @@ class UserRepository(
|
||||
result.body()
|
||||
}
|
||||
}
|
||||
suspend fun getMyLastVisits(pageNum: Int,
|
||||
pageSize: Int,
|
||||
token: String): Result<LastVisitsDto> = withContext(Dispatchers.IO){
|
||||
runCatching {
|
||||
val result = Network.client.get("$serverUrl/api/acs/visits/me?page=$pageNum&size=$pageSize") {
|
||||
headers {
|
||||
append(HttpHeaders.Authorization, "Bearer $token")
|
||||
}
|
||||
}
|
||||
Log.d("UserRepository", result.bodyAsText())
|
||||
if (result.status != HttpStatusCode.OK) {
|
||||
error("Status ${result.status}: ${result.body<String>()}")
|
||||
}
|
||||
|
||||
result.body()
|
||||
}
|
||||
}
|
||||
suspend fun getLastVisitsByLogin(pageNum: Int,
|
||||
pageSize: Int,
|
||||
token: String, login: String): Result<LastVisitsDto> = withContext(Dispatchers.IO){
|
||||
runCatching {
|
||||
val encodedLogin = login.encodeURLPath()
|
||||
val result = Network.client.get("$serverUrl/api/acs/login/${encodedLogin}?page=$pageNum&size=$pageSize") {
|
||||
headers {
|
||||
append(HttpHeaders.Authorization, "Bearer $token")
|
||||
}
|
||||
setBody("""{ "login": "$encodedLogin" }""")
|
||||
}
|
||||
if (result.status != HttpStatusCode.OK) {
|
||||
error("Status ${result.status}: ${result.body<String>()}")
|
||||
}
|
||||
Log.d("UserRepository", result.bodyAsText())
|
||||
result.body()
|
||||
}
|
||||
}
|
||||
suspend fun getAllLastVisitsAsAdmin(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" }""")
|
||||
}
|
||||
if (result.status != HttpStatusCode.OK) {
|
||||
error("Status ${result.status}: ${result.body<String>()}")
|
||||
}
|
||||
Log.d("UserRepository", result.bodyAsText())
|
||||
result.body()
|
||||
}
|
||||
}
|
||||
suspend fun openDoor(token: String, code: Long): Result<Unit> = withContext(Dispatchers.IO) {
|
||||
runCatching {
|
||||
val result = Network.client.patch("$serverUrl/api/open") {
|
||||
|
@ -0,0 +1,55 @@
|
||||
package com.displaynone.acss.components.auth.models.user.repository
|
||||
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.paging.PagingDataAdapter
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.VisitDto
|
||||
import com.displaynone.acss.databinding.ItemScannerViewBinding
|
||||
|
||||
class VisitAdapter: PagingDataAdapter<VisitDto, VisitAdapter.ViewHolder>(VisitDiff) {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
return ViewHolder(
|
||||
ItemScannerViewBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
holder.bind(getItem(position) ?:
|
||||
VisitDto(
|
||||
id = -1,
|
||||
userId = -1,
|
||||
gateId = -1,
|
||||
createdAt = "Loading...",
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
class ViewHolder(
|
||||
private val binding: ItemScannerViewBinding
|
||||
): RecyclerView.ViewHolder(binding.root) {
|
||||
fun bind(item: VisitDto){
|
||||
binding.scanTime.text = item.createdAt
|
||||
binding.scannerId.text = item.gateId.toString()
|
||||
}
|
||||
}
|
||||
|
||||
object VisitDiff : DiffUtil.ItemCallback<VisitDto>() {
|
||||
override fun areItemsTheSame(oldItem: VisitDto, newItem: VisitDto): Boolean {
|
||||
return oldItem.id == newItem.id
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: VisitDto, newItem: VisitDto): Boolean {
|
||||
return oldItem == newItem
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.displaynone.acss.components.auth.models.user.repository
|
||||
|
||||
import androidx.paging.PagingSource
|
||||
import androidx.paging.PagingState
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.VisitDto
|
||||
|
||||
class VisitListPagingSource(
|
||||
private val request: suspend (pageNum: Int, pageSize: Int) -> Result<List<VisitDto>>
|
||||
) : PagingSource<Int, VisitDto>() {
|
||||
override fun getRefreshKey(state: PagingState<Int, VisitDto>): Int? {
|
||||
return state.anchorPosition?.let {
|
||||
state.closestPageToPosition(it)?.prevKey?.plus(1)
|
||||
?: state.closestPageToPosition(it)?.nextKey?.minus(1)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, VisitDto> {
|
||||
val pageNum = params.key ?: 0
|
||||
return request.invoke(
|
||||
pageNum,
|
||||
params.loadSize
|
||||
).fold(
|
||||
onSuccess = { value ->
|
||||
LoadResult.Page(
|
||||
data = value,
|
||||
prevKey = (pageNum - 1).takeIf { it >= 0 },
|
||||
nextKey = (pageNum + 1).takeIf { value.size == params.loadSize }
|
||||
)
|
||||
},
|
||||
onFailure = { error ->
|
||||
LoadResult.Error(error)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.displaynone.acss.components.auth.models.user.repository.dto
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
|
||||
@Serializable
|
||||
data class LastVisitsDto(
|
||||
@SerialName("content")
|
||||
val content: List<VisitDto>
|
||||
) {
|
||||
}
|
@ -21,6 +21,6 @@ data class UserDTO (
|
||||
@SerialName("position")
|
||||
val position: String,
|
||||
|
||||
@SerialName("lastVisit")
|
||||
val lastVisit: String,
|
||||
// @SerialName("lastVisit")
|
||||
// val lastVisit: String,
|
||||
) : java.io.Serializable
|
@ -0,0 +1,13 @@
|
||||
package com.displaynone.acss.components.auth.models.user.repository.dto
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class UserLoginDto(
|
||||
@SerialName("login")
|
||||
val login: String,
|
||||
@SerialName("password")
|
||||
val password: String,
|
||||
) {
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.displaynone.acss.components.auth.models.user.repository.dto
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class VisitDto(
|
||||
@SerialName("id")
|
||||
val id: Long,
|
||||
@SerialName("userId")
|
||||
val userId: Long,
|
||||
@SerialName("gateId")
|
||||
val gateId: Long,
|
||||
@SerialName("createdAt")
|
||||
val createdAt: String,
|
||||
) {
|
||||
}
|
@ -40,9 +40,14 @@ class AdminFragment : Fragment(R.layout.fragment_admin) {
|
||||
val userDto = state.item
|
||||
val bundle = Bundle().apply{
|
||||
putSerializable("user", userDto)
|
||||
putBoolean("isMe", false)
|
||||
}
|
||||
navigateTo(view, R.id.action_adminFragment_to_profileFragment, bundle)
|
||||
}
|
||||
if (state is AdminViewModel.State.Error){
|
||||
val errorMessage = state.errorMessage
|
||||
binding.loginSearch.setError(errorMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -5,7 +5,6 @@ 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.UserDTO
|
||||
import com.displaynone.acss.ui.profile.ProfileViewModel.State
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
@ -20,7 +19,8 @@ class AdminViewModel: ViewModel() {
|
||||
_state.emit(State.Show(item = dto))
|
||||
},
|
||||
onFailure = { error ->
|
||||
error.message?.let { error(it) }
|
||||
// error.message?.let { error(it) }
|
||||
_state.emit(State.Error(error.message.toString()))
|
||||
Log.e("AdminViewModel", error.message.toString()) }
|
||||
)
|
||||
}
|
||||
@ -30,6 +30,9 @@ class AdminViewModel: ViewModel() {
|
||||
data class Show(
|
||||
val item: UserDTO
|
||||
): State
|
||||
data class Error(
|
||||
val errorMessage: String
|
||||
): State
|
||||
data object Loading : State
|
||||
}
|
||||
}
|
@ -59,6 +59,7 @@ class AuthFragment: Fragment(R.layout.fragment_auth) {
|
||||
val username = s.toString()
|
||||
val valid = isUsernameValid(username)
|
||||
|
||||
|
||||
binding.hint.visibility = if(valid) View.INVISIBLE else View.VISIBLE
|
||||
binding.next.isEnabled = valid
|
||||
val color = if (valid) R.color.primary else R.color.secondary
|
||||
@ -67,6 +68,35 @@ class AuthFragment: Fragment(R.layout.fragment_auth) {
|
||||
|
||||
override fun afterTextChanged(s: Editable?) {}
|
||||
})
|
||||
// binding.password.addTextChangedListener(object : TextWatcher {
|
||||
// override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
|
||||
// @SuppressLint("ResourceAsColor")
|
||||
// override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
// binding.error.visibility = View.GONE
|
||||
// val username = s.toString()
|
||||
// val valid = isPasswordValid(username)
|
||||
//
|
||||
// binding.hint.visibility = if(valid) View.INVISIBLE else View.VISIBLE
|
||||
// if (!valid){
|
||||
// val errorMessage = getPasswordValidError(s.toString())
|
||||
// binding.password.setError(errorMessage)
|
||||
// }
|
||||
// binding.next.isEnabled = valid
|
||||
// val color = if (valid) R.color.primary else R.color.secondary
|
||||
// binding.next.backgroundTintList = ContextCompat.getColorStateList(requireContext(), color)
|
||||
// }
|
||||
//
|
||||
// override fun afterTextChanged(s: Editable?) {}
|
||||
// })
|
||||
}
|
||||
private fun getPasswordValidError(password: String): String {
|
||||
if (password.length < 8){ return "LenError" }
|
||||
val letterRegex = Regex("^(?=.*[A-Z]).+$")
|
||||
if(!letterRegex.matches(password)){ return "UpperCaseError"}
|
||||
val digitRegex = Regex("^(?=.*\\\\d).+$")
|
||||
if(!digitRegex.matches(password)){ return "DigitCaseError"}
|
||||
|
||||
return "NoErrors"
|
||||
}
|
||||
|
||||
private fun isUsernameValid(username: String): Boolean {
|
||||
@ -76,6 +106,10 @@ class AuthFragment: Fragment(R.layout.fragment_auth) {
|
||||
!username[0].isDigit() &&
|
||||
alf.matches(username)
|
||||
}
|
||||
private fun isPasswordValid(password: String): Boolean {
|
||||
return password.isNotEmpty() &&
|
||||
password.length >= 8
|
||||
}
|
||||
// private fun subscribe() {
|
||||
// viewModel.state.collectWhenStarted(this) { state ->
|
||||
// binding.login.setOnClickListener(this::onLoginButtonClicked)
|
||||
@ -84,8 +118,9 @@ class AuthFragment: Fragment(R.layout.fragment_auth) {
|
||||
|
||||
private fun onLoginButtonClicked(view: View) {
|
||||
val login = binding.login.text.toString()
|
||||
val password = binding.password.text.toString()
|
||||
if (login.isEmpty()) return
|
||||
viewModel.login(login)
|
||||
viewModel.login(login, password)
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,10 +22,10 @@ class AuthViewModel(): ViewModel() {
|
||||
private val _errorState = MutableStateFlow<String?>(null)
|
||||
val errorState: StateFlow<String?> = _errorState.asStateFlow()
|
||||
|
||||
fun login(login: String){
|
||||
fun login(login: String, password:String){
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
UserServiceST.getInstance().login(login).fold(
|
||||
UserServiceST.getInstance().login(login, password).fold(
|
||||
onSuccess = { openProfile() },
|
||||
onFailure = { error ->
|
||||
Log.e("AuthViewModel", "Login failed: ${error.message ?: "Unknown error"}")
|
||||
|
@ -10,6 +10,7 @@ import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.bumptech.glide.Glide
|
||||
import com.displaynone.acss.R
|
||||
import com.displaynone.acss.components.auth.models.user.repository.VisitAdapter
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.UserDTO
|
||||
import com.displaynone.acss.databinding.FragmentProfileBinding
|
||||
import com.displaynone.acss.ui.profile.ProfileViewModel.Action
|
||||
@ -27,31 +28,58 @@ class ProfileFragment: Fragment(R.layout.fragment_profile) {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentProfileBinding.bind(view)
|
||||
|
||||
binding.swipeRefresh.setOnRefreshListener {
|
||||
refreshData()
|
||||
}
|
||||
//
|
||||
// binding.swipeRefresh.setOnRefreshListener {
|
||||
// if (getIsMe()){
|
||||
// refreshData()
|
||||
// } else{
|
||||
// showData(getUserDto()!!)
|
||||
// }
|
||||
// }
|
||||
binding.logout.setOnClickListener{
|
||||
logout()
|
||||
}
|
||||
binding.scan.setOnClickListener{
|
||||
viewModel.openScan()
|
||||
}
|
||||
val user = getUserDto()
|
||||
if (user == null) {
|
||||
val adapter = VisitAdapter()
|
||||
binding.recyclerViewLogs.adapter = adapter
|
||||
if (getIsMe()) {
|
||||
refreshData()
|
||||
// viewModel.visitListState.collectWithLifecycle(this) { data ->
|
||||
// adapter.submitData(data)
|
||||
// }
|
||||
waitForQRScanResult()
|
||||
} else{
|
||||
showData(user) // TODO() не показывать кнопки
|
||||
showData(getUserDto()!!)
|
||||
hideButtons()
|
||||
|
||||
}
|
||||
subscribe()
|
||||
|
||||
viewModel.visitListState.collectWithLifecycle(this) { data ->
|
||||
adapter.submitData(data)
|
||||
Log.d("ProfileFragment", "submitted data")
|
||||
}
|
||||
// viewModel.visitListStateFromLogin.collectWithLifecycle(this) { data ->
|
||||
// adapter.submitData(data)
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
private fun hideButtons() {
|
||||
binding.logout.visibility = View.INVISIBLE
|
||||
binding.scan.visibility = View.INVISIBLE
|
||||
}
|
||||
|
||||
fun showData(userDTO: UserDTO){
|
||||
binding.fio.text = userDTO.name
|
||||
binding.position.text = userDTO.position
|
||||
binding.lastEntry.text = userDTO.lastVisit
|
||||
viewModel.setLogin(login1 = userDTO.login)
|
||||
// binding.lastEntry.text = userDTO.lastVisit
|
||||
// viewModel.visitListStateFromLogin.collectWithLifecycle(this){
|
||||
//
|
||||
// }
|
||||
setAvatar(userDTO.photo)
|
||||
}
|
||||
private fun refreshData() {
|
||||
@ -72,6 +100,10 @@ class ProfileFragment: Fragment(R.layout.fragment_profile) {
|
||||
private fun getUserDto(): UserDTO? {
|
||||
return arguments?.getSerializable("user") as? UserDTO
|
||||
}
|
||||
private fun getIsMe(): Boolean {
|
||||
return arguments?.getBoolean("isMe", true) ?: true
|
||||
}
|
||||
|
||||
private fun waitForQRScanResult() {
|
||||
|
||||
requireActivity().onBackPressedDispatcher.addCallback(
|
||||
|
@ -3,7 +3,12 @@ package com.displaynone.acss.ui.profile
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.paging.Pager
|
||||
import androidx.paging.PagingConfig
|
||||
import androidx.paging.cachedIn
|
||||
import androidx.paging.log
|
||||
import com.displaynone.acss.components.auth.models.user.UserServiceST
|
||||
import com.displaynone.acss.components.auth.models.user.repository.VisitListPagingSource
|
||||
import com.displaynone.acss.components.auth.models.user.repository.dto.UserDTO
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
@ -17,10 +22,31 @@ class ProfileViewModel(): ViewModel() {
|
||||
capacity = Channel.BUFFERED,
|
||||
onBufferOverflow = BufferOverflow.DROP_OLDEST,
|
||||
)
|
||||
private var login: String = "" // FIXME()
|
||||
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,
|
||||
enablePlaceholders = false,
|
||||
maxSize = 100
|
||||
)
|
||||
) {
|
||||
VisitListPagingSource(UserServiceST.getInstance()::getMyLastVisits)
|
||||
}.flow
|
||||
.cachedIn(viewModelScope)
|
||||
|
||||
val visitListStateFromLogin = Pager(
|
||||
config = PagingConfig(pageSize = 20, enablePlaceholders = false, maxSize = 100)
|
||||
) {
|
||||
VisitListPagingSource { pageNum, pageSize ->
|
||||
UserServiceST.getInstance().getLastVisitsByLogin(pageNum,pageSize, login)
|
||||
}
|
||||
}.flow.cachedIn(viewModelScope)
|
||||
|
||||
fun logout(){
|
||||
UserServiceST.getInstance().logout()
|
||||
@ -48,6 +74,7 @@ class ProfileViewModel(): ViewModel() {
|
||||
_action.send(Action.GoToScan)
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface State {
|
||||
data object Loading : State
|
||||
data class Show(
|
||||
|
Loading…
x
Reference in New Issue
Block a user