fix to leave room before loading new one

-> add callback methods to ConductorRemapping to execute after chat room was left. Whenever there is a ChatController on top, it's room is now left, before replacing the controller or pushing another one on top.

this avoids problems where entering a chat before the old one was left led to sessionId="0" for the new chat.

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2022-12-12 16:48:24 +01:00
parent c708104cbe
commit 7745e75f5f
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
7 changed files with 94 additions and 86 deletions

View File

@ -50,13 +50,13 @@ import com.nextcloud.talk.databinding.ActivityMainBinding
import com.nextcloud.talk.models.json.conversations.RoomOverall import com.nextcloud.talk.models.json.conversations.RoomOverall
import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.ConductorRemapping.remapChatController
import com.nextcloud.talk.utils.SecurityUtils import com.nextcloud.talk.utils.SecurityUtils
import com.nextcloud.talk.utils.bundle.BundleKeys import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ACTIVE_CONVERSATION import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ACTIVE_CONVERSATION
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
import com.nextcloud.talk.utils.remapchat.ConductorRemapping.remapChatController
import io.reactivex.Observer import io.reactivex.Observer
import io.reactivex.SingleObserver import io.reactivex.SingleObserver
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers

View File

@ -96,7 +96,6 @@ import coil.load
import coil.request.ImageRequest import coil.request.ImageRequest
import coil.target.Target import coil.target.Target
import coil.transform.CircleCropTransformation import coil.transform.CircleCropTransformation
import com.bluelinelabs.conductor.Router
import com.bluelinelabs.conductor.RouterTransaction import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler
import com.google.android.flexbox.FlexboxLayout import com.google.android.flexbox.FlexboxLayout
@ -162,8 +161,6 @@ import com.nextcloud.talk.ui.dialog.ShowReactionsDialog
import com.nextcloud.talk.ui.recyclerview.MessageSwipeActions import com.nextcloud.talk.ui.recyclerview.MessageSwipeActions
import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.ConductorRemapping
import com.nextcloud.talk.utils.ConductorRemapping.remapChatController
import com.nextcloud.talk.utils.ContactUtils import com.nextcloud.talk.utils.ContactUtils
import com.nextcloud.talk.utils.DateConstants import com.nextcloud.talk.utils.DateConstants
import com.nextcloud.talk.utils.DateUtils import com.nextcloud.talk.utils.DateUtils
@ -182,6 +179,8 @@ import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil
import com.nextcloud.talk.utils.remapchat.ConductorRemapping
import com.nextcloud.talk.utils.remapchat.RemapChatModel
import com.nextcloud.talk.utils.rx.DisposableSet import com.nextcloud.talk.utils.rx.DisposableSet
import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder
import com.nextcloud.talk.utils.text.Spans import com.nextcloud.talk.utils.text.Spans
@ -1850,18 +1849,11 @@ class ChatController(args: Bundle) :
if (conversationUser != null && isActivityNotChangingConfigurations() && isNotInCall()) { if (conversationUser != null && isActivityNotChangingConfigurations() && isNotInCall()) {
ApplicationWideCurrentRoomHolder.getInstance().clear() ApplicationWideCurrentRoomHolder.getInstance().clear()
// sessionId is sometimes 0 here! this causes that leaveRoom is not executed and callbacks continue to
// live which causes bugs!!!
if (inConversation && validSessionId()) { if (inConversation && validSessionId()) {
leaveRoom() leaveRoom(null, null)
} else { } else {
Log.e(TAG, "not leaving room (inConversation is false and/or validSessionId is false)") Log.d(TAG, "not leaving room (inConversation is false and/or validSessionId is false)")
if (BuildConfig.DEBUG) { // room might have already been left...
Toast.makeText(
context, "not leaving room (inConversation is false and/or validSessionId is false)",
Toast.LENGTH_LONG
).show()
}
} }
} else { } else {
Log.e(TAG, "not leaving room...") Log.e(TAG, "not leaving room...")
@ -1908,7 +1900,7 @@ class ChatController(args: Bundle) :
currentlyPlayedVoiceMessage?.let { stopMediaPlayer(it) } currentlyPlayedVoiceMessage?.let { stopMediaPlayer(it) }
adapter = null adapter = null
inConversation = false // move to onDetach?? inConversation = false
Log.d(TAG, "inConversation was set to false!") Log.d(TAG, "inConversation was set to false!")
} }
@ -2005,33 +1997,9 @@ class ChatController(args: Bundle) :
} }
} }
private fun leaveRoom() { fun leaveRoom(
leaveRoom( remapChatModel: RemapChatModel?,
null, funToCallWhenLeaveSuccessful: ((RemapChatModel) -> Unit)?
null,
null,
null,
null,
null,
)
}
private fun leaveRoom(
router: Router?,
internalUserId: Long?,
roomTokenOrId: String?,
bundle: Bundle?,
replaceTop: Boolean?,
remapChatController:
(
(
router: Router,
internalUserId: Long,
roomTokenOrId: String,
bundle: Bundle,
replaceTop: Boolean
) -> Unit
)?
) { ) {
logConversationInfos("leaveRoom") logConversationInfos("leaveRoom")
@ -2086,15 +2054,9 @@ class ChatController(args: Bundle) :
currentConversation?.sessionId = "0" currentConversation?.sessionId = "0"
if (remapChatController != null) { if (remapChatModel != null && funToCallWhenLeaveSuccessful != null) {
Log.d(TAG, "remapChatController was set and is now executed after room was already left") Log.d(TAG, "a callback action was set and is now executed because room was left successfully")
remapChatController( funToCallWhenLeaveSuccessful(remapChatModel)
router!!,
internalUserId!!,
roomTokenOrId!!,
bundle!!,
replaceTop!!,
)
} else { } else {
Log.d(TAG, "remapChatController was not set") Log.d(TAG, "remapChatController was not set")
} }
@ -3069,7 +3031,8 @@ class ChatController(args: Bundle) :
KEY_ACTIVE_CONVERSATION, KEY_ACTIVE_CONVERSATION,
Parcels.wrap(roomOverall.ocs!!.data!!) Parcels.wrap(roomOverall.ocs!!.data!!)
) )
remapChatController(
ConductorRemapping.remapChatController(
router, router,
conversationUser!!.id!!, conversationUser!!.id!!,
roomOverall.ocs!!.data!!.token!!, roomOverall.ocs!!.data!!.token!!,
@ -3394,13 +3357,12 @@ class ChatController(args: Bundle) :
) )
conversationIntent.putExtras(bundle) conversationIntent.putExtras(bundle)
leaveRoom( ConductorRemapping.remapChatController(
router, router,
conversationUser.id!!, conversationUser.id!!,
roomOverall.ocs!!.data!!.token!!, roomOverall.ocs!!.data!!.token!!,
bundle, bundle,
false, true
ConductorRemapping::remapChatController
) )
} else { } else {
conversationIntent.putExtras(bundle) conversationIntent.putExtras(bundle)

View File

@ -66,9 +66,9 @@ import com.nextcloud.talk.models.json.participants.Participant
import com.nextcloud.talk.ui.dialog.ContactsBottomDialog import com.nextcloud.talk.ui.dialog.ContactsBottomDialog
import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.ConductorRemapping
import com.nextcloud.talk.utils.bundle.BundleKeys import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
import com.nextcloud.talk.utils.remapchat.ConductorRemapping
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.SelectableAdapter import eu.davidea.flexibleadapter.SelectableAdapter
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
@ -285,8 +285,11 @@ class ContactsController(args: Bundle) :
Parcels.wrap(roomOverall.ocs!!.data!!) Parcels.wrap(roomOverall.ocs!!.data!!)
) )
ConductorRemapping.remapChatController( ConductorRemapping.remapChatController(
router, currentUser!!.id!!, router,
roomOverall.ocs!!.data!!.token!!, bundle, true currentUser!!.id!!,
roomOverall.ocs!!.data!!.token!!,
bundle,
true
) )
} }
@ -738,9 +741,11 @@ class ContactsController(args: Bundle) :
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(openConversationEvent: OpenConversationEvent) { fun onMessageEvent(openConversationEvent: OpenConversationEvent) {
ConductorRemapping.remapChatController( ConductorRemapping.remapChatController(
router, currentUser!!.id!!, router,
currentUser!!.id!!,
openConversationEvent.conversation!!.token!!, openConversationEvent.conversation!!.token!!,
openConversationEvent.bundle!!, true openConversationEvent.bundle!!,
true
) )
contactsBottomDialog?.dismiss() contactsBottomDialog?.dismiss()
} }

View File

@ -99,7 +99,6 @@ import com.nextcloud.talk.ui.dialog.ConversationsListBottomDialog
import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.ClosedInterfaceImpl import com.nextcloud.talk.utils.ClosedInterfaceImpl
import com.nextcloud.talk.utils.ConductorRemapping.remapChatController
import com.nextcloud.talk.utils.FileUtils import com.nextcloud.talk.utils.FileUtils
import com.nextcloud.talk.utils.Mimetype import com.nextcloud.talk.utils.Mimetype
import com.nextcloud.talk.utils.ParticipantPermissions import com.nextcloud.talk.utils.ParticipantPermissions
@ -119,6 +118,7 @@ import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.hasSpreedFeatu
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.isServerEOL import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.isServerEOL
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.isUnifiedSearchAvailable import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.isUnifiedSearchAvailable
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.isUserStatusAvailable import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.isUserStatusAvailable
import com.nextcloud.talk.utils.remapchat.ConductorRemapping.remapChatController
import com.nextcloud.talk.utils.rx.SearchViewObservable.Companion.observeSearchView import com.nextcloud.talk.utils.rx.SearchViewObservable.Companion.observeSearchView
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager

View File

@ -41,8 +41,8 @@ import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet.AllowedAppIds.EMAIL
import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet.AllowedAppIds.PROFILE import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet.AllowedAppIds.PROFILE
import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet.AllowedAppIds.SPREED import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet.AllowedAppIds.SPREED
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.ConductorRemapping
import com.nextcloud.talk.utils.bundle.BundleKeys import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.remapchat.ConductorRemapping
import io.reactivex.Observer import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable

View File

@ -18,7 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.nextcloud.talk.utils package com.nextcloud.talk.utils.remapchat
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
@ -62,34 +62,43 @@ object ConductorRemapping {
} else { } else {
HorizontalChangeHandler() HorizontalChangeHandler()
} }
if (!replaceTop) {
if (!router.hasRootController()) { if (router.hasRootController()) {
Log.d(TAG, "router has no RootController. creating backstack with ConversationsListController") val backstack = router.backstack
val newBackstack = listOf( val topController = backstack[router.backstackSize - 1].controller
RouterTransaction.with(ConversationsListController(Bundle()))
.pushChangeHandler(HorizontalChangeHandler()) val remapChatModel = RemapChatModel(
.popChangeHandler(HorizontalChangeHandler()), router,
RouterTransaction.with(ChatController(bundle)) pushChangeHandler,
.pushChangeHandler(HorizontalChangeHandler()) chatControllerTag,
.popChangeHandler(HorizontalChangeHandler()).tag(chatControllerTag) bundle
) )
router.setBackstack(newBackstack, SimpleSwapChangeHandler())
if (topController is ChatController) {
if (replaceTop) {
topController.leaveRoom(remapChatModel, this::replaceTopController)
} else {
topController.leaveRoom(remapChatModel, this::pushController)
}
} else { } else {
Log.d(TAG, "router has RootController. pushing ChatController") if (replaceTop) {
router.pushController( replaceTopController(remapChatModel)
RouterTransaction.with(ChatController(bundle)) } else {
.pushChangeHandler(pushChangeHandler) pushController(remapChatModel)
.popChangeHandler(HorizontalChangeHandler()).tag(chatControllerTag) }
)
} }
} else { } else {
Log.d(TAG, "ChatController replace topController") Log.d(TAG, "router has no RootController. creating backstack with ConversationsListController")
val newBackstack = listOf(
router.replaceTopController( RouterTransaction.with(ConversationsListController(Bundle()))
.pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler()),
RouterTransaction.with(ChatController(bundle)) RouterTransaction.with(ChatController(bundle))
.pushChangeHandler(pushChangeHandler) .pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler()).tag(chatControllerTag) .popChangeHandler(HorizontalChangeHandler())
.tag(chatControllerTag)
) )
router.setBackstack(newBackstack, SimpleSwapChangeHandler())
} }
} }
@ -98,6 +107,26 @@ object ConductorRemapping {
} }
} }
fun pushController(remapChatModel: RemapChatModel) {
Log.d(TAG, "pushController")
remapChatModel.router.pushController(
RouterTransaction.with(ChatController(remapChatModel.bundle))
.pushChangeHandler(remapChatModel.controllerChangeHandler)
.popChangeHandler(HorizontalChangeHandler())
.tag(remapChatModel.chatControllerTag)
)
}
private fun replaceTopController(remapChatModel: RemapChatModel) {
Log.d(TAG, "replaceTopController")
remapChatModel.router.replaceTopController(
RouterTransaction.with(ChatController(remapChatModel.bundle))
.pushChangeHandler(remapChatModel.controllerChangeHandler)
.popChangeHandler(HorizontalChangeHandler())
.tag(remapChatModel.chatControllerTag)
)
}
private fun moveControllerToTop(router: Router, controllerTag: String) { private fun moveControllerToTop(router: Router, controllerTag: String) {
Log.d(TAG, "moving $controllerTag to top...") Log.d(TAG, "moving $controllerTag to top...")
val backstack = router.backstack val backstack = router.backstack

View File

@ -0,0 +1,12 @@
package com.nextcloud.talk.utils.remapchat
import android.os.Bundle
import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.Router
data class RemapChatModel(
val router: Router,
val controllerChangeHandler: ControllerChangeHandler,
val chatControllerTag: String,
val bundle: Bundle
)