main.com.sceyt.chatuikit.persistence.logicimpl.PersistenceUsersLogicImpl.kt Maven / Gradle / Ivy
package com.sceyt.chatuikit.persistence.logicimpl
import com.sceyt.chat.models.settings.UserSettings
import com.sceyt.chat.models.user.PresenceState
import com.sceyt.chat.models.user.User
import com.sceyt.chat.wrapper.ClientWrapper
import com.sceyt.chatuikit.SceytChatUIKit
import com.sceyt.chatuikit.data.models.SceytResponse
import com.sceyt.chatuikit.data.models.messages.SceytUser
import com.sceyt.chatuikit.koin.SceytKoinComponent
import com.sceyt.chatuikit.persistence.dao.UserDao
import com.sceyt.chatuikit.persistence.extensions.safeResume
import com.sceyt.chatuikit.persistence.logic.PersistenceChannelsLogic
import com.sceyt.chatuikit.persistence.logic.PersistenceUsersLogic
import com.sceyt.chatuikit.persistence.mappers.toSceytUser
import com.sceyt.chatuikit.persistence.mappers.toUserDb
import com.sceyt.chatuikit.persistence.mappers.toUserEntity
import com.sceyt.chatuikit.persistence.repositories.ProfileRepository
import com.sceyt.chatuikit.persistence.repositories.SceytSharedPreference
import com.sceyt.chatuikit.persistence.repositories.UsersRepository
import com.sceyt.chatuikit.services.SceytPresenceChecker
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.suspendCancellableCoroutine
import org.koin.core.component.inject
internal class PersistenceUsersLogicImpl(
private val userDao: UserDao,
private val userRepository: UsersRepository,
private val profileRepo: ProfileRepository,
private val preference: SceytSharedPreference,
) : PersistenceUsersLogic, SceytKoinComponent {
private val persistenceChannelsLogic: PersistenceChannelsLogic by inject()
override suspend fun loadUsers(query: String): SceytResponse> {
val response = userRepository.loadUsers(query)
if (response is SceytResponse.Success) {
response.data?.let { users ->
userDao.insertUsersWithMetadata(users.map { it.toUserDb() })
}
}
return response
}
override suspend fun loadMoreUsers(): SceytResponse> {
val response = userRepository.loadMoreUsers()
if (response is SceytResponse.Success) {
response.data?.let { users ->
userDao.insertUsersWithMetadata(users.map { it.toUserDb() })
}
}
return response
}
override suspend fun getSceytUsers(ids: List): SceytResponse> {
val response = userRepository.getSceytUsersByIds(ids)
if (response is SceytResponse.Success) {
response.data?.let { users ->
userDao.insertUsersWithMetadata(users.map { it.toUserDb() })
}
}
return response
}
override suspend fun getUserDbById(id: String): SceytUser? {
return userDao.getUserById(id)?.toSceytUser()
}
override suspend fun getUsersDbByIds(id: List): List {
return userDao.getUsersById(id).map { it.toSceytUser() }
}
override suspend fun getCurrentUser(): SceytUser? {
val clientUser = ClientWrapper.currentUser
if (!clientUser?.id.isNullOrBlank())
return clientUser?.toSceytUser()
return preference.getUserId()?.let {
userDao.getUserById(it)?.toSceytUser()
}
}
override fun getCurrentUserNonSuspend(): SceytUser? {
val clientUser = ClientWrapper.currentUser
if (!clientUser?.id.isNullOrBlank())
return clientUser?.toSceytUser()
return preference.getUserId()?.let { SceytUser(it) }
}
override fun getCurrentUserAsFlow(): Flow {
(preference.getUserId() ?: ClientWrapper.currentUser?.id)?.let {
return userDao.getUserByIdAsFlow(it).filterNotNull().map { entity -> entity.toSceytUser() }
} ?: return emptyFlow()
}
override suspend fun uploadAvatar(avatarUrl: String): SceytResponse {
return profileRepo.uploadAvatar(avatarUrl)
}
override suspend fun updateProfile(
firstName: String?,
lastName: String?,
avatarUri: String?,
metadataMap: Map?
): SceytResponse {
val request = User.setProfileRequest().apply {
avatarUri?.let { uri ->
setAvatar(uri)
}
setFirstName(firstName ?: "")
setLastName(lastName ?: "")
setMetadataMap(metadataMap ?: emptyMap())
}
val response = profileRepo.updateProfile(request)
if (response is SceytResponse.Success) {
response.data?.let {
userDao.insertUserWithMetadata(it.toUserDb())
}
}
return response
}
override suspend fun updateStatus(status: String): SceytResponse {
val presence = getCurrentUser()?.presence?.state ?: PresenceState.Offline
val response = suspendCancellableCoroutine> { continuation ->
ClientWrapper.setPresence(presence, status) {
if (it.isOk)
continuation.safeResume(SceytResponse.Success(true))
else continuation.safeResume(SceytResponse.Error(it.error))
}
}
if (response is SceytResponse.Success)
preference.getUserId()?.let { userDao.updateUserStatus(it, status) }
return response
}
override suspend fun setPresenceState(presenceState: PresenceState): SceytResponse {
val status = ClientWrapper.currentUser?.presence?.status
val response = suspendCancellableCoroutine> { continuation ->
ClientWrapper.setPresence(presenceState, if (status.isNullOrBlank())
SceytChatUIKit.config.presenceConfig.defaultPresenceStatus else status) {
if (it.isOk) {
continuation.safeResume(SceytResponse.Success(true))
} else continuation.safeResume(SceytResponse.Error(it.error))
}
}
if (response is SceytResponse.Success)
updateCurrentUser()
return response
}
override suspend fun getSettings(): SceytResponse {
return profileRepo.getSettings()
}
override suspend fun muteNotifications(muteUntil: Long): SceytResponse {
return profileRepo.muteNotifications(muteUntil)
}
override suspend fun unMuteNotifications(): SceytResponse {
return profileRepo.unMuteNotifications()
}
override suspend fun onUserPresenceChanged(users: List) {
userDao.updateUsers(users.map { it.user.toUserEntity() })
}
override suspend fun blockUnBlockUser(userId: String, block: Boolean): SceytResponse> {
val response = if (block) {
userRepository.blockUser(userId)
} else
userRepository.unblockUser(userId)
if (response is SceytResponse.Success) {
userDao.blockUnBlockUser(userId, block)
persistenceChannelsLogic.blockUnBlockUser(userId, block)
}
return response
}
private suspend fun updateCurrentUser() {
(preference.getUserId() ?: ClientWrapper.currentUser?.id)?.let {
val response = userRepository.getSceytUserById(it)
if (response is SceytResponse.Success)
response.data?.toUserDb()?.let { userDb ->
userDao.insertUserWithMetadata(userDb)
}
}
}
}