فهرست منبع

Merge pull request #4360 from nextcloud/last_moderator_should_delete_room

Last moderator should not leave the room
Marcel Hibbe 7 ماه پیش
والد
کامیت
f48c33d9b1

+ 43 - 10
app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt

@@ -27,7 +27,9 @@ import androidx.fragment.app.FragmentTransaction
 import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.lifecycleScope
 import androidx.work.Data
+import androidx.work.ExistingWorkPolicy
 import androidx.work.OneTimeWorkRequest
+import androidx.work.WorkInfo
 import androidx.work.WorkManager
 import autodagger.AutoInjector
 import com.afollestad.materialdialogs.LayoutMode.WRAP_CONTENT
@@ -635,17 +637,48 @@ class ConversationInfoActivity :
     }
 
     private fun leaveConversation() {
-        workerData?.let {
-            WorkManager.getInstance(context).enqueue(
-                OneTimeWorkRequest.Builder(
-                    LeaveConversationWorker::class
-                        .java
-                ).setInputData(it).build()
-            )
+        workerData?.let { data ->
+            val workRequest = OneTimeWorkRequest.Builder(LeaveConversationWorker::class.java)
+                .setInputData(data)
+                .build()
+
+            WorkManager.getInstance(context)
+                .enqueueUniqueWork(
+                    "leave_conversation_work",
+                    ExistingWorkPolicy.REPLACE,
+                    workRequest
+                )
 
-            val intent = Intent(context, MainActivity::class.java)
-            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
-            startActivity(intent)
+            WorkManager.getInstance(context).getWorkInfoByIdLiveData(workRequest.id)
+                .observe(this, { workInfo: WorkInfo? ->
+                    if (workInfo != null) {
+                        when (workInfo.state) {
+                            WorkInfo.State.SUCCEEDED -> {
+                                val intent = Intent(context, MainActivity::class.java)
+                                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) {
+                                    Snackbar.make(
+                                        binding.root,
+                                        R.string.nc_last_moderator_leaving_room_warning,
+                                        Snackbar.LENGTH_LONG
+                                    ).show()
+                                } else {
+                                    Snackbar.make(
+                                        binding.root,
+                                        R.string.nc_common_error_sorry,
+                                        Snackbar.LENGTH_LONG
+                                    ).show()
+                                }
+                            }
+                            else -> {
+                            }
+                        }
+                    }
+                })
         }
     }
 

+ 0 - 115
app/src/main/java/com/nextcloud/talk/jobs/LeaveConversationWorker.java

@@ -1,115 +0,0 @@
-/*
- * Nextcloud Talk - Android Client
- *
- * SPDX-FileCopyrightText: 2022 Andy Scherzinger <info@andy-scherzinger.de>
- * SPDX-FileCopyrightText: 2017-2018 Mario Danic <mario@lovelyhq.com>
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-package com.nextcloud.talk.jobs;
-
-import android.content.Context;
-import android.util.Log;
-
-import com.nextcloud.talk.api.NcApi;
-import com.nextcloud.talk.application.NextcloudTalkApplication;
-import com.nextcloud.talk.data.user.model.User;
-import com.nextcloud.talk.events.EventStatus;
-import com.nextcloud.talk.models.json.generic.GenericOverall;
-import com.nextcloud.talk.users.UserManager;
-import com.nextcloud.talk.utils.ApiUtils;
-import com.nextcloud.talk.utils.UserIdUtils;
-import com.nextcloud.talk.utils.bundle.BundleKeys;
-
-import org.greenrobot.eventbus.EventBus;
-
-import java.net.CookieManager;
-
-import javax.inject.Inject;
-
-import androidx.annotation.NonNull;
-import androidx.work.Data;
-import androidx.work.Worker;
-import androidx.work.WorkerParameters;
-import autodagger.AutoInjector;
-import io.reactivex.Observer;
-import io.reactivex.disposables.Disposable;
-import io.reactivex.schedulers.Schedulers;
-import okhttp3.JavaNetCookieJar;
-import okhttp3.OkHttpClient;
-import retrofit2.Retrofit;
-
-@AutoInjector(NextcloudTalkApplication.class)
-public class LeaveConversationWorker extends Worker {
-
-    private static final String TAG = "LeaveConversationWorker";
-
-    @Inject
-    Retrofit retrofit;
-
-    @Inject
-    OkHttpClient okHttpClient;
-
-    @Inject
-    UserManager userManager;
-
-    @Inject
-    EventBus eventBus;
-
-    NcApi ncApi;
-
-    public LeaveConversationWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
-        super(context, workerParams);
-        NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
-    }
-
-    @NonNull
-    @Override
-    public Result doWork() {
-        Data data = getInputData();
-        long operationUserId = data.getLong(BundleKeys.KEY_INTERNAL_USER_ID, -1);
-        String conversationToken = data.getString(BundleKeys.KEY_ROOM_TOKEN);
-        User operationUser = userManager.getUserWithId(operationUserId).blockingGet();
-
-        if (operationUser != null) {
-            String credentials = ApiUtils.getCredentials(operationUser.getUsername(), operationUser.getToken());
-            ncApi = retrofit.newBuilder().client(okHttpClient.newBuilder().cookieJar(new
-                    JavaNetCookieJar(new CookieManager())).build()).build().create(NcApi.class);
-
-            EventStatus eventStatus = new EventStatus(UserIdUtils.INSTANCE.getIdForUser(operationUser),
-                                                      EventStatus.EventType.CONVERSATION_UPDATE,
-                                                      true);
-
-            int apiVersion = ApiUtils.getConversationApiVersion(operationUser, new int[] {ApiUtils.API_V4, 1});
-
-            ncApi.removeSelfFromRoom(credentials, ApiUtils.getUrlForParticipantsSelf(apiVersion,
-                                                                                     operationUser.getBaseUrl(),
-                                                                                     conversationToken))
-                    .subscribeOn(Schedulers.io())
-                    .blockingSubscribe(new Observer<GenericOverall>() {
-                        Disposable disposable;
-
-                        @Override
-                        public void onSubscribe(Disposable d) {
-                            disposable = d;
-                        }
-
-                        @Override
-                        public void onNext(GenericOverall genericOverall) {
-                            eventBus.postSticky(eventStatus);
-                        }
-
-                        @Override
-                        public void onError(Throwable e) {
-                            Log.e(TAG, "failed to remove self from room", e);
-                        }
-
-                        @Override
-                        public void onComplete() {
-                            disposable.dispose();
-                        }
-                    });
-        }
-
-        return Result.success();
-    }
-}

+ 102 - 0
app/src/main/java/com/nextcloud/talk/jobs/LeaveConversationWorker.kt

@@ -0,0 +1,102 @@
+/*
+ * Nextcloud Talk - Android Client
+ *
+ * SPDX-FileCopyrightText: 2022 Andy Scherzinger <info@andy-scherzinger.de>
+ * SPDX-FileCopyrightText: 2017-2018 Mario Danic <mario@lovelyhq.com>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+package com.nextcloud.talk.jobs
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.util.Log
+import androidx.work.Data
+import androidx.work.ListenableWorker
+import androidx.work.WorkerParameters
+import androidx.work.impl.utils.futures.SettableFuture
+import autodagger.AutoInjector
+import com.google.common.util.concurrent.ListenableFuture
+import com.nextcloud.talk.api.NcApi
+import com.nextcloud.talk.application.NextcloudTalkApplication
+import com.nextcloud.talk.models.json.generic.GenericOverall
+import com.nextcloud.talk.users.UserManager
+import com.nextcloud.talk.utils.ApiUtils
+import com.nextcloud.talk.utils.ApiUtils.getConversationApiVersion
+import com.nextcloud.talk.utils.ApiUtils.getCredentials
+import com.nextcloud.talk.utils.ApiUtils.getUrlForParticipantsSelf
+import com.nextcloud.talk.utils.bundle.BundleKeys
+import io.reactivex.Observer
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.disposables.Disposable
+import io.reactivex.schedulers.Schedulers
+import retrofit2.HttpException
+import javax.inject.Inject
+
+@SuppressLint("RestrictedApi")
+@AutoInjector(NextcloudTalkApplication::class)
+class LeaveConversationWorker(context: Context, workerParams: WorkerParameters) :
+    ListenableWorker(context, workerParams) {
+
+    @Inject
+    lateinit var ncApi: NcApi
+
+    @Inject
+    lateinit var userManager: UserManager
+
+    private val result = SettableFuture.create<Result>()
+
+    override fun startWork(): ListenableFuture<Result> {
+        NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
+        val conversationToken = inputData.getString(BundleKeys.KEY_ROOM_TOKEN)
+        val currentUser = userManager.currentUser.blockingGet()
+
+        if (currentUser != null && conversationToken != null) {
+            val credentials = getCredentials(currentUser.username, currentUser.token)
+            val apiVersion = getConversationApiVersion(currentUser, intArrayOf(ApiUtils.API_V4, 1))
+
+            ncApi.removeSelfFromRoom(
+                credentials,
+                getUrlForParticipantsSelf(apiVersion, currentUser.baseUrl, conversationToken)
+            )
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(object : Observer<GenericOverall?> {
+                    override fun onSubscribe(d: Disposable) {
+                    }
+
+                    override fun onNext(p0: GenericOverall) {
+                    }
+
+                    override fun onError(e: Throwable) {
+                        Log.e(TAG, "Failed to remove self from room", e)
+                        val httpException = e as? HttpException
+                        val errorData = if (httpException?.code() == HTTP_ERROR_CODE_400) {
+                            Data.Builder()
+                                .putString("error_type", ERROR_NO_OTHER_MODERATORS_OR_OWNERS_LEFT)
+                                .build()
+                        } else {
+                            Data.Builder()
+                                .putString("error_type", ERROR_OTHER)
+                                .build()
+                        }
+                        result.set(Result.failure(errorData))
+                    }
+
+                    override fun onComplete() {
+                        result.set(Result.success())
+                    }
+                })
+        } else {
+            result.set(Result.failure())
+        }
+
+        return result
+    }
+
+    companion object {
+        private const val TAG = "LeaveConversationWorker"
+        const val ERROR_NO_OTHER_MODERATORS_OR_OWNERS_LEFT = "NO_OTHER_MODERATORS_OR_OWNERS_LEFT"
+        const val ERROR_OTHER = "ERROR_OTHER"
+        const val HTTP_ERROR_CODE_400 = 400
+    }
+}

+ 4 - 0
app/src/main/java/com/nextcloud/talk/ui/dialog/ConversationsListBottomDialog.kt

@@ -6,6 +6,7 @@
  */
 package com.nextcloud.talk.ui.dialog
 
+import android.content.Intent
 import android.os.Bundle
 import android.text.TextUtils
 import android.view.View
@@ -18,6 +19,7 @@ import autodagger.AutoInjector
 import com.google.android.material.bottomsheet.BottomSheetBehavior
 import com.google.android.material.bottomsheet.BottomSheetDialog
 import com.nextcloud.talk.R
+import com.nextcloud.talk.activities.MainActivity
 import com.nextcloud.talk.api.NcApi
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.conversation.RenameConversationDialogFragment
@@ -393,6 +395,8 @@ class ConversationsListBottomDialog(
                                     conversation.displayName
                                 )
                             )
+                            val intent = Intent(context, MainActivity::class.java)
+                            context.startActivity(intent)
                         }
 
                         WorkInfo.State.FAILED -> {

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

@@ -505,6 +505,7 @@ How to translate with transifex:
     <string name="nc_delete_message">Delete</string>
     <string name="nc_delete_message_leaked_to_matterbridge">Message deleted successfully, but it might have been leaked to other services</string>
     <string name="startCallForbidden">You are not allowed to start a call</string>
+    <string name="nc_last_moderator_leaving_room_warning">You need to promote a new moderator before you can leave the conversation</string>
 
     <string name="share">Share</string>
     <string name="send_to">Send to</string>