Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrating Rxjava to coroutines #1 #4437

Merged
merged 6 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions app/src/main/java/com/nextcloud/talk/api/NcApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -459,16 +459,6 @@ Observable<GenericOverall> setLobbyForConversation(@Header("Authorization") Stri
@Field("state") Integer state,
@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
Observable<ContactsByNumberOverall> searchContactsByPhoneNumber(@Header("Authorization") String authorization,
@Url String url,
Expand Down
16 changes: 16 additions & 0 deletions app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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.participants.AddParticipantOverall
import okhttp3.MultipartBody
import okhttp3.RequestBody
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
Expand Down Expand Up @@ -116,4 +118,18 @@ interface NcApiCoroutines {

@DELETE
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
}
90 changes: 48 additions & 42 deletions app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import androidx.core.view.ViewCompat
import androidx.lifecycle.lifecycleScope
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkInfo
import androidx.work.WorkManager
Expand All @@ -49,6 +50,7 @@ import com.nextcloud.talk.R
import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.activities.MainActivity
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.api.NcApiCoroutines
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.setAppTheme
import com.nextcloud.talk.conversationlist.ConversationsListActivity
Expand Down Expand Up @@ -88,8 +90,10 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.toRequestBody
import retrofit2.HttpException
import java.net.URI
import java.net.URISyntaxException
import java.util.Locale
Expand All @@ -103,6 +107,9 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu
@Inject
lateinit var ncApi: NcApi

@Inject
lateinit var ncApiCoroutines: NcApiCoroutines

@Inject
lateinit var userManager: UserManager

Expand All @@ -123,6 +130,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu
private var profileQueryDisposable: Disposable? = null
private var dbQueryDisposable: Disposable? = null

@SuppressLint("StringFormatInvalid")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
Expand Down Expand Up @@ -260,6 +268,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu
setupNotificationPermissionSettings()
}

@SuppressLint("StringFormatInvalid")
@Suppress("LongMethod")
private fun setupNotificationPermissionSettings() {
if (ClosedInterfaceImpl().isGooglePlayServicesAvailable) {
Expand Down Expand Up @@ -603,7 +612,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu
}
}

@SuppressLint("CheckResult")
@SuppressLint("CheckResult", "StringFormatInvalid")
private fun removeCurrentAccount() {
userManager.scheduleUserForDeletionWithId(currentUser!!.id!!).blockingGet()
val accountRemovalWork = OneTimeWorkRequest.Builder(AccountRemovalWorker::class.java).build()
Expand Down Expand Up @@ -1271,77 +1280,73 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu
}

private fun observeReadPrivacy() {
CoroutineScope(Dispatchers.Main).launch {
lifecycleScope.launch {
var state = appPreferences.readPrivacy
readPrivacyFlow.collect { newBoolean ->
if (state != newBoolean) {
state = newBoolean
val booleanValue = if (newBoolean) "0" else "1"
val json = "{\"key\": \"read_status_privacy\", \"value\" : $booleanValue}"
ncApi.setReadStatusPrivacy(
ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token),
ApiUtils.getUrlForUserSettings(currentUser!!.baseUrl!!),
json.toRequestBody("application/json".toMediaTypeOrNull())
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<GenericOverall> {
override fun onSubscribe(d: Disposable) {
// unused atm
withContext(Dispatchers.IO) {
try {
credentials?.let { credentials ->
ncApiCoroutines.setReadStatusPrivacy(
credentials,
ApiUtils.getUrlForUserSettings(currentUser!!.baseUrl!!),
json.toRequestBody("application/json".toMediaTypeOrNull())
)
Log.i(TAG, "reading status set")
}

override fun onNext(genericOverall: GenericOverall) {
// unused atm
}

override fun onError(e: Throwable) {
} catch (e: Exception) {
withContext(Dispatchers.Main) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not the scope of this PR (so should not be done in this PR) and it was already with RxJava:

When something goes wrong and the exception is thrown or onError was triggered, this will result in an endless loop as the preference is set and immediately triggers the readPrivacyFlow again.

appPreferences.setReadPrivacy(!newBoolean)
binding.settingsReadPrivacySwitch.isChecked = !newBoolean
}

override fun onComplete() {
// unused atm
if (e is HttpException && e.code() == HTTP_ERROR_CODE_BAD_REQUEST) {
Log.e(TAG, "read_status_privacy : Key or value is invalid")
} else {
Log.e(TAG, "Error setting read status", e)
}
})
}
}
}
}
}
}

private fun observeTypingStatus() {
CoroutineScope(Dispatchers.Main).launch {
lifecycleScope.launch {
var state = appPreferences.typingStatus
typingStatusFlow.collect { newBoolean ->
if (state != newBoolean) {
state = newBoolean
val booleanValue = if (newBoolean) "0" else "1"
val json = "{\"key\": \"typing_privacy\", \"value\" : $booleanValue}"
ncApi.setTypingStatusPrivacy(
ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token),
ApiUtils.getUrlForUserSettings(currentUser!!.baseUrl!!),
json.toRequestBody("application/json".toMediaTypeOrNull())
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<GenericOverall> {
override fun onSubscribe(d: Disposable) {
// unused atm
withContext(Dispatchers.IO) {
try {
credentials?.let { credentials ->
ncApiCoroutines.setTypingStatusPrivacy(
credentials,
ApiUtils.getUrlForUserSettings(currentUser!!.baseUrl!!),
json.toRequestBody("application/json".toMediaTypeOrNull())
)
}

override fun onNext(genericOverall: GenericOverall) {
withContext(Dispatchers.Main) {
loadCapabilitiesAndUpdateSettings()
Log.i(TAG, "onNext called typing status set")
Log.i(TAG, "typing status set")
}

override fun onError(e: Throwable) {
} catch (e: Exception) {
withContext(Dispatchers.Main) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same endless loop situation as with read privacy. Not to be solved in this PR

appPreferences.typingStatus = !newBoolean
binding.settingsTypingStatusSwitch.isChecked = !newBoolean
}

override fun onComplete() {
// unused atm
if (e is HttpException && e.code() == HTTP_ERROR_CODE_BAD_REQUEST) {
Log.e(TAG, "typing_privacy : Key or value is invalid")
} else {
Log.e(TAG, "Error setting typing status", e)
}
})
}
}
}
}
}
Expand All @@ -1354,5 +1359,6 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu
private const val DISABLED_ALPHA: Float = 0.38f
private const val ENABLED_ALPHA: Float = 1.0f
const val HTTP_CODE_OK: Int = 200
const val HTTP_ERROR_CODE_BAD_REQUEST: Int = 400
}
}
Loading