diff --git a/app/src/main/java/com/nextcloud/talk/api/NcApi.java b/app/src/main/java/com/nextcloud/talk/api/NcApi.java index e4811c780f..297bba392e 100644 --- a/app/src/main/java/com/nextcloud/talk/api/NcApi.java +++ b/app/src/main/java/com/nextcloud/talk/api/NcApi.java @@ -459,16 +459,6 @@ Observable setLobbyForConversation(@Header("Authorization") Stri @Field("state") Integer state, @Field("timer") Long timer); - @POST - Observable setReadStatusPrivacy(@Header("Authorization") String authorization, - @Url String url, - @Body RequestBody body); - - @POST - Observable setTypingStatusPrivacy(@Header("Authorization") String authorization, - @Url String url, - @Body RequestBody body); - @POST Observable searchContactsByPhoneNumber(@Header("Authorization") String authorization, @Url String url, diff --git a/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt b/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt index 8d399f1ec1..5707ae3972 100644 --- a/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt +++ b/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt @@ -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 @@ -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 } diff --git a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt index e86439a59a..c7ea56607f 100644 --- a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt @@ -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 @@ -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 @@ -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 @@ -103,6 +107,9 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu @Inject lateinit var ncApi: NcApi + @Inject + lateinit var ncApiCoroutines: NcApiCoroutines + @Inject lateinit var userManager: UserManager @@ -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) @@ -260,6 +268,7 @@ class SettingsActivity : BaseActivity(), SetPhoneNumberDialogFragment.SetPhoneNu setupNotificationPermissionSettings() } + @SuppressLint("StringFormatInvalid") @Suppress("LongMethod") private fun setupNotificationPermissionSettings() { if (ClosedInterfaceImpl().isGooglePlayServicesAvailable) { @@ -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() @@ -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 { - 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) { 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 { - 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) { 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) } - }) + } + } } } } @@ -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 } }