mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-17 19:38:08 +00:00
Updated conversation top bar layout
This commit is contained in:
parent
a2b86ff5f6
commit
4bf0a2fa5d
7 changed files with 165 additions and 26 deletions
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -10,15 +10,12 @@
|
|||
<variable
|
||||
name="backClickListener"
|
||||
type="View.OnClickListener" />
|
||||
<variable
|
||||
name="startCallClickListener"
|
||||
type="View.OnClickListener" />
|
||||
<variable
|
||||
name="startVideoCallClickListener"
|
||||
type="View.OnClickListener" />
|
||||
<variable
|
||||
name="goToInfoClickListener"
|
||||
type="View.OnClickListener" />
|
||||
<variable
|
||||
name="showMenuClickListener"
|
||||
type="View.OnClickListener" />
|
||||
<variable
|
||||
name="openFilePickerClickListener"
|
||||
type="View.OnClickListener" />
|
||||
|
|
@ -48,7 +45,7 @@
|
|||
<androidx.constraintlayout.widget.Group
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="avatar, title, search_toggle, info"
|
||||
app:constraint_referenced_ids="avatar, title, start_call, show_menu"
|
||||
android:visibility="@{viewModel.searchBarVisible ? View.GONE : View.VISIBLE}" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
|
|
@ -127,32 +124,32 @@
|
|||
android:textSize="16sp"
|
||||
android:textColor="?attr/color_main2_600"
|
||||
android:gravity="center_vertical"
|
||||
app:layout_constraintEnd_toStartOf="@id/search_toggle"
|
||||
app:layout_constraintEnd_toStartOf="@id/start_call"
|
||||
app:layout_constraintStart_toEndOf="@id/avatar"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/info"
|
||||
android:onClick="@{goToInfoClickListener}"
|
||||
android:id="@+id/show_menu"
|
||||
android:onClick="@{showMenuClickListener}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:padding="15dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:src="@drawable/info"
|
||||
android:src="@drawable/dots_three_vertical"
|
||||
app:layout_constraintTop_toTopOf="@id/title"
|
||||
app:layout_constraintBottom_toBottomOf="@id/title"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:tint="?attr/color_main2_500"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/search_toggle"
|
||||
android:onClick="@{() -> viewModel.openSearchBar()}"
|
||||
android:id="@+id/start_call"
|
||||
android:onClick="@{() -> viewModel.startCall()}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:padding="15dp"
|
||||
android:src="@drawable/magnifying_glass"
|
||||
android:src="@drawable/phone_call"
|
||||
app:layout_constraintBottom_toBottomOf="@id/title"
|
||||
app:layout_constraintEnd_toStartOf="@id/info"
|
||||
app:layout_constraintEnd_toStartOf="@id/show_menu"
|
||||
app:layout_constraintTop_toTopOf="@id/title"
|
||||
app:tint="?attr/color_main2_500" />
|
||||
|
||||
|
|
|
|||
69
app/src/main/res/layout/chat_conversation_popup_menu.xml
Normal file
69
app/src/main/res/layout/chat_conversation_popup_menu.xml
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<data>
|
||||
<import type="android.view.View" />
|
||||
<import type="android.graphics.Typeface" />
|
||||
<variable
|
||||
name="searchClickListener"
|
||||
type="View.OnClickListener" />
|
||||
<variable
|
||||
name="goToInfoClickListener"
|
||||
type="View.OnClickListener" />
|
||||
</data>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/shape_round_popup_menu_background">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/search"
|
||||
android:onClick="@{searchClickListener}"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:text="@string/conversation_menu_search_in_messages"
|
||||
android:textSize="14sp"
|
||||
android:textColor="?attr/color_main2_500"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:drawableStart="@drawable/magnifying_glass"
|
||||
android:drawablePadding="5dp"
|
||||
app:drawableTint="?attr/color_main2_700"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/info"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/info"
|
||||
android:onClick="@{goToInfoClickListener}"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:text="@string/conversation_menu_go_to_info"
|
||||
android:textSize="14sp"
|
||||
android:textColor="?attr/color_main2_500"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:drawableStart="@drawable/info"
|
||||
android:drawablePadding="5dp"
|
||||
app:drawableTint="?attr/color_main2_700"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/search"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</layout>
|
||||
|
|
@ -408,6 +408,8 @@
|
|||
</plurals>
|
||||
<string name="conversation_add_participants_title">Add participants</string>
|
||||
<string name="conversation_reply_to_message_title">Replying to:</string>
|
||||
<string name="conversation_menu_search_in_messages">Search</string>
|
||||
<string name="conversation_menu_go_to_info">Conversation info</string>
|
||||
|
||||
<string name="conversation_info_participants_list_title">Group members</string>
|
||||
<string name="conversation_info_add_participants_label">Add participants</string>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue