diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index 470960180fb..2637a278f17 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -58,6 +58,7 @@ import androidx.fragment.app.DialogFragment import androidx.recyclerview.widget.RecyclerView import androidx.work.Data import androidx.work.OneTimeWorkRequest +import androidx.work.WorkInfo import androidx.work.WorkManager import autodagger.AutoInjector import coil.imageLoader @@ -86,7 +87,6 @@ import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.databinding.ControllerConversationsRvBinding import com.nextcloud.talk.events.ConversationsListFetchDataEvent import com.nextcloud.talk.events.EventStatus -import com.nextcloud.talk.interfaces.ConversationMenuInterface import com.nextcloud.talk.jobs.AccountRemovalWorker import com.nextcloud.talk.jobs.ContactAddressBookWorker.Companion.run import com.nextcloud.talk.jobs.DeleteConversationWorker @@ -143,8 +143,7 @@ import javax.inject.Inject class ConversationsListActivity : BaseActivity(), FlexibleAdapter.OnItemClickListener, - FlexibleAdapter.OnItemLongClickListener, - ConversationMenuInterface { + FlexibleAdapter.OnItemLongClickListener { private lateinit var binding: ControllerConversationsRvBinding @@ -181,7 +180,6 @@ class ConversationsListActivity : private var credentials: String? = null private var adapterWasNull = true private var isRefreshing = false - private var conversationMenuBundle: Bundle? = null private var showShareToScreen = false private var filesToShare: ArrayList? = null private var selectedConversation: Conversation? = null @@ -1002,7 +1000,7 @@ class ConversationsListActivity : @SuppressLint("CheckResult") // handled by helper private fun loadMoreMessages() { - binding?.swipeRefreshLayoutView?.isRefreshing = true + binding.swipeRefreshLayoutView.isRefreshing = true val observable = searchHelper!!.loadMore() observable?.observeOn(AndroidSchedulers.mainThread()) ?.subscribe({ results: MessageSearchResults -> onMessageSearchResult(results) }) { throwable: Throwable -> @@ -1305,50 +1303,34 @@ class ConversationsListActivity : }, BOTTOM_SHEET_DELAY) } - override fun showDeleteConversationDialog(bundle: Bundle) { - conversationMenuBundle = bundle - if (conversationMenuBundle != null && - isInternalUserEqualsCurrentUser(currentUser, conversationMenuBundle) - ) { - binding?.floatingActionButton?.let { - val dialogBuilder = MaterialAlertDialogBuilder(it.context) - .setIcon( - viewThemeUtils.dialog - .colorMaterialAlertDialogIcon(context, R.drawable.ic_delete_black_24dp) - ) - .setTitle(R.string.nc_delete_call) - .setMessage(R.string.nc_delete_conversation_more) - .setPositiveButton(R.string.nc_delete) { _, _ -> - val data = Data.Builder() - data.putLong( - KEY_INTERNAL_USER_ID, - conversationMenuBundle!!.getLong(KEY_INTERNAL_USER_ID) - ) - data.putString(KEY_ROOM_TOKEN, bundle.getString(KEY_ROOM_TOKEN)) - conversationMenuBundle = null - deleteConversation(data.build()) - } - .setNegativeButton(R.string.nc_cancel) { _, _ -> - conversationMenuBundle = null - } - - viewThemeUtils.dialog - .colorMaterialAlertDialogBackground(it.context, dialogBuilder) - val dialog = dialogBuilder.show() - viewThemeUtils.platform.colorTextButtons( - dialog.getButton(AlertDialog.BUTTON_POSITIVE), - dialog.getButton(AlertDialog.BUTTON_NEGATIVE) + fun showDeleteConversationDialog(conversation: Conversation) { + binding.floatingActionButton.let { + val dialogBuilder = MaterialAlertDialogBuilder(it.context) + .setIcon( + viewThemeUtils.dialog + .colorMaterialAlertDialogIcon(context, R.drawable.ic_delete_black_24dp) ) - } - } - } + .setTitle(R.string.nc_delete_call) + .setMessage(R.string.nc_delete_conversation_more) + .setPositiveButton(R.string.nc_delete) { _, _ -> + deleteConversation(conversation) + } + .setNegativeButton(R.string.nc_cancel) { _, _ -> + + } - private fun isInternalUserEqualsCurrentUser(currentUser: User?, conversationMenuBundle: Bundle?): Boolean { - return currentUser != null && conversationMenuBundle!!.getLong(KEY_INTERNAL_USER_ID) == currentUser.id + viewThemeUtils.dialog + .colorMaterialAlertDialogBackground(it.context, dialogBuilder) + val dialog = dialogBuilder.show() + viewThemeUtils.platform.colorTextButtons( + dialog.getButton(AlertDialog.BUTTON_POSITIVE), + dialog.getButton(AlertDialog.BUTTON_NEGATIVE) + ) + } } private fun showUnauthorizedDialog() { - binding?.floatingActionButton?.let { + binding.floatingActionButton.let { val dialogBuilder = MaterialAlertDialogBuilder(it.context) .setIcon( viewThemeUtils.dialog.colorMaterialAlertDialogIcon( @@ -1520,10 +1502,39 @@ class ConversationsListActivity : Runtime.getRuntime().exit(0) } - private fun deleteConversation(data: Data) { + private fun deleteConversation(conversation: Conversation) { + val data = Data.Builder() + data.putLong( + KEY_INTERNAL_USER_ID, + currentUser?.id!! + ) + data.putString(KEY_ROOM_TOKEN, conversation.token) + val deleteConversationWorker = - OneTimeWorkRequest.Builder(DeleteConversationWorker::class.java).setInputData(data).build() + OneTimeWorkRequest.Builder(DeleteConversationWorker::class.java).setInputData(data.build()).build() WorkManager.getInstance().enqueue(deleteConversationWorker) + + WorkManager.getInstance(context).getWorkInfoByIdLiveData(deleteConversationWorker.id) + .observeForever { workInfo: WorkInfo? -> + if (workInfo != null) { + when (workInfo.state) { + WorkInfo.State.SUCCEEDED -> { + showSnackbar( + String.format( + context.resources.getString(R.string.deleted_conversation), + conversation.displayName + )) + } + + WorkInfo.State.FAILED -> { + showSnackbar(context.resources.getString(R.string.nc_common_error_sorry)) + } + + else -> { + } + } + } + } } private fun onMessageSearchResult(results: MessageSearchResults) { diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/ConversationsListBottomDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/ConversationsListBottomDialog.kt index a29baca692f..f05b915b69c 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/ConversationsListBottomDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/ConversationsListBottomDialog.kt @@ -26,6 +26,7 @@ import android.view.View import android.view.ViewGroup import androidx.work.Data import androidx.work.OneTimeWorkRequest +import androidx.work.WorkInfo import androidx.work.WorkManager import autodagger.AutoInjector import com.google.android.material.bottomsheet.BottomSheetBehavior @@ -88,6 +89,13 @@ class ConversationsListBottomDialog( credentials = ApiUtils.getCredentials(currentUser.username, currentUser.token) } + override fun onStart() { + super.onStart() + val bottomSheet = findViewById(R.id.design_bottom_sheet) + val behavior = BottomSheetBehavior.from(bottomSheet as View) + behavior.state = BottomSheetBehavior.STATE_COLLAPSED + } + private fun initHeaderDescription() { if (!TextUtils.isEmpty(conversation.displayName)) { binding.conversationOperationHeader.text = conversation.displayName @@ -100,18 +108,18 @@ class ConversationsListBottomDialog( val hasFavoritesCapability = CapabilitiesUtilNew.hasSpreedFeatureCapability(currentUser, "favorites") val canModerate = conversation.canModerate(currentUser) - binding.conversationOperationRemoveFavorite.visibility = setVisibleIf( + binding.conversationRemoveFromFavorites.visibility = setVisibleIf( hasFavoritesCapability && conversation.favorite ) - binding.conversationOperationAddFavorite.visibility = setVisibleIf( + binding.conversationAddToFavorites.visibility = setVisibleIf( hasFavoritesCapability && !conversation.favorite ) - binding.conversationOperationMarkAsRead.visibility = setVisibleIf( + binding.conversationMarkAsRead.visibility = setVisibleIf( conversation.unreadMessages > 0 && CapabilitiesUtilNew.canSetChatReadMarker(currentUser) ) - binding.conversationOperationMarkAsUnread.visibility = setVisibleIf( + binding.conversationMarkAsUnread.visibility = setVisibleIf( conversation.unreadMessages <= 0 && CapabilitiesUtilNew.canMarkRoomAsUnread(currentUser) ) @@ -140,198 +148,252 @@ class ConversationsListBottomDialog( } private fun initClickListeners() { - binding.conversationOperationAddFavorite.setOnClickListener { - val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv1)) - ncApi.addConversationToFavorites( - credentials, - ApiUtils.getUrlForRoomFavorite( - apiVersion, - currentUser!!.baseUrl, - conversation!!.token - ) - ) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .retry(1) - .subscribe(object : Observer { - override fun onSubscribe(d: Disposable) { - // unused atm - } - - override fun onNext(genericOverall: GenericOverall) { - activity.fetchRooms() - activity.showSnackbar("added to favorite") - dismiss() - } - - override fun onError(e: Throwable) { - activity.showSnackbar("failed to add to favorite") - dismiss() - } - - override fun onComplete() { - // unused atm - } - }) - + binding.conversationAddToFavorites.setOnClickListener { + addConversationToFavorites() } - binding.conversationOperationRemoveFavorite.setOnClickListener { - val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv1)) - ncApi.removeConversationFromFavorites( - credentials, - ApiUtils.getUrlForRoomFavorite( - apiVersion, - currentUser.baseUrl, - conversation.token - ) - ) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .retry(1) - .subscribe(object : Observer { - override fun onSubscribe(d: Disposable) { - // unused atm - } + binding.conversationRemoveFromFavorites.setOnClickListener { + removeConversationFromFavorites() + } - override fun onNext(genericOverall: GenericOverall) { - activity.fetchRooms() - activity.showSnackbar("removed from favorite") - dismiss() - } + binding.conversationMarkAsRead.setOnClickListener { + markConversationAsRead() + } - override fun onError(e: Throwable) { - activity.showSnackbar("failed to remove from favorite") - dismiss() - } + binding.conversationMarkAsUnread.setOnClickListener { + markConversationAsUnread() + } - override fun onComplete() { - // unused atm - } - }) + binding.conversationOperationRename.setOnClickListener { + renameConversation() } binding.conversationOperationLeave.setOnClickListener { - val dataBuilder = Data.Builder() - dataBuilder.putString(KEY_ROOM_TOKEN, conversation.token) - dataBuilder.putLong(KEY_INTERNAL_USER_ID, currentUser.id!!) - val data = dataBuilder.build() - - val leaveConversationWorker = - OneTimeWorkRequest.Builder(LeaveConversationWorker::class.java).setInputData( - data - ).build() - WorkManager.getInstance().enqueue(leaveConversationWorker) - - dismiss() + leaveConversation() } binding.conversationOperationDelete.setOnClickListener { - if (!TextUtils.isEmpty(conversation.token)) { - val bundle = Bundle() - bundle.putLong(KEY_INTERNAL_USER_ID, currentUser.id!!) - bundle.putString(KEY_ROOM_TOKEN, conversation.token) - activity.showDeleteConversationDialog(bundle) - } - - dismiss() - } - - binding.conversationOperationRename.setOnClickListener { - if (!TextUtils.isEmpty(conversation.token)) { - dismiss() - val conversationDialog = RenameConversationDialogFragment.newInstance( - conversation.token!!, - conversation.displayName!! - ) - conversationDialog.show( - activity.supportFragmentManager, - TAG - ) - } + deleteConversation() } + } - binding.conversationOperationMarkAsRead.setOnClickListener { - ncApi.setChatReadMarker( - credentials, - ApiUtils.getUrlForChatReadMarker( - chatApiVersion(), - currentUser.baseUrl, - conversation.token - ), - conversation.lastMessage!!.jsonMessageId + private fun addConversationToFavorites() { + val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv1)) + ncApi.addConversationToFavorites( + credentials, + ApiUtils.getUrlForRoomFavorite( + apiVersion, + currentUser.baseUrl, + conversation.token ) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .retry(1) - .subscribe(object : Observer { - override fun onSubscribe(d: Disposable) { - // unused atm - } + ) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .retry(1) + .subscribe(object : Observer { + override fun onSubscribe(d: Disposable) { + // unused atm + } + + override fun onNext(genericOverall: GenericOverall) { + activity.fetchRooms() + activity.showSnackbar( + String.format( + context.resources.getString(R.string.added_to_favorites), + conversation.displayName + )) + dismiss() + } + + override fun onError(e: Throwable) { + activity.showSnackbar(context.resources.getString(R.string.nc_common_error_sorry)) + dismiss() + } + + override fun onComplete() { + // unused atm + } + }) + } - override fun onNext(genericOverall: GenericOverall) { - activity.fetchRooms() - activity.showSnackbar("marked as read") - dismiss() - } + private fun removeConversationFromFavorites() { + val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv1)) + ncApi.removeConversationFromFavorites( + credentials, + ApiUtils.getUrlForRoomFavorite( + apiVersion, + currentUser.baseUrl, + conversation.token + ) + ) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .retry(1) + .subscribe(object : Observer { + override fun onSubscribe(d: Disposable) { + // unused atm + } + + override fun onNext(genericOverall: GenericOverall) { + activity.fetchRooms() + activity.showSnackbar( + String.format( + context.resources.getString(R.string.removed_from_favorites), + conversation.displayName + )) + dismiss() + } + + override fun onError(e: Throwable) { + activity.showSnackbar(context.resources.getString(R.string.nc_common_error_sorry)) + dismiss() + } + + override fun onComplete() { + // unused atm + } + }) + } - override fun onError(e: Throwable) { - activity.showSnackbar("failed to mark as read") - dismiss() - } + private fun markConversationAsUnread() { + ncApi.markRoomAsUnread( + credentials, + ApiUtils.getUrlForChatReadMarker( + chatApiVersion(), + currentUser.baseUrl, + conversation.token + ) + ) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .retry(1) + .subscribe(object : Observer { + override fun onSubscribe(d: Disposable) { + // unused atm + } + + override fun onNext(genericOverall: GenericOverall) { + activity.fetchRooms() + activity.showSnackbar( + String.format( + context.resources.getString(R.string.marked_as_unread), + conversation.displayName + )) + dismiss() + } + + override fun onError(e: Throwable) { + activity.showSnackbar(context.resources.getString(R.string.nc_common_error_sorry)) + dismiss() + } + + override fun onComplete() { + // unused atm + } + }) + } - override fun onComplete() { - // unused atm - } - }) - } + private fun markConversationAsRead() { + ncApi.setChatReadMarker( + credentials, + ApiUtils.getUrlForChatReadMarker( + chatApiVersion(), + currentUser.baseUrl, + conversation.token + ), + conversation.lastMessage!!.jsonMessageId + ) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .retry(1) + .subscribe(object : Observer { + override fun onSubscribe(d: Disposable) { + // unused atm + } + + override fun onNext(genericOverall: GenericOverall) { + activity.fetchRooms() + activity.showSnackbar( + String.format( + context.resources.getString(R.string.marked_as_read), + conversation.displayName + )) + dismiss() + } + + override fun onError(e: Throwable) { + activity.showSnackbar(context.resources.getString(R.string.nc_common_error_sorry)) + dismiss() + } + + override fun onComplete() { + // unused atm + } + }) + } - binding.conversationOperationMarkAsUnread.setOnClickListener { - ncApi.markRoomAsUnread( - credentials, - ApiUtils.getUrlForChatReadMarker( - chatApiVersion(), - currentUser.baseUrl, - conversation.token - ) + private fun renameConversation() { + if (!TextUtils.isEmpty(conversation.token)) { + dismiss() + val conversationDialog = RenameConversationDialogFragment.newInstance( + conversation.token!!, + conversation.displayName!! ) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .retry(1) - .subscribe(object : Observer { - override fun onSubscribe(d: Disposable) { - // unused atm - } - - override fun onNext(genericOverall: GenericOverall) { - activity.fetchRooms() - activity.showSnackbar("marked as unread") - dismiss() + conversationDialog.show( + activity.supportFragmentManager, + TAG + ) + } + } + private fun leaveConversation() { + val dataBuilder = Data.Builder() + dataBuilder.putString(KEY_ROOM_TOKEN, conversation.token) + dataBuilder.putLong(KEY_INTERNAL_USER_ID, currentUser.id!!) + val data = dataBuilder.build() + + val leaveConversationWorker = + OneTimeWorkRequest.Builder(LeaveConversationWorker::class.java).setInputData( + data + ).build() + WorkManager.getInstance().enqueue(leaveConversationWorker) + + WorkManager.getInstance(context).getWorkInfoByIdLiveData(leaveConversationWorker.id) + .observeForever { workInfo: WorkInfo? -> + if (workInfo != null) { + when (workInfo.state) { + WorkInfo.State.SUCCEEDED -> { + activity.showSnackbar( + String.format( + context.resources.getString(R.string.left_conversation), + conversation.displayName + )) + } + + WorkInfo.State.FAILED -> { + activity.showSnackbar(context.resources.getString(R.string.nc_common_error_sorry)) + } + + else -> { + } } + } + } - override fun onError(e: Throwable) { - activity.showSnackbar("failed to mark as unread") - dismiss() - } + dismiss() + } - override fun onComplete() { - // unused atm - } - }) + private fun deleteConversation() { + if (!TextUtils.isEmpty(conversation.token)) { + activity.showDeleteConversationDialog(conversation) } + + dismiss() } private fun chatApiVersion(): Int { return ApiUtils.getChatApiVersion(currentUser, intArrayOf(ApiUtils.APIv1)) } - override fun onStart() { - super.onStart() - val bottomSheet = findViewById(R.id.design_bottom_sheet) - val behavior = BottomSheetBehavior.from(bottomSheet as View) - behavior.state = BottomSheetBehavior.STATE_COLLAPSED - } - companion object { val TAG = ConversationsListBottomDialog::class.simpleName } diff --git a/app/src/main/res/layout/dialog_conversation_operations.xml b/app/src/main/res/layout/dialog_conversation_operations.xml index 7e05f329fac..65df06d174a 100644 --- a/app/src/main/res/layout/dialog_conversation_operations.xml +++ b/app/src/main/res/layout/dialog_conversation_operations.xml @@ -47,7 +47,7 @@ tools:text="conversation name" /> Calendar Error 429 Too Many Requests + Added conversation %1$s to favorites + Removed conversation %1$s from favorites + Marked conversation %1$s as unread + Marked conversation %1$s as read + Deleted conversation %1$s + You left the conversation %1$s +