瀏覽代碼

Merge pull request #4428 from nextcloud/lock_room

Lock room
Sowjanya Kota 5 月之前
父節點
當前提交
5ff1003154

+ 1 - 1
app/src/main/java/com/nextcloud/talk/api/NcApi.java

@@ -436,7 +436,7 @@ public interface NcApi {
 
     @FormUrlEncoded
     @PUT
-    Observable<GenericOverall> setReadOnlyState(@Header("Authorization") String authorization,
+    Observable<GenericOverall> setConversationReadOnly(@Header("Authorization") String authorization,
                                                 @Url String url,
                                                 @Field("state") int state);
 

+ 33 - 1
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

+ 31 - 0
app/src/main/java/com/nextcloud/talk/conversationinfo/viewmodel/ConversationInfoViewModel.kt

@@ -76,6 +76,13 @@ class ConversationInfoViewModel @Inject constructor(
     val getUnBanActorState: LiveData<ViewState>
         get() = _getUnBanActorState
 
+    object SetConversationReadOnlySuccessState : ViewState
+    object SetConversationReadOnlyErrorState : ViewState
+
+    private val _getConversationReadOnlyState: MutableLiveData<ViewState> = MutableLiveData()
+    val getConversationReadOnlyState: LiveData<ViewState>
+        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<GenericOverall> {
+                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)

+ 2 - 0
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<GenericOverall>
 }

+ 4 - 0
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<GenericOverall> {
+        return api.setConversationReadOnly(credentials, url, state)
+    }
+
     private fun apiVersion(): Int {
         return ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.API_V4))
     }

+ 1 - 1
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"
     }
 

+ 8 - 0
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) &&
             (

+ 45 - 0
app/src/main/res/layout/activity_conversation_info.xml

@@ -300,6 +300,51 @@
 
             </LinearLayout>
 
+            <LinearLayout
+                android:id="@+id/lock_conversation"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:paddingStart="@dimen/standard_margin"
+                android:paddingEnd="@dimen/standard_margin"
+                android:orientation="horizontal"
+                android:background="?android:attr/selectableItemBackground">
+
+                <LinearLayout
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:paddingTop="@dimen/standard_half_margin"
+                    android:paddingBottom="@dimen/standard_half_margin"
+                    android:layout_weight="1"
+                    android:orientation="horizontal">
+
+                    <ImageView
+                        android:layout_width="24dp"
+                        android:layout_height="40dp"
+                        android:layout_marginEnd="@dimen/standard_margin"
+                        android:contentDescription="@null"
+                        android:src="@drawable/ic_lock_white_24px"
+                        app:tint="@color/grey_600" />
+
+                    <com.google.android.material.textview.MaterialTextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="match_parent"
+                        android:gravity="center_vertical"
+                        android:text="@string/lock_conversation"
+                        android:textSize="@dimen/headline_text_size" />
+
+                </LinearLayout>
+
+                <com.google.android.material.materialswitch.MaterialSwitch
+                    android:id="@+id/lock_conversation_switch"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:layout_gravity="center_vertical"
+                    android:layout_marginStart="@dimen/standard_margin"
+                    android:layout_marginEnd="1dp"
+                    android:clickable="false"
+                    android:focusable="true" />
+            </LinearLayout>
+
             <LinearLayout
                 android:id="@+id/participants"
                 android:layout_width="match_parent"

+ 2 - 0
app/src/main/res/values/strings.xml

@@ -386,6 +386,7 @@ How to translate with transifex:
     <string name="nc_new_mention">Unread mentions</string>
     <string name="conversations">Conversations</string>
     <string name="openConversations">Open conversations</string>
+    <string name="lock_conversation">Lock conversation</string>
     <string name="error_loading_chats">There was a problem loading your chats</string>
     <string name="close">Close</string>
     <string name="close_icon">Close Icon</string>
@@ -825,4 +826,5 @@ How to translate with transifex:
     <string name="archived">Archived</string>
     <string name="archive_hint">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.</string>
     <string name="unarchive_hint">Once a conversation is unarchived, it will be shown by default again.</string>
+    <string name="conversation_read_only_failed">Failed to set conversation Read-only</string>
 </resources>