mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-04-29 15:06:21 +00:00
Changes
This commit is contained in:
parent
bd51fe383b
commit
5dfd04ad70
11 changed files with 88 additions and 52 deletions
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.MainActivity"
|
android:name=".ui.MainActivity"
|
||||||
|
android:windowSoftInputMode="adjustResize"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:label="@string/app_name">
|
android:label="@string/app_name">
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ import androidx.lifecycle.ViewModel
|
||||||
import org.linphone.utils.Event
|
import org.linphone.utils.Event
|
||||||
|
|
||||||
open class TopBarViewModel : ViewModel() {
|
open class TopBarViewModel : ViewModel() {
|
||||||
|
val title = MutableLiveData<String>()
|
||||||
|
|
||||||
val searchBarVisible = MutableLiveData<Boolean>()
|
val searchBarVisible = MutableLiveData<Boolean>()
|
||||||
|
|
||||||
val searchFilter = MutableLiveData<String>()
|
val searchFilter = MutableLiveData<String>()
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import org.linphone.databinding.ContactsFragmentBinding
|
||||||
import org.linphone.ui.MainActivity
|
import org.linphone.ui.MainActivity
|
||||||
import org.linphone.ui.contacts.viewmodel.ContactsListViewModel
|
import org.linphone.ui.contacts.viewmodel.ContactsListViewModel
|
||||||
import org.linphone.utils.hideKeyboard
|
import org.linphone.utils.hideKeyboard
|
||||||
|
import org.linphone.utils.setKeyboardInsetListener
|
||||||
import org.linphone.utils.showKeyboard
|
import org.linphone.utils.showKeyboard
|
||||||
|
|
||||||
class ContactsFragment : Fragment() {
|
class ContactsFragment : Fragment() {
|
||||||
|
|
@ -67,6 +68,11 @@ class ContactsFragment : Fragment() {
|
||||||
binding.lifecycleOwner = viewLifecycleOwner
|
binding.lifecycleOwner = viewLifecycleOwner
|
||||||
binding.viewModel = listViewModel
|
binding.viewModel = listViewModel
|
||||||
|
|
||||||
|
binding.root.setKeyboardInsetListener { keyboardVisible ->
|
||||||
|
// val portraitOrientation = resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE
|
||||||
|
listViewModel.bottomNavBarVisible.value = !keyboardVisible
|
||||||
|
}
|
||||||
|
|
||||||
// postponeEnterTransition()
|
// postponeEnterTransition()
|
||||||
|
|
||||||
binding.setOnNewContactClicked {
|
binding.setOnNewContactClicked {
|
||||||
|
|
@ -92,8 +98,8 @@ class ContactsFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
listViewModel.focusSearchBarEvent.observe(viewLifecycleOwner) {
|
listViewModel.focusSearchBarEvent.observe(viewLifecycleOwner) {
|
||||||
it.consume { take ->
|
it.consume { show ->
|
||||||
if (take) {
|
if (show) {
|
||||||
// To automatically open keyboard
|
// To automatically open keyboard
|
||||||
binding.topBar.search.showKeyboard(requireActivity().window)
|
binding.topBar.search.showKeyboard(requireActivity().window)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,14 @@
|
||||||
*/
|
*/
|
||||||
package org.linphone.ui.contacts.viewmodel
|
package org.linphone.ui.contacts.viewmodel
|
||||||
|
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
import org.linphone.ui.TopBarViewModel
|
import org.linphone.ui.TopBarViewModel
|
||||||
|
|
||||||
class ContactsListViewModel : TopBarViewModel()
|
class ContactsListViewModel : TopBarViewModel() {
|
||||||
|
val bottomNavBarVisible = MutableLiveData<Boolean>()
|
||||||
|
|
||||||
|
init {
|
||||||
|
title.value = "Contacts"
|
||||||
|
bottomNavBarVisible.value = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,8 @@ import org.linphone.R
|
||||||
import org.linphone.databinding.ConversationsFragmentBinding
|
import org.linphone.databinding.ConversationsFragmentBinding
|
||||||
import org.linphone.ui.conversations.adapter.ConversationsListAdapter
|
import org.linphone.ui.conversations.adapter.ConversationsListAdapter
|
||||||
import org.linphone.ui.conversations.viewmodel.ConversationsListViewModel
|
import org.linphone.ui.conversations.viewmodel.ConversationsListViewModel
|
||||||
|
import org.linphone.utils.hideKeyboard
|
||||||
|
import org.linphone.utils.showKeyboard
|
||||||
|
|
||||||
class ConversationsFragment : Fragment() {
|
class ConversationsFragment : Fragment() {
|
||||||
private lateinit var binding: ConversationsFragmentBinding
|
private lateinit var binding: ConversationsFragmentBinding
|
||||||
|
|
@ -144,6 +146,17 @@ class ConversationsFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listViewModel.focusSearchBarEvent.observe(viewLifecycleOwner) {
|
||||||
|
it.consume { show ->
|
||||||
|
if (show) {
|
||||||
|
// To automatically open keyboard
|
||||||
|
binding.topBar.search.showKeyboard(requireActivity().window)
|
||||||
|
} else {
|
||||||
|
binding.topBar.search.hideKeyboard()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
binding.setOnNewConversationClicked {
|
binding.setOnNewConversationClicked {
|
||||||
if (findNavController().currentDestination?.id == R.id.conversationsFragment) {
|
if (findNavController().currentDestination?.id == R.id.conversationsFragment) {
|
||||||
val action = ConversationsFragmentDirections.actionConversationsFragmentToNewConversationFragment()
|
val action = ConversationsFragmentDirections.actionConversationsFragmentToNewConversationFragment()
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@
|
||||||
package org.linphone.ui.conversations.viewmodel
|
package org.linphone.ui.conversations.viewmodel
|
||||||
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||||
import org.linphone.contacts.ContactsListener
|
import org.linphone.contacts.ContactsListener
|
||||||
|
|
@ -29,11 +28,12 @@ import org.linphone.core.ChatRoom
|
||||||
import org.linphone.core.Core
|
import org.linphone.core.Core
|
||||||
import org.linphone.core.CoreListenerStub
|
import org.linphone.core.CoreListenerStub
|
||||||
import org.linphone.core.tools.Log
|
import org.linphone.core.tools.Log
|
||||||
|
import org.linphone.ui.TopBarViewModel
|
||||||
import org.linphone.ui.conversations.data.ChatRoomData
|
import org.linphone.ui.conversations.data.ChatRoomData
|
||||||
import org.linphone.utils.Event
|
import org.linphone.utils.Event
|
||||||
import org.linphone.utils.LinphoneUtils
|
import org.linphone.utils.LinphoneUtils
|
||||||
|
|
||||||
class ConversationsListViewModel : ViewModel() {
|
class ConversationsListViewModel : TopBarViewModel() {
|
||||||
val chatRoomsList = MutableLiveData<ArrayList<ChatRoomData>>()
|
val chatRoomsList = MutableLiveData<ArrayList<ChatRoomData>>()
|
||||||
|
|
||||||
val notifyItemChangedEvent = MutableLiveData<Event<Int>>()
|
val notifyItemChangedEvent = MutableLiveData<Event<Int>>()
|
||||||
|
|
@ -101,6 +101,8 @@ class ConversationsListViewModel : ViewModel() {
|
||||||
coreContext.postOnCoreThread { core ->
|
coreContext.postOnCoreThread { core ->
|
||||||
updateChatRoomsList()
|
updateChatRoomsList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
title.value = "Conversations"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCleared() {
|
override fun onCleared() {
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,15 @@
|
||||||
package org.linphone.utils
|
package org.linphone.utils
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.view.View
|
||||||
import android.view.Window
|
import android.view.Window
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.core.view.doOnLayout
|
||||||
import androidx.databinding.BindingAdapter
|
import androidx.databinding.BindingAdapter
|
||||||
import coil.load
|
import coil.load
|
||||||
import coil.transform.CircleCropTransformation
|
import coil.transform.CircleCropTransformation
|
||||||
|
|
@ -49,6 +52,29 @@ fun TextInputLayout.hideKeyboard() {
|
||||||
imm.hideSoftInputFromWindow(this.windowToken, 0)
|
imm.hideSoftInputFromWindow(this.windowToken, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun View.setKeyboardInsetListener(lambda: (visible: Boolean) -> Unit) {
|
||||||
|
doOnLayout {
|
||||||
|
var isKeyboardVisible = ViewCompat.getRootWindowInsets(this)?.isVisible(
|
||||||
|
WindowInsetsCompat.Type.ime()
|
||||||
|
) == true
|
||||||
|
|
||||||
|
lambda(isKeyboardVisible)
|
||||||
|
|
||||||
|
// See https://issuetracker.google.com/issues/281942480
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(
|
||||||
|
rootView
|
||||||
|
) { view, insets ->
|
||||||
|
val keyboardVisibilityChanged = ViewCompat.getRootWindowInsets(view)
|
||||||
|
?.isVisible(WindowInsetsCompat.Type.ime()) == true
|
||||||
|
if (keyboardVisibilityChanged != isKeyboardVisible) {
|
||||||
|
isKeyboardVisible = keyboardVisibilityChanged
|
||||||
|
lambda(isKeyboardVisible)
|
||||||
|
}
|
||||||
|
ViewCompat.onApplyWindowInsets(view, insets)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@BindingAdapter("android:src")
|
@BindingAdapter("android:src")
|
||||||
fun ImageView.setSourceImageResource(resource: Int) {
|
fun ImageView.setSourceImageResource(resource: Int) {
|
||||||
this.setImageResource(resource)
|
this.setImageResource(resource)
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:transitionName="bottom_nav_bar"
|
android:transitionName="bottom_nav_bar"
|
||||||
|
android:id="@+id/bottom_nav_bar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
android:id="@+id/top_bar"
|
android:id="@+id/top_bar"
|
||||||
bind:viewModel="@{viewModel}"
|
bind:viewModel="@{viewModel}"
|
||||||
bind:onAvatarClickListener="@{onAvatarClickListener}"
|
bind:onAvatarClickListener="@{onAvatarClickListener}"
|
||||||
layout="@layout/main_fragment_top_bar" />
|
layout="@layout/top_search_bar" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/background"
|
android:id="@+id/background"
|
||||||
|
|
@ -66,8 +66,21 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/no_contacts_image" />
|
app:layout_constraintTop_toBottomOf="@id/no_contacts_image" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/contactsList"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_marginEnd="10dp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/background"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
|
||||||
|
|
||||||
<include
|
<include
|
||||||
bind:onConversationsClicked="@{onConversationsClicked}"
|
bind:onConversationsClicked="@{onConversationsClicked}"
|
||||||
|
android:visibility="@{viewModel.bottomNavBarVisible ? View.VISIBLE : View.GONE}"
|
||||||
android:id="@+id/bottom_nav_bar"
|
android:id="@+id/bottom_nav_bar"
|
||||||
layout="@layout/bottom_nav_bar_contacts"
|
layout="@layout/bottom_nav_bar_contacts"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
|
|
||||||
|
|
@ -21,56 +21,21 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/primary_color">
|
android:background="@color/primary_color">
|
||||||
|
|
||||||
<TextView
|
<include
|
||||||
android:id="@+id/title"
|
android:id="@+id/top_bar"
|
||||||
android:layout_width="wrap_content"
|
bind:viewModel="@{viewModel}"
|
||||||
android:layout_height="wrap_content"
|
layout="@layout/top_search_bar" />
|
||||||
android:text="Conversations"
|
|
||||||
android:textSize="20sp"
|
|
||||||
android:textColor="#FFFFFF"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:layout_margin="20dp"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"/>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/menu"
|
|
||||||
android:layout_marginStart="22dp"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/title"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/title"/>
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_marginTop="10dp"
|
android:layout_marginTop="17dp"
|
||||||
android:src="@drawable/shape_white_background"
|
android:src="@drawable/shape_white_background"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/title"
|
app:layout_constraintTop_toBottomOf="@id/top_bar"
|
||||||
app:layout_constraintBottom_toBottomOf="parent" />
|
app:layout_constraintBottom_toBottomOf="parent" />
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/search_bar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="30dp"
|
|
||||||
android:layout_marginStart="30dp"
|
|
||||||
android:layout_marginEnd="30dp"
|
|
||||||
android:padding="10dp"
|
|
||||||
android:drawableStart="@drawable/search"
|
|
||||||
android:drawablePadding="10dp"
|
|
||||||
android:background="@drawable/shape_search_round_background"
|
|
||||||
android:hint="Rechercher un contact, une conversation..."
|
|
||||||
android:textSize="14sp"
|
|
||||||
android:inputType="textPersonName|textNoSuggestions"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/title" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/sort_by_label"
|
android:id="@+id/sort_by_label"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
@ -79,7 +44,7 @@
|
||||||
android:text="Trier par"
|
android:text="Trier par"
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
android:textColor="@color/gray_5"
|
android:textColor="@color/gray_5"
|
||||||
app:layout_constraintStart_toStartOf="@id/search_bar"
|
app:layout_constraintStart_toStartOf="@id/top_bar"
|
||||||
app:layout_constraintTop_toTopOf="@id/sort_by"
|
app:layout_constraintTop_toTopOf="@id/sort_by"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/sort_by"/>
|
app:layout_constraintBottom_toBottomOf="@id/sort_by"/>
|
||||||
|
|
||||||
|
|
@ -94,7 +59,7 @@
|
||||||
android:textColor="@color/blue_filter"
|
android:textColor="@color/blue_filter"
|
||||||
android:drawablePadding="5dp"
|
android:drawablePadding="5dp"
|
||||||
app:layout_constraintStart_toEndOf="@id/sort_by_label"
|
app:layout_constraintStart_toEndOf="@id/sort_by_label"
|
||||||
app:layout_constraintTop_toBottomOf="@id/search_bar"
|
app:layout_constraintTop_toBottomOf="@id/top_bar"
|
||||||
app:drawableEndCompat="@drawable/spinner" />
|
app:drawableEndCompat="@drawable/spinner" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
android:layout_marginTop="20dp"
|
android:layout_marginTop="20dp"
|
||||||
android:layout_marginEnd="10dp"
|
android:layout_marginEnd="10dp"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:text="Contacts"
|
android:text="@{viewModel.title, default=`Title`}"
|
||||||
android:textColor="#FFFFFF"
|
android:textColor="#FFFFFF"
|
||||||
android:textSize="20sp"
|
android:textSize="20sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
|
|
@ -98,8 +98,7 @@
|
||||||
android:layout_marginTop="20dp"
|
android:layout_marginTop="20dp"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:textColorHint="@color/gray_6"
|
android:textColorHint="@color/gray_6"
|
||||||
android:hint="Search contacts"
|
app:hintEnabled="false"
|
||||||
app:hintEnabled="@{viewModel.searchFilter.length() == 0}"
|
|
||||||
app:hintAnimationEnabled="false"
|
app:hintAnimationEnabled="false"
|
||||||
app:hintTextColor="@color/gray_6"
|
app:hintTextColor="@color/gray_6"
|
||||||
app:boxStrokeWidth="0dp"
|
app:boxStrokeWidth="0dp"
|
||||||
Loading…
Add table
Reference in a new issue