From cd2ef40dc88c63bccec5a3dcbeefdcd17065b211 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Fri, 31 Mar 2023 15:23:52 +0200 Subject: [PATCH 01/14] Replace Controller with Activity for chat chat opens, but quite some todos open. expect crashes. Signed-off-by: Marcel Hibbe --- app/src/main/AndroidManifest.xml | 4 + .../nextcloud/talk/activities/MainActivity.kt | 84 +- .../messages/IncomingTextMessageViewHolder.kt | 6 +- .../OutcomingTextMessageViewHolder.kt | 6 +- .../messages/TalkMessagesListAdapter.java | 38 +- .../ChatActivity.kt} | 884 +++++++++--------- .../ConversationsListController.kt | 25 +- .../talk/jobs/UploadAndShareFilesWorker.kt | 10 +- .../ui/bottom/sheet/ProfileBottomSheet.kt | 20 +- .../talk/ui/dialog/AttachmentDialog.kt | 28 +- .../talk/ui/dialog/MessageActionsDialog.kt | 22 +- .../utils/remapchat/ConductorRemapping.kt | 228 +++-- app/src/main/res/layout/controller_chat.xml | 17 + 13 files changed, 704 insertions(+), 668 deletions(-) rename app/src/main/java/com/nextcloud/talk/{controllers/ChatController.kt => chat/ChatActivity.kt} (92%) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a318d1c25..57a515233 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -218,6 +218,10 @@ android:name=".contacts.ContactsActivity" android:theme="@style/AppTheme" /> + + diff --git a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt b/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt index 70e2bb568..737bf1927 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt @@ -39,6 +39,7 @@ import com.nextcloud.talk.BuildConfig import com.nextcloud.talk.R import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.application.NextcloudTalkApplication +import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.controllers.ConversationsListController import com.nextcloud.talk.controllers.LockedController import com.nextcloud.talk.controllers.ServerSelectionController @@ -56,7 +57,6 @@ 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_TOKEN 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.SingleObserver import io.reactivex.android.schedulers.AndroidSchedulers @@ -93,16 +93,22 @@ class MainActivity : BaseActivity(), ActionBarProvider { router = Conductor.attachRouter(this, binding.controllerContainer, savedInstanceState) + // TODO: delete this. open chats directly via intent if (intent.getBooleanExtra(BundleKeys.KEY_OPEN_CHAT, false)) { logRouterBackStack(router!!) - remapChatController( - router!!, - intent.getParcelableExtra(KEY_USER_ENTITY)!!.id!!, - intent.getStringExtra(KEY_ROOM_TOKEN)!!, - intent.extras!!, - true, - true - ) + // remapChatController( + // router!!, + // intent.getParcelableExtra(KEY_USER_ENTITY)!!.id!!, + // intent.getStringExtra(KEY_ROOM_TOKEN)!!, + // intent.extras!!, + // true, + // true + // ) + + val intent = Intent(context, ChatActivity::class.java) + intent.putExtras(intent.extras!!) + startActivity(intent) + logRouterBackStack(router!!) } @@ -306,13 +312,17 @@ class MainActivity : BaseActivity(), ActionBarProvider { KEY_ACTIVE_CONVERSATION, Parcels.wrap(roomOverall.ocs!!.data) ) - remapChatController( - router!!, - currentUser!!.id!!, - roomOverall.ocs!!.data!!.token!!, - bundle, - true - ) + // remapChatController( + // router!!, + // currentUser!!.id!!, + // roomOverall.ocs!!.data!!.token!!, + // bundle, + // true + // ) + + val intent = Intent(context, ChatActivity::class.java) + intent.putExtras(bundle) + startActivity(intent) } override fun onError(e: Throwable) { @@ -367,14 +377,19 @@ class MainActivity : BaseActivity(), ActionBarProvider { if (intent.getBooleanExtra(BundleKeys.KEY_SWITCH_TO_ROOM_AND_START_CALL, false)) { logRouterBackStack(router!!) - remapChatController( - router!!, - intent.getParcelableExtra(KEY_USER_ENTITY)!!.id!!, - intent.getStringExtra(KEY_ROOM_TOKEN)!!, - intent.extras!!, - true, - true - ) + // remapChatController( + // router!!, + // intent.getParcelableExtra(KEY_USER_ENTITY)!!.id!!, + // intent.getStringExtra(KEY_ROOM_TOKEN)!!, + // intent.extras!!, + // true, + // true + // ) + + val intent = Intent(context, ChatActivity::class.java) + intent.putExtras(intent.extras!!) + startActivity(intent) + logRouterBackStack(router!!) } @@ -388,14 +403,19 @@ class MainActivity : BaseActivity(), ActionBarProvider { startActivity(callNotificationIntent) } else { logRouterBackStack(router!!) - remapChatController( - router!!, - intent.getParcelableExtra(KEY_USER_ENTITY)!!.id!!, - intent.getStringExtra(KEY_ROOM_TOKEN)!!, - intent.extras!!, - true, - true - ) + // remapChatController( + // router!!, + // intent.getParcelableExtra(KEY_USER_ENTITY)!!.id!!, + // intent.getStringExtra(KEY_ROOM_TOKEN)!!, + // intent.extras!!, + // true, + // true + // ) + + val intent = Intent(context, ChatActivity::class.java) + intent.putExtras(intent.extras!!) + startActivity(intent) + logRouterBackStack(router!!) } } diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingTextMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingTextMessageViewHolder.kt index 559a40a2d..7e9b67356 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingTextMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingTextMessageViewHolder.kt @@ -40,7 +40,7 @@ import coil.load import com.nextcloud.talk.R import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication -import com.nextcloud.talk.controllers.ChatController +import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.databinding.ItemCustomIncomingTextMessageBinding import com.nextcloud.talk.extensions.loadBotsAvatar import com.nextcloud.talk.extensions.loadChangelogBotAvatar @@ -201,8 +201,8 @@ class IncomingTextMessageViewHolder(itemView: View, payload: Any) : MessageHolde } binding.messageQuote.quotedChatMessageView.setOnClickListener() { - val chatController = commonMessageInterface as ChatController - chatController.jumpToQuotedMessage(parentChatMessage) + val chatActivity = commonMessageInterface as ChatActivity + chatActivity.jumpToQuotedMessage(parentChatMessage) } } diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingTextMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingTextMessageViewHolder.kt index 5eaef83e8..7f5176137 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingTextMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingTextMessageViewHolder.kt @@ -38,7 +38,7 @@ import com.google.android.flexbox.FlexboxLayout import com.nextcloud.talk.R import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication -import com.nextcloud.talk.controllers.ChatController +import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.databinding.ItemCustomOutcomingTextMessageBinding import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.models.json.chat.ReadStatus @@ -172,8 +172,8 @@ class OutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessageViewH binding.messageQuote.quoteColoredView.setBackgroundColor(textColor) binding.messageQuote.quotedChatMessageView.setOnClickListener() { - val chatController = commonMessageInterface as ChatController - chatController.jumpToQuotedMessage(parentChatMessage) + val chatActivity = commonMessageInterface as ChatActivity + chatActivity.jumpToQuotedMessage(parentChatMessage) } } diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/TalkMessagesListAdapter.java b/app/src/main/java/com/nextcloud/talk/adapters/messages/TalkMessagesListAdapter.java index fec78dd69..dcc9e2370 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/TalkMessagesListAdapter.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/TalkMessagesListAdapter.java @@ -20,7 +20,7 @@ package com.nextcloud.talk.adapters.messages; -import com.nextcloud.talk.controllers.ChatController; +import com.nextcloud.talk.chat.ChatActivity; import com.stfalcon.chatkit.commons.ImageLoader; import com.stfalcon.chatkit.commons.ViewHolder; import com.stfalcon.chatkit.commons.models.IMessage; @@ -30,15 +30,15 @@ import com.stfalcon.chatkit.messages.MessagesListAdapter; import java.util.List; public class TalkMessagesListAdapter extends MessagesListAdapter { - private final ChatController chatController; + private final ChatActivity chatActivity; public TalkMessagesListAdapter( - String senderId, - MessageHolders holders, - ImageLoader imageLoader, - ChatController chatController) { + String senderId, + MessageHolders holders, + ImageLoader imageLoader, + ChatActivity chatActivity) { super(senderId, holders, imageLoader); - this.chatController = chatController; + this.chatActivity = chatActivity; } public List getItems() { @@ -50,30 +50,30 @@ public class TalkMessagesListAdapter extends MessagesListAda super.onBindViewHolder(holder, position); if (holder instanceof IncomingTextMessageViewHolder) { - ((IncomingTextMessageViewHolder) holder).assignCommonMessageInterface(chatController); + ((IncomingTextMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); } else if (holder instanceof OutcomingTextMessageViewHolder) { - ((OutcomingTextMessageViewHolder) holder).assignCommonMessageInterface(chatController); + ((OutcomingTextMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); } else if (holder instanceof IncomingLocationMessageViewHolder) { - ((IncomingLocationMessageViewHolder) holder).assignCommonMessageInterface(chatController); + ((IncomingLocationMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); } else if (holder instanceof OutcomingLocationMessageViewHolder) { - ((OutcomingLocationMessageViewHolder) holder).assignCommonMessageInterface(chatController); + ((OutcomingLocationMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); } else if (holder instanceof IncomingLinkPreviewMessageViewHolder) { - ((IncomingLinkPreviewMessageViewHolder) holder).assignCommonMessageInterface(chatController); + ((IncomingLinkPreviewMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); } else if (holder instanceof OutcomingLinkPreviewMessageViewHolder) { - ((OutcomingLinkPreviewMessageViewHolder) holder).assignCommonMessageInterface(chatController); + ((OutcomingLinkPreviewMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); } else if (holder instanceof IncomingVoiceMessageViewHolder) { - ((IncomingVoiceMessageViewHolder) holder).assignVoiceMessageInterface(chatController); - ((IncomingVoiceMessageViewHolder) holder).assignCommonMessageInterface(chatController); + ((IncomingVoiceMessageViewHolder) holder).assignVoiceMessageInterface(chatActivity); + ((IncomingVoiceMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); } else if (holder instanceof OutcomingVoiceMessageViewHolder) { - ((OutcomingVoiceMessageViewHolder) holder).assignVoiceMessageInterface(chatController); - ((OutcomingVoiceMessageViewHolder) holder).assignCommonMessageInterface(chatController); + ((OutcomingVoiceMessageViewHolder) holder).assignVoiceMessageInterface(chatActivity); + ((OutcomingVoiceMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); } else if (holder instanceof PreviewMessageViewHolder) { - ((PreviewMessageViewHolder) holder).assignPreviewMessageInterface(chatController); - ((PreviewMessageViewHolder) holder).assignCommonMessageInterface(chatController); + ((PreviewMessageViewHolder) holder).assignPreviewMessageInterface(chatActivity); + ((PreviewMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); } } } diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt similarity index 92% rename from app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt rename to app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 4fa5c195d..b7e4bd954 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -24,11 +24,10 @@ * along with this program. If not, see . */ -package com.nextcloud.talk.controllers +package com.nextcloud.talk.chat import android.Manifest import android.annotation.SuppressLint -import android.app.Activity.RESULT_OK import android.content.ClipData import android.content.ClipboardManager import android.content.Context @@ -58,7 +57,6 @@ import android.util.Log import android.util.TypedValue import android.view.Gravity import android.view.Menu -import android.view.MenuInflater import android.view.MenuItem import android.view.MotionEvent import android.view.View @@ -76,6 +74,7 @@ import androidx.appcompat.view.ContextThemeWrapper import androidx.core.content.ContextCompat import androidx.core.content.FileProvider import androidx.core.content.PermissionChecker +import androidx.core.content.res.ResourcesCompat import androidx.core.graphics.drawable.toBitmap import androidx.core.widget.doAfterTextChanged import androidx.emoji2.text.EmojiCompat @@ -93,14 +92,12 @@ import coil.load import coil.request.ImageRequest import coil.target.Target import coil.transform.CircleCropTransformation -import com.bluelinelabs.conductor.RouterTransaction -import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler import com.google.android.flexbox.FlexboxLayout import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.nextcloud.talk.BuildConfig import com.nextcloud.talk.R +import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.activities.CallActivity -import com.nextcloud.talk.activities.MainActivity import com.nextcloud.talk.activities.TakePhotoActivity import com.nextcloud.talk.adapters.messages.CommonMessageInterface import com.nextcloud.talk.adapters.messages.IncomingLinkPreviewMessageViewHolder @@ -124,8 +121,7 @@ import com.nextcloud.talk.adapters.messages.VoiceMessageInterface import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.callbacks.MentionAutocompleteCallback -import com.nextcloud.talk.controllers.base.BaseController -import com.nextcloud.talk.controllers.util.viewBinding +import com.nextcloud.talk.controllers.ConversationsListController import com.nextcloud.talk.conversation.info.ConversationInfoActivity import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.databinding.ControllerChatBinding @@ -164,6 +160,7 @@ import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ContactUtils import com.nextcloud.talk.utils.DateConstants import com.nextcloud.talk.utils.DateUtils +import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.FileUtils import com.nextcloud.talk.utils.ImageEmojiEditText import com.nextcloud.talk.utils.MagicCharPolicy @@ -183,7 +180,6 @@ 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.database.user.CapabilitiesUtilNew 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.singletons.ApplicationWideCurrentRoomHolder @@ -202,7 +198,6 @@ import io.reactivex.Observer import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable import io.reactivex.schedulers.Schedulers -import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode import org.parceler.Parcels @@ -221,11 +216,8 @@ import kotlin.collections.set import kotlin.math.roundToInt @AutoInjector(NextcloudTalkApplication::class) -class ChatController(args: Bundle) : - BaseController( - R.layout.controller_chat, - args - ), +class ChatActivity : + BaseActivity(), MessagesListAdapter.OnLoadMoreListener, MessagesListAdapter.Formatter, MessagesListAdapter.OnMessageViewLongClickListener, @@ -234,14 +226,11 @@ class ChatController(args: Bundle) : CommonMessageInterface, PreviewMessageInterface { - private val binding: ControllerChatBinding? by viewBinding(ControllerChatBinding::bind) + private lateinit var binding: ControllerChatBinding @Inject lateinit var ncApi: NcApi - @Inject - lateinit var eventBus: EventBus - @Inject lateinit var reactionsRepository: ReactionsRepository @@ -254,9 +243,9 @@ class ChatController(args: Bundle) : val disposables = DisposableSet() var sessionIdAfterRoomJoined: String? = null - var roomToken: String? = null - val conversationUser: User? - private val roomPassword: String + lateinit var roomToken: String + var conversationUser: User? = null + private var roomPassword: String = "" var credentials: String? = null var currentConversation: Conversation? = null private var globalLastKnownFutureMessageId = -1 @@ -268,8 +257,8 @@ class ChatController(args: Bundle) : var newMessagesCount = 0 var startCallFromNotification: Boolean? = null var startCallFromRoomSwitch: Boolean = false - val roomId: String - val voiceOnly: Boolean + lateinit var roomId: String + var voiceOnly: Boolean = true var isFirstMessagesProcessing = true private var emojiPopup: EmojiPopup? = null @@ -288,7 +277,7 @@ class ChatController(args: Bundle) : var futurePreconditionFailed = false private val filesToUpload: MutableList = ArrayList() - private var sharedText: String + private lateinit var sharedText: String var isVoiceRecordingInProgress: Boolean = false var currentVoiceRecordFile: String = "" @@ -310,230 +299,119 @@ class ChatController(args: Bundle) : } } - init { - Log.d(TAG, "init ChatController: " + System.identityHashCode(this).toString()) - - setHasOptionsMenu(true) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) - conversationUser = args.getParcelable(KEY_USER_ENTITY) - roomId = args.getString(KEY_ROOM_ID, "") - roomToken = args.getString(KEY_ROOM_TOKEN, "") - sharedText = args.getString(BundleKeys.KEY_SHARED_TEXT, "") + binding = ControllerChatBinding.inflate(layoutInflater) + setupActionBar() + setupSystemColors() + setContentView(binding.root) + + conversationUser = intent.getParcelableExtra(KEY_USER_ENTITY) + roomId = intent.getStringExtra(KEY_ROOM_ID)!! + roomToken = intent.getStringExtra(KEY_ROOM_TOKEN)!! + sharedText = intent.getStringExtra(BundleKeys.KEY_SHARED_TEXT)!! Log.d(TAG, " roomToken = $roomToken") if (roomToken.isNullOrEmpty()) { Log.d(TAG, " roomToken was null or empty!") } - if (args.containsKey(KEY_ACTIVE_CONVERSATION)) { - currentConversation = Parcels.unwrap(args.getParcelable(KEY_ACTIVE_CONVERSATION)) + if (intent.hasExtra(KEY_ACTIVE_CONVERSATION)) { + currentConversation = Parcels.unwrap(intent.getParcelableExtra(KEY_ACTIVE_CONVERSATION)) participantPermissions = ParticipantPermissions(conversationUser!!, currentConversation!!) } - roomPassword = args.getString(BundleKeys.KEY_CONVERSATION_PASSWORD, "") + if (intent.hasExtra(BundleKeys.KEY_CONVERSATION_PASSWORD)) { + roomPassword = intent.getStringExtra(BundleKeys.KEY_CONVERSATION_PASSWORD)!! + } credentials = if (conversationUser?.userId == "?") { null } else { - ApiUtils.getCredentials(conversationUser!!.username, conversationUser.token) + ApiUtils.getCredentials(conversationUser!!.username, conversationUser!!.token) } - if (args.containsKey(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL)) { - startCallFromNotification = args.getBoolean(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL) + if (intent.hasExtra(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL)) { + startCallFromNotification = intent.getBooleanExtra(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL, false) } - if (args.containsKey(BundleKeys.KEY_SWITCH_TO_ROOM_AND_START_CALL)) { - startCallFromRoomSwitch = args.getBoolean(BundleKeys.KEY_SWITCH_TO_ROOM_AND_START_CALL) + if (intent.hasExtra(BundleKeys.KEY_SWITCH_TO_ROOM_AND_START_CALL)) { + startCallFromRoomSwitch = intent.getBooleanExtra(BundleKeys.KEY_SWITCH_TO_ROOM_AND_START_CALL, false) } - voiceOnly = args.getBoolean(BundleKeys.KEY_CALL_VOICE_ONLY, false) + voiceOnly = intent.getBooleanExtra(BundleKeys.KEY_CALL_VOICE_ONLY, false) } - private fun getRoomInfo() { - logConversationInfos("getRoomInfo") - - if (conversationUser != null) { - val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1)) - - val startNanoTime = System.nanoTime() - Log.d(TAG, "getRoomInfo - getRoom - calling: $startNanoTime") - ncApi.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, conversationUser.baseUrl, roomToken)) - ?.subscribeOn(Schedulers.io()) - ?.observeOn(AndroidSchedulers.mainThread()) - ?.subscribe(object : Observer { - override fun onSubscribe(d: Disposable) { - disposables.add(d) - } - - @Suppress("Detekt.TooGenericExceptionCaught") - override fun onNext(roomOverall: RoomOverall) { - Log.d(TAG, "getRoomInfo - getRoom - got response: $startNanoTime") - currentConversation = roomOverall.ocs!!.data - - logConversationInfos("getRoomInfo#onNext") - - loadAvatarForStatusBar() - setTitle() - participantPermissions = ParticipantPermissions(conversationUser, currentConversation!!) - - setupSwipeToReply() - setupMentionAutocomplete() - checkShowCallButtons() - checkShowMessageInputView() - checkLobbyState() - - if (!validSessionId()) { - joinRoomWithPassword() - } else { - Log.d(TAG, "already inConversation. joinRoomWithPassword is skipped") - } - } - - override fun onError(e: Throwable) { - Log.e(TAG, "getRoomInfo - getRoom - ERROR", e) - } - - override fun onComplete() { - Log.d(TAG, "getRoomInfo - getRoom - onComplete: $startNanoTime") - - val delayForRecursiveCall = if (shouldShowLobby()) { - GET_ROOM_INFO_DELAY_LOBBY - } else { - GET_ROOM_INFO_DELAY_NORMAL - } - - if (getRoomInfoTimerHandler == null) { - getRoomInfoTimerHandler = Handler() - } - getRoomInfoTimerHandler?.postDelayed({ getRoomInfo() }, delayForRecursiveCall) - } - }) - } - } - - private fun setupSwipeToReply() { - if (this::participantPermissions.isInitialized && - participantPermissions.hasChatPermission() && - !isReadOnlyConversation() - ) { - activity?.let { - val messageSwipeController = MessageSwipeCallback( - it, - object : MessageSwipeActions { - override fun showReplyUI(position: Int) { - val chatMessage = adapter?.items?.get(position)?.item as ChatMessage? - replyToMessage(chatMessage) - } - } - ) - - val itemTouchHelper = ItemTouchHelper(messageSwipeController) - itemTouchHelper.attachToRecyclerView(binding?.messagesListView) - } - } - } - - private fun handleFromNotification() { - var apiVersion = 1 - // FIXME Can this be called for guests? - if (conversationUser != null) { - apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1)) - } - - Log.d(TAG, "handleFromNotification - getRooms - calling") - ncApi.getRooms(credentials, ApiUtils.getUrlForRooms(apiVersion, conversationUser?.baseUrl), false) - ?.subscribeOn(Schedulers.io())?.observeOn(AndroidSchedulers.mainThread()) - ?.subscribe(object : Observer { - override fun onSubscribe(d: Disposable) { - disposables.add(d) - } - - override fun onNext(roomsOverall: RoomsOverall) { - Log.d(TAG, "handleFromNotification - getRooms - got response") - for (conversation in roomsOverall.ocs!!.data!!) { - if (roomId == conversation.roomId) { - roomToken = conversation.token - currentConversation = conversation - participantPermissions = ParticipantPermissions(conversationUser!!, currentConversation!!) - setTitle() - getRoomInfo() - break - } - } - } - - override fun onError(e: Throwable) { - Log.e(TAG, "handleFromNotification - getRooms - ERROR: ", e) - } - - override fun onComplete() { - // unused atm - } - }) - } - - private fun loadAvatarForStatusBar() { - if (isOneToOneConversation() && activity != null) { - val url = ApiUtils.getUrlForAvatar( - conversationUser!!.baseUrl, - currentConversation!!.name, - true - ) - val target = object : Target { - - private fun setIcon(drawable: Drawable?) { - actionBar?.let { - val avatarSize = (it.height / TOOLBAR_AVATAR_RATIO).roundToInt() - - if (drawable != null && avatarSize > 0) { - val bitmap = drawable.toBitmap(avatarSize, avatarSize) - it.setIcon(BitmapDrawable(resources, bitmap)) - } else { - Log.d(TAG, "loadAvatarForStatusBar avatarSize <= 0") - } - } - } - - override fun onStart(placeholder: Drawable?) { - this.setIcon(placeholder) - } - - override fun onSuccess(result: Drawable) { - this.setIcon(result) - } - } - - val credentials = ApiUtils.getCredentials(conversationUser.username, conversationUser.token) - - context.imageLoader.enqueue( - ImageRequest.Builder(context) - .data(url) - .addHeader("Authorization", credentials) - .placeholder(R.drawable.ic_user) - .transformations(CircleCropTransformation()) - .crossfade(true) - .target(target) - .build() - ) - } - } - - fun isOneToOneConversation() = currentConversation != null && currentConversation?.type != null && - currentConversation?.type == Conversation.ConversationType - .ROOM_TYPE_ONE_TO_ONE_CALL - @SuppressLint("ClickableViewAccessibility") @Suppress("Detekt.TooGenericExceptionCaught") - override fun onViewBound(view: View) { - Log.d(TAG, "onViewBound: " + System.identityHashCode(this).toString()) + override fun onResume() { + super.onResume() + + logConversationInfos("onResume") + + setupWebsocket() + webSocketInstance?.getSignalingMessageReceiver()?.addListener(localParticipantMessageListener) + + if (conversationUser?.userId != "?" && + CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "mention-flag") + ) { + findViewById(R.id.toolbar)?.setOnClickListener { v -> showConversationInfoScreen() } + } + + val smileyButton = binding?.messageInputView?.findViewById(R.id.smileyButton) + + emojiPopup = binding?.messageInputView?.inputEditText?.let { + EmojiPopup( + rootView = binding.root, + editText = it, + onEmojiPopupShownListener = { + if (resources != null) { + smileyButton?.setImageDrawable( + ContextCompat.getDrawable(context, R.drawable.ic_baseline_keyboard_24) + ) + } + }, + onEmojiPopupDismissListener = { + smileyButton?.setImageDrawable( + ContextCompat.getDrawable(context, R.drawable.ic_insert_emoticon_black_24dp) + ) + }, + onEmojiClickListener = { + binding?.messageInputView?.inputEditText?.editableText?.append(" ") + } + ) + } + + smileyButton?.setOnClickListener { + emojiPopup?.toggle() + } + + binding?.messageInputView?.findViewById(R.id.cancelReplyButton)?.setOnClickListener { + cancelReply() + } + + binding?.messageInputView?.findViewById(R.id.cancelReplyButton)?.let { + viewThemeUtils.platform + .themeImageButton(it) + } + + cancelNotificationsForCurrentConversation() + + if (TextUtils.isEmpty(roomToken)) { + handleFromNotification() + } else { + getRoomInfo() + } + actionBar?.show() if (adapter == null) { binding?.progressBar?.visibility = View.VISIBLE val messageHolders = MessageHolders() - val profileBottomSheet = ProfileBottomSheet(ncApi, conversationUser!!, router) + val profileBottomSheet = ProfileBottomSheet(ncApi, conversationUser!!) val payload = MessagePayload(roomToken!!, currentConversation?.isParticipantOwnerOrModerator, profileBottomSheet) @@ -621,8 +499,8 @@ class ChatController(args: Bundle) : this ) - val senderId = if (!conversationUser.userId.equals("?")) { - "users/" + conversationUser.userId + val senderId = if (!conversationUser!!.userId.equals("?")) { + "users/" + conversationUser!!.userId } else { currentConversation?.actorType + "/" + currentConversation?.actorId } @@ -633,7 +511,7 @@ class ChatController(args: Bundle) : senderId, messageHolders, ImageLoader { imageView, url, placeholder -> - imageView.loadAvatarOrImagePreview(url!!, conversationUser, placeholder as Drawable?) + imageView.loadAvatarOrImagePreview(url!!, conversationUser!!, placeholder as Drawable?) }, this ) @@ -796,7 +674,7 @@ class ChatController(args: Bundle) : binding?.messageInputView?.recordAudioButton?.setOnTouchListener(object : View.OnTouchListener { override fun onTouch(v: View?, event: MotionEvent?): Boolean { - view.performClick() + v?.performClick() // ????????? when (event?.action) { MotionEvent.ACTION_DOWN -> { if (!isRecordAudioPermissionGranted()) { @@ -804,7 +682,7 @@ class ChatController(args: Bundle) : return true } if (!permissionUtil.isFilesPermissionGranted()) { - UploadAndShareFilesWorker.requestStoragePermission(this@ChatController) + UploadAndShareFilesWorker.requestStoragePermission(this@ChatActivity) return true } @@ -895,7 +773,7 @@ class ChatController(args: Bundle) : binding?.messageInputView?.inputEditText?.setText(sharedText) binding?.messageInputView?.setAttachmentsListener { - activity?.let { AttachmentDialog(it, this).show() } + AttachmentDialog(this, this).show() } binding?.messageInputView?.button?.setOnClickListener { submitMessage(false) } @@ -914,12 +792,207 @@ class ChatController(args: Bundle) : if (currentConversation != null && currentConversation?.roomId != null) { loadAvatarForStatusBar() - setTitle() + setActionBarTitle() + } + } + + private fun setupActionBar() { + setSupportActionBar(binding.chatToolbar) + binding.chatToolbar.setNavigationOnClickListener { + onBackPressed() + } + supportActionBar?.setDisplayHomeAsUpEnabled(true) + supportActionBar?.setDisplayShowHomeEnabled(true) + supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(R.color.transparent))) + setActionBarTitle() + } + + private fun setupSystemColors() { + DisplayUtils.applyColorToStatusBar( + this, + ResourcesCompat.getColor( + resources, + R.color.appbar, + null + ) + ) + DisplayUtils.applyColorToNavigationBar( + this.window, + ResourcesCompat.getColor(resources, R.color.bg_default, null) + ) + } + + private fun getRoomInfo() { + logConversationInfos("getRoomInfo") + + conversationUser?.let { + val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1)) + + val startNanoTime = System.nanoTime() + Log.d(TAG, "getRoomInfo - getRoom - calling: $startNanoTime") + ncApi.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, it.baseUrl, roomToken)) + ?.subscribeOn(Schedulers.io()) + ?.observeOn(AndroidSchedulers.mainThread()) + ?.subscribe(object : Observer { + override fun onSubscribe(d: Disposable) { + disposables.add(d) + } + + @Suppress("Detekt.TooGenericExceptionCaught") + override fun onNext(roomOverall: RoomOverall) { + Log.d(TAG, "getRoomInfo - getRoom - got response: $startNanoTime") + currentConversation = roomOverall.ocs!!.data + + logConversationInfos("getRoomInfo#onNext") + + loadAvatarForStatusBar() + setActionBarTitle() + participantPermissions = ParticipantPermissions(it, currentConversation!!) + + setupSwipeToReply() + setupMentionAutocomplete() + checkShowCallButtons() + checkShowMessageInputView() + checkLobbyState() + + if (!validSessionId()) { + joinRoomWithPassword() + } else { + Log.d(TAG, "already inConversation. joinRoomWithPassword is skipped") + } + } + + override fun onError(e: Throwable) { + Log.e(TAG, "getRoomInfo - getRoom - ERROR", e) + } + + override fun onComplete() { + Log.d(TAG, "getRoomInfo - getRoom - onComplete: $startNanoTime") + + val delayForRecursiveCall = if (shouldShowLobby()) { + GET_ROOM_INFO_DELAY_LOBBY + } else { + GET_ROOM_INFO_DELAY_NORMAL + } + + if (getRoomInfoTimerHandler == null) { + getRoomInfoTimerHandler = Handler() + } + getRoomInfoTimerHandler?.postDelayed({ getRoomInfo() }, delayForRecursiveCall) + } + }) + } + } + + private fun setupSwipeToReply() { + if (this::participantPermissions.isInitialized && + participantPermissions.hasChatPermission() && + !isReadOnlyConversation() + ) { + val messageSwipeController = MessageSwipeCallback( + this, + object : MessageSwipeActions { + override fun showReplyUI(position: Int) { + val chatMessage = adapter?.items?.get(position)?.item as ChatMessage? + replyToMessage(chatMessage) + } + } + ) + + val itemTouchHelper = ItemTouchHelper(messageSwipeController) + itemTouchHelper.attachToRecyclerView(binding?.messagesListView) + } + } + + private fun handleFromNotification() { + var apiVersion = 1 + // FIXME Can this be called for guests? + if (conversationUser != null) { + apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1)) } - super.onViewBound(view) + Log.d(TAG, "handleFromNotification - getRooms - calling") + ncApi.getRooms(credentials, ApiUtils.getUrlForRooms(apiVersion, conversationUser?.baseUrl), false) + ?.subscribeOn(Schedulers.io())?.observeOn(AndroidSchedulers.mainThread()) + ?.subscribe(object : Observer { + override fun onSubscribe(d: Disposable) { + disposables.add(d) + } + + override fun onNext(roomsOverall: RoomsOverall) { + Log.d(TAG, "handleFromNotification - getRooms - got response") + for (conversation in roomsOverall.ocs!!.data!!) { + if (roomId == conversation.roomId) { + roomToken = conversation.token!! + currentConversation = conversation + participantPermissions = ParticipantPermissions(conversationUser!!, currentConversation!!) + setActionBarTitle() + getRoomInfo() + break + } + } + } + + override fun onError(e: Throwable) { + Log.e(TAG, "handleFromNotification - getRooms - ERROR: ", e) + } + + override fun onComplete() { + // unused atm + } + }) } + private fun loadAvatarForStatusBar() { + if (isOneToOneConversation()) { + val url = ApiUtils.getUrlForAvatar( + conversationUser!!.baseUrl, + currentConversation!!.name, + true + ) + val target = object : Target { + + private fun setIcon(drawable: Drawable?) { + actionBar?.let { + val avatarSize = (it.height / TOOLBAR_AVATAR_RATIO).roundToInt() + + if (drawable != null && avatarSize > 0) { + val bitmap = drawable.toBitmap(avatarSize, avatarSize) + it.setIcon(BitmapDrawable(resources, bitmap)) + } else { + Log.d(TAG, "loadAvatarForStatusBar avatarSize <= 0") + } + } + } + + override fun onStart(placeholder: Drawable?) { + this.setIcon(placeholder) + } + + override fun onSuccess(result: Drawable) { + this.setIcon(result) + } + } + + val credentials = ApiUtils.getCredentials(conversationUser!!.username, conversationUser!!.token) + + context.imageLoader.enqueue( + ImageRequest.Builder(context) + .data(url) + .addHeader("Authorization", credentials) + .placeholder(R.drawable.ic_user) + .transformations(CircleCropTransformation()) + .crossfade(true) + .target(target) + .build() + ) + } + } + + fun isOneToOneConversation() = currentConversation != null && currentConversation?.type != null && + currentConversation?.type == Conversation.ConversationType + .ROOM_TYPE_ONE_TO_ONE_CALL + private fun switchToRoom(token: String) { if (CallActivity.active) { Log.d(TAG, "CallActivity is running. Ignore to switch chat in ChatController...") @@ -927,7 +1000,7 @@ class ChatController(args: Bundle) : } if (conversationUser != null) { - activity?.runOnUiThread { + runOnUiThread { if (currentConversation?.objectType == Conversation.ObjectType.ROOM) { Toast.makeText( context, @@ -947,19 +1020,20 @@ class ChatController(args: Bundle) : bundle.putParcelable(KEY_USER_ENTITY, conversationUser) bundle.putString(KEY_ROOM_TOKEN, token) - ConductorRemapping.remapChatController( - router, - conversationUser.id!!, - token, - bundle, - true - ) + // TODO + // ConductorRemapping.remapChatController( + // router, + // conversationUser.id!!, + // token, + // bundle, + // true + // ) } } private fun showSendButtonMenu() { val popupMenu = PopupMenu( - ContextThemeWrapper(view?.context, R.style.ChatSendButtonMenu), + ContextThemeWrapper(this, R.style.ChatSendButtonMenu), binding?.messageInputView?.button, Gravity.END ) @@ -980,14 +1054,14 @@ class ChatController(args: Bundle) : private fun showCallButtonMenu(isVoiceOnlyCall: Boolean) { val anchor: View? = if (isVoiceOnlyCall) { - activity?.findViewById(R.id.conversation_voice_call) + findViewById(R.id.conversation_voice_call) } else { - activity?.findViewById(R.id.conversation_video_call) + findViewById(R.id.conversation_video_call) } if (anchor != null) { val popupMenu = PopupMenu( - ContextThemeWrapper(view?.context, R.style.CallButtonMenu), + ContextThemeWrapper(this, R.style.CallButtonMenu), anchor, Gravity.END ) @@ -1008,13 +1082,14 @@ class ChatController(args: Bundle) : } private fun startPlayback(message: ChatMessage) { - if (!this.isAttached) { - // 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. - // If user returns to chatview, the old chatview instance is not attached anymore - // and he has to click the play button again (which is considered to be okay) - return - } + // TODO check how to handle this when conductor is removed + // if (!this.isAttached) { + // // 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. + // // If user returns to chatview, the old chatview instance is not attached anymore + // // and he has to click the play button again (which is considered to be okay) + // return + // } initMediaPlayer(message) @@ -1024,7 +1099,7 @@ class ChatController(args: Bundle) : } mediaPlayerHandler = Handler() - activity?.runOnUiThread(object : Runnable { + runOnUiThread(object : Runnable { override fun run() { if (mediaPlayer != null) { val currentPosition: Int = mediaPlayer!!.currentPosition / VOICE_MESSAGE_SEEKBAR_BASE @@ -1335,25 +1410,21 @@ class ChatController(args: Bundle) : } private fun checkShowCallButtons() { - if (isAlive()) { - if (isReadOnlyConversation() || shouldShowLobby()) { - disableCallButtons() - } else { - enableCallButtons() - } + if (isReadOnlyConversation() || shouldShowLobby()) { + disableCallButtons() + } else { + enableCallButtons() } } private fun checkShowMessageInputView() { - if (isAlive()) { - if (isReadOnlyConversation() || - shouldShowLobby() || - !participantPermissions.hasChatPermission() - ) { - binding?.messageInputView?.visibility = View.GONE - } else { - binding?.messageInputView?.visibility = View.VISIBLE - } + if (isReadOnlyConversation() || + shouldShowLobby() || + !participantPermissions.hasChatPermission() + ) { + binding?.messageInputView?.visibility = View.GONE + } else { + binding?.messageInputView?.visibility = View.VISIBLE } } @@ -1401,8 +1472,7 @@ class ChatController(args: Bundle) : private fun checkLobbyState() { if (currentConversation != null && - currentConversation?.isLobbyViewApplicable(conversationUser!!) == true && - isAlive() + currentConversation?.isLobbyViewApplicable(conversationUser!!) == true ) { if (shouldShowLobby()) { binding?.lobby?.lobbyView?.visibility = View.VISIBLE @@ -1451,6 +1521,7 @@ class ChatController(args: Bundle) : @Throws(IllegalStateException::class) override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) { + super.onActivityResult(requestCode, resultCode, intent) if (resultCode != RESULT_OK && (requestCode != REQUEST_CODE_MESSAGE_SEARCH)) { Log.e(TAG, "resultCode for received intent was != ok") return @@ -1543,7 +1614,7 @@ class ChatController(args: Bundle) : } REQUEST_CODE_SELECT_CONTACT -> { val contactUri = intent?.data ?: return - val cursor: Cursor? = activity?.contentResolver!!.query(contactUri, null, null, null, null) + val cursor: Cursor? = contentResolver!!.query(contactUri, null, null, null, null) if (cursor != null && cursor.moveToFirst()) { val id = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID)) @@ -1552,7 +1623,7 @@ class ChatController(args: Bundle) : writeContactToVcfFile(cursor, file) val shareUri = FileProvider.getUriForFile( - activity!!, + this, BuildConfig.APPLICATION_ID, File(file.absolutePath) ) @@ -1627,7 +1698,7 @@ class ChatController(args: Bundle) : val lookupKey = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.LOOKUP_KEY)) val uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey) - val fd: AssetFileDescriptor = activity?.contentResolver!!.openAssetFileDescriptor(uri, "r")!! + val fd: AssetFileDescriptor = contentResolver!!.openAssetFileDescriptor(uri, "r")!! fd.use { val fis = fd.createInputStream() @@ -1645,6 +1716,7 @@ class ChatController(args: Bundle) : } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == UploadAndShareFilesWorker.REQUEST_PERMISSION) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Log.d(ConversationsListController.TAG, "upload starting after permissions were granted") @@ -1762,16 +1834,16 @@ class ChatController(args: Bundle) : } fun showBrowserScreen() { - val sharingFileBrowserIntent = Intent(activity, RemoteFileBrowserActivity::class.java) + val sharingFileBrowserIntent = Intent(this, RemoteFileBrowserActivity::class.java) startActivityForResult(sharingFileBrowserIntent, REQUEST_CODE_SELECT_REMOTE_FILES) } fun showShareLocationScreen() { Log.d(TAG, "showShareLocationScreen") - val intent = Intent(activity, LocationPickerActivity::class.java) + val intent = Intent(this, LocationPickerActivity::class.java) intent.putExtra(KEY_ROOM_TOKEN, roomToken) - activity!!.startActivity(intent) + startActivity(intent) } private fun showConversationInfoScreen() { @@ -1780,33 +1852,31 @@ class ChatController(args: Bundle) : bundle.putString(KEY_ROOM_TOKEN, roomToken) bundle.putBoolean(BundleKeys.KEY_ROOM_ONE_TO_ONE, isOneToOneConversation()) - val intent = Intent(activity, ConversationInfoActivity::class.java) + val intent = Intent(this, ConversationInfoActivity::class.java) intent.putExtras(bundle) - activity!!.startActivity(intent) + startActivity(intent) } private fun setupMentionAutocomplete() { - if (isAlive()) { - val elevation = MENTION_AUTO_COMPLETE_ELEVATION - resources?.let { - val backgroundDrawable = ColorDrawable(it.getColor(R.color.bg_default)) - val presenter = MentionAutocompletePresenter(activity, roomToken) - val callback = MentionAutocompleteCallback( - activity, - conversationUser!!, - binding?.messageInputView?.inputEditText, - viewThemeUtils - ) + val elevation = MENTION_AUTO_COMPLETE_ELEVATION + resources?.let { + val backgroundDrawable = ColorDrawable(it.getColor(R.color.bg_default)) + val presenter = MentionAutocompletePresenter(this, roomToken) + val callback = MentionAutocompleteCallback( + this, + conversationUser!!, + binding?.messageInputView?.inputEditText, + viewThemeUtils + ) - if (mentionAutocomplete == null && binding?.messageInputView?.inputEditText != null) { - mentionAutocomplete = Autocomplete.on(binding?.messageInputView?.inputEditText) - .with(elevation) - .with(backgroundDrawable) - .with(MagicCharPolicy('@')) - .with(presenter) - .with(callback) - .build() - } + if (mentionAutocomplete == null && binding?.messageInputView?.inputEditText != null) { + mentionAutocomplete = Autocomplete.on(binding?.messageInputView?.inputEditText) + .with(elevation) + .with(backgroundDrawable) + .with(MagicCharPolicy('@')) + .with(presenter) + .with(callback) + .build() } } } @@ -1817,69 +1887,6 @@ class ChatController(args: Bundle) : sessionIdAfterRoomJoined != "0" } - @Suppress("Detekt.TooGenericExceptionCaught") - override fun onAttach(view: View) { - super.onAttach(view) - logConversationInfos("onAttach") - - eventBus.register(this) - - setupWebsocket() - webSocketInstance?.getSignalingMessageReceiver()?.addListener(localParticipantMessageListener) - - if (conversationUser?.userId != "?" && - CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "mention-flag") && - activity != null - ) { - activity?.findViewById(R.id.toolbar)?.setOnClickListener { v -> showConversationInfoScreen() } - } - - val smileyButton = binding?.messageInputView?.findViewById(R.id.smileyButton) - - emojiPopup = binding?.messageInputView?.inputEditText?.let { - EmojiPopup( - rootView = view, - editText = it, - onEmojiPopupShownListener = { - if (resources != null) { - smileyButton?.setImageDrawable( - ContextCompat.getDrawable(context, R.drawable.ic_baseline_keyboard_24) - ) - } - }, - onEmojiPopupDismissListener = { - smileyButton?.setImageDrawable( - ContextCompat.getDrawable(context, R.drawable.ic_insert_emoticon_black_24dp) - ) - }, - onEmojiClickListener = { - binding?.messageInputView?.inputEditText?.editableText?.append(" ") - } - ) - } - - smileyButton?.setOnClickListener { - emojiPopup?.toggle() - } - - binding?.messageInputView?.findViewById(R.id.cancelReplyButton)?.setOnClickListener { - cancelReply() - } - - binding?.messageInputView?.findViewById(R.id.cancelReplyButton)?.let { - viewThemeUtils.platform - .themeImageButton(it) - } - - cancelNotificationsForCurrentConversation() - - if (TextUtils.isEmpty(roomToken)) { - handleFromNotification() - } else { - getRoomInfo() - } - } - private fun cancelReply() { binding?.messageInputView?.findViewById(R.id.quotedChatMessageView)?.visibility = View.GONE binding?.messageInputView?.findViewById(R.id.attachmentButton)?.visibility = View.VISIBLE @@ -1892,7 +1899,7 @@ class ChatController(args: Bundle) : try { NotificationUtils.cancelExistingNotificationsForRoom( applicationContext, - conversationUser, + conversationUser!!, roomToken!! ) } catch (e: RuntimeException) { @@ -1902,8 +1909,8 @@ class ChatController(args: Bundle) : } } - override fun onDetach(view: View) { - super.onDetach(view) + override fun onPause() { + super.onPause() logConversationInfos("onDetach") @@ -1911,9 +1918,7 @@ class ChatController(args: Bundle) : webSocketInstance?.getSignalingMessageReceiver()?.removeListener(localParticipantMessageListener) - if (activity != null) { - activity?.findViewById(R.id.toolbar)?.setOnClickListener(null) - } + findViewById(R.id.toolbar)?.setOnClickListener(null) checkingLobbyStatus = false @@ -1938,7 +1943,7 @@ class ChatController(args: Bundle) : } private fun isActivityNotChangingConfigurations(): Boolean { - return activity != null && !activity?.isChangingConfigurations!! + return !isChangingConfigurations!! } private fun isNotInCall(): Boolean { @@ -1946,8 +1951,8 @@ class ChatController(args: Bundle) : !ApplicationWideCurrentRoomHolder.getInstance().isDialing } - override val title: String - get() = + private fun setActionBarTitle() { + supportActionBar?.title = if (currentConversation?.displayName != null) { try { " " + EmojiCompat.get().process(currentConversation?.displayName as CharSequence).toString() @@ -1957,14 +1962,13 @@ class ChatController(args: Bundle) : } else { "" } + } public override fun onDestroy() { super.onDestroy() logConversationInfos("onDestroy") - if (activity != null) { - activity?.findViewById(R.id.toolbar)?.setOnClickListener(null) - } + findViewById(R.id.toolbar)?.setOnClickListener(null) if (actionBar != null) { actionBar?.setIcon(null) @@ -1991,7 +1995,7 @@ class ChatController(args: Bundle) : "Restricted to open chat controller because a call in another room is active. This is an " + "edge case which is not properly handled yet." ) - router.popToRoot() + finish() return } @@ -2178,10 +2182,10 @@ class ChatController(args: Bundle) : } binding?.messageInputView?.inputEditText?.setText("") - val replyMessageId: Int? = view?.findViewById(R.id.quotedChatMessageView)?.tag as Int? + val replyMessageId: Int? = findViewById(R.id.quotedChatMessageView)?.tag as Int? sendMessage( editable, - if (view?.findViewById(R.id.quotedChatMessageView)?.visibility == View.VISIBLE) { + if (findViewById(R.id.quotedChatMessageView)?.visibility == View.VISIBLE) { replyMessageId } else { null @@ -2198,9 +2202,9 @@ class ChatController(args: Bundle) : ncApi.sendChatMessage( credentials, - ApiUtils.getUrlForChat(apiVersion, conversationUser.baseUrl, roomToken), + ApiUtils.getUrlForChat(apiVersion, conversationUser!!.baseUrl, roomToken), message, - conversationUser.displayName, + conversationUser!!.displayName, replyTo, sendWithoutNotification ) @@ -2248,7 +2252,7 @@ class ChatController(args: Bundle) : if (conversationUser == null) { return } - webSocketInstance = WebSocketConnectionHelper.getWebSocketInstanceForUserId(conversationUser.id!!) + webSocketInstance = WebSocketConnectionHelper.getWebSocketInstanceForUserId(conversationUser!!.id!!) if (webSocketInstance == null) { Log.d(TAG, "webSocketInstance not set up. This should only happen when not using the HPB") @@ -2629,7 +2633,7 @@ class ChatController(args: Bundle) : } private fun scrollToRequestedMessageIfNeeded() { - args.getString(BundleKeys.KEY_MESSAGE_ID)?.let { + intent.getStringExtra(BundleKeys.KEY_MESSAGE_ID)?.let { scrollToMessageWithId(it) } } @@ -2654,9 +2658,9 @@ class ChatController(args: Bundle) : } } - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - super.onCreateOptionsMenu(menu, inflater) - inflater.inflate(R.menu.menu_conversation, menu) + override fun onCreateOptionsMenu(menu: Menu): Boolean { + super.onCreateOptionsMenu(menu) + menuInflater.inflate(R.menu.menu_conversation, menu) binding?.messageInputView?.context?.let { viewThemeUtils.platform.colorToolbarMenuIcon( @@ -2690,14 +2694,14 @@ class ChatController(args: Bundle) : if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "silent-call")) { Handler().post { - activity?.findViewById(R.id.conversation_voice_call)?.setOnLongClickListener { + findViewById(R.id.conversation_voice_call)?.setOnLongClickListener { showCallButtonMenu(true) true } } Handler().post { - activity?.findViewById(R.id.conversation_video_call)?.setOnLongClickListener { + findViewById(R.id.conversation_video_call)?.setOnLongClickListener { showCallButtonMenu(false) true } @@ -2707,9 +2711,10 @@ class ChatController(args: Bundle) : menu.removeItem(R.id.conversation_video_call) menu.removeItem(R.id.conversation_voice_call) } + return true } - override fun onPrepareOptionsMenu(menu: Menu) { + override fun onPrepareOptionsMenu(menu: Menu): Boolean { super.onPrepareOptionsMenu(menu) conversationUser?.let { if (CapabilitiesUtilNew.hasSpreedFeatureCapability(it, "read-only-rooms")) { @@ -2718,12 +2723,14 @@ class ChatController(args: Bundle) : val searchItem = menu.findItem(R.id.conversation_search) searchItem.isVisible = CapabilitiesUtilNew.isUnifiedSearchAvailable(it) } + return true } override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { android.R.id.home -> { - (activity as MainActivity).resetConversationsList() + // TODO + // (activity as MainActivity).resetConversationsList() true } R.id.conversation_video_call -> { @@ -2751,7 +2758,7 @@ class ChatController(args: Bundle) : } private fun showSharedItems() { - val intent = Intent(activity, SharedItemsActivity::class.java) + val intent = Intent(this, SharedItemsActivity::class.java) intent.putExtra(KEY_CONVERSATION_NAME, currentConversation?.displayName) intent.putExtra(KEY_ROOM_TOKEN, roomToken) intent.putExtra(KEY_USER_ENTITY, conversationUser as Parcelable) @@ -2759,11 +2766,11 @@ class ChatController(args: Bundle) : SharedItemsActivity.KEY_USER_IS_OWNER_OR_MODERATOR, currentConversation?.isParticipantOwnerOrModerator ) - activity!!.startActivity(intent) + startActivity(intent) } private fun startMessageSearch() { - val intent = Intent(activity, MessageSearchActivity::class.java) + val intent = Intent(this, MessageSearchActivity::class.java) intent.putExtra(KEY_CONVERSATION_NAME, currentConversation?.displayName) intent.putExtra(KEY_ROOM_TOKEN, roomToken) startActivityForResult(intent, REQUEST_CODE_MESSAGE_SEARCH) @@ -2822,7 +2829,7 @@ class ChatController(args: Bundle) : private fun startACall(isVoiceOnlyCall: Boolean, callWithoutNotification: Boolean) { currentConversation?.let { if (conversationUser != null) { - val pp = ParticipantPermissions(conversationUser, it) + val pp = ParticipantPermissions(conversationUser!!, it) if (!pp.canStartCall() && currentConversation?.hasCall == false) { Toast.makeText(context, R.string.startCallForbidden, Toast.LENGTH_LONG).show() } else { @@ -2867,13 +2874,9 @@ class ChatController(args: Bundle) : bundle.putBoolean(KEY_IS_BREAKOUT_ROOM, true) } - return if (activity != null) { - val callIntent = Intent(activity, CallActivity::class.java) - callIntent.putExtras(bundle) - callIntent - } else { - null - } + val callIntent = Intent(this, CallActivity::class.java) + callIntent.putExtras(bundle) + return callIntent } ?: run { return null } @@ -2895,16 +2898,14 @@ class ChatController(args: Bundle) : } override fun onLongClickReactions(chatMessage: ChatMessage) { - activity?.let { - ShowReactionsDialog( - activity!!, - currentConversation, - chatMessage, - conversationUser, - participantPermissions.hasChatPermission(), - ncApi - ).show() - } + ShowReactionsDialog( + this, + currentConversation, + chatMessage, + conversationUser, + participantPermissions.hasChatPermission(), + ncApi + ).show() } inner class ReactionAddedObserver : Observer { @@ -2968,16 +2969,14 @@ class ChatController(args: Bundle) : private fun openMessageActionsDialog(iMessage: IMessage?) { val message = iMessage as ChatMessage if (hasVisibleItems(message) && !isSystemMessage(message)) { - activity?.let { - MessageActionsDialog( - this, - message, - conversationUser, - currentConversation, - isShowMessageDeletionButton(message), - participantPermissions.hasChatPermission() - ).show() - } + MessageActionsDialog( + this, + message, + conversationUser, + currentConversation, + isShowMessageDeletionButton(message), + participantPermissions.hasChatPermission() + ).show() } } @@ -3093,13 +3092,14 @@ class ChatController(args: Bundle) : Parcels.wrap(roomOverall.ocs!!.data!!) ) - ConductorRemapping.remapChatController( - router, - conversationUser!!.id!!, - roomOverall.ocs!!.data!!.token!!, - bundle, - true - ) + // TODO + // ConductorRemapping.remapChatController( + // router, + // conversationUser!!.id!!, + // roomOverall.ocs!!.data!!.token!!, + // bundle, + // true + // ) } override fun onError(e: Throwable) { @@ -3127,11 +3127,13 @@ class ChatController(args: Bundle) : bundle.putBoolean(BundleKeys.KEY_FORWARD_MSG_FLAG, true) bundle.putString(BundleKeys.KEY_FORWARD_MSG_TEXT, message?.text) bundle.putString(BundleKeys.KEY_FORWARD_HIDE_SOURCE_ROOM, roomId) - router.pushController( - RouterTransaction.with(ConversationsListController(bundle)) - .pushChangeHandler(HorizontalChangeHandler()) - .popChangeHandler(HorizontalChangeHandler()) - ) + + // TODO + // router.pushController( + // RouterTransaction.with(ConversationsListController(bundle)) + // .pushChangeHandler(HorizontalChangeHandler()) + // .popChangeHandler(HorizontalChangeHandler()) + // ) } fun markAsUnread(message: IMessage?) { @@ -3170,7 +3172,7 @@ class ChatController(args: Bundle) : fun copyMessage(message: IMessage?) { val clipboardManager = - activity?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val clipData = ClipData.newPlainText( resources?.getString(R.string.nc_app_product_name), message?.text @@ -3182,7 +3184,7 @@ class ChatController(args: Bundle) : return !message.isDeleted || // copy message message.replyable || // reply to message.replyable && // reply privately - conversationUser?.userId?.isNotEmpty() == true && conversationUser.userId != "?" && + conversationUser?.userId?.isNotEmpty() == true && conversationUser!!.userId != "?" && message.user.id.startsWith("users/") && message.user.id.substring(ACTOR_LENGTH) != currentConversation?.actorId && currentConversation?.type != Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL || @@ -3309,10 +3311,10 @@ class ChatController(args: Bundle) : private fun isShowMessageDeletionButton(message: ChatMessage): Boolean { if (conversationUser == null) return false - val isUserAllowedByPrivileges = if (message.actorId == conversationUser.userId) { + val isUserAllowedByPrivileges = if (message.actorId == conversationUser!!.userId) { true } else { - currentConversation!!.canModerate(conversationUser) + currentConversation!!.canModerate(conversationUser!!) } val isOlderThanSixHours = message @@ -3397,7 +3399,7 @@ class ChatController(args: Bundle) : } override fun onNext(roomOverall: RoomOverall) { - val conversationIntent = Intent(activity, CallActivity::class.java) + val conversationIntent = Intent(context, CallActivity::class.java) val bundle = Bundle() bundle.putParcelable(KEY_USER_ENTITY, conversationUser) bundle.putString(KEY_ROOM_TOKEN, roomOverall.ocs!!.data!!.token) @@ -3411,20 +3413,21 @@ class ChatController(args: Bundle) : ) conversationIntent.putExtras(bundle) - ConductorRemapping.remapChatController( - router, - conversationUser.id!!, - roomOverall.ocs!!.data!!.token!!, - bundle, - true - ) + // TODO + // ConductorRemapping.remapChatController( + // router, + // conversationUser.id!!, + // roomOverall.ocs!!.data!!.token!!, + // bundle, + // true + // ) } else { conversationIntent.putExtras(bundle) startActivity(conversationIntent) Handler().postDelayed( { - if (!isDestroyed && !isBeingDestroyed) { - router.popCurrentController() + if (!isDestroyed) { + finish() } }, POP_CURRENT_CONTROLLER_DELAY @@ -3456,7 +3459,7 @@ class ChatController(args: Bundle) : requestCameraPermissions() } else { Intent(MediaStore.ACTION_VIDEO_CAPTURE).also { takeVideoIntent -> - takeVideoIntent.resolveActivity(activity!!.packageManager)?.also { + takeVideoIntent.resolveActivity(packageManager)?.also { val videoFile: File? = try { val outputDir = context.cacheDir val dateFormat = SimpleDateFormat(FILE_DATE_PATTERN, Locale.ROOT) @@ -3486,10 +3489,7 @@ class ChatController(args: Bundle) : val pollVoteDialog = PollCreateDialogFragment.newInstance( roomToken!! ) - pollVoteDialog.show( - (activity as MainActivity?)!!.supportFragmentManager, - TAG - ) + pollVoteDialog.show(supportFragmentManager, TAG) } fun jumpToQuotedMessage(parentMessage: ChatMessage) { diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.kt index 4bc0dad35..6e8c6d3ab 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.kt @@ -75,6 +75,7 @@ import com.nextcloud.talk.adapters.items.MessagesTextHeaderItem import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication +import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.contacts.ContactsActivity import com.nextcloud.talk.controllers.base.BaseController import com.nextcloud.talk.controllers.util.viewBinding @@ -87,7 +88,6 @@ import com.nextcloud.talk.jobs.AccountRemovalWorker import com.nextcloud.talk.jobs.ContactAddressBookWorker.Companion.run import com.nextcloud.talk.jobs.DeleteConversationWorker import com.nextcloud.talk.jobs.UploadAndShareFilesWorker -import com.nextcloud.talk.jobs.UploadAndShareFilesWorker.Companion.requestStoragePermission import com.nextcloud.talk.messagesearch.MessageSearchHelper import com.nextcloud.talk.messagesearch.MessageSearchHelper.MessageSearchResults import com.nextcloud.talk.models.json.conversations.Conversation @@ -120,7 +120,6 @@ 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.isUserStatusAvailable import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil -import com.nextcloud.talk.utils.remapchat.ConductorRemapping.remapChatController import com.nextcloud.talk.utils.rx.SearchViewObservable.Companion.observeSearchView import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder import eu.davidea.flexibleadapter.FlexibleAdapter @@ -996,7 +995,8 @@ class ConversationsListController(bundle: Bundle) : ) } } else { - requestStoragePermission(this@ConversationsListController) + // TODO + // requestStoragePermission(this@ConversationsListController) } } @@ -1132,13 +1132,18 @@ class ConversationsListController(bundle: Bundle) : bundle.putString(BundleKeys.KEY_MESSAGE_ID, selectedMessageId) selectedMessageId = null } - remapChatController( - router, - currentUser!!.id!!, - selectedConversation!!.token!!, - bundle, - false - ) + // remapChatController( + // router, + // currentUser!!.id!!, + // selectedConversation!!.token!!, + // bundle, + // false + // ) + + val intent = Intent(context, ChatActivity::class.java) + intent.putExtras(bundle) + startActivity(intent) + clearIntentAction() } diff --git a/app/src/main/java/com/nextcloud/talk/jobs/UploadAndShareFilesWorker.kt b/app/src/main/java/com/nextcloud/talk/jobs/UploadAndShareFilesWorker.kt index 4f106c609..7eb57005c 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/UploadAndShareFilesWorker.kt +++ b/app/src/main/java/com/nextcloud/talk/jobs/UploadAndShareFilesWorker.kt @@ -21,6 +21,7 @@ package com.nextcloud.talk.jobs import android.Manifest +import android.app.Activity import android.app.Notification import android.app.NotificationManager import android.app.PendingIntent @@ -39,7 +40,6 @@ import androidx.work.WorkManager import androidx.work.Worker import androidx.work.WorkerParameters import autodagger.AutoInjector -import com.bluelinelabs.conductor.Controller import com.nextcloud.talk.R import com.nextcloud.talk.activities.MainActivity import com.nextcloud.talk.api.NcApi @@ -288,11 +288,11 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa private const val ZERO_PERCENT = 0 const val REQUEST_PERMISSION = 3123 - fun requestStoragePermission(controller: Controller) { + fun requestStoragePermission(activity: Activity) { when { Build.VERSION .SDK_INT >= Build.VERSION_CODES.TIRAMISU -> { - controller.requestPermissions( + activity.requestPermissions( arrayOf( Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_VIDEO, @@ -302,7 +302,7 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa ) } Build.VERSION.SDK_INT > Build.VERSION_CODES.Q -> { - controller.requestPermissions( + activity.requestPermissions( arrayOf( Manifest.permission.READ_EXTERNAL_STORAGE ), @@ -310,7 +310,7 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa ) } else -> { - controller.requestPermissions( + activity.requestPermissions( arrayOf( Manifest.permission.WRITE_EXTERNAL_STORAGE ), diff --git a/app/src/main/java/com/nextcloud/talk/ui/bottom/sheet/ProfileBottomSheet.kt b/app/src/main/java/com/nextcloud/talk/ui/bottom/sheet/ProfileBottomSheet.kt index c524ce959..a52685e39 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/bottom/sheet/ProfileBottomSheet.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/bottom/sheet/ProfileBottomSheet.kt @@ -28,7 +28,6 @@ import android.util.Log import com.afollestad.materialdialogs.LayoutMode import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.bottomsheets.BottomSheet -import com.bluelinelabs.conductor.Router import com.nextcloud.talk.R import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.controllers.bottomsheet.items.BasicListItemWithImage @@ -42,7 +41,6 @@ import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet.AllowedAppIds.PROFI import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet.AllowedAppIds.SPREED import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.bundle.BundleKeys -import com.nextcloud.talk.utils.remapchat.ConductorRemapping import io.reactivex.Observer import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable @@ -51,7 +49,7 @@ import org.parceler.Parcels private const val TAG = "ProfileBottomSheet" -class ProfileBottomSheet(val ncApi: NcApi, val userModel: User, val router: Router) { +class ProfileBottomSheet(val ncApi: NcApi, val userModel: User) { private val allowedAppIds = listOf(SPREED.stringValue, PROFILE.stringValue, EMAIL.stringValue) @@ -170,13 +168,15 @@ class ProfileBottomSheet(val ncApi: NcApi, val userModel: User, val router: Rout BundleKeys.KEY_ACTIVE_CONVERSATION, Parcels.wrap(roomOverall.ocs!!.data) ) - ConductorRemapping.remapChatController( - router, - userModel.id!!, - roomOverall.ocs!!.data!!.token!!, - bundle, - true - ) + + // TODO + // ConductorRemapping.remapChatController( + // router, + // userModel.id!!, + // roomOverall.ocs!!.data!!.token!!, + // bundle, + // true + // ) } override fun onError(e: Throwable) { diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/AttachmentDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/AttachmentDialog.kt index 55ae66898..0171c3f0e 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/AttachmentDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/AttachmentDialog.kt @@ -32,14 +32,14 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.nextcloud.talk.R import com.nextcloud.talk.application.NextcloudTalkApplication -import com.nextcloud.talk.controllers.ChatController +import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.databinding.DialogAttachmentBinding import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew import javax.inject.Inject @AutoInjector(NextcloudTalkApplication::class) -class AttachmentDialog(val activity: Activity, var chatController: ChatController) : BottomSheetDialog(activity) { +class AttachmentDialog(val activity: Activity, var chatActivity: ChatActivity) : BottomSheetDialog(activity) { @Inject lateinit var viewThemeUtils: ViewThemeUtils @@ -61,8 +61,8 @@ class AttachmentDialog(val activity: Activity, var chatController: ChatControlle } private fun initItemsStrings() { - var serverName = CapabilitiesUtilNew.getServerName(chatController.conversationUser) - dialogAttachmentBinding.txtAttachFileFromCloud.text = chatController.resources?.let { + var serverName = CapabilitiesUtilNew.getServerName(chatActivity.conversationUser) + dialogAttachmentBinding.txtAttachFileFromCloud.text = chatActivity.resources?.let { if (serverName.isNullOrEmpty()) { serverName = it.getString(R.string.nc_server_product_name) } @@ -72,15 +72,15 @@ class AttachmentDialog(val activity: Activity, var chatController: ChatControlle private fun initItemsVisibility() { if (!CapabilitiesUtilNew.hasSpreedFeatureCapability( - chatController.conversationUser, + chatActivity.conversationUser, "geo-location-sharing" ) ) { dialogAttachmentBinding.menuShareLocation.visibility = View.GONE } - if (!CapabilitiesUtilNew.hasSpreedFeatureCapability(chatController.conversationUser, "talk-polls") || - chatController.isOneToOneConversation() + if (!CapabilitiesUtilNew.hasSpreedFeatureCapability(chatActivity.conversationUser, "talk-polls") || + chatActivity.isOneToOneConversation() ) { dialogAttachmentBinding.menuAttachPoll.visibility = View.GONE } @@ -92,37 +92,37 @@ class AttachmentDialog(val activity: Activity, var chatController: ChatControlle private fun initItemsClickListeners() { dialogAttachmentBinding.menuShareLocation.setOnClickListener { - chatController.showShareLocationScreen() + chatActivity.showShareLocationScreen() dismiss() } dialogAttachmentBinding.menuAttachFileFromLocal.setOnClickListener { - chatController.sendSelectLocalFileIntent() + chatActivity.sendSelectLocalFileIntent() dismiss() } dialogAttachmentBinding.menuAttachPictureFromCam.setOnClickListener { - chatController.sendPictureFromCamIntent() + chatActivity.sendPictureFromCamIntent() dismiss() } dialogAttachmentBinding.menuAttachVideoFromCam.setOnClickListener { - chatController.sendVideoFromCamIntent() + chatActivity.sendVideoFromCamIntent() dismiss() } dialogAttachmentBinding.menuAttachPoll.setOnClickListener { - chatController.createPoll() + chatActivity.createPoll() dismiss() } dialogAttachmentBinding.menuAttachFileFromCloud.setOnClickListener { - chatController.showBrowserScreen() + chatActivity.showBrowserScreen() dismiss() } dialogAttachmentBinding.menuAttachContact.setOnClickListener { - chatController.sendChooseContactIntent() + chatActivity.sendChooseContactIntent() dismiss() } } diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt index f9250399c..9b93117fc 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt @@ -37,7 +37,7 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.nextcloud.talk.R import com.nextcloud.talk.application.NextcloudTalkApplication -import com.nextcloud.talk.controllers.ChatController +import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.databinding.DialogMessageActionsBinding import com.nextcloud.talk.models.domain.ReactionAddedModel @@ -59,13 +59,13 @@ import javax.inject.Inject @AutoInjector(NextcloudTalkApplication::class) class MessageActionsDialog( - private val chatController: ChatController, + private val chatActivity: ChatActivity, private val message: ChatMessage, private val user: User?, private val currentConversation: Conversation?, private val showMessageDeletionButton: Boolean, private val hasChatPermission: Boolean -) : BottomSheetDialog(chatController.activity!!) { +) : BottomSheetDialog(chatActivity) { @Inject lateinit var viewThemeUtils: ViewThemeUtils @@ -233,7 +233,7 @@ class MessageActionsDialog( private fun initMenuMarkAsUnread(visible: Boolean) { if (visible) { dialogMessageActionsBinding.menuMarkAsUnread.setOnClickListener { - chatController.markAsUnread(message) + chatActivity.markAsUnread(message) dismiss() } } @@ -244,7 +244,7 @@ class MessageActionsDialog( private fun initMenuForwardMessage(visible: Boolean) { if (visible) { dialogMessageActionsBinding.menuForwardMessage.setOnClickListener { - chatController.forwardMessage(message) + chatActivity.forwardMessage(message) dismiss() } } @@ -255,7 +255,7 @@ class MessageActionsDialog( private fun initMenuDeleteMessage(visible: Boolean) { if (visible) { dialogMessageActionsBinding.menuDeleteMessage.setOnClickListener { - chatController.deleteMessage(message) + chatActivity.deleteMessage(message) dismiss() } } @@ -266,7 +266,7 @@ class MessageActionsDialog( private fun initMenuReplyPrivately(visible: Boolean) { if (visible) { dialogMessageActionsBinding.menuReplyPrivately.setOnClickListener { - chatController.replyPrivately(message) + chatActivity.replyPrivately(message) dismiss() } } @@ -277,7 +277,7 @@ class MessageActionsDialog( private fun initMenuReplyToMessage(visible: Boolean) { if (visible) { dialogMessageActionsBinding.menuReplyToMessage.setOnClickListener { - chatController.replyToMessage(message) + chatActivity.replyToMessage(message) dismiss() } } @@ -288,7 +288,7 @@ class MessageActionsDialog( private fun initMenuItemCopy(visible: Boolean) { if (visible) { dialogMessageActionsBinding.menuCopyMessage.setOnClickListener { - chatController.copyMessage(message) + chatActivity.copyMessage(message) dismiss() } } @@ -325,7 +325,7 @@ class MessageActionsDialog( override fun onNext(reactionAddedModel: ReactionAddedModel) { if (reactionAddedModel.success) { - chatController.updateUiToAddReaction( + chatActivity.updateUiToAddReaction( reactionAddedModel.chatMessage, reactionAddedModel.emoji ) @@ -348,7 +348,7 @@ class MessageActionsDialog( override fun onNext(reactionDeletedModel: ReactionDeletedModel) { if (reactionDeletedModel.success) { - chatController.updateUiToDeleteReaction( + chatActivity.updateUiToDeleteReaction( reactionDeletedModel.chatMessage, reactionDeletedModel.emoji ) diff --git a/app/src/main/java/com/nextcloud/talk/utils/remapchat/ConductorRemapping.kt b/app/src/main/java/com/nextcloud/talk/utils/remapchat/ConductorRemapping.kt index 215753556..ce212e433 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/remapchat/ConductorRemapping.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/remapchat/ConductorRemapping.kt @@ -20,128 +20,118 @@ package com.nextcloud.talk.utils.remapchat -import android.os.Bundle -import android.util.Log -import com.bluelinelabs.conductor.Router -import com.bluelinelabs.conductor.RouterTransaction -import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler -import com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler -import com.nextcloud.talk.controllers.ChatController -import com.nextcloud.talk.controllers.ConversationsListController -import com.nextcloud.talk.controllers.LockedController - object ConductorRemapping { private val TAG = ConductorRemapping::class.simpleName - fun remapChatController( - router: Router, - internalUserId: Long, - roomTokenOrId: String, - bundle: Bundle, - replaceTop: Boolean - ) { - remapChatController(router, internalUserId, roomTokenOrId, bundle, replaceTop, false) - } + // fun remapChatController( + // router: Router, + // internalUserId: Long, + // roomTokenOrId: String, + // bundle: Bundle, + // replaceTop: Boolean + // ) { + // remapChatController(router, internalUserId, roomTokenOrId, bundle, replaceTop, false) + // } - fun remapChatController( - router: Router, - internalUserId: Long, - roomTokenOrId: String, - bundle: Bundle, - replaceTop: Boolean, - pushImmediately: Boolean - ) { - val chatControllerTag = "$internalUserId@$roomTokenOrId" - - if (router.getControllerWithTag(chatControllerTag) != null) { - moveControllerToTop(router, chatControllerTag) - } else { - val pushChangeHandler = if (pushImmediately) { - SimpleSwapChangeHandler() - } else { - HorizontalChangeHandler() - } - - if (router.hasRootController()) { - val backstack = router.backstack - val topController = backstack[router.backstackSize - 1].controller - - val remapChatModel = RemapChatModel( - router, - pushChangeHandler, - chatControllerTag, - bundle - ) - - if (topController is ChatController) { - if (replaceTop) { - topController.leaveRoom(remapChatModel, this::replaceTopController) - } else { - topController.leaveRoom(remapChatModel, this::pushController) - } - } else { - if (replaceTop) { - replaceTopController(remapChatModel) - } else { - pushController(remapChatModel) - } - } - } else { - Log.d(TAG, "router has no RootController. creating backstack with ConversationsListController") - val newBackstack = listOf( - RouterTransaction.with(ConversationsListController(Bundle())) - .pushChangeHandler(HorizontalChangeHandler()) - .popChangeHandler(HorizontalChangeHandler()), - RouterTransaction.with(ChatController(bundle)) - .pushChangeHandler(HorizontalChangeHandler()) - .popChangeHandler(HorizontalChangeHandler()) - .tag(chatControllerTag) - ) - router.setBackstack(newBackstack, SimpleSwapChangeHandler()) - } - } - - if (router.getControllerWithTag(LockedController.TAG) != null) { - moveControllerToTop(router, LockedController.TAG) - } - } - - 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) { - Log.d(TAG, "moving $controllerTag to top...") - val backstack = router.backstack - var routerTransaction: RouterTransaction? = null - for (i in 0 until router.backstackSize) { - if (controllerTag == backstack[i].tag()) { - routerTransaction = backstack[i] - backstack.remove(routerTransaction) - Log.d(TAG, "removed controller: " + routerTransaction.controller) - break - } - } - - backstack.add(routerTransaction) - Log.d(TAG, "added controller to top: " + routerTransaction!!.controller) - router.setBackstack(backstack, HorizontalChangeHandler()) - } + // fun remapChatController( + // router: Router, + // internalUserId: Long, + // roomTokenOrId: String, + // bundle: Bundle, + // replaceTop: Boolean, + // pushImmediately: Boolean + // ) { + // val chatControllerTag = "$internalUserId@$roomTokenOrId" + // + // if (router.getControllerWithTag(chatControllerTag) != null) { + // moveControllerToTop(router, chatControllerTag) + // } else { + // val pushChangeHandler = if (pushImmediately) { + // SimpleSwapChangeHandler() + // } else { + // HorizontalChangeHandler() + // } + // + // if (router.hasRootController()) { + // val backstack = router.backstack + // val topController = backstack[router.backstackSize - 1].controller + // + // val remapChatModel = RemapChatModel( + // router, + // pushChangeHandler, + // chatControllerTag, + // bundle + // ) + // + // if (topController is ChatActivity) { + // if (replaceTop) { + // topController.leaveRoom(remapChatModel, this::replaceTopController) + // } else { + // topController.leaveRoom(remapChatModel, this::pushController) + // } + // } else { + // if (replaceTop) { + // replaceTopController(remapChatModel) + // } else { + // pushController(remapChatModel) + // } + // } + // } else { + // Log.d(TAG, "router has no RootController. creating backstack with ConversationsListController") + // val newBackstack = listOf( + // RouterTransaction.with(ConversationsListController(Bundle())) + // .pushChangeHandler(HorizontalChangeHandler()) + // .popChangeHandler(HorizontalChangeHandler()), + // RouterTransaction.with(ChatActivity(bundle)) + // .pushChangeHandler(HorizontalChangeHandler()) + // .popChangeHandler(HorizontalChangeHandler()) + // .tag(chatControllerTag) + // ) + // router.setBackstack(newBackstack, SimpleSwapChangeHandler()) + // } + // } + // + // if (router.getControllerWithTag(LockedController.TAG) != null) { + // moveControllerToTop(router, LockedController.TAG) + // } + // } + // + // fun pushController(remapChatModel: RemapChatModel) { + // Log.d(TAG, "pushController") + // remapChatModel.router.pushController( + // RouterTransaction.with(ChatActivity(remapChatModel.bundle)) + // .pushChangeHandler(remapChatModel.controllerChangeHandler) + // .popChangeHandler(HorizontalChangeHandler()) + // .tag(remapChatModel.chatControllerTag) + // ) + // } + // + // private fun replaceTopController(remapChatModel: RemapChatModel) { + // Log.d(TAG, "replaceTopController") + // remapChatModel.router.replaceTopController( + // RouterTransaction.with(ChatActivity(remapChatModel.bundle)) + // .pushChangeHandler(remapChatModel.controllerChangeHandler) + // .popChangeHandler(HorizontalChangeHandler()) + // .tag(remapChatModel.chatControllerTag) + // ) + // } + // + // private fun moveControllerToTop(router: Router, controllerTag: String) { + // Log.d(TAG, "moving $controllerTag to top...") + // val backstack = router.backstack + // var routerTransaction: RouterTransaction? = null + // for (i in 0 until router.backstackSize) { + // if (controllerTag == backstack[i].tag()) { + // routerTransaction = backstack[i] + // backstack.remove(routerTransaction) + // Log.d(TAG, "removed controller: " + routerTransaction.controller) + // break + // } + // } + // + // backstack.add(routerTransaction) + // Log.d(TAG, "added controller to top: " + routerTransaction!!.controller) + // router.setBackstack(backstack, HorizontalChangeHandler()) + // } } diff --git a/app/src/main/res/layout/controller_chat.xml b/app/src/main/res/layout/controller_chat.xml index 34a935ab9..26adaf994 100644 --- a/app/src/main/res/layout/controller_chat.xml +++ b/app/src/main/res/layout/controller_chat.xml @@ -32,6 +32,23 @@ android:background="@color/bg_default" android:orientation="vertical"> + + + + Date: Sun, 2 Apr 2023 20:50:41 +0200 Subject: [PATCH 02/14] leave room before joining another room refactor retrieving of extras Signed-off-by: Marcel Hibbe --- .../nextcloud/talk/activities/MainActivity.kt | 31 +++---- .../com/nextcloud/talk/chat/ChatActivity.kt | 81 ++++++++----------- 2 files changed, 45 insertions(+), 67 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt b/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt index 737bf1927..a98899fb3 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt @@ -105,9 +105,9 @@ class MainActivity : BaseActivity(), ActionBarProvider { // true // ) - val intent = Intent(context, ChatActivity::class.java) - intent.putExtras(intent.extras!!) - startActivity(intent) + val chatIntent = Intent(context, ChatActivity::class.java) + chatIntent.putExtras(intent.extras!!) + startActivity(chatIntent) logRouterBackStack(router!!) } @@ -312,17 +312,10 @@ class MainActivity : BaseActivity(), ActionBarProvider { KEY_ACTIVE_CONVERSATION, Parcels.wrap(roomOverall.ocs!!.data) ) - // remapChatController( - // router!!, - // currentUser!!.id!!, - // roomOverall.ocs!!.data!!.token!!, - // bundle, - // true - // ) - val intent = Intent(context, ChatActivity::class.java) - intent.putExtras(bundle) - startActivity(intent) + val chatIntent = Intent(context, ChatActivity::class.java) + chatIntent.putExtras(bundle) + startActivity(chatIntent) } override fun onError(e: Throwable) { @@ -386,9 +379,9 @@ class MainActivity : BaseActivity(), ActionBarProvider { // true // ) - val intent = Intent(context, ChatActivity::class.java) - intent.putExtras(intent.extras!!) - startActivity(intent) + val chatIntent = Intent(context, ChatActivity::class.java) + chatIntent.putExtras(intent.extras!!) + startActivity(chatIntent) logRouterBackStack(router!!) } @@ -412,9 +405,9 @@ class MainActivity : BaseActivity(), ActionBarProvider { // true // ) - val intent = Intent(context, ChatActivity::class.java) - intent.putExtras(intent.extras!!) - startActivity(intent) + val chatIntent = Intent(context, ChatActivity::class.java) + chatIntent.putExtras(intent.extras!!) + startActivity(chatIntent) logRouterBackStack(router!!) } diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index b7e4bd954..9a8fabd61 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -180,7 +180,6 @@ 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.database.user.CapabilitiesUtilNew import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil -import com.nextcloud.talk.utils.remapchat.RemapChatModel import com.nextcloud.talk.utils.rx.DisposableSet import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder import com.nextcloud.talk.utils.text.Spans @@ -255,7 +254,7 @@ class ChatActivity : var layoutManager: LinearLayoutManager? = null var pullChatMessagesPending = false var newMessagesCount = 0 - var startCallFromNotification: Boolean? = null + var startCallFromNotification: Boolean = false var startCallFromRoomSwitch: Boolean = false lateinit var roomId: String var voiceOnly: Boolean = true @@ -308,24 +307,25 @@ class ChatActivity : setupSystemColors() setContentView(binding.root) - conversationUser = intent.getParcelableExtra(KEY_USER_ENTITY) - roomId = intent.getStringExtra(KEY_ROOM_ID)!! - roomToken = intent.getStringExtra(KEY_ROOM_TOKEN)!! - sharedText = intent.getStringExtra(BundleKeys.KEY_SHARED_TEXT)!! + val extras: Bundle? = intent.extras + + conversationUser = extras?.getParcelable(KEY_USER_ENTITY) + roomId = extras?.getString(KEY_ROOM_ID).orEmpty() + roomToken = extras?.getString(KEY_ROOM_TOKEN).orEmpty() + + sharedText = extras?.getString(BundleKeys.KEY_SHARED_TEXT).orEmpty() Log.d(TAG, " roomToken = $roomToken") - if (roomToken.isNullOrEmpty()) { + if (roomToken.isEmpty()) { Log.d(TAG, " roomToken was null or empty!") } if (intent.hasExtra(KEY_ACTIVE_CONVERSATION)) { - currentConversation = Parcels.unwrap(intent.getParcelableExtra(KEY_ACTIVE_CONVERSATION)) + currentConversation = Parcels.unwrap(extras?.getParcelable(KEY_ACTIVE_CONVERSATION)) participantPermissions = ParticipantPermissions(conversationUser!!, currentConversation!!) } - if (intent.hasExtra(BundleKeys.KEY_CONVERSATION_PASSWORD)) { - roomPassword = intent.getStringExtra(BundleKeys.KEY_CONVERSATION_PASSWORD)!! - } + roomPassword = extras?.getString(BundleKeys.KEY_CONVERSATION_PASSWORD).orEmpty() credentials = if (conversationUser?.userId == "?") { null @@ -333,15 +333,10 @@ class ChatActivity : ApiUtils.getCredentials(conversationUser!!.username, conversationUser!!.token) } - if (intent.hasExtra(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL)) { - startCallFromNotification = intent.getBooleanExtra(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL, false) - } + startCallFromNotification = extras?.getBoolean(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL, false) == true + startCallFromRoomSwitch = extras?.getBoolean(BundleKeys.KEY_SWITCH_TO_ROOM_AND_START_CALL, false) == true - if (intent.hasExtra(BundleKeys.KEY_SWITCH_TO_ROOM_AND_START_CALL)) { - startCallFromRoomSwitch = intent.getBooleanExtra(BundleKeys.KEY_SWITCH_TO_ROOM_AND_START_CALL, false) - } - - voiceOnly = intent.getBooleanExtra(BundleKeys.KEY_CALL_VOICE_ONLY, false) + voiceOnly = extras?.getBoolean(BundleKeys.KEY_CALL_VOICE_ONLY, false) == true } @SuppressLint("ClickableViewAccessibility") @@ -1020,14 +1015,11 @@ class ChatActivity : bundle.putParcelable(KEY_USER_ENTITY, conversationUser) bundle.putString(KEY_ROOM_TOKEN, token) - // TODO - // ConductorRemapping.remapChatController( - // router, - // conversationUser.id!!, - // token, - // bundle, - // true - // ) + leaveRoom { + val chatIntent = Intent(context, ChatActivity::class.java) + chatIntent.putExtras(bundle) + startActivity(chatIntent) + } } } @@ -1929,7 +1921,7 @@ class ChatActivity : if (conversationUser != null && isActivityNotChangingConfigurations() && isNotInCall()) { ApplicationWideCurrentRoomHolder.getInstance().clear() if (validSessionId()) { - leaveRoom(null, null) + leaveRoom(null) } else { Log.d(TAG, "not leaving room (validSessionId is false)") } @@ -2097,8 +2089,7 @@ class ChatActivity : } fun leaveRoom( - remapChatModel: RemapChatModel?, - funToCallWhenLeaveSuccessful: ((RemapChatModel) -> Unit)? + funToCallWhenLeaveSuccessful: (() -> Unit)? ) { logConversationInfos("leaveRoom") @@ -2144,9 +2135,9 @@ class ChatActivity : sessionIdAfterRoomJoined = "0" - if (remapChatModel != null && funToCallWhenLeaveSuccessful != null) { + if (funToCallWhenLeaveSuccessful != null) { Log.d(TAG, "a callback action was set and is now executed because room was left successfully") - funToCallWhenLeaveSuccessful(remapChatModel) + funToCallWhenLeaveSuccessful() } else { Log.d(TAG, "remapChatController was not set") } @@ -3092,14 +3083,11 @@ class ChatActivity : Parcels.wrap(roomOverall.ocs!!.data!!) ) - // TODO - // ConductorRemapping.remapChatController( - // router, - // conversationUser!!.id!!, - // roomOverall.ocs!!.data!!.token!!, - // bundle, - // true - // ) + leaveRoom { + val chatIntent = Intent(context, ChatActivity::class.java) + chatIntent.putExtras(bundle) + startActivity(chatIntent) + } } override fun onError(e: Throwable) { @@ -3413,14 +3401,11 @@ class ChatActivity : ) conversationIntent.putExtras(bundle) - // TODO - // ConductorRemapping.remapChatController( - // router, - // conversationUser.id!!, - // roomOverall.ocs!!.data!!.token!!, - // bundle, - // true - // ) + leaveRoom { + val chatIntent = Intent(context, ChatActivity::class.java) + chatIntent.putExtras(bundle) + startActivity(chatIntent) + } } else { conversationIntent.putExtras(bundle) startActivity(conversationIntent) From 63b24557451eb73eae5812f5bbda9eb08b9e7a2e Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Sun, 2 Apr 2023 20:55:15 +0200 Subject: [PATCH 03/14] remove KEY_OPEN_CHAT this was temporarily used until now Chat is an Activity Signed-off-by: Marcel Hibbe --- .../nextcloud/talk/activities/MainActivity.kt | 19 -------- .../talk/contacts/ContactsActivity.kt | 43 ++++++------------- .../nextcloud/talk/utils/bundle/BundleKeys.kt | 1 - 3 files changed, 13 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt b/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt index a98899fb3..b89204974 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt @@ -93,25 +93,6 @@ class MainActivity : BaseActivity(), ActionBarProvider { router = Conductor.attachRouter(this, binding.controllerContainer, savedInstanceState) - // TODO: delete this. open chats directly via intent - if (intent.getBooleanExtra(BundleKeys.KEY_OPEN_CHAT, false)) { - logRouterBackStack(router!!) - // remapChatController( - // router!!, - // intent.getParcelableExtra(KEY_USER_ENTITY)!!.id!!, - // intent.getStringExtra(KEY_ROOM_TOKEN)!!, - // intent.extras!!, - // true, - // true - // ) - - val chatIntent = Intent(context, ChatActivity::class.java) - chatIntent.putExtras(intent.extras!!) - startActivity(chatIntent) - - logRouterBackStack(router!!) - } - if (intent.hasExtra(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL)) { onNewIntent(intent) } else if (!router!!.hasRootController()) { diff --git a/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivity.kt b/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivity.kt index 74c128dde..1052cc12b 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivity.kt @@ -46,11 +46,11 @@ import autodagger.AutoInjector import com.bluelinelabs.logansquare.LoganSquare import com.nextcloud.talk.R import com.nextcloud.talk.activities.BaseActivity -import com.nextcloud.talk.activities.MainActivity import com.nextcloud.talk.adapters.items.ContactItem import com.nextcloud.talk.adapters.items.GenericTextHeaderItem import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.application.NextcloudTalkApplication +import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.databinding.ControllerContactsRvBinding @@ -68,7 +68,6 @@ import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.bundle.BundleKeys -import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_OPEN_CHAT import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.SelectableAdapter @@ -376,12 +375,10 @@ class ContactsActivity : Parcels.wrap(roomOverall.ocs!!.data!!) ) - // TODO: go directly to ChatActivity when conductor is removed - bundle.putBoolean(KEY_OPEN_CHAT, true) - val intent = Intent(context, MainActivity::class.java) - intent.putExtras(bundle) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - startActivity(intent) + val chatIntent = Intent(context, ChatActivity::class.java) + chatIntent.putExtras(bundle) + chatIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + startActivity(chatIntent) } override fun onError(e: Throwable) { @@ -759,23 +756,11 @@ class ContactsActivity : @Subscribe(threadMode = ThreadMode.MAIN) fun onMessageEvent(openConversationEvent: OpenConversationEvent) { - // ConductorRemapping.remapChatController( - // router, - // currentUser!!.id!!, - // openConversationEvent.conversation!!.token!!, - // openConversationEvent.bundle!!, - // true - // ) + val chatIntent = Intent(context, ChatActivity::class.java) + chatIntent.putExtras(openConversationEvent.bundle!!) + chatIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + startActivity(chatIntent) - // TODO: go directly to ChatActivity when conductor is removed - - var bundle = openConversationEvent.bundle!! - - bundle.putBoolean(KEY_OPEN_CHAT, true) - val intent = Intent(context, MainActivity::class.java) - intent.putExtras(bundle) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - startActivity(intent) contactsBottomDialog?.dismiss() } @@ -847,12 +832,10 @@ class ContactsActivity : Parcels.wrap(roomOverall.ocs!!.data!!) ) - // TODO: go directly to ChatActivity when conductor is removed - bundle.putBoolean(KEY_OPEN_CHAT, true) - val intent = Intent(context, MainActivity::class.java) - intent.putExtras(bundle) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - startActivity(intent) + val chatIntent = Intent(context, ChatActivity::class.java) + chatIntent.putExtras(bundle) + chatIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + startActivity(chatIntent) } override fun onError(e: Throwable) { diff --git a/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt b/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt index 611a1093c..4b643b1ed 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt @@ -86,5 +86,4 @@ object BundleKeys { const val KEY_DISMISS_RECORDING_URL = "KEY_DISMISS_RECORDING_URL" const val KEY_SHARE_RECORDING_TO_CHAT_URL = "KEY_SHARE_RECORDING_TO_CHAT_URL" const val KEY_GEOCODING_RESULT = "KEY_GEOCODING_RESULT" - const val KEY_OPEN_CHAT = "KEY_OPEN_CHAT" // just temporarily used until conductor is deleted } From 5fc69201fe8578fea44b9ab1e5f2d1fa8ca8a8f6 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Sun, 2 Apr 2023 21:03:32 +0200 Subject: [PATCH 04/14] fix to open Conversation List for onBackPressed when switched chats Signed-off-by: Marcel Hibbe --- app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 9a8fabd61..549135347 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -1018,6 +1018,7 @@ class ChatActivity : leaveRoom { val chatIntent = Intent(context, ChatActivity::class.java) chatIntent.putExtras(bundle) + chatIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) startActivity(chatIntent) } } @@ -3086,6 +3087,7 @@ class ChatActivity : leaveRoom { val chatIntent = Intent(context, ChatActivity::class.java) chatIntent.putExtras(bundle) + chatIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) startActivity(chatIntent) } } @@ -3404,6 +3406,7 @@ class ChatActivity : leaveRoom { val chatIntent = Intent(context, ChatActivity::class.java) chatIntent.putExtras(bundle) + chatIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) startActivity(chatIntent) } } else { From 906c1f7529360ddb075740cc2283430e750fd1fa Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Sun, 2 Apr 2023 21:41:27 +0200 Subject: [PATCH 05/14] fix to show avatar, fix onClick listener Signed-off-by: Marcel Hibbe --- app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 549135347..32b498923 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -352,7 +352,7 @@ class ChatActivity : if (conversationUser?.userId != "?" && CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "mention-flag") ) { - findViewById(R.id.toolbar)?.setOnClickListener { v -> showConversationInfoScreen() } + binding.chatToolbar.setOnClickListener { v -> showConversationInfoScreen() } } val smileyButton = binding?.messageInputView?.findViewById(R.id.smileyButton) @@ -948,7 +948,7 @@ class ChatActivity : val target = object : Target { private fun setIcon(drawable: Drawable?) { - actionBar?.let { + supportActionBar?.let { val avatarSize = (it.height / TOOLBAR_AVATAR_RATIO).roundToInt() if (drawable != null && avatarSize > 0) { From 52266a563266ec1c7fef5060156bfc74847e7aad Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Mon, 3 Apr 2023 10:11:39 +0200 Subject: [PATCH 06/14] fix NPE when quoted message is expired or deleted for now the message is shown empty. should be improved! D/AndroidRuntime: Shutting down VM E/AndroidRuntime: FATAL EXCEPTION: main Process: com.nextcloud.talk2, PID: 29567 java.lang.NullPointerException at com.nextcloud.talk.models.json.chat.ChatMessage.getText(ChatMessage.kt:264) at com.nextcloud.talk.adapters.messages.OutcomingTextMessageViewHolder.processParentMessage(OutcomingTextMessageViewHolder.kt:168) at com.nextcloud.talk.adapters.messages.OutcomingTextMessageViewHolder.onBind(OutcomingTextMessageViewHolder.kt:100) at com.nextcloud.talk.adapters.messages.OutcomingTextMessageViewHolder.onBind(OutcomingTextMessageViewHolder.kt:54) at com.stfalcon.chatkit.messages.MessageHolders.bind(MessageHolders.java:596) at com.stfalcon.chatkit.messages.MessagesListAdapter.onBindViewHolder(MessagesListAdapter.java:110) at com.nextcloud.talk.adapters.messages.TalkMessagesListAdapter.onBindViewHolder(TalkMessagesListAdapter.java:50) at com.nextcloud.talk.adapters.messages.TalkMessagesListAdapter.onBindViewHolder(TalkMessagesListAdapter.java:32) at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7678) at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7761) at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6582) at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6848) at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6688) at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6684) at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2362) at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1662) at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1622) at androidx.recyclerview.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1425) at androidx.recyclerview.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:1158) at androidx.recyclerview.widget.RecyclerView.scrollStep(RecyclerView.java:2009) at androidx.recyclerview.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:5789) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1301) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1309) at android.view.Choreographer.doCallbacks(Choreographer.java:923) at android.view.Choreographer.doFrame(Choreographer.java:847) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1283) at android.os.Handler.handleCallback(Handler.java:942) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:226) at android.os.Looper.loop(Looper.java:313) at android.app.ActivityThread.main(ActivityThread.java:8741) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067) Signed-off-by: Marcel Hibbe --- .../java/com/nextcloud/talk/models/json/chat/ChatMessage.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.kt b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.kt index 79f99f5b0..b8045faf3 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.kt @@ -261,7 +261,11 @@ data class ChatMessage( } override fun getText(): String { - return getParsedMessage(message, messageParameters)!! + return if (message != null) { + getParsedMessage(message, messageParameters)!! + } else { + "" + } } /*} else if (getCalculateMessageType().equals(MessageType.SINGLE_LINK_MESSAGE)) { From 0b0387115e6e681f25f07ee109d95721ab5117fc Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Mon, 3 Apr 2023 10:25:43 +0200 Subject: [PATCH 07/14] fix to open poll dialog Signed-off-by: Marcel Hibbe --- .../talk/adapters/messages/IncomingPollMessageViewHolder.kt | 4 ++-- .../talk/adapters/messages/OutcomingPollMessageViewHolder.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingPollMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingPollMessageViewHolder.kt index 125ddae46..4960daf89 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingPollMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingPollMessageViewHolder.kt @@ -28,10 +28,10 @@ import androidx.core.content.ContextCompat import autodagger.AutoInjector import coil.load 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.application.NextcloudTalkApplication.Companion.sharedApplication +import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.databinding.ItemCustomIncomingPollMessageBinding import com.nextcloud.talk.extensions.loadBotsAvatar import com.nextcloud.talk.extensions.loadChangelogBotAvatar @@ -136,7 +136,7 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) : MessageH pollName ) pollVoteDialog.show( - (binding.messagePollIcon.context as MainActivity).supportFragmentManager, + (binding.messagePollIcon.context as ChatActivity).supportFragmentManager, TAG ) } diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt index 1963725f6..f73619641 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt @@ -29,10 +29,10 @@ import androidx.appcompat.content.res.AppCompatResources import autodagger.AutoInjector import coil.load 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.application.NextcloudTalkApplication.Companion.sharedApplication +import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.databinding.ItemCustomOutcomingPollMessageBinding import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.models.json.chat.ReadStatus @@ -160,7 +160,7 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag pollName ) pollVoteDialog.show( - (binding.messagePollIcon.context as MainActivity).supportFragmentManager, + (binding.messagePollIcon.context as ChatActivity).supportFragmentManager, TAG ) } From 708beabe9d88e6b6cb9cdc37d576320b2f092331 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Mon, 3 Apr 2023 12:49:32 +0200 Subject: [PATCH 08/14] setup adapter in onCreate + extract some functions from onResume Signed-off-by: Marcel Hibbe --- .../com/nextcloud/talk/chat/ChatActivity.kt | 424 +++++++++--------- 1 file changed, 217 insertions(+), 207 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 32b498923..1f4c60201 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -337,9 +337,13 @@ class ChatActivity : startCallFromRoomSwitch = extras?.getBoolean(BundleKeys.KEY_SWITCH_TO_ROOM_AND_START_CALL, false) == true voiceOnly = extras?.getBoolean(BundleKeys.KEY_CALL_VOICE_ONLY, false) == true + + binding.progressBar.visibility = View.VISIBLE + + initAdapter() + binding.messagesListView.setAdapter(adapter) } - @SuppressLint("ClickableViewAccessibility") @Suppress("Detekt.TooGenericExceptionCaught") override fun onResume() { super.onResume() @@ -355,33 +359,7 @@ class ChatActivity : binding.chatToolbar.setOnClickListener { v -> showConversationInfoScreen() } } - val smileyButton = binding?.messageInputView?.findViewById(R.id.smileyButton) - - emojiPopup = binding?.messageInputView?.inputEditText?.let { - EmojiPopup( - rootView = binding.root, - editText = it, - onEmojiPopupShownListener = { - if (resources != null) { - smileyButton?.setImageDrawable( - ContextCompat.getDrawable(context, R.drawable.ic_baseline_keyboard_24) - ) - } - }, - onEmojiPopupDismissListener = { - smileyButton?.setImageDrawable( - ContextCompat.getDrawable(context, R.drawable.ic_insert_emoticon_black_24dp) - ) - }, - onEmojiClickListener = { - binding?.messageInputView?.inputEditText?.editableText?.append(" ") - } - ) - } - - smileyButton?.setOnClickListener { - emojiPopup?.toggle() - } + initSmileyKeyboardToggler() binding?.messageInputView?.findViewById(R.id.cancelReplyButton)?.setOnClickListener { cancelReply() @@ -402,139 +380,6 @@ class ChatActivity : actionBar?.show() - if (adapter == null) { - binding?.progressBar?.visibility = View.VISIBLE - - val messageHolders = MessageHolders() - val profileBottomSheet = ProfileBottomSheet(ncApi, conversationUser!!) - - val payload = - MessagePayload(roomToken!!, currentConversation?.isParticipantOwnerOrModerator, profileBottomSheet) - - messageHolders.setIncomingTextConfig( - IncomingTextMessageViewHolder::class.java, - R.layout.item_custom_incoming_text_message, - payload - ) - messageHolders.setOutcomingTextConfig( - OutcomingTextMessageViewHolder::class.java, - R.layout.item_custom_outcoming_text_message - ) - - messageHolders.setIncomingImageConfig( - IncomingPreviewMessageViewHolder::class.java, - R.layout.item_custom_incoming_preview_message, - payload - ) - - messageHolders.setOutcomingImageConfig( - OutcomingPreviewMessageViewHolder::class.java, - R.layout.item_custom_outcoming_preview_message - ) - - messageHolders.registerContentType( - CONTENT_TYPE_SYSTEM_MESSAGE, - SystemMessageViewHolder::class.java, - R.layout.item_system_message, - SystemMessageViewHolder::class.java, - R.layout.item_system_message, - this - ) - - messageHolders.registerContentType( - CONTENT_TYPE_UNREAD_NOTICE_MESSAGE, - UnreadNoticeMessageViewHolder::class.java, - R.layout.item_date_header, - UnreadNoticeMessageViewHolder::class.java, - R.layout.item_date_header, - this - ) - - messageHolders.registerContentType( - CONTENT_TYPE_LOCATION, - IncomingLocationMessageViewHolder::class.java, - payload, - R.layout.item_custom_incoming_location_message, - OutcomingLocationMessageViewHolder::class.java, - null, - R.layout.item_custom_outcoming_location_message, - this - ) - - messageHolders.registerContentType( - CONTENT_TYPE_VOICE_MESSAGE, - IncomingVoiceMessageViewHolder::class.java, - payload, - R.layout.item_custom_incoming_voice_message, - OutcomingVoiceMessageViewHolder::class.java, - null, - R.layout.item_custom_outcoming_voice_message, - this - ) - - messageHolders.registerContentType( - CONTENT_TYPE_POLL, - IncomingPollMessageViewHolder::class.java, - payload, - R.layout.item_custom_incoming_poll_message, - OutcomingPollMessageViewHolder::class.java, - payload, - R.layout.item_custom_outcoming_poll_message, - this - ) - - messageHolders.registerContentType( - CONTENT_TYPE_LINK_PREVIEW, - IncomingLinkPreviewMessageViewHolder::class.java, - payload, - R.layout.item_custom_incoming_link_preview_message, - OutcomingLinkPreviewMessageViewHolder::class.java, - payload, - R.layout.item_custom_outcoming_link_preview_message, - this - ) - - val senderId = if (!conversationUser!!.userId.equals("?")) { - "users/" + conversationUser!!.userId - } else { - currentConversation?.actorType + "/" + currentConversation?.actorId - } - - Log.d(TAG, "Initialize TalkMessagesListAdapter with senderId: $senderId") - - adapter = TalkMessagesListAdapter( - senderId, - messageHolders, - ImageLoader { imageView, url, placeholder -> - imageView.loadAvatarOrImagePreview(url!!, conversationUser!!, placeholder as Drawable?) - }, - this - ) - } else { - binding?.messagesListView?.visibility = View.VISIBLE - } - - binding?.messagesListView?.setAdapter(adapter) - adapter?.setLoadMoreListener(this) - adapter?.setDateHeadersFormatter { format(it) } - adapter?.setOnMessageViewLongClickListener { view, message -> onMessageViewLongClick(view, message) } - - adapter?.registerViewClickListener( - R.id.playPauseBtn - ) { view, message -> - val filename = message.selectedIndividualHashMap!!["name"] - val file = File(context.cacheDir, filename!!) - if (file.exists()) { - if (message.isPlayingVoiceMessage) { - pausePlayback(message) - } else { - startPlayback(message) - } - } else { - downloadFileToCache(message) - } - } - setupSwipeToReply() layoutManager = binding?.messagesListView?.layoutManager as LinearLayoutManager? @@ -650,6 +495,191 @@ class ChatActivity : uploadFile(it.toString(), false) } + initVoiceRecordButton() + + binding?.messageInputView?.inputEditText?.setText(sharedText) + binding?.messageInputView?.setAttachmentsListener { + AttachmentDialog(this, this).show() + } + + binding?.messageInputView?.button?.setOnClickListener { submitMessage(false) } + + if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "silent-send")) { + binding?.messageInputView?.button?.setOnLongClickListener { + showSendButtonMenu() + true + } + } + + binding?.messageInputView?.button?.contentDescription = + resources?.getString(R.string.nc_description_send_message_button) + + binding?.messageInputView?.button?.let { viewThemeUtils.platform.colorImageView(it) } + + if (currentConversation != null && currentConversation?.roomId != null) { + loadAvatarForStatusBar() + setActionBarTitle() + } + } + + private fun setupActionBar() { + setSupportActionBar(binding.chatToolbar) + binding.chatToolbar.setNavigationOnClickListener { + onBackPressed() + } + supportActionBar?.setDisplayHomeAsUpEnabled(true) + supportActionBar?.setDisplayShowHomeEnabled(true) + supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(R.color.transparent))) + setActionBarTitle() + } + + private fun setupSystemColors() { + DisplayUtils.applyColorToStatusBar( + this, + ResourcesCompat.getColor( + resources, + R.color.appbar, + null + ) + ) + DisplayUtils.applyColorToNavigationBar( + this.window, + ResourcesCompat.getColor(resources, R.color.bg_default, null) + ) + } + + private fun initAdapter() { + val senderId = if (!conversationUser!!.userId.equals("?")) { + "users/" + conversationUser!!.userId + } else { + currentConversation?.actorType + "/" + currentConversation?.actorId + } + + Log.d(TAG, "Initialize TalkMessagesListAdapter with senderId: $senderId") + + adapter = TalkMessagesListAdapter( + senderId, + initMessageHolders(), + ImageLoader { imageView, url, placeholder -> + imageView.loadAvatarOrImagePreview(url!!, conversationUser!!, placeholder as Drawable?) + }, + this + ) + + adapter?.setLoadMoreListener(this) + adapter?.setDateHeadersFormatter { format(it) } + adapter?.setOnMessageViewLongClickListener { view, message -> onMessageViewLongClick(view, message) } + adapter?.registerViewClickListener( + R.id.playPauseBtn + ) { view, message -> + val filename = message.selectedIndividualHashMap!!["name"] + val file = File(context.cacheDir, filename!!) + if (file.exists()) { + if (message.isPlayingVoiceMessage) { + pausePlayback(message) + } else { + startPlayback(message) + } + } else { + downloadFileToCache(message) + } + } + } + + private fun initMessageHolders(): MessageHolders { + val messageHolders = MessageHolders() + val profileBottomSheet = ProfileBottomSheet(ncApi, conversationUser!!) + + val payload = + MessagePayload(roomToken!!, currentConversation?.isParticipantOwnerOrModerator, profileBottomSheet) + + messageHolders.setIncomingTextConfig( + IncomingTextMessageViewHolder::class.java, + R.layout.item_custom_incoming_text_message, + payload + ) + messageHolders.setOutcomingTextConfig( + OutcomingTextMessageViewHolder::class.java, + R.layout.item_custom_outcoming_text_message + ) + + messageHolders.setIncomingImageConfig( + IncomingPreviewMessageViewHolder::class.java, + R.layout.item_custom_incoming_preview_message, + payload + ) + + messageHolders.setOutcomingImageConfig( + OutcomingPreviewMessageViewHolder::class.java, + R.layout.item_custom_outcoming_preview_message + ) + + messageHolders.registerContentType( + CONTENT_TYPE_SYSTEM_MESSAGE, + SystemMessageViewHolder::class.java, + R.layout.item_system_message, + SystemMessageViewHolder::class.java, + R.layout.item_system_message, + this + ) + + messageHolders.registerContentType( + CONTENT_TYPE_UNREAD_NOTICE_MESSAGE, + UnreadNoticeMessageViewHolder::class.java, + R.layout.item_date_header, + UnreadNoticeMessageViewHolder::class.java, + R.layout.item_date_header, + this + ) + + messageHolders.registerContentType( + CONTENT_TYPE_LOCATION, + IncomingLocationMessageViewHolder::class.java, + payload, + R.layout.item_custom_incoming_location_message, + OutcomingLocationMessageViewHolder::class.java, + null, + R.layout.item_custom_outcoming_location_message, + this + ) + + messageHolders.registerContentType( + CONTENT_TYPE_VOICE_MESSAGE, + IncomingVoiceMessageViewHolder::class.java, + payload, + R.layout.item_custom_incoming_voice_message, + OutcomingVoiceMessageViewHolder::class.java, + null, + R.layout.item_custom_outcoming_voice_message, + this + ) + + messageHolders.registerContentType( + CONTENT_TYPE_POLL, + IncomingPollMessageViewHolder::class.java, + payload, + R.layout.item_custom_incoming_poll_message, + OutcomingPollMessageViewHolder::class.java, + payload, + R.layout.item_custom_outcoming_poll_message, + this + ) + + messageHolders.registerContentType( + CONTENT_TYPE_LINK_PREVIEW, + IncomingLinkPreviewMessageViewHolder::class.java, + payload, + R.layout.item_custom_incoming_link_preview_message, + OutcomingLinkPreviewMessageViewHolder::class.java, + payload, + R.layout.item_custom_outcoming_link_preview_message, + this + ) + return messageHolders + } + + @SuppressLint("ClickableViewAccessibility") + private fun initVoiceRecordButton() { showMicrophoneButton(true) binding?.messageInputView?.messageInput?.doAfterTextChanged { @@ -765,56 +795,36 @@ class ChatActivity : return v?.onTouchEvent(event) ?: true } }) - - binding?.messageInputView?.inputEditText?.setText(sharedText) - binding?.messageInputView?.setAttachmentsListener { - AttachmentDialog(this, this).show() - } - - binding?.messageInputView?.button?.setOnClickListener { submitMessage(false) } - - if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "silent-send")) { - binding?.messageInputView?.button?.setOnLongClickListener { - showSendButtonMenu() - true - } - } - - binding?.messageInputView?.button?.contentDescription = - resources?.getString(R.string.nc_description_send_message_button) - - binding?.messageInputView?.button?.let { viewThemeUtils.platform.colorImageView(it) } - - if (currentConversation != null && currentConversation?.roomId != null) { - loadAvatarForStatusBar() - setActionBarTitle() - } } - private fun setupActionBar() { - setSupportActionBar(binding.chatToolbar) - binding.chatToolbar.setNavigationOnClickListener { - onBackPressed() - } - supportActionBar?.setDisplayHomeAsUpEnabled(true) - supportActionBar?.setDisplayShowHomeEnabled(true) - supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(R.color.transparent))) - setActionBarTitle() - } + private fun initSmileyKeyboardToggler() { + val smileyButton = binding?.messageInputView?.findViewById(R.id.smileyButton) - private fun setupSystemColors() { - DisplayUtils.applyColorToStatusBar( - this, - ResourcesCompat.getColor( - resources, - R.color.appbar, - null + emojiPopup = binding?.messageInputView?.inputEditText?.let { + EmojiPopup( + rootView = binding.root, + editText = it, + onEmojiPopupShownListener = { + if (resources != null) { + smileyButton?.setImageDrawable( + ContextCompat.getDrawable(context, R.drawable.ic_baseline_keyboard_24) + ) + } + }, + onEmojiPopupDismissListener = { + smileyButton?.setImageDrawable( + ContextCompat.getDrawable(context, R.drawable.ic_insert_emoticon_black_24dp) + ) + }, + onEmojiClickListener = { + binding?.messageInputView?.inputEditText?.editableText?.append(" ") + } ) - ) - DisplayUtils.applyColorToNavigationBar( - this.window, - ResourcesCompat.getColor(resources, R.color.bg_default, null) - ) + } + + smileyButton?.setOnClickListener { + emojiPopup?.toggle() + } } private fun getRoomInfo() { From da9edbce9749fc95a0559c6810d6d71fa868821a Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Mon, 3 Apr 2023 13:31:04 +0200 Subject: [PATCH 09/14] temporarily allow only portrait for chat until MVVM is used Signed-off-by: Marcel Hibbe --- app/src/main/AndroidManifest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 57a515233..27a5f6d87 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -220,7 +220,8 @@ + android:theme="@style/AppTheme" + android:screenOrientation="portrait" /> From 9e66c3192c92df6213d0f89dbcca4738b2f3482e Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Mon, 3 Apr 2023 14:17:56 +0200 Subject: [PATCH 10/14] fix to open chat via bottom menu Signed-off-by: Marcel Hibbe --- .../talk/ui/bottom/sheet/ProfileBottomSheet.kt | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/ui/bottom/sheet/ProfileBottomSheet.kt b/app/src/main/java/com/nextcloud/talk/ui/bottom/sheet/ProfileBottomSheet.kt index a52685e39..355355dc6 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/bottom/sheet/ProfileBottomSheet.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/bottom/sheet/ProfileBottomSheet.kt @@ -30,6 +30,7 @@ import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.bottomsheets.BottomSheet import com.nextcloud.talk.R import com.nextcloud.talk.api.NcApi +import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.controllers.bottomsheet.items.BasicListItemWithImage import com.nextcloud.talk.controllers.bottomsheet.items.listItemsWithImage import com.nextcloud.talk.data.user.model.User @@ -98,7 +99,7 @@ class ProfileBottomSheet(val ncApi: NcApi, val userModel: User) { when (AllowedAppIds.createFor(action)) { PROFILE -> openProfile(action.hyperlink!!, context) EMAIL -> composeEmail(action.title!!, context) - SPREED -> talkTo(userId) + SPREED -> talkTo(userId, context) } } } @@ -117,7 +118,7 @@ class ProfileBottomSheet(val ncApi: NcApi, val userModel: User) { ) } - private fun talkTo(userId: String) { + private fun talkTo(userId: String, context: Context) { val apiVersion = ApiUtils.getConversationApiVersion(userModel, intArrayOf(ApiUtils.APIv4, 1)) val retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom( @@ -169,14 +170,10 @@ class ProfileBottomSheet(val ncApi: NcApi, val userModel: User) { Parcels.wrap(roomOverall.ocs!!.data) ) - // TODO - // ConductorRemapping.remapChatController( - // router, - // userModel.id!!, - // roomOverall.ocs!!.data!!.token!!, - // bundle, - // true - // ) + val chatIntent = Intent(context, ChatActivity::class.java) + chatIntent.putExtras(bundle) + chatIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + context.startActivity(chatIntent) } override fun onError(e: Throwable) { From f7529446a4c1a3b322b67143660d773af95f526c Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Mon, 3 Apr 2023 14:33:32 +0200 Subject: [PATCH 11/14] remove unused item from onOptionsItemSelected Signed-off-by: Marcel Hibbe --- app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 1f4c60201..95541d3f1 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -2730,11 +2730,6 @@ class ChatActivity : override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { - android.R.id.home -> { - // TODO - // (activity as MainActivity).resetConversationsList() - true - } R.id.conversation_video_call -> { startACall(false, false) true From f9836da4a83b0799a29786ac376b6da728cff5ac Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Mon, 3 Apr 2023 15:02:32 +0200 Subject: [PATCH 12/14] fix to start voice message playback only when activity is visible Signed-off-by: Marcel Hibbe --- .../com/nextcloud/talk/chat/ChatActivity.kt | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 95541d3f1..b2272934e 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -225,6 +225,8 @@ class ChatActivity : CommonMessageInterface, PreviewMessageInterface { + var active = false + private lateinit var binding: ControllerChatBinding @Inject @@ -344,6 +346,16 @@ class ChatActivity : binding.messagesListView.setAdapter(adapter) } + override fun onStart() { + super.onStart() + active = true + } + + override fun onStop() { + super.onStop() + active = false + } + @Suppress("Detekt.TooGenericExceptionCaught") override fun onResume() { super.onResume() @@ -1085,14 +1097,13 @@ class ChatActivity : } private fun startPlayback(message: ChatMessage) { - // TODO check how to handle this when conductor is removed - // if (!this.isAttached) { - // // 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. - // // If user returns to chatview, the old chatview instance is not attached anymore - // // and he has to click the play button again (which is considered to be okay) - // return - // } + if (!active) { + // 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. + // If user returns to chatview, the old chatview instance is not attached anymore + // and he has to click the play button again (which is considered to be okay) + return + } initMediaPlayer(message) From 68b930a0d965d9e98882abb1e53d050980e747e7 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Wed, 5 Apr 2023 09:15:45 +0200 Subject: [PATCH 13/14] remove ConductorRemapping.kt Signed-off-by: Marcel Hibbe --- .../utils/remapchat/ConductorRemapping.kt | 137 ------------------ 1 file changed, 137 deletions(-) delete mode 100644 app/src/main/java/com/nextcloud/talk/utils/remapchat/ConductorRemapping.kt diff --git a/app/src/main/java/com/nextcloud/talk/utils/remapchat/ConductorRemapping.kt b/app/src/main/java/com/nextcloud/talk/utils/remapchat/ConductorRemapping.kt deleted file mode 100644 index ce212e433..000000000 --- a/app/src/main/java/com/nextcloud/talk/utils/remapchat/ConductorRemapping.kt +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Nextcloud Talk application - * - * @author Mario Danic - * Copyright (C) 2017-2019 Mario Danic - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.nextcloud.talk.utils.remapchat - -object ConductorRemapping { - - private val TAG = ConductorRemapping::class.simpleName - - // fun remapChatController( - // router: Router, - // internalUserId: Long, - // roomTokenOrId: String, - // bundle: Bundle, - // replaceTop: Boolean - // ) { - // remapChatController(router, internalUserId, roomTokenOrId, bundle, replaceTop, false) - // } - - // fun remapChatController( - // router: Router, - // internalUserId: Long, - // roomTokenOrId: String, - // bundle: Bundle, - // replaceTop: Boolean, - // pushImmediately: Boolean - // ) { - // val chatControllerTag = "$internalUserId@$roomTokenOrId" - // - // if (router.getControllerWithTag(chatControllerTag) != null) { - // moveControllerToTop(router, chatControllerTag) - // } else { - // val pushChangeHandler = if (pushImmediately) { - // SimpleSwapChangeHandler() - // } else { - // HorizontalChangeHandler() - // } - // - // if (router.hasRootController()) { - // val backstack = router.backstack - // val topController = backstack[router.backstackSize - 1].controller - // - // val remapChatModel = RemapChatModel( - // router, - // pushChangeHandler, - // chatControllerTag, - // bundle - // ) - // - // if (topController is ChatActivity) { - // if (replaceTop) { - // topController.leaveRoom(remapChatModel, this::replaceTopController) - // } else { - // topController.leaveRoom(remapChatModel, this::pushController) - // } - // } else { - // if (replaceTop) { - // replaceTopController(remapChatModel) - // } else { - // pushController(remapChatModel) - // } - // } - // } else { - // Log.d(TAG, "router has no RootController. creating backstack with ConversationsListController") - // val newBackstack = listOf( - // RouterTransaction.with(ConversationsListController(Bundle())) - // .pushChangeHandler(HorizontalChangeHandler()) - // .popChangeHandler(HorizontalChangeHandler()), - // RouterTransaction.with(ChatActivity(bundle)) - // .pushChangeHandler(HorizontalChangeHandler()) - // .popChangeHandler(HorizontalChangeHandler()) - // .tag(chatControllerTag) - // ) - // router.setBackstack(newBackstack, SimpleSwapChangeHandler()) - // } - // } - // - // if (router.getControllerWithTag(LockedController.TAG) != null) { - // moveControllerToTop(router, LockedController.TAG) - // } - // } - // - // fun pushController(remapChatModel: RemapChatModel) { - // Log.d(TAG, "pushController") - // remapChatModel.router.pushController( - // RouterTransaction.with(ChatActivity(remapChatModel.bundle)) - // .pushChangeHandler(remapChatModel.controllerChangeHandler) - // .popChangeHandler(HorizontalChangeHandler()) - // .tag(remapChatModel.chatControllerTag) - // ) - // } - // - // private fun replaceTopController(remapChatModel: RemapChatModel) { - // Log.d(TAG, "replaceTopController") - // remapChatModel.router.replaceTopController( - // RouterTransaction.with(ChatActivity(remapChatModel.bundle)) - // .pushChangeHandler(remapChatModel.controllerChangeHandler) - // .popChangeHandler(HorizontalChangeHandler()) - // .tag(remapChatModel.chatControllerTag) - // ) - // } - // - // private fun moveControllerToTop(router: Router, controllerTag: String) { - // Log.d(TAG, "moving $controllerTag to top...") - // val backstack = router.backstack - // var routerTransaction: RouterTransaction? = null - // for (i in 0 until router.backstackSize) { - // if (controllerTag == backstack[i].tag()) { - // routerTransaction = backstack[i] - // backstack.remove(routerTransaction) - // Log.d(TAG, "removed controller: " + routerTransaction.controller) - // break - // } - // } - // - // backstack.add(routerTransaction) - // Log.d(TAG, "added controller to top: " + routerTransaction!!.controller) - // router.setBackstack(backstack, HorizontalChangeHandler()) - // } -} From 48a4fbc3cc9e25652a14204ad442efa2c8b16ab8 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Wed, 5 Apr 2023 12:31:07 +0200 Subject: [PATCH 14/14] Reimplement breakout rooms for usage of Activity instead of Controller Signed-off-by: Marcel Hibbe --- app/src/main/AndroidManifest.xml | 1 + .../talk/activities/CallActivity.java | 23 ++--- .../nextcloud/talk/activities/MainActivity.kt | 26 ------ .../com/nextcloud/talk/chat/ChatActivity.kt | 87 +++++++++++-------- .../nextcloud/talk/utils/bundle/BundleKeys.kt | 3 +- scripts/analysis/lint-results.txt | 2 +- 6 files changed, 61 insertions(+), 81 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 27a5f6d87..c15528198 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -221,6 +221,7 @@ (KEY_USER_ENTITY)!!.id!!, - // intent.getStringExtra(KEY_ROOM_TOKEN)!!, - // intent.extras!!, - // true, - // true - // ) - - val chatIntent = Intent(context, ChatActivity::class.java) - chatIntent.putExtras(intent.extras!!) - startActivity(chatIntent) - - logRouterBackStack(router!!) - } - if (intent.hasExtra(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL)) { if (intent.getBooleanExtra(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL, false)) { if (!router!!.hasRootController()) { @@ -377,14 +359,6 @@ class MainActivity : BaseActivity(), ActionBarProvider { startActivity(callNotificationIntent) } else { logRouterBackStack(router!!) - // remapChatController( - // router!!, - // intent.getParcelableExtra(KEY_USER_ENTITY)!!.id!!, - // intent.getStringExtra(KEY_ROOM_TOKEN)!!, - // intent.extras!!, - // true, - // true - // ) val chatIntent = Intent(context, ChatActivity::class.java) chatIntent.putExtras(intent.extras!!) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index b2272934e..60a0d1089 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -169,6 +169,7 @@ import com.nextcloud.talk.utils.ParticipantPermissions import com.nextcloud.talk.utils.VibrationUtils 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_CALL_VOICE_ONLY import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_NAME import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FILE_PATHS import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID @@ -177,6 +178,8 @@ import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_IS_MODERATOR import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_RECORDING_STATE 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_START_CALL_AFTER_ROOM_SWITCH +import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SWITCH_TO_ROOM import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil @@ -295,7 +298,11 @@ class ChatActivity : private val localParticipantMessageListener = object : SignalingMessageReceiver.LocalParticipantMessageListener { override fun onSwitchTo(token: String?) { if (token != null) { - switchToRoom(token) + if (CallActivity.active) { + Log.d(TAG, "CallActivity is running. Ignore to switch chat in ChatActivity...") + } else { + switchToRoom(token, false, false) + } } } } @@ -309,6 +316,34 @@ class ChatActivity : setupSystemColors() setContentView(binding.root) + handleIntent(intent) + + binding.progressBar.visibility = View.VISIBLE + + initAdapter() + binding.messagesListView.setAdapter(adapter) + } + + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + val extras: Bundle? = intent.extras + + val requestedRoomSwitch = extras?.getBoolean(KEY_SWITCH_TO_ROOM, false) == true + + if (requestedRoomSwitch) { + val newRoomToken = extras?.getString(KEY_ROOM_TOKEN).orEmpty() + val startCallAfterRoomSwitch = extras?.getBoolean(KEY_START_CALL_AFTER_ROOM_SWITCH, false) == true + val isVoiceOnlyCall = extras?.getBoolean(KEY_CALL_VOICE_ONLY, false) == true + + if (newRoomToken != roomToken) { + switchToRoom(newRoomToken, startCallAfterRoomSwitch, isVoiceOnlyCall) + } + } else { + handleIntent(intent) + } + } + + private fun handleIntent(intent: Intent) { val extras: Bundle? = intent.extras conversationUser = extras?.getParcelable(KEY_USER_ENTITY) @@ -336,14 +371,9 @@ class ChatActivity : } startCallFromNotification = extras?.getBoolean(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL, false) == true - startCallFromRoomSwitch = extras?.getBoolean(BundleKeys.KEY_SWITCH_TO_ROOM_AND_START_CALL, false) == true + startCallFromRoomSwitch = extras?.getBoolean(KEY_START_CALL_AFTER_ROOM_SWITCH, false) == true - voiceOnly = extras?.getBoolean(BundleKeys.KEY_CALL_VOICE_ONLY, false) == true - - binding.progressBar.visibility = View.VISIBLE - - initAdapter() - binding.messagesListView.setAdapter(adapter) + voiceOnly = extras?.getBoolean(KEY_CALL_VOICE_ONLY, false) == true } override fun onStart() { @@ -1010,12 +1040,7 @@ class ChatActivity : currentConversation?.type == Conversation.ConversationType .ROOM_TYPE_ONE_TO_ONE_CALL - private fun switchToRoom(token: String) { - if (CallActivity.active) { - Log.d(TAG, "CallActivity is running. Ignore to switch chat in ChatController...") - return - } - + private fun switchToRoom(token: String, startCallAfterRoomSwitch: Boolean, isVoiceOnlyCall: Boolean) { if (conversationUser != null) { runOnUiThread { if (currentConversation?.objectType == Conversation.ObjectType.ROOM) { @@ -1037,6 +1062,11 @@ class ChatActivity : bundle.putParcelable(KEY_USER_ENTITY, conversationUser) bundle.putString(KEY_ROOM_TOKEN, token) + if (startCallAfterRoomSwitch) { + bundle.putBoolean(KEY_START_CALL_AFTER_ROOM_SWITCH, true) + bundle.putBoolean(KEY_CALL_VOICE_ONLY, isVoiceOnlyCall) + } + leaveRoom { val chatIntent = Intent(context, ChatActivity::class.java) chatIntent.putExtras(bundle) @@ -1926,7 +1956,7 @@ class ChatActivity : override fun onPause() { super.onPause() - logConversationInfos("onDetach") + logConversationInfos("onPause") eventBus.unregister(this) @@ -1995,24 +2025,6 @@ class ChatActivity : } private fun joinRoomWithPassword() { - if (CallActivity.active && - roomToken != ApplicationWideCurrentRoomHolder.getInstance().currentRoomToken - ) { - Toast.makeText( - context, - context.getString(R.string.restrict_join_other_room_while_call), - Toast.LENGTH_LONG - ).show() - - Log.e( - TAG, - "Restricted to open chat controller because a call in another room is active. This is an " + - "edge case which is not properly handled yet." - ) - finish() - return - } - // if ApplicationWideCurrentRoomHolder contains a session (because a call is active), then keep the sessionId if (ApplicationWideCurrentRoomHolder.getInstance().currentRoomId == currentConversation!!.roomId @@ -2080,6 +2092,7 @@ class ChatActivity : } if (startCallFromRoomSwitch) { + startCallFromRoomSwitch = false startACall(voiceOnly, true) } } @@ -2160,8 +2173,6 @@ class ChatActivity : if (funToCallWhenLeaveSuccessful != null) { Log.d(TAG, "a callback action was set and is now executed because room was left successfully") funToCallWhenLeaveSuccessful() - } else { - Log.d(TAG, "remapChatController was not set") } } @@ -2872,7 +2883,7 @@ class ChatActivity : ) if (isVoiceOnlyCall) { - bundle.putBoolean(BundleKeys.KEY_CALL_VOICE_ONLY, true) + bundle.putBoolean(KEY_CALL_VOICE_ONLY, true) } if (callWithoutNotification) { bundle.putBoolean(BundleKeys.KEY_CALL_WITHOUT_NOTIFICATION, true) @@ -3509,7 +3520,7 @@ class ChatActivity : private fun logConversationInfos(methodName: String) { Log.d(TAG, " |-----------------------------------------------") Log.d(TAG, " | method: $methodName") - Log.d(TAG, " | ChatController: " + System.identityHashCode(this).toString()) + Log.d(TAG, " | ChatActivity: " + System.identityHashCode(this).toString()) Log.d(TAG, " | roomToken: $roomToken") Log.d(TAG, " | currentConversation?.displayName: ${currentConversation?.displayName}") Log.d(TAG, " | sessionIdAfterRoomJoined: $sessionIdAfterRoomJoined") @@ -3517,7 +3528,7 @@ class ChatActivity : } companion object { - private const val TAG = "ChatController" + private val TAG = ChatActivity::class.simpleName private const val CONTENT_TYPE_SYSTEM_MESSAGE: Byte = 1 private const val CONTENT_TYPE_UNREAD_NOTICE_MESSAGE: Byte = 2 private const val CONTENT_TYPE_LOCATION: Byte = 3 diff --git a/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt b/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt index 4b643b1ed..2dd613648 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt @@ -80,7 +80,8 @@ object BundleKeys { const val KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_AUDIO = "KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_AUDIO" const val KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_VIDEO = "KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_VIDEO" const val KEY_IS_MODERATOR = "KEY_IS_MODERATOR" - const val KEY_SWITCH_TO_ROOM_AND_START_CALL = "KEY_SWITCH_TO_ROOM_AND_START_CALL" + const val KEY_SWITCH_TO_ROOM = "KEY_SWITCH_TO_ROOM" + const val KEY_START_CALL_AFTER_ROOM_SWITCH = "KEY_START_CALL_AFTER_ROOM_SWITCH" const val KEY_IS_BREAKOUT_ROOM = "KEY_IS_BREAKOUT_ROOM" const val KEY_NOTIFICATION_RESTRICT_DELETION = "KEY_NOTIFICATION_RESTRICT_DELETION" const val KEY_DISMISS_RECORDING_URL = "KEY_DISMISS_RECORDING_URL" diff --git a/scripts/analysis/lint-results.txt b/scripts/analysis/lint-results.txt index 3694e6bcc..dd9daf562 100644 --- a/scripts/analysis/lint-results.txt +++ b/scripts/analysis/lint-results.txt @@ -1,2 +1,2 @@ DO NOT TOUCH; GENERATED BY DRONE - Lint Report: 108 warnings + Lint Report: 109 warnings