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 8f9dd2ca2..a1603d356 100644 --- a/app/src/main/java/com/nextcloud/talk/api/NcApi.java +++ b/app/src/main/java/com/nextcloud/talk/api/NcApi.java @@ -436,7 +436,7 @@ public interface NcApi { @FormUrlEncoded @PUT - Observable setReadOnlyState(@Header("Authorization") String authorization, + Observable setConversationReadOnly(@Header("Authorization") String authorization, @Url String url, @Field("state") int state); diff --git a/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt index aed4473ef..f0bae76ee 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt @@ -257,6 +257,18 @@ class ConversationInfoActivity : else -> {} } } + + viewModel.getConversationReadOnlyState.observe(this) { state -> + when (state) { + is ConversationInfoViewModel.SetConversationReadOnlySuccessState -> { + } + is ConversationInfoViewModel.SetConversationReadOnlyErrorState -> { + Snackbar.make(binding.root, R.string.conversation_read_only_failed, Snackbar.LENGTH_LONG).show() + } + else -> { + } + } + } } private fun setupActionBar() { @@ -658,6 +670,7 @@ class ConversationInfoActivity : intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) startActivity(intent) } + WorkInfo.State.FAILED -> { val errorType = workInfo.outputData.getString("error_type") if (errorType == LeaveConversationWorker.ERROR_NO_OTHER_MODERATORS_OR_OWNERS_LEFT) { @@ -674,6 +687,7 @@ class ConversationInfoActivity : ).show() } } + else -> { } } @@ -826,6 +840,20 @@ class ConversationInfoActivity : binding.archiveConversationText.text = resources.getString(R.string.archive_conversation) binding.archiveConversationTextHint.text = resources.getString(R.string.archive_hint) } + if (ConversationUtils.isConversationReadOnlyAvailable(conversationCopy, spreedCapabilities)) { + binding.lockConversation.visibility = VISIBLE + binding.lockConversationSwitch.isChecked = databaseStorageModule!!.getBoolean("lock_switch", false) + + binding.lockConversation.setOnClickListener { + val isLocked = binding.lockConversationSwitch.isChecked + binding.lockConversationSwitch.isChecked = !isLocked + databaseStorageModule!!.saveBoolean("lock_switch", !isLocked) + val state = if (isLocked) 0 else 1 + makeConversationReadOnly(conversationUser, conversationToken, state) + } + } else { + binding.lockConversation.visibility = GONE + } if (!isDestroyed) { binding.dangerZoneOptions.visibility = VISIBLE @@ -899,6 +927,10 @@ class ConversationInfoActivity : } } + private fun makeConversationReadOnly(conversationUser: User, roomToken: String, state: Int) { + viewModel.setConversationReadOnly(conversationUser, roomToken, state) + } + private fun initRecordingConsentOption() { fun hide() { binding.recordingConsentView.recordingConsentSettingsCategory.visibility = GONE @@ -1296,7 +1328,7 @@ class ConversationInfoActivity : } } - @SuppressLint("CheckResult") + @SuppressLint("CheckResult", "StringFormatInvalid") override fun onItemClick(view: View?, position: Int): Boolean { if (!ConversationUtils.canModerate(conversation!!, spreedCapabilities)) { return true diff --git a/app/src/main/java/com/nextcloud/talk/conversationinfo/viewmodel/ConversationInfoViewModel.kt b/app/src/main/java/com/nextcloud/talk/conversationinfo/viewmodel/ConversationInfoViewModel.kt index a84fd4da8..68e278a99 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationinfo/viewmodel/ConversationInfoViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationinfo/viewmodel/ConversationInfoViewModel.kt @@ -76,6 +76,13 @@ class ConversationInfoViewModel @Inject constructor( val getUnBanActorState: LiveData get() = _getUnBanActorState + object SetConversationReadOnlySuccessState : ViewState + object SetConversationReadOnlyErrorState : ViewState + + private val _getConversationReadOnlyState: MutableLiveData = MutableLiveData() + val getConversationReadOnlyState: LiveData + get() = _getConversationReadOnlyState + object GetRoomStartState : ViewState object GetRoomErrorState : ViewState open class GetRoomSuccessState(val conversationModel: ConversationModel) : ViewState @@ -178,6 +185,30 @@ class ConversationInfoViewModel @Inject constructor( }) } + fun setConversationReadOnly(user: User, token: String, state: Int) { + val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1)) + val url = ApiUtils.getUrlForConversationReadOnly(apiVersion, user.baseUrl!!, token) + conversationsRepository.setConversationReadOnly(user.getCredentials(), url, state) + .subscribeOn(Schedulers.io()) + ?.observeOn(AndroidSchedulers.mainThread()) + ?.subscribe(object : Observer { + override fun onSubscribe(p0: Disposable) { + } + + override fun onError(error: Throwable) { + _getConversationReadOnlyState.value = SetConversationReadOnlyErrorState + } + + override fun onComplete() { + // unused atm + } + + override fun onNext(p0: GenericOverall) { + _getConversationReadOnlyState.value = SetConversationReadOnlySuccessState + } + }) + } + fun unbanActor(user: User, token: String, banId: Int) { val url = ApiUtils.getUrlForUnban(user.baseUrl!!, token, banId) chatNetworkDataSource.unbanActor(user.getCredentials(), url) diff --git a/app/src/main/java/com/nextcloud/talk/repositories/conversations/ConversationsRepository.kt b/app/src/main/java/com/nextcloud/talk/repositories/conversations/ConversationsRepository.kt index 2905da2e6..941592732 100644 --- a/app/src/main/java/com/nextcloud/talk/repositories/conversations/ConversationsRepository.kt +++ b/app/src/main/java/com/nextcloud/talk/repositories/conversations/ConversationsRepository.kt @@ -34,4 +34,6 @@ interface ConversationsRepository { suspend fun archiveConversation(credentials: String, url: String): GenericOverall suspend fun unarchiveConversation(credentials: String, url: String): GenericOverall + + fun setConversationReadOnly(credentials: String, url: String, state: Int): Observable } diff --git a/app/src/main/java/com/nextcloud/talk/repositories/conversations/ConversationsRepositoryImpl.kt b/app/src/main/java/com/nextcloud/talk/repositories/conversations/ConversationsRepositoryImpl.kt index 3f0549612..458b97efe 100644 --- a/app/src/main/java/com/nextcloud/talk/repositories/conversations/ConversationsRepositoryImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/repositories/conversations/ConversationsRepositoryImpl.kt @@ -100,6 +100,10 @@ class ConversationsRepositoryImpl( return coroutineApi.unarchiveConversation(credentials, url) } + override fun setConversationReadOnly(credentials: String, url: String, state: Int): Observable { + return api.setConversationReadOnly(credentials, url, state) + } + private fun apiVersion(): Int { return ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.API_V4)) } diff --git a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt index 557c876fc..04ee69e5d 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt @@ -231,7 +231,7 @@ object ApiUtils { return getUrlForRoom(version, baseUrl, token) + "/password" } - fun getUrlForRoomReadOnlyState(version: Int, baseUrl: String?, token: String?): String { + fun getUrlForConversationReadOnly(version: Int, baseUrl: String?, token: String?): String { return getUrlForRoom(version, baseUrl, token) + "/read-only" } diff --git a/app/src/main/java/com/nextcloud/talk/utils/ConversationUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/ConversationUtils.kt index 08dbb8587..04345b3c8 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/ConversationUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/ConversationUtils.kt @@ -42,6 +42,14 @@ object ConversationUtils { !isNoteToSelfConversation(conversation) } + fun isConversationReadOnlyAvailable( + conversation: ConversationModel, + spreedCapabilities: SpreedCapability + ): Boolean { + return CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.READ_ONLY_ROOMS) && + canModerate(conversation, spreedCapabilities) + } + fun isLobbyViewApplicable(conversation: ConversationModel, spreedCapabilities: SpreedCapability): Boolean { return !canModerate(conversation, spreedCapabilities) && ( diff --git a/app/src/main/res/layout/activity_conversation_info.xml b/app/src/main/res/layout/activity_conversation_info.xml index ded8afea1..f1c830ca3 100644 --- a/app/src/main/res/layout/activity_conversation_info.xml +++ b/app/src/main/res/layout/activity_conversation_info.xml @@ -300,6 +300,51 @@ + + + + + + + + + + + + + Unread mentions Conversations Open conversations + Lock conversation There was a problem loading your chats Close Close Icon @@ -825,4 +826,5 @@ How to translate with transifex: Archived Once a conversation is archived, it will be hidden by default. Select the filter \'Archived\' to view archived conversations. Direct mentions will still be received. Once a conversation is unarchived, it will be shown by default again. + Failed to set conversation Read-only