Started chat room layout

This commit is contained in:
Sylvain Berfini 2023-06-26 10:11:11 +02:00
parent 7b71f32d18
commit 33a33867b5
22 changed files with 527 additions and 23 deletions

View file

@ -22,6 +22,7 @@ package org.linphone.ui
import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.WindowCompat
@ -105,4 +106,12 @@ class MainActivity : AppCompatActivity() {
private fun getNavBar(): NavigationBarView? {
return binding.mainNavView ?: binding.mainNavRail
}
fun hideNavBar() {
getNavBar()?.visibility = View.GONE
}
fun showNavBar() {
getNavBar()?.visibility = View.VISIBLE
}
}

View file

@ -32,6 +32,8 @@ import org.linphone.utils.TimestampUtils
class ChatRoomData(val chatRoom: ChatRoom) {
val id = LinphoneUtils.getChatRoomId(chatRoom)
val localSipUri = chatRoom.localAddress.asString()
val remoteSipUri = chatRoom.peerAddress.asString()
val contactName = MutableLiveData<String>()

View file

@ -24,10 +24,15 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.navGraphViewModels
import org.linphone.R
import org.linphone.databinding.ConversationFragmentBinding
class ConversationFragment : Fragment() {
private lateinit var binding: ConversationFragmentBinding
private val viewModel: ConversationViewModel by navGraphViewModels(
R.id.conversationFragment
)
override fun onCreateView(
inflater: LayoutInflater,
@ -42,5 +47,23 @@ class ConversationFragment : Fragment() {
super.onViewCreated(view, savedInstanceState)
binding.lifecycleOwner = viewLifecycleOwner
binding.viewModel = viewModel
val localSipUri = arguments?.getString("localSipUri")
?: savedInstanceState?.getString("localSipUri")
val remoteSipUri = arguments?.getString("remoteSipUri")
?: savedInstanceState?.getString("remoteSipUri")
if (localSipUri != null && remoteSipUri != null) {
viewModel.loadChatRoom(localSipUri, remoteSipUri)
} else {
// Chat room not found, going back
// TODO FIXME : show error
}
arguments?.clear()
binding.setBackClickListener {
requireActivity().onBackPressedDispatcher.onBackPressed()
}
}
}

View file

@ -54,6 +54,7 @@ class ConversationMenuDialogFragment(
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// TODO FIXME: use a viewmodel and use core thread
val view = ChatRoomMenuBinding.inflate(layoutInflater)
val id = LinphoneUtils.getChatRoomId(chatRoom)

View file

@ -0,0 +1,106 @@
/*
* Copyright (c) 2010-2023 Belledonne Communications SARL.
*
* This file is part of linphone-android
* (see https://www.linphone.org).
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.linphone.ui.conversations
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.contacts.ContactData
import org.linphone.contacts.ContactsListener
import org.linphone.core.ChatRoom
import org.linphone.core.Factory
import org.linphone.core.tools.Log
import org.linphone.utils.LinphoneUtils
class ConversationViewModel : ViewModel() {
private lateinit var chatRoom: ChatRoom
val contactName = MutableLiveData<String>()
val contactData = MutableLiveData<ContactData>()
val subject = MutableLiveData<String>()
val isOneToOne = MutableLiveData<Boolean>()
private val contactsListener = object : ContactsListener {
override fun onContactsLoaded() {
contactLookup()
}
}
init {
coreContext.contactsManager.addListener(contactsListener)
}
override fun onCleared() {
coreContext.contactsManager.removeListener(contactsListener)
}
fun loadChatRoom(localSipUri: String, remoteSipUri: String) {
coreContext.postOnCoreThread { core ->
val localAddress = Factory.instance().createAddress(localSipUri)
val remoteSipAddress = Factory.instance().createAddress(remoteSipUri)
val found = core.searchChatRoom(
null,
localAddress,
remoteSipAddress,
arrayOfNulls(
0
)
)
if (found != null) {
chatRoom = found
isOneToOne.postValue(chatRoom.hasCapability(ChatRoom.Capabilities.OneToOne.toInt()))
subject.postValue(chatRoom.subject)
contactLookup()
}
}
}
private fun contactLookup() {
if (chatRoom.hasCapability(ChatRoom.Capabilities.Basic.toInt())) {
val remoteAddress = chatRoom.peerAddress
val friend = chatRoom.core.findFriend(remoteAddress)
if (friend != null) {
contactData.postValue(ContactData(friend))
}
contactName.postValue(friend?.name ?: LinphoneUtils.getDisplayName(remoteAddress))
} else {
if (chatRoom.hasCapability(ChatRoom.Capabilities.OneToOne.toInt())) {
val first = chatRoom.participants.firstOrNull()
if (first != null) {
val remoteAddress = first.address
val friend = chatRoom.core.findFriend(remoteAddress)
if (friend != null) {
contactData.postValue(ContactData(friend))
}
contactName.postValue(
friend?.name ?: LinphoneUtils.getDisplayName(remoteAddress)
)
} else {
Log.e("[Conversation View Model] No participant in the chat room!")
}
}
}
}
}

View file

@ -25,6 +25,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import androidx.core.os.bundleOf
import androidx.core.view.doOnPreDraw
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
@ -33,6 +34,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import org.linphone.R
import org.linphone.databinding.ConversationsFragmentBinding
import org.linphone.ui.MainActivity
class ConversationsFragment : Fragment() {
private lateinit var binding: ConversationsFragmentBinding
@ -58,6 +60,7 @@ class ConversationsFragment : Fragment() {
}
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
// Holds fragment in place while new fragment slides over it
return AnimationUtils.loadAnimation(activity, R.anim.hold)
}
@ -91,9 +94,17 @@ class ConversationsFragment : Fragment() {
adapter.chatRoomClickedEvent.observe(viewLifecycleOwner) {
it.consume { data ->
findNavController().navigate(
R.id.action_conversationsFragment_to_conversationFragment
)
val bundle = bundleOf()
bundle.putString("localSipUri", data.localSipUri)
bundle.putString("remoteSipUri", data.remoteSipUri)
if (findNavController().currentDestination?.id == R.id.conversationsFragment) {
(requireActivity() as MainActivity).hideNavBar()
findNavController().navigate(
R.id.action_conversationsFragment_to_conversationFragment,
bundle
)
}
}
}
@ -126,12 +137,20 @@ class ConversationsFragment : Fragment() {
}
binding.setOnNewConversationClicked {
findNavController().navigate(
R.id.action_conversationsFragment_to_newConversationFragment
)
if (findNavController().currentDestination?.id == R.id.conversationsFragment) {
(requireActivity() as MainActivity).hideNavBar()
findNavController().navigate(
R.id.action_conversationsFragment_to_newConversationFragment
)
}
}
}
override fun onResume() {
super.onResume()
(requireActivity() as MainActivity).showNavBar()
}
private fun scrollToTop() {
binding.conversationsList.scrollToPosition(0)
}

View file

@ -23,8 +23,11 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import androidx.core.view.doOnPreDraw
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import androidx.navigation.navGraphViewModels
import androidx.recyclerview.widget.LinearLayoutManager
import org.linphone.LinphoneApplication.Companion.coreContext
@ -39,6 +42,14 @@ class NewConversationFragment : Fragment() {
R.id.conversationsFragment
)
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
if (findNavController().currentDestination?.id == R.id.conversationFragment) {
// Holds fragment in place while created conversation fragment slides over it
return AnimationUtils.loadAnimation(activity, R.anim.hold)
}
return super.onCreateAnimation(transit, enter, nextAnim)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -85,5 +96,15 @@ class NewConversationFragment : Fragment() {
binding.setCancelClickListener {
requireActivity().onBackPressedDispatcher.onBackPressed()
}
viewModel.goToChatRoom.observe(viewLifecycleOwner) {
it.consume {
if (findNavController().currentDestination?.id == R.id.newConversationFragment) {
findNavController().navigate(
R.id.action_newConversationFragment_to_conversationFragment
)
}
}
}
}
}

View file

@ -28,10 +28,17 @@ import org.linphone.core.MagicSearch
import org.linphone.core.MagicSearchListenerStub
import org.linphone.core.SearchResult
import org.linphone.core.tools.Log
import org.linphone.utils.Event
class NewConversationViewModel : ViewModel() {
val contactsList = MutableLiveData<ArrayList<ContactData>>()
val groupEnabled = MutableLiveData<Boolean>()
val goToChatRoom: MutableLiveData<Event<Pair<String, String>>> by lazy {
MutableLiveData<Event<Pair<String, String>>>()
}
val filter = MutableLiveData<String>()
private var previousFilter = "NotSet"
@ -56,16 +63,16 @@ class NewConversationViewModel : ViewModel() {
init {
coreContext.postOnCoreThread {
magicSearch.addListener(magicSearchListener)
coreContext.contactsManager.addListener(contactsListener)
applyFilter("")
}
coreContext.contactsManager.addListener(contactsListener)
}
override fun onCleared() {
coreContext.postOnCoreThread {
coreContext.contactsManager.removeListener(contactsListener)
magicSearch.removeListener(magicSearchListener)
}
coreContext.contactsManager.removeListener(contactsListener)
super.onCleared()
}
@ -88,6 +95,14 @@ class NewConversationViewModel : ViewModel() {
)
}
fun createGroup() {
goToChatRoom.value = Event(Pair("", ""))
}
fun enableGroupSelection() {
groupEnabled.value = true
}
private fun processMagicSearchResults(results: Array<SearchResult>) {
Log.i("[New Conversation ViewModel] [${results.size}] matching results")
contactsList.value.orEmpty().forEach(ContactData::onDestroy)

View file

@ -0,0 +1,26 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="vector"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group android:name="group">
<path
android:name="path"
android:pathData="M 12 8.327 L 12 15.654 M 15.667 11.991 L 8.333 11.991"
android:fillColor="#6c7a87"
android:fillAlpha="0"
android:strokeColor="#6c7a87"
android:strokeWidth="1"
android:fillType="evenOdd"/>
<path
android:name="path_1"
android:pathData="M 16.686 2 L 7.314 2 C 4.048 2 2 4.312 2 7.585 L 2 16.415 C 2 19.688 4.038 22 7.314 22 L 16.686 22 C 19.962 22 22 19.688 22 16.415 L 22 7.585 C 22 4.312 19.962 2 16.686 2 Z"
android:fillColor="#6c7a87"
android:fillAlpha="0"
android:strokeColor="#6c7a87"
android:strokeWidth="1"
android:fillType="evenOdd"/>
</group>
</vector>

View file

@ -0,0 +1,15 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="vector"
android:width="21dp"
android:height="20dp"
android:viewportWidth="21"
android:viewportHeight="20">
<path
android:name="path"
android:pathData="M 13.912 15.833 L 8.079 10 L 13.912 4.167"
android:strokeColor="#fe5e00"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:strokeLineJoin="round"/>
</vector>

View file

@ -7,7 +7,7 @@
android:viewportHeight="12">
<path
android:name="path"
android:pathData="M 5.801 6.88 L 6.507 7.586 L 10.74 3.353 L 11.447 4.06 L 6.507 9 L 3.325 5.818 L 4.032 5.111 L 5.095 6.173 L 5.801 6.879 L 5.801 6.88 Z M 5.802 5.466 L 8.278 2.989 L 8.983 3.694 L 6.507 6.171 L 5.802 5.466 Z M 4.388 8.293 L 3.682 9 L 0.5 5.818 L 1.207 5.111 L 1.913 5.817 L 1.913 5.818 L 4.388 8.293 Z"
android:fillColor="#6c7a87"
android:pathData="M 5 7.586 L 9.596 2.99 L 10.303 3.696 L 5 9 L 1.818 5.818 L 2.525 5.111 L 5 7.586 Z"
android:fillColor="#fe5e00"
android:strokeWidth="1"/>
</vector>

View file

@ -0,0 +1,13 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="vector"
android:width="19dp"
android:height="18dp"
android:viewportWidth="19"
android:viewportHeight="18">
<path
android:name="path"
android:pathData="M 9.549 18 C 4.578 18 0.549 13.971 0.549 9 C 0.549 4.029 4.578 0 9.549 0 C 14.52 0 18.549 4.029 18.549 9 C 18.549 13.971 14.52 18 9.549 18 Z M 9.549 16.2 C 11.459 16.2 13.29 15.441 14.64 14.091 C 15.991 12.741 16.749 10.91 16.749 9 C 16.749 7.09 15.991 5.259 14.64 3.909 C 13.29 2.559 11.459 1.8 9.549 1.8 C 7.64 1.8 5.808 2.559 4.458 3.909 C 3.108 5.259 2.349 7.09 2.349 9 C 2.349 10.91 3.108 12.741 4.458 14.091 C 5.808 15.441 7.64 16.2 9.549 16.2 Z M 8.649 4.5 L 10.449 4.5 L 10.449 6.3 L 8.649 6.3 L 8.649 4.5 Z M 8.649 8.1 L 10.449 8.1 L 10.449 13.5 L 8.649 13.5 L 8.649 8.1 Z"
android:fillColor="#6c7a87"
android:strokeWidth="1"/>
</vector>

View file

@ -0,0 +1,20 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="vector"
android:width="19dp"
android:height="18dp"
android:viewportWidth="19"
android:viewportHeight="18">
<group android:name="wrapper">
<clip-path
android:name="clip0_96_25861"
android:pathData="M 0.549 0 L 18.549 0 L 18.549 18 L 0.549 18 Z"/>
<group android:name="group">
<path
android:name="path"
android:pathData="M 5.454 3.75 C 5.499 4.418 5.612 5.07 5.792 5.692 L 4.892 6.593 C 4.584 5.692 4.389 4.74 4.322 3.75 L 5.454 3.75 Z M 12.849 12.765 C 13.487 12.945 14.139 13.057 14.799 13.102 L 14.799 14.22 C 13.809 14.152 12.857 13.957 11.949 13.658 L 12.849 12.765 Z M 6.174 2.25 L 3.549 2.25 C 3.137 2.25 2.799 2.587 2.799 3 C 2.799 10.043 8.507 15.75 15.549 15.75 C 15.962 15.75 16.299 15.412 16.299 15 L 16.299 12.383 C 16.299 11.97 15.962 11.633 15.549 11.633 C 14.619 11.633 13.712 11.482 12.872 11.205 C 12.797 11.175 12.714 11.168 12.639 11.168 C 12.444 11.168 12.257 11.242 12.107 11.385 L 10.457 13.035 C 8.334 11.947 6.594 10.215 5.514 8.092 L 7.164 6.442 C 7.374 6.232 7.434 5.94 7.352 5.678 C 7.074 4.838 6.924 3.938 6.924 3 C 6.924 2.587 6.587 2.25 6.174 2.25 Z"
android:fillColor="#fe5e00"
android:strokeWidth="1"/>
</group>
</group>
</vector>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<corners android:radius="24dp" />
<solid android:color="@color/white"/>
<size android:height="48dp" android:width="234dp" />
</shape>

View file

@ -0,0 +1,13 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="vector"
android:width="19dp"
android:height="14dp"
android:viewportWidth="19"
android:viewportHeight="14">
<path
android:name="path"
android:pathData="M 3.089 13.23 C 2.416 13.23 1.77 12.962 1.294 12.487 C 0.818 12.011 0.55 11.366 0.55 10.693 L 0.55 3.308 C 0.55 2.635 0.818 1.99 1.294 1.514 C 1.77 1.038 2.415 0.77 3.089 0.77 L 11.396 0.77 C 12.052 0.77 12.682 1.025 13.155 1.479 C 13.627 1.934 13.906 2.554 13.933 3.209 L 16.333 2.248 C 16.73 2.09 17.175 2.095 17.569 2.264 C 17.963 2.433 18.273 2.751 18.433 3.148 C 18.509 3.339 18.549 3.543 18.549 3.748 L 18.549 10.248 C 18.549 10.513 18.484 10.773 18.36 11.006 C 18.237 11.239 18.058 11.439 17.839 11.587 C 17.62 11.735 17.368 11.827 17.106 11.855 C 16.843 11.883 16.578 11.847 16.333 11.748 L 13.933 10.789 C 13.906 11.444 13.627 12.064 13.155 12.519 C 12.682 12.973 12.052 13.228 11.396 13.229 L 3.089 13.23 Z M 1.934 3.308 L 1.934 10.693 C 1.934 10.999 2.056 11.292 2.272 11.508 C 2.489 11.725 2.782 11.846 3.089 11.847 L 11.396 11.847 C 11.701 11.846 11.995 11.725 12.211 11.508 C 12.428 11.292 12.549 10.998 12.55 10.693 L 12.55 3.308 C 12.549 3.002 12.428 2.709 12.211 2.492 C 11.995 2.276 11.702 2.154 11.396 2.154 L 3.089 2.154 C 2.782 2.154 2.489 2.276 2.272 2.492 C 2.056 2.709 1.934 3.002 1.934 3.308 Z M 16.85 10.47 C 16.884 10.483 16.922 10.488 16.96 10.484 C 16.997 10.48 17.033 10.467 17.064 10.446 C 17.095 10.425 17.121 10.396 17.138 10.363 C 17.156 10.33 17.165 10.293 17.166 10.255 L 17.166 3.756 C 17.165 3.718 17.156 3.681 17.138 3.648 C 17.121 3.614 17.095 3.586 17.064 3.565 C 17.033 3.544 16.997 3.531 16.96 3.527 C 16.922 3.523 16.884 3.528 16.85 3.542 L 13.935 4.699 L 13.935 9.3 L 16.85 10.47 Z"
android:fillColor="#fe5e00"
android:strokeWidth="1"/>
</vector>

View file

@ -0,0 +1,31 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="vector"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group android:name="group_1">
<path
android:name="path_2"
android:pathData="M 12 22 L 12 18.839"
android:fillColor="#000"
android:fillAlpha="0"
android:strokeColor="#6c7a87"
android:strokeWidth="1"/>
<path
android:name="path_3"
android:pathData="M 12 14.848 C 9.757 14.848 7.938 13.022 7.938 10.768 L 7.938 6.081 C 7.938 3.827 9.757 2 12 2 C 14.244 2 16.062 3.827 16.062 6.081 L 16.062 10.768 C 16.062 13.022 14.244 14.848 12 14.848 Z"
android:fillColor="#000"
android:fillAlpha="0"
android:strokeColor="#6c7a87"
android:strokeWidth="1"/>
<path
android:name="path_4"
android:pathData="M 20 10.801 C 20 15.239 16.419 18.838 11.999 18.838 C 7.581 18.838 4 15.239 4 10.801"
android:fillColor="#000"
android:fillAlpha="0"
android:strokeColor="#6c7a87"
android:strokeWidth="1"/>
</group>
</vector>

View file

@ -56,7 +56,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:text="@{data.isComposing ? `... est en train d'écrire` : data.lastMessage, default=`Lorem Ipsum`}"
android:textColor="@{data.unreadChatCount > 0 ? @color/black : @color/gray_4, default=@color/gray_4}"
android:textColor="@{data.isComposing ? @color/primary_color : data.unreadChatCount > 0 ? @color/black : @color/gray_4, default=@color/gray_4}"
android:textSize="14sp"
android:textStyle="@{data.unreadChatCount > 0 ? Typeface.BOLD : Typeface.NORMAL, default=normal}"
android:maxLines="1"

View file

@ -8,23 +8,176 @@
<variable
name="backClickListener"
type="View.OnClickListener" />
<variable
name="viewModel"
type="org.linphone.ui.conversations.ConversationViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent">
android:background="@color/white">
<ImageView
android:id="@+id/back"
android:onClick="@{backClickListener}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/back"
android:padding="20dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/avatar"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:adjustViewBounds="true"
android:src="@{viewModel.isOneToOne ? @drawable/contact_avatar : @drawable/group_avatar, default=@drawable/contact_avatar}"
coilContact="@{viewModel.contactData}"
app:layout_constraintStart_toEndOf="@id/back"
app:layout_constraintTop_toTopOf="@id/back"
app:layout_constraintBottom_toBottomOf="@id/back"/>
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:text="@{viewModel.isOneToOne ? viewModel.contactName : viewModel.subject, default=`John Doe`}"
android:textColor="@color/black"
android:textSize="14sp"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintEnd_toStartOf="@id/phone_call"
app:layout_constraintTop_toTopOf="@id/avatar" />
<TextView
android:id="@+id/presence"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:text="Online"
android:textColor="@color/green_online"
android:textSize="14sp"
android:textStyle=""
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintEnd_toStartOf="@id/phone_call"
app:layout_constraintTop_toBottomOf="@id/title"
app:layout_constraintBottom_toBottomOf="@id/avatar"/>
<ImageView
android:id="@+id/info"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginTop="10dp"
android:src="@drawable/shape_white_background"
android:src="@drawable/info"
android:padding="10dp"
android:layout_marginEnd="5dp"
app:layout_constraintTop_toTopOf="@id/back"
app:layout_constraintBottom_toBottomOf="@id/back"
app:layout_constraintEnd_toEndOf="parent" />
<ImageView
android:id="@+id/video_call"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:src="@drawable/video_call"
android:padding="10dp"
app:layout_constraintTop_toTopOf="@id/back"
app:layout_constraintBottom_toBottomOf="@id/back"
app:layout_constraintEnd_toStartOf="@id/info" />
<ImageView
android:id="@+id/phone_call"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:src="@drawable/phone_call"
android:padding="10dp"
app:layout_constraintTop_toTopOf="@id/back"
app:layout_constraintBottom_toBottomOf="@id/back"
app:layout_constraintEnd_toStartOf="@id/video_call" />
<TextView
android:id="@+id/composing_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="... est en train décrire..."
android:textSize="12sp"
android:textColor="#73000000"
android:layout_marginStart="10dp"
android:layout_marginBottom="15dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_background" />
<View
android:id="@+id/bottom_background"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@color/gray_7"
android:layout_marginTop="-15dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toTopOf="@id/message"
app:layout_constraintBottom_toBottomOf="parent" />
<TextView
android:id="@+id/emoji_picker"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:text="🙂"
android:textSize="18sp"
android:padding="5dp"
android:gravity="center"
android:layout_marginStart="10dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/message"
app:layout_constraintBottom_toBottomOf="@id/message" />
<ImageView
android:id="@+id/attach_file"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:src="@drawable/add_file"
android:padding="5dp"
android:layout_marginStart="10dp"
app:layout_constraintStart_toEndOf="@id/emoji_picker"
app:layout_constraintTop_toTopOf="@id/message"
app:layout_constraintBottom_toBottomOf="@id/message" />
<EditText
android:id="@+id/message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="Dites quelque chose..."
android:layout_marginBottom="15dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:paddingStart="24dp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:maxLines="5"
android:textSize="14sp"
android:background="@drawable/shape_edittext_white_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/attach_file"
app:layout_constraintEnd_toStartOf="@id/voice_message"/>
<ImageView
android:id="@+id/voice_message"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:src="@drawable/voice_message"
android:padding="5dp"
android:layout_marginEnd="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/message"
app:layout_constraintBottom_toBottomOf="@id/message" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -91,7 +91,7 @@
android:layout_marginTop="10dp"
android:text="Récents"
android:textSize="14sp"
android:textColor="@color/gray_1"
android:textColor="@color/blue_filter"
android:drawablePadding="5dp"
app:layout_constraintStart_toEndOf="@id/sort_by_label"
app:layout_constraintTop_toBottomOf="@id/search_bar"

View file

@ -42,6 +42,21 @@
app:layout_constraintTop_toTopOf="@id/title"
app:layout_constraintBottom_toBottomOf="@id/subtitle"/>
<TextView
android:id="@+id/create_group"
android:onClick="@{() -> viewModel.createGroup()}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Créer"
android:textSize="15sp"
android:padding="10dp"
android:textColor="@color/primary_color"
android:layout_marginEnd="15dp"
android:visibility="@{viewModel.groupEnabled ? View.VISIBLE : View.GONE}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/title"
app:layout_constraintBottom_toBottomOf="@id/subtitle"/>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
@ -86,6 +101,7 @@
app:layout_constraintTop_toBottomOf="@id/subtitle" />
<ImageView
android:onClick="@{() -> viewModel.enableGroupSelection()}"
android:id="@+id/new_group_avatar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -94,21 +110,23 @@
android:background="@drawable/shape_orange_round"
android:layout_marginTop="30dp"
android:layout_marginStart="20dp"
android:visibility="@{viewModel.filter.length() > 0 ? View.GONE : View.VISIBLE}"
android:visibility="@{viewModel.filter.length() > 0 || viewModel.groupEnabled ? View.GONE : View.VISIBLE}"
app:layout_constraintTop_toBottomOf="@id/search_bar"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:onClick="@{() -> viewModel.enableGroupSelection()}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Créer un nouveau groupe"
android:textStyle="bold"
android:textSize="16sp"
android:layout_marginStart="12dp"
android:layout_marginEnd="25dp"
android:padding="5dp"
android:layout_marginStart="7dp"
android:layout_marginEnd="20dp"
android:drawableEnd="@drawable/next"
android:drawablePadding="5dp"
android:visibility="@{viewModel.filter.length() > 0 ? View.GONE : View.VISIBLE}"
android:visibility="@{viewModel.filter.length() > 0 || viewModel.groupEnabled ? View.GONE : View.VISIBLE}"
app:layout_constraintStart_toEndOf="@id/new_group_avatar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/new_group_avatar"

View file

@ -14,7 +14,7 @@
android:id="@+id/action_conversationsFragment_to_newConversationFragment"
app:destination="@id/newConversationFragment"
app:enterAnim="@anim/slide_in"
app:popExitAnim="@anim/slide_out" />
app:popExitAnim="@anim/slide_out"/>
<action
android:id="@+id/action_conversationsFragment_to_conversationFragment"
app:destination="@id/conversationFragment"
@ -29,13 +29,23 @@
tools:layout="@layout/new_conversation_fragment" >
<action
android:id="@+id/action_newConversationFragment_to_conversationFragment"
app:destination="@id/conversationFragment" />
app:destination="@id/conversationFragment"
app:enterAnim="@anim/slide_in_right"
app:popExitAnim="@anim/slide_out_right"
app:popUpTo="@id/conversationsFragment" />
</fragment>
<fragment
android:id="@+id/conversationFragment"
android:name="org.linphone.ui.conversations.ConversationFragment"
android:label="ConversationFragment"
tools:layout="@layout/conversation_fragment" />
tools:layout="@layout/conversation_fragment" >
<argument
android:name="localSipUri"
app:argType="string" />
<argument
android:name="remoteSipUri"
app:argType="string" />
</fragment>
</navigation>

View file

@ -5,6 +5,8 @@
<color name="black">#000000</color>
<color name="white">#FFFFFF</color>
<color name="red_danger">#DD5F5F</color>
<color name="green_online">#4FAE80</color>
<color name="blue_filter">#09C5F4</color>
<color name="gray_1">#6C7A87</color>
<color name="gray_2">#F9F9F9</color>
@ -12,5 +14,6 @@
<color name="gray_4">#949494</color>
<color name="gray_5">#4E4E4E</color>
<color name="gray_6">#EDEDED</color>
<color name="gray_7">#F9F9F9</color>
<color name="separator">#E5E5EA</color>
</resources>