diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationFragment.kt
index f0c7719a3..2522beff2 100644
--- a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationFragment.kt
+++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationFragment.kt
@@ -32,11 +32,13 @@ import android.net.Uri
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
+import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
+import android.widget.PopupWindow
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.UiThread
@@ -68,6 +70,7 @@ import org.linphone.core.ChatMessage
import org.linphone.core.tools.Log
import org.linphone.databinding.ChatBubbleLongPressMenuBinding
import org.linphone.databinding.ChatConversationFragmentBinding
+import org.linphone.databinding.ChatConversationPopupMenuBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.main.chat.adapter.ConversationEventAdapter
import org.linphone.ui.main.chat.adapter.MessageBottomSheetAdapter
@@ -180,13 +183,12 @@ class ConversationFragment : SlidingPaneChildFragment() {
Log.i(
"$TAG [$itemCount] events have been loaded, scrolling to first unread message"
)
- scrollToFirstUnreadMessageOrBottom(false)
} else {
Log.i(
"$TAG [$itemCount] new events have been loaded, scrolling to first unread message"
)
- scrollToFirstUnreadMessageOrBottom(true)
}
+ scrollToFirstUnreadMessageOrBottom(false)
}
}
@@ -384,6 +386,10 @@ class ConversationFragment : SlidingPaneChildFragment() {
}
}
+ binding.setShowMenuClickListener {
+ showPopupMenu(binding.showMenu)
+ }
+
binding.setOpenFilePickerClickListener {
Log.i("$TAG Opening media picker")
pickMedia.launch(
@@ -426,14 +432,7 @@ class ConversationFragment : SlidingPaneChildFragment() {
}
binding.setGoToInfoClickListener {
- if (findNavController().currentDestination?.id == R.id.conversationFragment) {
- val action =
- ConversationFragmentDirections.actionConversationFragmentToConversationInfoFragment(
- localSipUri,
- remoteSipUri
- )
- findNavController().navigate(action)
- }
+ goToInfoFragment()
}
binding.setScrollToBottomClickListener {
@@ -679,6 +678,49 @@ class ConversationFragment : SlidingPaneChildFragment() {
}
}
+ private fun goToInfoFragment() {
+ Log.i("TAG Navigating to info fragment")
+ if (findNavController().currentDestination?.id == R.id.conversationFragment) {
+ val action =
+ ConversationFragmentDirections.actionConversationFragmentToConversationInfoFragment(
+ viewModel.localSipUri,
+ viewModel.remoteSipUri
+ )
+ findNavController().navigate(action)
+ }
+ }
+
+ private fun showPopupMenu(view: View) {
+ val popupView: ChatConversationPopupMenuBinding = DataBindingUtil.inflate(
+ LayoutInflater.from(requireContext()),
+ R.layout.chat_conversation_popup_menu,
+ null,
+ false
+ )
+
+ val popupWindow = PopupWindow(
+ popupView.root,
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ true
+ )
+
+ popupView.setGoToInfoClickListener {
+ goToInfoFragment()
+ popupWindow.dismiss()
+ }
+
+ popupView.setSearchClickListener {
+ Log.i("$TAG Opening search bar")
+ viewModel.openSearchBar()
+ popupWindow.dismiss()
+ }
+
+ // Elevation is for showing a shadow around the popup
+ popupWindow.elevation = 20f
+ popupWindow.showAsDropDown(view, 0, 0, Gravity.BOTTOM)
+ }
+
private fun showChatMessageLongPressMenu(chatMessageModel: MessageModel) {
Compatibility.setBlurRenderEffect(binding.root)
diff --git a/app/src/main/java/org/linphone/ui/main/chat/model/MessageModel.kt b/app/src/main/java/org/linphone/ui/main/chat/model/MessageModel.kt
index f12377e55..7d3fc46ce 100644
--- a/app/src/main/java/org/linphone/ui/main/chat/model/MessageModel.kt
+++ b/app/src/main/java/org/linphone/ui/main/chat/model/MessageModel.kt
@@ -375,6 +375,9 @@ class MessageModel @WorkerThread constructor(
if (name.isNotEmpty()) {
val fileModel = if (isOutgoing && chatMessage.isFileTransferInProgress) {
val path = content.filePath ?: ""
+ if (filesContentCount == 1) {
+ firstImagePath.postValue(path)
+ }
FileModel(path, name, content.fileSize.toLong(), false) { model ->
onContentClicked?.invoke(model.file)
}
diff --git a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationInfoViewModel.kt b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationInfoViewModel.kt
index 197fbd0dd..b0aca27e6 100644
--- a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationInfoViewModel.kt
+++ b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationInfoViewModel.kt
@@ -288,11 +288,12 @@ class ConversationInfoViewModel @UiThread constructor() : ViewModel() {
fun call() {
coreContext.postOnCoreThread { core ->
if (LinphoneUtils.isChatRoomAGroup(chatRoom)) {
- // TODO
+ // TODO: group chat room call
} else {
val firstParticipant = chatRoom.participants.firstOrNull()
val address = firstParticipant?.address
if (address != null) {
+ Log.i("$TAG Audio calling SIP address [${address.asStringUriOnly()}]")
val params = core.createCallParams(null)
params?.isVideoEnabled = false
coreContext.startCall(address, params)
diff --git a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt
index 6841f053e..e8fadef6e 100644
--- a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt
+++ b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt
@@ -91,6 +91,10 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
lateinit var chatRoom: ChatRoom
+ lateinit var localSipUri: String
+
+ lateinit var remoteSipUri: String
+
private val chatRoomListener = object : ChatRoomListenerStub() {
@WorkerThread
override fun onStateChanged(chatRoom: ChatRoom, newState: ChatRoom.State?) {
@@ -269,6 +273,9 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
@UiThread
fun findChatRoom(room: ChatRoom?, localSipUri: String, remoteSipUri: String) {
+ this.localSipUri = localSipUri
+ this.remoteSipUri = remoteSipUri
+
coreContext.postOnCoreThread { core ->
Log.i(
"$TAG Looking for conversation with local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]"
@@ -361,6 +368,24 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
}
}
+ @UiThread
+ fun startCall() {
+ coreContext.postOnCoreThread { core ->
+ if (LinphoneUtils.isChatRoomAGroup(chatRoom)) {
+ // TODO: group chat room call
+ } else {
+ val firstParticipant = chatRoom.participants.firstOrNull()
+ val address = firstParticipant?.address
+ if (address != null) {
+ Log.i("$TAG Audio calling SIP address [${address.asStringUriOnly()}]")
+ val params = core.createCallParams(null)
+ params?.isVideoEnabled = false
+ coreContext.startCall(address, params)
+ }
+ }
+ }
+ }
+
@WorkerThread
private fun configureChatRoom() {
scrollingPosition = SCROLLING_POSITION_NOT_SET
diff --git a/app/src/main/res/layout/chat_conversation_fragment.xml b/app/src/main/res/layout/chat_conversation_fragment.xml
index 05c40ac03..e89742b3c 100644
--- a/app/src/main/res/layout/chat_conversation_fragment.xml
+++ b/app/src/main/res/layout/chat_conversation_fragment.xml
@@ -10,15 +10,12 @@
-
-
+
@@ -48,7 +45,7 @@
diff --git a/app/src/main/res/layout/chat_conversation_popup_menu.xml b/app/src/main/res/layout/chat_conversation_popup_menu.xml
new file mode 100644
index 000000000..105cea437
--- /dev/null
+++ b/app/src/main/res/layout/chat_conversation_popup_menu.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 333ad17d8..7fbfbcbba 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -408,6 +408,8 @@
Add participants
Replying to:
+ Search
+ Conversation info
Group members
Add participants