diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 531d00c0d..c9f0f1591 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -66,9 +66,6 @@
-
-
-
diff --git a/app/build.gradle b/app/build.gradle
index 763a11b0b..93eec3574 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -209,6 +209,7 @@ dependencies {
implementation "androidx.exifinterface:exifinterface:1.3.3"
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
+ implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0'
implementation 'androidx.biometric:biometric:1.1.0'
diff --git a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt b/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt
index 10bf10f84..592263844 100644
--- a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt
+++ b/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt
@@ -117,13 +117,15 @@ class MainActivity : BaseActivity(), ActionBarProvider {
} else if (!router!!.hasRootController()) {
if (hasDb) {
GlobalScope.launch {
- if (usersRepository.getUsers().isNotEmpty()) {
- runOnUiThread {
- setDefaultRootController()
- }
- } else {
- runOnUiThread {
- launchLoginScreen()
+ usersRepository.getUsers().collect {
+ if (it.isNotEmpty()) {
+ runOnUiThread {
+ setDefaultRootController()
+ }
+ } else {
+ runOnUiThread {
+ launchLoginScreen()
+ }
}
}
}
@@ -186,8 +188,14 @@ class MainActivity : BaseActivity(), ActionBarProvider {
}
fun resetConversationsList() {
- if (usersRepository.getUsers().isNotEmpty()) {
- setDefaultRootController()
+ GlobalScope.launch {
+ usersRepository.getUsers().collect {
+ if (it.isNotEmpty()) {
+ runOnUiThread {
+ setDefaultRootController()
+ }
+ }
+ }
}
}
@@ -226,14 +234,22 @@ class MainActivity : BaseActivity(), ActionBarProvider {
"vnd.android.cursor.item/vnd.com.nextcloud.talk2.chat" -> {
val user = userId.substringBeforeLast("@")
val baseUrl = userId.substringAfterLast("@")
- if (usersRepository.getActiveUser()?.baseUrl?.endsWith(baseUrl) == true) {
- startConversation(user)
- } else {
- Snackbar.make(
- binding.controllerContainer,
- R.string.nc_phone_book_integration_account_not_found,
- Snackbar.LENGTH_LONG
- ).show()
+ GlobalScope.launch {
+ usersRepository.getActiveUser().collect {
+ if (it?.baseUrl?.endsWith(baseUrl) == true) {
+ runOnUiThread {
+ startConversation(user)
+ }
+ } else {
+ runOnUiThread {
+ Snackbar.make(
+ binding.controllerContainer,
+ R.string.nc_phone_book_integration_account_not_found,
+ Snackbar.LENGTH_LONG
+ ).show()
+ }
+ }
+ }
}
}
}
@@ -242,38 +258,19 @@ class MainActivity : BaseActivity(), ActionBarProvider {
private fun startConversation(userId: String) {
val roomType = "1"
- val currentUser = usersRepository.getActiveUser() ?: return
- val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, 1))
- val credentials = ApiUtils.getCredentials(currentUser.username, currentUser.token)
- val retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(
- apiVersion, currentUser.baseUrl, roomType,
- null, userId, null
- )
- ncApi.createRoom(
- credentials,
- retrofitBucket.url, retrofitBucket.queryMap
- )
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(object : Observer {
- override fun onSubscribe(d: Disposable) {
- // unused atm
- }
- override fun onNext(roomOverall: RoomOverall) {
- val bundle = Bundle()
- bundle.putParcelable(KEY_USER_ENTITY, currentUser)
- bundle.putString(KEY_ROOM_TOKEN, roomOverall.ocs!!.data!!.token)
- bundle.putString(KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId)
-
- // FIXME once APIv2 or later is used only, the createRoom already returns all the data
- ncApi.getRoom(
+ GlobalScope.launch {
+ usersRepository.getActiveUser().collect { currentUser ->
+ if (currentUser != null) {
+ val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, 1))
+ val credentials = ApiUtils.getCredentials(currentUser.username, currentUser.token)
+ val retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(
+ apiVersion, currentUser.baseUrl, roomType,
+ null, userId, null
+ )
+ ncApi.createRoom(
credentials,
- ApiUtils.getUrlForRoom(
- apiVersion,
- currentUser.baseUrl,
- roomOverall.ocs!!.data!!.token
- )
+ retrofitBucket.url, retrofitBucket.queryMap
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
@@ -281,33 +278,61 @@ class MainActivity : BaseActivity(), ActionBarProvider {
override fun onSubscribe(d: Disposable) {
// unused atm
}
+
override fun onNext(roomOverall: RoomOverall) {
- bundle.putParcelable(
- KEY_ACTIVE_CONVERSATION,
- Parcels.wrap(roomOverall.ocs!!.data)
- )
- remapChatController(
- router!!, currentUser.id,
- roomOverall.ocs!!.data!!.token!!, bundle, true
+ val bundle = Bundle()
+ bundle.putParcelable(KEY_USER_ENTITY, currentUser)
+ bundle.putString(KEY_ROOM_TOKEN, roomOverall.ocs!!.data!!.token)
+ bundle.putString(KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId)
+
+ // FIXME once APIv2 or later is used only, the createRoom already returns all the data
+ ncApi.getRoom(
+ credentials,
+ ApiUtils.getUrlForRoom(
+ apiVersion,
+ currentUser.baseUrl,
+ roomOverall.ocs!!.data!!.token
+ )
)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : Observer {
+ override fun onSubscribe(d: Disposable) {
+ // unused atm
+ }
+
+ override fun onNext(roomOverall: RoomOverall) {
+ bundle.putParcelable(
+ KEY_ACTIVE_CONVERSATION,
+ Parcels.wrap(roomOverall.ocs!!.data)
+ )
+ remapChatController(
+ router!!, currentUser.id,
+ roomOverall.ocs!!.data!!.token!!, bundle, true
+ )
+ }
+
+ override fun onError(e: Throwable) {
+ // unused atm
+ }
+
+ override fun onComplete() {
+ // unused atm
+ }
+ })
}
override fun onError(e: Throwable) {
// unused atm
}
+
override fun onComplete() {
// unused atm
}
})
}
-
- override fun onError(e: Throwable) {
- // unused atm
- }
- override fun onComplete() {
- // unused atm
- }
- })
+ }
+ }
}
@RequiresApi(api = Build.VERSION_CODES.M)
@@ -359,6 +384,6 @@ class MainActivity : BaseActivity(), ActionBarProvider {
}
companion object {
- private val TAG = "MainActivity"
+ private const val TAG = "MainActivity"
}
}
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt
index d6593607a..f8c0c1502 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt
+++ b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt
@@ -53,6 +53,7 @@ import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
+import androidx.lifecycle.lifecycleScope
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import autodagger.AutoInjector
@@ -63,6 +64,7 @@ import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler
import com.google.android.material.textfield.TextInputLayout
import com.nextcloud.talk.BuildConfig
import com.nextcloud.talk.R
+import com.nextcloud.talk.activities.MainActivity
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.setAppTheme
@@ -89,6 +91,7 @@ import com.nextcloud.talk.utils.NotificationUtils.getMessageRingtoneUri
import com.nextcloud.talk.utils.SecurityUtils
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ARE_CALL_SOUNDS
import com.nextcloud.talk.utils.database.user.CapabilitiesNgUtil
+import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
import com.nextcloud.talk.utils.database.user.UserUtils
import com.nextcloud.talk.utils.preferences.MagicUserInputModule
import com.nextcloud.talk.utils.singletons.ApplicationWideMessageHolder
@@ -98,6 +101,9 @@ import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
+import kotlinx.coroutines.MainScope
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.launch
import net.orange_box.storebox.listeners.OnPreferenceValueChangedListener
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody
@@ -120,6 +126,9 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
@Inject
lateinit var userRepository: UsersRepository
+ @Inject
+ lateinit var currentUserProvider: CurrentUserProviderNew
+
private var saveStateHandler: LovelySaveStateHandler? = null
private var currentUser: UserNgEntity? = null
private var credentials: String? = null
@@ -134,13 +143,19 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
private var profileQueryDisposable: Disposable? = null
private var dbQueryDisposable: Disposable? = null
+ val scope = MainScope()
+
override val title: String
get() =
resources!!.getString(R.string.nc_settings)
private fun getCurrentUser() {
- currentUser = userRepository.getActiveUser()
- credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token)
+ (activity as MainActivity).lifecycleScope.launchWhenCreated {
+ currentUserProvider.currentUser.collect {
+ currentUser = it
+ credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token)
+ }
+ }
}
override fun onViewBound(view: View) {
@@ -189,10 +204,18 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
}
private fun setupPhoneBookIntegration() {
- if (CapabilitiesNgUtil.isPhoneBookIntegrationAvailable(userRepository.getActiveUser())) {
- binding.settingsPhoneBookIntegration.visibility = View.VISIBLE
- } else {
- binding.settingsPhoneBookIntegration.visibility = View.GONE
+ scope.launch {
+ userRepository.getActiveUser().collect {
+ if (CapabilitiesNgUtil.isPhoneBookIntegrationAvailable(it)) {
+ activity!!.runOnUiThread {
+ binding.settingsPhoneBookIntegration.visibility = View.VISIBLE
+ }
+ } else {
+ activity!!.runOnUiThread {
+ binding.settingsPhoneBookIntegration.visibility = View.GONE
+ }
+ }
+ }
}
}
@@ -730,6 +753,8 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
appPreferences?.unregisterReadPrivacyChangeListener(readPrivacyChangeListener)
appPreferences?.unregisterPhoneBookIntegrationChangeListener(phoneBookIntegrationChangeListener)
+ scope.cancel()
+
super.onDestroy()
}
diff --git a/app/src/main/java/com/nextcloud/talk/data/user/UsersDao.kt b/app/src/main/java/com/nextcloud/talk/data/user/UsersDao.kt
index d58ec58c2..d01cf1363 100644
--- a/app/src/main/java/com/nextcloud/talk/data/user/UsersDao.kt
+++ b/app/src/main/java/com/nextcloud/talk/data/user/UsersDao.kt
@@ -22,7 +22,6 @@
package com.nextcloud.talk.data.user
-import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
@@ -30,6 +29,8 @@ import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update
import com.nextcloud.talk.data.user.model.UserNgEntity
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOf
import java.lang.Boolean.FALSE
import java.lang.Boolean.TRUE
@@ -38,16 +39,16 @@ import java.lang.Boolean.TRUE
abstract class UsersDao {
// get active user
@Query("SELECT * FROM User where current = 1")
- abstract fun getActiveUser(): UserNgEntity?
+ abstract fun getActiveUser(): Flow
@Query("SELECT * FROM User WHERE current = 1")
- abstract fun getActiveUserLiveData(): LiveData
+ abstract fun getActiveUserLiveData(): Flow
@Query("SELECT * FROM User ORDER BY current DESC")
- abstract fun getUsersLiveData(): LiveData>
+ abstract fun getUsersLiveData(): Flow>
@Query("SELECT * FROM User WHERE current != 1 ORDER BY current DESC")
- abstract fun getUsersLiveDataWithoutActive(): LiveData>
+ abstract fun getUsersLiveDataWithoutActive(): Flow>
@Query("DELETE FROM User WHERE id = :id")
abstract suspend fun deleteUserWithId(id: Long)
@@ -56,66 +57,70 @@ abstract class UsersDao {
abstract suspend fun updateUser(user: UserNgEntity): Int
@Insert(onConflict = OnConflictStrategy.REPLACE)
- abstract fun saveUser(user: UserNgEntity): Long
+ abstract suspend fun saveUser(user: UserNgEntity): Long
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract suspend fun saveUsers(vararg users: UserNgEntity): List
// get all users not scheduled for deletion
@Query("SELECT * FROM User where current != 0")
- abstract fun getUsers(): List
+ abstract fun getUsers(): Flow>
@Query("SELECT * FROM User where id = :id")
- abstract fun getUserWithId(id: Long): UserNgEntity?
+ abstract fun getUserWithId(id: Long): Flow
@Query("SELECT * FROM User where id = :id")
- abstract fun getUserWithIdLiveData(id: Long): LiveData
+ abstract fun getUserWithIdLiveData(id: Long): Flow
@Query("SELECT * FROM User where id = :id AND scheduledForDeletion != 1")
- abstract fun getUserWithIdNotScheduledForDeletion(id: Long): UserNgEntity?
+ abstract fun getUserWithIdNotScheduledForDeletion(id: Long): Flow
@Query("SELECT * FROM User where userId = :userId")
- abstract fun getUserWithUserId(userId: String): UserNgEntity?
+ abstract fun getUserWithUserId(userId: String): Flow
@Query("SELECT * FROM User where userId != :userId")
- abstract fun getUsersWithoutUserId(userId: Long): List
+ abstract fun getUsersWithoutUserId(userId: Long): Flow>
@Query("SELECT * FROM User where current = 0")
- abstract fun getUsersScheduledForDeletion(): List
+ abstract fun getUsersScheduledForDeletion(): Flow>
@Query("SELECT * FROM User where scheduledForDeletion = 0")
- abstract fun getUsersNotScheduledForDeletion(): List
+ abstract fun getUsersNotScheduledForDeletion(): Flow>
@Query("SELECT * FROM User WHERE username = :username AND baseUrl = :server")
- abstract suspend fun getUserWithUsernameAndServer(username: String, server: String): UserNgEntity?
+ abstract fun getUserWithUsernameAndServer(username: String, server: String): Flow
@Transaction
- open suspend fun setUserAsActiveWithId(id: Long): Boolean {
+ open suspend fun setUserAsActiveWithId(id: Long): Flow {
val users = getUsers()
- for (user in users) {
- // removed from clause: && UserStatus.ACTIVE == user.status
- if (user.id != id) {
- user.current = TRUE
- updateUser(user)
- } // removed from clause: && UserStatus.ACTIVE != user.status
- else if (user.id == id) {
- user.current = TRUE
- updateUser(user)
+ users.collect {
+ for (user in it) {
+ // removed from clause: && UserStatus.ACTIVE == user.status
+ if (user.id != id) {
+ user.current = TRUE
+ updateUser(user)
+ } // removed from clause: && UserStatus.ACTIVE != user.status
+ else if (user.id == id) {
+ user.current = TRUE
+ updateUser(user)
+ }
}
}
- return true
+ return flowOf(TRUE)
}
@Transaction
- open suspend fun markUserForDeletion(id: Long): Boolean {
+ open suspend fun markUserForDeletion(id: Long): Flow {
val users = getUsers()
- for (user in users) {
- if (user.id == id) {
- // TODO currently we only have a boolean, no intermediate states
- user.current = FALSE
- updateUser(user)
- break
+ users.collect {
+ for (user in it) {
+ if (user.id == id) {
+ // TODO currently we only have a boolean, no intermediate states
+ user.current = FALSE
+ updateUser(user)
+ break
+ }
}
}
@@ -123,14 +128,18 @@ abstract class UsersDao {
}
@Transaction
- open suspend fun setAnyUserAsActive(): Boolean {
+ open suspend fun setAnyUserAsActive(): Flow {
val users = getUsers()
- for (user in users) {
- user.current = TRUE
- updateUser(user)
- return true
+ var result = FALSE
+ users.collect {
+ for (user in it) {
+ user.current = TRUE
+ updateUser(user)
+ result = true
+ break
+ }
}
- return false
+ return flowOf(result)
}
}
diff --git a/app/src/main/java/com/nextcloud/talk/data/user/UsersRepository.kt b/app/src/main/java/com/nextcloud/talk/data/user/UsersRepository.kt
index 2e8780da9..522975af1 100644
--- a/app/src/main/java/com/nextcloud/talk/data/user/UsersRepository.kt
+++ b/app/src/main/java/com/nextcloud/talk/data/user/UsersRepository.kt
@@ -22,29 +22,28 @@
package com.nextcloud.talk.data.user
-import androidx.lifecycle.LiveData
import com.nextcloud.talk.data.user.model.UserNgEntity
-import com.nextcloud.talk.data.user.model.User
+import kotlinx.coroutines.flow.Flow
@Suppress("TooManyFunctions")
interface UsersRepository {
- fun getActiveUserLiveData(): LiveData
- fun getActiveUser(): UserNgEntity?
- fun getUsers(): List
- fun getUserWithId(id: Long): UserNgEntity?
- fun getUserWithIdLiveData(id: Long): LiveData
- fun getUserWithIdNotScheduledForDeletion(id: Long): UserNgEntity?
- fun getUserWithUserId(userId: String): UserNgEntity?
- fun getUsersWithoutUserId(userId: Long): List
- fun getUsersLiveData(): LiveData>
- fun getUsersLiveDataWithoutActive(): LiveData>
- fun getUsersScheduledForDeletion(): List
- fun getUsersNotScheduledForDeletion(): List
- suspend fun getUserWithUsernameAndServer(username: String, server: String): UserNgEntity?
+ fun getActiveUserLiveData(): Flow
+ fun getActiveUser(): Flow
+ fun getUsers(): Flow>
+ fun getUserWithId(id: Long): Flow
+ fun getUserWithIdLiveData(id: Long): Flow
+ fun getUserWithIdNotScheduledForDeletion(id: Long): Flow
+ fun getUserWithUserId(userId: String): Flow
+ fun getUsersWithoutUserId(userId: Long): Flow>
+ fun getUsersLiveData(): Flow>
+ fun getUsersLiveDataWithoutActive(): Flow>
+ fun getUsersScheduledForDeletion(): Flow>
+ fun getUsersNotScheduledForDeletion(): Flow>
+ fun getUserWithUsernameAndServer(username: String, server: String): Flow
suspend fun updateUser(user: UserNgEntity): Int
suspend fun insertUser(user: UserNgEntity): Long
- suspend fun setUserAsActiveWithId(id: Long): Boolean
+ suspend fun setUserAsActiveWithId(id: Long): Flow
suspend fun deleteUserWithId(id: Long)
- suspend fun setAnyUserAsActive(): Boolean
- suspend fun markUserForDeletion(id: Long): Boolean
+ suspend fun setAnyUserAsActive(): Flow
+ suspend fun markUserForDeletion(id: Long): Flow
}
diff --git a/app/src/main/java/com/nextcloud/talk/data/user/UsersRepositoryImpl.kt b/app/src/main/java/com/nextcloud/talk/data/user/UsersRepositoryImpl.kt
index 5ca2e75a0..f13de9a67 100644
--- a/app/src/main/java/com/nextcloud/talk/data/user/UsersRepositoryImpl.kt
+++ b/app/src/main/java/com/nextcloud/talk/data/user/UsersRepositoryImpl.kt
@@ -22,75 +22,61 @@
package com.nextcloud.talk.data.user
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.distinctUntilChanged
-import androidx.lifecycle.map
import com.nextcloud.talk.data.user.model.UserNgEntity
-import com.nextcloud.talk.data.user.model.User
-import com.nextcloud.talk.data.user.model.toUser
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChanged
@Suppress("TooManyFunctions")
class UsersRepositoryImpl(private val usersDao: UsersDao) : UsersRepository {
- override fun getActiveUserLiveData(): LiveData {
+ override fun getActiveUserLiveData(): Flow {
return usersDao.getActiveUserLiveData().distinctUntilChanged()
}
- override fun getActiveUser(): UserNgEntity? {
+ override fun getActiveUser(): Flow {
return usersDao.getActiveUser()
}
- override fun getUsers(): List {
+ override fun getUsers(): Flow> {
return usersDao.getUsers()
}
- override fun getUserWithId(id: Long): UserNgEntity? {
+ override fun getUserWithId(id: Long): Flow {
return usersDao.getUserWithId(id)
}
- override fun getUserWithIdLiveData(id: Long): LiveData {
+ override fun getUserWithIdLiveData(id: Long): Flow {
return usersDao.getUserWithIdLiveData(id).distinctUntilChanged()
}
- override fun getUserWithIdNotScheduledForDeletion(id: Long): UserNgEntity? {
+ override fun getUserWithIdNotScheduledForDeletion(id: Long): Flow {
return usersDao.getUserWithIdNotScheduledForDeletion(id)
}
- override fun getUserWithUserId(userId: String): UserNgEntity? {
+ override fun getUserWithUserId(userId: String): Flow {
return usersDao.getUserWithUserId(userId)
}
- override fun getUsersWithoutUserId(userId: Long): List {
+ override fun getUsersWithoutUserId(userId: Long): Flow> {
return usersDao.getUsersWithoutUserId(userId)
}
- override fun getUsersLiveData(): LiveData> {
- return usersDao.getUsersLiveData().distinctUntilChanged().map { usersList ->
- usersList.map {
- it.toUser()
- }
- }
+ override fun getUsersLiveData(): Flow> {
+ return usersDao.getUsersLiveData().distinctUntilChanged()
}
- override fun getUsersLiveDataWithoutActive(): LiveData> {
- return usersDao.getUsersLiveDataWithoutActive().distinctUntilChanged().map { usersList ->
- usersList.map {
- it.toUser()
- }
- }
+ override fun getUsersLiveDataWithoutActive(): Flow> {
+ return usersDao.getUsersLiveDataWithoutActive().distinctUntilChanged()
}
- override fun getUsersScheduledForDeletion(): List {
+ override fun getUsersScheduledForDeletion(): Flow> {
return usersDao.getUsersScheduledForDeletion()
}
- override fun getUsersNotScheduledForDeletion(): List {
+ override fun getUsersNotScheduledForDeletion(): Flow> {
return usersDao.getUsersNotScheduledForDeletion()
}
- override suspend fun getUserWithUsernameAndServer(
- username: String,
- server: String
- ): UserNgEntity? {
+ override fun getUserWithUsernameAndServer(username: String, server: String): Flow {
return usersDao.getUserWithUsernameAndServer(username, server)
}
@@ -102,7 +88,7 @@ class UsersRepositoryImpl(private val usersDao: UsersDao) : UsersRepository {
return usersDao.saveUser(user)
}
- override suspend fun setUserAsActiveWithId(id: Long): Boolean {
+ override suspend fun setUserAsActiveWithId(id: Long): Flow {
return usersDao.setUserAsActiveWithId(id)
}
@@ -110,11 +96,11 @@ class UsersRepositoryImpl(private val usersDao: UsersDao) : UsersRepository {
usersDao.deleteUserWithId(id)
}
- override suspend fun setAnyUserAsActive(): Boolean {
+ override suspend fun setAnyUserAsActive(): Flow {
return usersDao.setAnyUserAsActive()
}
- override suspend fun markUserForDeletion(id: Long): Boolean {
+ override suspend fun markUserForDeletion(id: Long): Flow {
return usersDao.markUserForDeletion(id)
}
}
diff --git a/app/src/main/java/com/nextcloud/talk/users/UserManager.kt b/app/src/main/java/com/nextcloud/talk/users/UserManager.kt
index 3014569de..0ec4c51fa 100644
--- a/app/src/main/java/com/nextcloud/talk/users/UserManager.kt
+++ b/app/src/main/java/com/nextcloud/talk/users/UserManager.kt
@@ -22,7 +22,6 @@
package com.nextcloud.talk.users
import android.text.TextUtils
-import androidx.lifecycle.LiveData
import com.bluelinelabs.logansquare.LoganSquare
import com.nextcloud.talk.data.user.UsersRepository
import com.nextcloud.talk.data.user.model.UserNgEntity
@@ -30,35 +29,54 @@ import com.nextcloud.talk.models.ExternalSignalingServer
import com.nextcloud.talk.models.json.capabilities.Capabilities
import com.nextcloud.talk.models.json.push.PushConfigurationState
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOf
+import java.lang.Boolean.FALSE
@Suppress("TooManyFunctions")
class UserManager internal constructor(private val userRepository: UsersRepository) : CurrentUserProviderNew {
- fun anyUserExists(): Boolean {
- return userRepository.getUsers().isNotEmpty()
+ suspend fun anyUserExists(): Boolean {
+ var result = FALSE
+ userRepository.getUsers().collect {
+ result = it.isNotEmpty()
+ }
+
+ return result
}
- fun hasMultipleUsers(): Boolean {
- return userRepository.getUsers().size > 1
+ suspend fun hasMultipleUsers(): Flow {
+ var result = FALSE
+ userRepository.getUsers().collect {
+ result = it.size > 1
+ }
+
+ return flowOf(result)
}
- val users: List
+ val users: Flow>
get() = userRepository.getUsers()
- val usersScheduledForDeletion: List
+ val usersScheduledForDeletion: Flow>
get() = userRepository.getUsersScheduledForDeletion()
- suspend fun setAnyUserAndSetAsActive(): UserNgEntity? {
+ private suspend fun setAnyUserAndSetAsActive(): Flow {
val results = userRepository.getUsersNotScheduledForDeletion()
- if (results.isNotEmpty()) {
- val user = results[0]
- user.current = true
- userRepository.updateUser(user)
- return user
+
+ var result: UserNgEntity? = null
+
+ results.collect {
+ if (it.isNotEmpty()) {
+ val user = it[0]
+ user.current = true
+ userRepository.updateUser(user)
+ result = user
+ }
}
- return null
+
+ return flowOf(result)
}
- override val currentUser: UserNgEntity?
+ override val currentUser: Flow
get() {
return userRepository.getActiveUser()
}
@@ -71,59 +89,84 @@ class UserManager internal constructor(private val userRepository: UsersReposito
userRepository.deleteUserWithId(internalId)
}
- fun getUserById(userId: String): UserNgEntity? {
+ fun getUserById(userId: String): Flow {
return userRepository.getUserWithUserId(userId)
}
- fun getUserWithId(id: Long): UserNgEntity? {
+ fun getUserWithId(id: Long): Flow {
return userRepository.getUserWithId(id)
}
suspend fun disableAllUsersWithoutId(userId: Long) {
val results = userRepository.getUsersWithoutUserId(userId)
- if (results.isNotEmpty()) {
- for (entity in results) {
- entity.current = false
- userRepository.updateUser(entity)
+
+ results.collect {
+ if (it.isNotEmpty()) {
+ for (entity in it) {
+ entity.current = false
+ userRepository.updateUser(entity)
+ }
}
}
}
- suspend fun checkIfUserIsScheduledForDeletion(username: String, server: String): Boolean {
+ suspend fun checkIfUserIsScheduledForDeletion(username: String, server: String): Flow {
val results = userRepository.getUserWithUsernameAndServer(username, server)
- return results?.scheduledForDeletion ?: false
+ var result = FALSE
+ results.collect {
+ result = it?.scheduledForDeletion ?: FALSE
+ }
+
+ return flowOf(result)
}
- fun getUserWithInternalId(id: Long): UserNgEntity? {
+ fun getUserWithInternalId(id: Long): Flow {
return userRepository.getUserWithIdNotScheduledForDeletion(id)
}
- suspend fun getIfUserWithUsernameAndServer(username: String, server: String): Boolean {
- return userRepository.getUserWithUsernameAndServer(username, server) != null
- }
-
- suspend fun scheduleUserForDeletionWithId(id: Long): Boolean {
- val result = userRepository.getUserWithId(id)
-
- if (result != null) {
- result.scheduledForDeletion = true
- result.current = false
- userRepository.updateUser(result)
+ suspend fun getIfUserWithUsernameAndServer(username: String, server: String): Flow {
+ val results = userRepository.getUserWithUsernameAndServer(username, server)
+ var result = FALSE
+ results.collect {
+ result = it != null
}
- return setAnyUserAndSetAsActive() != null
+ return flowOf(result)
+ }
+
+ suspend fun scheduleUserForDeletionWithId(id: Long): Flow {
+ val results = userRepository.getUserWithId(id)
+ var result = FALSE
+
+ results.collect {
+ if (it != null) {
+ it.scheduledForDeletion = true
+ it.current = false
+ userRepository.updateUser(it)
+ }
+ }
+
+ setAnyUserAndSetAsActive().collect {
+ result = it != null
+ }
+
+ return flowOf(result)
}
suspend fun createOrUpdateUser(
username: String?,
userAttributes: UserAttributes,
- ): LiveData {
- var user = if (userAttributes.id == null && username != null && userAttributes.serverUrl != null) {
- userRepository.getUserWithUsernameAndServer(username, userAttributes.serverUrl)
+ ): Flow {
+ var user: UserNgEntity? = null
+
+ if (userAttributes.id == null && username != null && userAttributes.serverUrl != null) {
+ userRepository.getUserWithUsernameAndServer(username, userAttributes.serverUrl).collect {
+ user = it
+ }
} else if (userAttributes.id != null) {
- userRepository.getUserWithId(userAttributes.id)
- } else {
- null
+ userRepository.getUserWithId(userAttributes.id).collect {
+ user = it
+ }
}
if (user == null) {
@@ -133,12 +176,13 @@ class UserManager internal constructor(private val userRepository: UsersReposito
)
} else {
updateUserData(
- user,
+ user!!,
userAttributes
)
}
- userRepository.insertUser(user)
- return userRepository.getUserWithIdLiveData(user.id)
+
+ userRepository.insertUser(user!!)
+ return userRepository.getUserWithIdLiveData(user!!.id)
}
private fun updateUserData(user: UserNgEntity, userAttributes: UserAttributes) {
diff --git a/app/src/main/java/com/nextcloud/talk/utils/database/user/CurrentUserProviderNew.kt b/app/src/main/java/com/nextcloud/talk/utils/database/user/CurrentUserProviderNew.kt
index 63d0fdf66..6af4e4da2 100644
--- a/app/src/main/java/com/nextcloud/talk/utils/database/user/CurrentUserProviderNew.kt
+++ b/app/src/main/java/com/nextcloud/talk/utils/database/user/CurrentUserProviderNew.kt
@@ -21,7 +21,8 @@
package com.nextcloud.talk.utils.database.user
import com.nextcloud.talk.data.user.model.UserNgEntity
+import kotlinx.coroutines.flow.Flow
interface CurrentUserProviderNew {
- val currentUser: UserNgEntity?
+ val currentUser: Flow
}
diff --git a/app/src/main/java/com/nextcloud/talk/utils/database/user/UserModule.kt b/app/src/main/java/com/nextcloud/talk/utils/database/user/UserModule.kt
index aad73490a..d29eedb56 100644
--- a/app/src/main/java/com/nextcloud/talk/utils/database/user/UserModule.kt
+++ b/app/src/main/java/com/nextcloud/talk/utils/database/user/UserModule.kt
@@ -20,6 +20,8 @@
package com.nextcloud.talk.utils.database.user
import com.nextcloud.talk.dagger.modules.DatabaseModule
+import com.nextcloud.talk.data.user.UsersRepository
+import com.nextcloud.talk.users.UserManager
import dagger.Binds
import dagger.Module
import dagger.Provides
@@ -32,10 +34,18 @@ abstract class UserModule {
@Binds
abstract fun bindCurrentUserProvider(userUtils: UserUtils): CurrentUserProvider
+ @Binds
+ abstract fun bindCurrentUserProviderNew(userManager: UserManager): CurrentUserProviderNew
+
companion object {
@Provides
fun provideUserUtils(dataStore: ReactiveEntityStore?): UserUtils {
return UserUtils(dataStore)
}
+
+ @Provides
+ fun provideUserManager(userRepository: UsersRepository): UserManager {
+ return UserManager(userRepository)
+ }
}
}