Merge pull request #4437 from nextcloud/coroutine_1

Migrating Rxjava to coroutines #1
This commit is contained in:
Marcel Hibbe 2024-11-18 21:00:08 +01:00 committed by GitHub
commit 7d097474ab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 64 additions and 52 deletions

View file

@ -459,16 +459,6 @@ public interface NcApi {
@Field("state") Integer state, @Field("state") Integer state,
@Field("timer") Long timer); @Field("timer") Long timer);
@POST
Observable<GenericOverall> setReadStatusPrivacy(@Header("Authorization") String authorization,
@Url String url,
@Body RequestBody body);
@POST
Observable<GenericOverall> setTypingStatusPrivacy(@Header("Authorization") String authorization,
@Url String url,
@Body RequestBody body);
@POST @POST
Observable<ContactsByNumberOverall> searchContactsByPhoneNumber(@Header("Authorization") String authorization, Observable<ContactsByNumberOverall> searchContactsByPhoneNumber(@Header("Authorization") String authorization,
@Url String url, @Url String url,

View file

@ -12,6 +12,8 @@ import com.nextcloud.talk.models.json.conversations.RoomOverall
import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.models.json.participants.AddParticipantOverall import com.nextcloud.talk.models.json.participants.AddParticipantOverall
import okhttp3.MultipartBody import okhttp3.MultipartBody
import okhttp3.RequestBody
import retrofit2.http.Body
import retrofit2.http.DELETE import retrofit2.http.DELETE
import retrofit2.http.Field import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded import retrofit2.http.FormUrlEncoded
@ -116,4 +118,18 @@ interface NcApiCoroutines {
@DELETE @DELETE
suspend fun unarchiveConversation(@Header("Authorization") authorization: String, @Url url: String): GenericOverall suspend fun unarchiveConversation(@Header("Authorization") authorization: String, @Url url: String): GenericOverall
@POST
suspend fun setReadStatusPrivacy(
@Header("Authorization") authorization: String,
@Url url: String,
@Body body: RequestBody
): GenericOverall
@POST
suspend fun setTypingStatusPrivacy(
@Header("Authorization") authorization: String,
@Url url: String,
@Body body: RequestBody
): GenericOverall
} }

View file

@ -36,6 +36,7 @@ import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.lifecycle.lifecycleScope
import androidx.work.OneTimeWorkRequest import androidx.work.OneTimeWorkRequest
import androidx.work.WorkInfo import androidx.work.WorkInfo
import androidx.work.WorkManager import androidx.work.WorkManager
@ -49,6 +50,7 @@ import com.nextcloud.talk.R
import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.activities.MainActivity import com.nextcloud.talk.activities.MainActivity
import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.api.NcApiCoroutines
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.setAppTheme import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.setAppTheme
import com.nextcloud.talk.conversationlist.ConversationsListActivity import com.nextcloud.talk.conversationlist.ConversationsListActivity
@ -88,8 +90,10 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import retrofit2.HttpException
import java.net.URI import java.net.URI
import java.net.URISyntaxException import java.net.URISyntaxException
import java.util.Locale import java.util.Locale
@ -103,6 +107,9 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu
@Inject @Inject
lateinit var ncApi: NcApi lateinit var ncApi: NcApi
@Inject
lateinit var ncApiCoroutines: NcApiCoroutines
@Inject @Inject
lateinit var userManager: UserManager lateinit var userManager: UserManager
@ -123,6 +130,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu
private var profileQueryDisposable: Disposable? = null private var profileQueryDisposable: Disposable? = null
private var dbQueryDisposable: Disposable? = null private var dbQueryDisposable: Disposable? = null
@SuppressLint("StringFormatInvalid")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
@ -260,6 +268,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu
setupNotificationPermissionSettings() setupNotificationPermissionSettings()
} }
@SuppressLint("StringFormatInvalid")
@Suppress("LongMethod") @Suppress("LongMethod")
private fun setupNotificationPermissionSettings() { private fun setupNotificationPermissionSettings() {
if (ClosedInterfaceImpl().isGooglePlayServicesAvailable) { if (ClosedInterfaceImpl().isGooglePlayServicesAvailable) {
@ -603,7 +612,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu
} }
} }
@SuppressLint("CheckResult") @SuppressLint("CheckResult", "StringFormatInvalid")
private fun removeCurrentAccount() { private fun removeCurrentAccount() {
userManager.scheduleUserForDeletionWithId(currentUser!!.id!!).blockingGet() userManager.scheduleUserForDeletionWithId(currentUser!!.id!!).blockingGet()
val accountRemovalWork = OneTimeWorkRequest.Builder(AccountRemovalWorker::class.java).build() val accountRemovalWork = OneTimeWorkRequest.Builder(AccountRemovalWorker::class.java).build()
@ -1271,77 +1280,73 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu
} }
private fun observeReadPrivacy() { private fun observeReadPrivacy() {
CoroutineScope(Dispatchers.Main).launch { lifecycleScope.launch {
var state = appPreferences.readPrivacy var state = appPreferences.readPrivacy
readPrivacyFlow.collect { newBoolean -> readPrivacyFlow.collect { newBoolean ->
if (state != newBoolean) { if (state != newBoolean) {
state = newBoolean state = newBoolean
val booleanValue = if (newBoolean) "0" else "1" val booleanValue = if (newBoolean) "0" else "1"
val json = "{\"key\": \"read_status_privacy\", \"value\" : $booleanValue}" val json = "{\"key\": \"read_status_privacy\", \"value\" : $booleanValue}"
ncApi.setReadStatusPrivacy( withContext(Dispatchers.IO) {
ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token), try {
credentials?.let { credentials ->
ncApiCoroutines.setReadStatusPrivacy(
credentials,
ApiUtils.getUrlForUserSettings(currentUser!!.baseUrl!!), ApiUtils.getUrlForUserSettings(currentUser!!.baseUrl!!),
json.toRequestBody("application/json".toMediaTypeOrNull()) json.toRequestBody("application/json".toMediaTypeOrNull())
) )
.subscribeOn(Schedulers.io()) Log.i(TAG, "reading status set")
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<GenericOverall> {
override fun onSubscribe(d: Disposable) {
// unused atm
} }
} catch (e: Exception) {
override fun onNext(genericOverall: GenericOverall) { withContext(Dispatchers.Main) {
// unused atm
}
override fun onError(e: Throwable) {
appPreferences.setReadPrivacy(!newBoolean) appPreferences.setReadPrivacy(!newBoolean)
binding.settingsReadPrivacySwitch.isChecked = !newBoolean binding.settingsReadPrivacySwitch.isChecked = !newBoolean
} }
if (e is HttpException && e.code() == HTTP_ERROR_CODE_BAD_REQUEST) {
override fun onComplete() { Log.e(TAG, "read_status_privacy : Key or value is invalid")
// unused atm } else {
Log.e(TAG, "Error setting read status", e)
}
}
} }
})
} }
} }
} }
} }
private fun observeTypingStatus() { private fun observeTypingStatus() {
CoroutineScope(Dispatchers.Main).launch { lifecycleScope.launch {
var state = appPreferences.typingStatus var state = appPreferences.typingStatus
typingStatusFlow.collect { newBoolean -> typingStatusFlow.collect { newBoolean ->
if (state != newBoolean) { if (state != newBoolean) {
state = newBoolean state = newBoolean
val booleanValue = if (newBoolean) "0" else "1" val booleanValue = if (newBoolean) "0" else "1"
val json = "{\"key\": \"typing_privacy\", \"value\" : $booleanValue}" val json = "{\"key\": \"typing_privacy\", \"value\" : $booleanValue}"
ncApi.setTypingStatusPrivacy( withContext(Dispatchers.IO) {
ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token), try {
credentials?.let { credentials ->
ncApiCoroutines.setTypingStatusPrivacy(
credentials,
ApiUtils.getUrlForUserSettings(currentUser!!.baseUrl!!), ApiUtils.getUrlForUserSettings(currentUser!!.baseUrl!!),
json.toRequestBody("application/json".toMediaTypeOrNull()) json.toRequestBody("application/json".toMediaTypeOrNull())
) )
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<GenericOverall> {
override fun onSubscribe(d: Disposable) {
// unused atm
} }
withContext(Dispatchers.Main) {
override fun onNext(genericOverall: GenericOverall) {
loadCapabilitiesAndUpdateSettings() loadCapabilitiesAndUpdateSettings()
Log.i(TAG, "onNext called typing status set") Log.i(TAG, "typing status set")
} }
} catch (e: Exception) {
override fun onError(e: Throwable) { withContext(Dispatchers.Main) {
appPreferences.typingStatus = !newBoolean appPreferences.typingStatus = !newBoolean
binding.settingsTypingStatusSwitch.isChecked = !newBoolean binding.settingsTypingStatusSwitch.isChecked = !newBoolean
} }
if (e is HttpException && e.code() == HTTP_ERROR_CODE_BAD_REQUEST) {
override fun onComplete() { Log.e(TAG, "typing_privacy : Key or value is invalid")
// unused atm } else {
Log.e(TAG, "Error setting typing status", e)
}
}
} }
})
} }
} }
} }
@ -1354,5 +1359,6 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu
private const val DISABLED_ALPHA: Float = 0.38f private const val DISABLED_ALPHA: Float = 0.38f
private const val ENABLED_ALPHA: Float = 1.0f private const val ENABLED_ALPHA: Float = 1.0f
const val HTTP_CODE_OK: Int = 200 const val HTTP_CODE_OK: Int = 200
const val HTTP_ERROR_CODE_BAD_REQUEST: Int = 400
} }
} }