ChatController: fix crash when opening conversation from notification

This happens because there is no Conversation object available in the Controller when coming from a notification.

This patch means that when opening a notification for a poll, it will always look like the user is not the owner of the poll even if they are.
This is unfortunately difficult to fix as the initialization logic for ChatController is all kinds of messed up: ideally we'd always load the Conversation object before showing any kind of UI but that's too big of a change to do without tests.

Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
This commit is contained in:
Álvaro Brey 2022-08-10 13:10:30 +02:00
parent 228952d85c
commit cdc818b720
No known key found for this signature in database
GPG Key ID: 2585783189A62105
4 changed files with 43 additions and 33 deletions

View File

@ -112,8 +112,8 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) : MessageH
if (pollId != null && pollName != null) { if (pollId != null && pollName != null) {
binding.messagePollTitle.text = pollName binding.messagePollTitle.text = pollName
val roomToken = (payload as? MessagePayload)!!.currentConversation.token!! val roomToken = (payload as? MessagePayload)!!.roomToken
val isOwnerOrModerator = (payload as? MessagePayload)!!.currentConversation.isParticipantOwnerOrModerator val isOwnerOrModerator = (payload as? MessagePayload)!!.isOwnerOrModerator ?: false
binding.bubble.setOnClickListener { binding.bubble.setOnClickListener {
val pollVoteDialog = PollMainDialogFragment.newInstance( val pollVoteDialog = PollMainDialogFragment.newInstance(
@ -199,7 +199,8 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) : MessageH
val bubbleDrawable = DisplayUtils.getMessageSelector( val bubbleDrawable = DisplayUtils.getMessageSelector(
bgBubbleColor, bgBubbleColor,
ResourcesCompat.getColor(resources, R.color.transparent, null), ResourcesCompat.getColor(resources, R.color.transparent, null),
bgBubbleColor, bubbleResource bgBubbleColor,
bubbleResource
) )
ViewCompat.setBackground(bubble, bubbleDrawable) ViewCompat.setBackground(bubble, bubbleDrawable)
} }

View File

@ -20,10 +20,10 @@
package com.nextcloud.talk.adapters.messages package com.nextcloud.talk.adapters.messages
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet
data class MessagePayload( data class MessagePayload(
var currentConversation: Conversation, var roomToken: String,
val isOwnerOrModerator: Boolean?,
val profileBottomSheet: ProfileBottomSheet val profileBottomSheet: ProfileBottomSheet
) )

View File

@ -128,8 +128,8 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag
if (pollId != null && pollName != null) { if (pollId != null && pollName != null) {
binding.messagePollTitle.text = pollName binding.messagePollTitle.text = pollName
val roomToken = (payload as? MessagePayload)!!.currentConversation.token!! val roomToken = (payload as? MessagePayload)!!.roomToken
val isOwnerOrModerator = (payload as? MessagePayload)!!.currentConversation.isParticipantOwnerOrModerator val isOwnerOrModerator = (payload as? MessagePayload)!!.isOwnerOrModerator ?: false
binding.bubble.setOnClickListener { binding.bubble.setOnClickListener {
val pollVoteDialog = PollMainDialogFragment.newInstance( val pollVoteDialog = PollMainDialogFragment.newInstance(

View File

@ -430,11 +430,11 @@ class ChatController(args: Bundle) :
private fun loadAvatarForStatusBar() { private fun loadAvatarForStatusBar() {
if (inOneToOneCall() && activity != null) { if (inOneToOneCall() && activity != null) {
val imageRequest = DisplayUtils.getImageRequestForUrl( val imageRequest = DisplayUtils.getImageRequestForUrl(
ApiUtils.getUrlForAvatar( ApiUtils.getUrlForAvatar(
conversationUser?.baseUrl, conversationUser?.baseUrl,
currentConversation?.name, true currentConversation?.name,
true
), ),
conversationUser!! conversationUser!!
) )
@ -446,7 +446,6 @@ class ChatController(args: Bundle) :
object : BaseBitmapDataSubscriber() { object : BaseBitmapDataSubscriber() {
override fun onNewResultImpl(bitmap: Bitmap?) { override fun onNewResultImpl(bitmap: Bitmap?) {
if (actionBar != null && bitmap != null && resources != null) { if (actionBar != null && bitmap != null && resources != null) {
val avatarSize = (actionBar?.height!! / TOOLBAR_AVATAR_RATIO).roundToInt() val avatarSize = (actionBar?.height!! / TOOLBAR_AVATAR_RATIO).roundToInt()
if (avatarSize > 0) { if (avatarSize > 0) {
val bitmapResized = Bitmap.createScaledBitmap(bitmap, avatarSize, avatarSize, false) val bitmapResized = Bitmap.createScaledBitmap(bitmap, avatarSize, avatarSize, false)
@ -487,9 +486,10 @@ class ChatController(args: Bundle) :
adapterWasNull = true adapterWasNull = true
val messageHolders = MessageHolders() val messageHolders = MessageHolders()
val profileBottomSheet = ProfileBottomSheet(ncApi!!, conversationUser!!, router) val profileBottomSheet = ProfileBottomSheet(ncApi, conversationUser!!, router)
val payload = MessagePayload(currentConversation!!, profileBottomSheet) val payload =
MessagePayload(roomToken!!, currentConversation?.isParticipantOwnerOrModerator, profileBottomSheet)
messageHolders.setIncomingTextConfig( messageHolders.setIncomingTextConfig(
MagicIncomingTextMessageViewHolder::class.java, MagicIncomingTextMessageViewHolder::class.java,
@ -696,7 +696,8 @@ class ChatController(args: Bundle) :
val editable = binding.messageInputView.inputEditText?.editableText val editable = binding.messageInputView.inputEditText?.editableText
if (editable != null && binding.messageInputView.inputEditText != null) { if (editable != null && binding.messageInputView.inputEditText != null) {
val mentionSpans = editable.getSpans( val mentionSpans = editable.getSpans(
0, binding.messageInputView.inputEditText!!.length(), 0,
binding.messageInputView.inputEditText!!.length(),
Spans.MentionChipSpan::class.java Spans.MentionChipSpan::class.java
) )
var mentionSpan: Spans.MentionChipSpan var mentionSpan: Spans.MentionChipSpan
@ -938,7 +939,6 @@ class ChatController(args: Bundle) :
} }
private fun startPlayback(message: ChatMessage) { private fun startPlayback(message: ChatMessage) {
if (!this.isAttached) { if (!this.isAttached) {
// don't begin to play voice message if screen is not visible anymore. // don't begin to play voice message if screen is not visible anymore.
// this situation might happen if file is downloading but user already left the chatview. // this situation might happen if file is downloading but user already left the chatview.
@ -1090,7 +1090,8 @@ class ChatController(args: Bundle) :
val fileNameWithoutSuffix = String.format( val fileNameWithoutSuffix = String.format(
context!!.resources.getString(R.string.nc_voice_message_filename), context!!.resources.getString(R.string.nc_voice_message_filename),
date, currentConversation!!.displayName date,
currentConversation!!.displayName
) )
val fileName = fileNameWithoutSuffix + VOICE_MESSAGE_FILE_SUFFIX val fileName = fileNameWithoutSuffix + VOICE_MESSAGE_FILE_SUFFIX
@ -1305,7 +1306,6 @@ class ChatController(args: Bundle) :
currentConversation?.isLobbyViewApplicable(conversationUser!!) ?: false && currentConversation?.isLobbyViewApplicable(conversationUser!!) ?: false &&
isAlive() isAlive()
) { ) {
if (!checkingLobbyStatus) { if (!checkingLobbyStatus) {
getRoomInfo() getRoomInfo()
} }
@ -1603,7 +1603,8 @@ class ChatController(args: Bundle) :
if (!isVoiceMessage) { if (!isVoiceMessage) {
Toast.makeText( Toast.makeText(
context, context?.getString(R.string.nc_upload_in_progess), context,
context?.getString(R.string.nc_upload_in_progess),
Toast.LENGTH_LONG Toast.LENGTH_LONG
).show() ).show()
} }
@ -2000,7 +2001,8 @@ class ChatController(args: Bundle) :
if (binding.messageInputView.inputEditText != null) { if (binding.messageInputView.inputEditText != null) {
val editable = binding.messageInputView.inputEditText!!.editableText val editable = binding.messageInputView.inputEditText!!.editableText
val mentionSpans = editable.getSpans( val mentionSpans = editable.getSpans(
0, editable.length, 0,
editable.length,
Spans.MentionChipSpan::class.java Spans.MentionChipSpan::class.java
) )
var mentionSpan: Spans.MentionChipSpan var mentionSpan: Spans.MentionChipSpan
@ -2029,7 +2031,6 @@ class ChatController(args: Bundle) :
} }
private fun sendMessage(message: CharSequence, replyTo: Int?, sendWithoutNotification: Boolean) { private fun sendMessage(message: CharSequence, replyTo: Int?, sendWithoutNotification: Boolean) {
if (conversationUser != null) { if (conversationUser != null) {
val apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1)) val apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1))
@ -2167,7 +2168,8 @@ class ChatController(args: Bundle) :
Log.d(TAG, "pullChatMessages - pullChatMessages[lookIntoFuture > 0] - calling") Log.d(TAG, "pullChatMessages - pullChatMessages[lookIntoFuture > 0] - calling")
ncApi.pullChatMessages( ncApi.pullChatMessages(
credentials, credentials,
ApiUtils.getUrlForChat(apiVersion, conversationUser?.baseUrl, roomToken), fieldMap ApiUtils.getUrlForChat(apiVersion, conversationUser?.baseUrl, roomToken),
fieldMap
) )
?.subscribeOn(Schedulers.io()) ?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread()) ?.observeOn(AndroidSchedulers.mainThread())
@ -2209,7 +2211,8 @@ class ChatController(args: Bundle) :
Log.d(TAG, "pullChatMessages - pullChatMessages[lookIntoFuture <= 0] - calling") Log.d(TAG, "pullChatMessages - pullChatMessages[lookIntoFuture <= 0] - calling")
ncApi.pullChatMessages( ncApi.pullChatMessages(
credentials, credentials,
ApiUtils.getUrlForChat(apiVersion, conversationUser?.baseUrl, roomToken), fieldMap ApiUtils.getUrlForChat(apiVersion, conversationUser?.baseUrl, roomToken),
fieldMap
) )
?.subscribeOn(Schedulers.io()) ?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread()) ?.observeOn(AndroidSchedulers.mainThread())
@ -2253,7 +2256,6 @@ class ChatController(args: Bundle) :
Integer.parseInt(it) Integer.parseInt(it)
} }
if (response.headers().size > 0 && !TextUtils.isEmpty(xChatLastGivenHeader)) { if (response.headers().size > 0 && !TextUtils.isEmpty(xChatLastGivenHeader)) {
val header = Integer.parseInt(xChatLastGivenHeader!!) val header = Integer.parseInt(xChatLastGivenHeader!!)
if (header > 0) { if (header > 0) {
if (isFromTheFuture) { if (isFromTheFuture) {
@ -2268,7 +2270,6 @@ class ChatController(args: Bundle) :
} }
if (response.code() == HTTP_CODE_OK) { if (response.code() == HTTP_CODE_OK) {
val chatOverall = response.body() as ChatOverall? val chatOverall = response.body() as ChatOverall?
val chatMessageList = handleSystemMessages(chatOverall?.ocs!!.data!!) val chatMessageList = handleSystemMessages(chatOverall?.ocs!!.data!!)
@ -2331,7 +2332,6 @@ class ChatController(args: Bundle) :
} }
scrollToRequestedMessageIfNeeded() scrollToRequestedMessageIfNeeded()
} else { } else {
var chatMessage: ChatMessage var chatMessage: ChatMessage
val shouldAddNewMessagesNotice = (adapter?.itemCount ?: 0) > 0 && chatMessageList.isNotEmpty() val shouldAddNewMessagesNotice = (adapter?.itemCount ?: 0) > 0 && chatMessageList.isNotEmpty()
@ -2746,7 +2746,8 @@ class ChatController(args: Bundle) :
override fun onNext(t: ChatOverallSingleMessage) { override fun onNext(t: ChatOverallSingleMessage) {
if (t.ocs!!.meta!!.statusCode == HttpURLConnection.HTTP_ACCEPTED) { if (t.ocs!!.meta!!.statusCode == HttpURLConnection.HTTP_ACCEPTED) {
Toast.makeText( Toast.makeText(
context, R.string.nc_delete_message_leaked_to_matterbridge, context,
R.string.nc_delete_message_leaked_to_matterbridge,
Toast.LENGTH_LONG Toast.LENGTH_LONG
).show() ).show()
} }
@ -2782,7 +2783,8 @@ class ChatController(args: Bundle) :
) )
ncApi!!.createRoom( ncApi!!.createRoom(
credentials, credentials,
retrofitBucket.url, retrofitBucket.queryMap retrofitBucket.url,
retrofitBucket.queryMap
) )
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
@ -2801,7 +2803,8 @@ class ChatController(args: Bundle) :
ncApi!!.getRoom( ncApi!!.getRoom(
credentials, credentials,
ApiUtils.getUrlForRoom( ApiUtils.getUrlForRoom(
apiVersion, conversationUser?.baseUrl, apiVersion,
conversationUser?.baseUrl,
roomOverall.ocs!!.data!!.token roomOverall.ocs!!.data!!.token
) )
) )
@ -2818,8 +2821,11 @@ class ChatController(args: Bundle) :
Parcels.wrap(roomOverall.ocs!!.data!!) Parcels.wrap(roomOverall.ocs!!.data!!)
) )
remapChatController( remapChatController(
router, conversationUser!!.id!!, router,
roomOverall.ocs!!.data!!.token!!, bundle, true conversationUser!!.id!!,
roomOverall.ocs!!.data!!.token!!,
bundle,
true
) )
} }
@ -3079,7 +3085,6 @@ class ChatController(args: Bundle) :
if (currentConversation?.type != Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL || if (currentConversation?.type != Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL ||
currentConversation?.name != userMentionClickEvent.userId currentConversation?.name != userMentionClickEvent.userId
) { ) {
var apiVersion = 1 var apiVersion = 1
// FIXME Fix API checking with guests? // FIXME Fix API checking with guests?
if (conversationUser != null) { if (conversationUser != null) {
@ -3097,7 +3102,8 @@ class ChatController(args: Bundle) :
ncApi.createRoom( ncApi.createRoom(
credentials, credentials,
retrofitBucket.url, retrofitBucket.queryMap retrofitBucket.url,
retrofitBucket.queryMap
) )
?.subscribeOn(Schedulers.io()) ?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread()) ?.observeOn(AndroidSchedulers.mainThread())
@ -3121,8 +3127,11 @@ class ChatController(args: Bundle) :
conversationIntent.putExtras(bundle) conversationIntent.putExtras(bundle)
ConductorRemapping.remapChatController( ConductorRemapping.remapChatController(
router, conversationUser.id!!, router,
roomOverall.ocs!!.data!!.token!!, bundle, false conversationUser.id!!,
roomOverall.ocs!!.data!!.token!!,
bundle,
false
) )
} else { } else {
conversationIntent.putExtras(bundle) conversationIntent.putExtras(bundle)