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

[stable-20.0] Last moderator should not leave the room #4419

Merged
merged 11 commits into from
Nov 5, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.ViewModelProvider
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
Expand Down Expand Up @@ -632,17 +634,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 -> {
}
}
}
})
}
}

Expand Down
115 changes: 0 additions & 115 deletions app/src/main/java/com/nextcloud/talk/jobs/LeaveConversationWorker.java

This file was deleted.

102 changes: 102 additions & 0 deletions app/src/main/java/com/nextcloud/talk/jobs/LeaveConversationWorker.kt
Original file line number Diff line number Diff line change
@@ -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
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -393,6 +395,8 @@ class ConversationsListBottomDialog(
conversation.displayName
)
)
val intent = Intent(context, MainActivity::class.java)
context.startActivity(intent)
}

WorkInfo.State.FAILED -> {
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,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>
Expand Down
Loading