diff --git a/app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationsContactsAndSuggestionsListAdapter.kt b/app/src/main/java/org/linphone/ui/adapter/ConversationsContactsAndSuggestionsListAdapter.kt
similarity index 73%
rename from app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationsContactsAndSuggestionsListAdapter.kt
rename to app/src/main/java/org/linphone/ui/adapter/ConversationsContactsAndSuggestionsListAdapter.kt
index 0b005a4ee..97cde1bb0 100644
--- a/app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationsContactsAndSuggestionsListAdapter.kt
+++ b/app/src/main/java/org/linphone/ui/adapter/ConversationsContactsAndSuggestionsListAdapter.kt
@@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package org.linphone.ui.main.chat.adapter
+package org.linphone.ui.adapter
import android.content.Context
import android.view.LayoutInflater
@@ -31,11 +31,11 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import org.linphone.R
-import org.linphone.databinding.ChatMessageForwardContactListCellBinding
-import org.linphone.databinding.ChatMessageForwardConversationListCellBinding
-import org.linphone.databinding.ChatMessageForwardSuggestionListCellBinding
-import org.linphone.databinding.StartCallSuggestionListDecorationBinding
-import org.linphone.ui.main.chat.model.ConversationContactOrSuggestionModel
+import org.linphone.databinding.GenericAddressPickerContactListCellBinding
+import org.linphone.databinding.GenericAddressPickerConversationListCellBinding
+import org.linphone.databinding.GenericAddressPickerListDecorationBinding
+import org.linphone.databinding.GenericAddressPickerSuggestionListCellBinding
+import org.linphone.ui.main.model.ConversationContactOrSuggestionModel
import org.linphone.utils.AppUtils
import org.linphone.utils.Event
import org.linphone.utils.HeaderAdapter
@@ -64,16 +64,18 @@ class ConversationsContactsAndSuggestionsListAdapter :
}
override fun getHeaderViewForPosition(context: Context, position: Int): View {
- val binding = StartCallSuggestionListDecorationBinding.inflate(LayoutInflater.from(context))
+ val binding = GenericAddressPickerListDecorationBinding.inflate(
+ LayoutInflater.from(context)
+ )
binding.header.text = when (getItemViewType(position)) {
CONVERSATION_TYPE -> {
- AppUtils.getString(R.string.conversation_message_forward_conversations_list_title)
+ AppUtils.getString(R.string.generic_address_picker_conversations_list_title)
}
SUGGESTION_TYPE -> {
- AppUtils.getString(R.string.history_call_start_suggestions_list_title)
+ AppUtils.getString(R.string.generic_address_picker_suggestions_list_title)
}
else -> {
- AppUtils.getString(R.string.history_call_start_contacts_list_title)
+ AppUtils.getString(R.string.generic_address_picker_contacts_list_title)
}
}
return binding.root
@@ -93,33 +95,51 @@ class ConversationsContactsAndSuggestionsListAdapter :
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
CONVERSATION_TYPE -> {
- val binding: ChatMessageForwardConversationListCellBinding = DataBindingUtil.inflate(
+ val binding: GenericAddressPickerConversationListCellBinding = DataBindingUtil.inflate(
LayoutInflater.from(parent.context),
- R.layout.chat_message_forward_conversation_list_cell,
+ R.layout.generic_address_picker_conversation_list_cell,
parent,
false
)
- binding.lifecycleOwner = parent.findViewTreeLifecycleOwner()
+ binding.apply {
+ lifecycleOwner = parent.findViewTreeLifecycleOwner()
+
+ setOnClickListener {
+ onClickedEvent.value = Event(model!!)
+ }
+ }
ConversationViewHolder(binding)
}
CONTACT_TYPE -> {
- val binding: ChatMessageForwardContactListCellBinding = DataBindingUtil.inflate(
+ val binding: GenericAddressPickerContactListCellBinding = DataBindingUtil.inflate(
LayoutInflater.from(parent.context),
- R.layout.chat_message_forward_contact_list_cell,
+ R.layout.generic_address_picker_contact_list_cell,
parent,
false
)
- binding.lifecycleOwner = parent.findViewTreeLifecycleOwner()
+ binding.apply {
+ lifecycleOwner = parent.findViewTreeLifecycleOwner()
+
+ setOnClickListener {
+ onClickedEvent.value = Event(model!!)
+ }
+ }
ContactViewHolder(binding)
}
else -> {
- val binding: ChatMessageForwardSuggestionListCellBinding = DataBindingUtil.inflate(
+ val binding: GenericAddressPickerSuggestionListCellBinding = DataBindingUtil.inflate(
LayoutInflater.from(parent.context),
- R.layout.chat_message_forward_suggestion_list_cell,
+ R.layout.generic_address_picker_suggestion_list_cell,
parent,
false
)
- binding.lifecycleOwner = parent.findViewTreeLifecycleOwner()
+ binding.apply {
+ lifecycleOwner = parent.findViewTreeLifecycleOwner()
+
+ setOnClickListener {
+ onClickedEvent.value = Event(model!!)
+ }
+ }
SuggestionViewHolder(binding)
}
}
@@ -134,33 +154,25 @@ class ConversationsContactsAndSuggestionsListAdapter :
}
inner class ConversationViewHolder(
- val binding: ChatMessageForwardConversationListCellBinding
+ val binding: GenericAddressPickerConversationListCellBinding
) : RecyclerView.ViewHolder(binding.root) {
@UiThread
fun bind(conversationContactOrSuggestionModel: ConversationContactOrSuggestionModel) {
with(binding) {
model = conversationContactOrSuggestionModel
- setOnClickListener {
- onClickedEvent.value = Event(conversationContactOrSuggestionModel)
- }
-
executePendingBindings()
}
}
}
inner class ContactViewHolder(
- val binding: ChatMessageForwardContactListCellBinding
+ val binding: GenericAddressPickerContactListCellBinding
) : RecyclerView.ViewHolder(binding.root) {
@UiThread
fun bind(conversationContactOrSuggestionModel: ConversationContactOrSuggestionModel) {
with(binding) {
- model = conversationContactOrSuggestionModel.avatarModel.value
-
- setOnClickListener {
- onClickedEvent.value = Event(conversationContactOrSuggestionModel)
- }
+ model = conversationContactOrSuggestionModel
val previousItem = bindingAdapterPosition - 1
val previousLetter = if (previousItem >= 0) {
@@ -179,17 +191,13 @@ class ConversationsContactsAndSuggestionsListAdapter :
}
inner class SuggestionViewHolder(
- val binding: ChatMessageForwardSuggestionListCellBinding
+ val binding: GenericAddressPickerSuggestionListCellBinding
) : RecyclerView.ViewHolder(binding.root) {
@UiThread
fun bind(conversationContactOrSuggestionModel: ConversationContactOrSuggestionModel) {
with(binding) {
model = conversationContactOrSuggestionModel
- setOnClickListener {
- onClickedEvent.value = Event(conversationContactOrSuggestionModel)
- }
-
executePendingBindings()
}
}
diff --git a/app/src/main/java/org/linphone/ui/call/conference/fragment/ConferenceAddParticipantsFragment.kt b/app/src/main/java/org/linphone/ui/call/conference/fragment/ConferenceAddParticipantsFragment.kt
index 19baceba1..4bba36a4c 100644
--- a/app/src/main/java/org/linphone/ui/call/conference/fragment/ConferenceAddParticipantsFragment.kt
+++ b/app/src/main/java/org/linphone/ui/call/conference/fragment/ConferenceAddParticipantsFragment.kt
@@ -84,7 +84,7 @@ class ConferenceAddParticipantsFragment : GenericAddressPickerFragment() {
setupRecyclerView(binding.contactsList)
- viewModel.contactsAndSuggestionsList.observe(
+ viewModel.modelsList.observe(
viewLifecycleOwner
) {
Log.i("$TAG Contacts & suggestions list is ready with [${it.size}] items")
diff --git a/app/src/main/java/org/linphone/ui/call/fragment/AbstractNewTransferCallFragment.kt b/app/src/main/java/org/linphone/ui/call/fragment/AbstractNewTransferCallFragment.kt
index bdae477a1..93d2fef78 100644
--- a/app/src/main/java/org/linphone/ui/call/fragment/AbstractNewTransferCallFragment.kt
+++ b/app/src/main/java/org/linphone/ui/call/fragment/AbstractNewTransferCallFragment.kt
@@ -37,12 +37,12 @@ import org.linphone.contacts.getListOfSipAddressesAndPhoneNumbers
import org.linphone.core.Address
import org.linphone.core.tools.Log
import org.linphone.databinding.StartCallFragmentBinding
+import org.linphone.ui.adapter.ConversationsContactsAndSuggestionsListAdapter
import org.linphone.ui.main.contacts.model.ContactNumberOrAddressClickListener
import org.linphone.ui.main.contacts.model.ContactNumberOrAddressModel
import org.linphone.ui.main.contacts.model.NumberOrAddressPickerDialogModel
-import org.linphone.ui.main.history.adapter.ContactsAndSuggestionsListAdapter
-import org.linphone.ui.main.history.model.ContactOrSuggestionModel
import org.linphone.ui.main.history.viewmodel.StartCallViewModel
+import org.linphone.ui.main.model.ConversationContactOrSuggestionModel
import org.linphone.ui.main.model.isEndToEndEncryptionMandatory
import org.linphone.utils.DialogUtils
import org.linphone.utils.LinphoneUtils
@@ -62,7 +62,7 @@ abstract class AbstractNewTransferCallFragment : GenericCallFragment() {
R.id.call_nav_graph
)
- private lateinit var adapter: ContactsAndSuggestionsListAdapter
+ private lateinit var adapter: ConversationsContactsAndSuggestionsListAdapter
private val listener = object : ContactNumberOrAddressClickListener {
@UiThread
@@ -87,7 +87,7 @@ abstract class AbstractNewTransferCallFragment : GenericCallFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- adapter = ContactsAndSuggestionsListAdapter()
+ adapter = ConversationsContactsAndSuggestionsListAdapter()
}
override fun onCreateView(
@@ -125,7 +125,7 @@ abstract class AbstractNewTransferCallFragment : GenericCallFragment() {
binding.contactsAndSuggestionsList.adapter = adapter
}
- adapter.contactClickedEvent.observe(viewLifecycleOwner) {
+ adapter.onClickedEvent.observe(viewLifecycleOwner) {
it.consume { model ->
startCall(model)
}
@@ -133,7 +133,7 @@ abstract class AbstractNewTransferCallFragment : GenericCallFragment() {
binding.contactsAndSuggestionsList.layoutManager = LinearLayoutManager(requireContext())
- viewModel.contactsAndSuggestionsList.observe(
+ viewModel.modelsList.observe(
viewLifecycleOwner
) {
Log.i("$TAG Contacts & suggestions list is ready with [${it.size}] items")
@@ -213,7 +213,7 @@ abstract class AbstractNewTransferCallFragment : GenericCallFragment() {
@WorkerThread
abstract fun action(address: Address)
- private fun startCall(model: ContactOrSuggestionModel) {
+ private fun startCall(model: ConversationContactOrSuggestionModel) {
coreContext.postOnCoreThread { core ->
val friend = model.friend
if (friend == null) {
@@ -225,7 +225,7 @@ abstract class AbstractNewTransferCallFragment : GenericCallFragment() {
val numbersCount = friend.phoneNumbers.size
// Do not consider phone numbers if default account is in secure mode
- val enablePhoneNumbers = isEndToEndEncryptionMandatory() != true
+ val enablePhoneNumbers = !isEndToEndEncryptionMandatory()
if (addressesCount == 1 && (numbersCount == 0 || !enablePhoneNumbers)) {
Log.i(
diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationForwardMessageFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationForwardMessageFragment.kt
index 4b9ca79be..4c9310b18 100644
--- a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationForwardMessageFragment.kt
+++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationForwardMessageFragment.kt
@@ -32,7 +32,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.ChatMessageForwardFragmentBinding
-import org.linphone.ui.main.chat.adapter.ConversationsContactsAndSuggestionsListAdapter
+import org.linphone.ui.adapter.ConversationsContactsAndSuggestionsListAdapter
import org.linphone.ui.main.chat.viewmodel.ConversationForwardMessageViewModel
import org.linphone.ui.main.contacts.model.ContactNumberOrAddressModel
import org.linphone.ui.main.contacts.model.NumberOrAddressPickerDialogModel
@@ -103,7 +103,7 @@ class ConversationForwardMessageFragment : SlidingPaneChildFragment() {
val headerItemDecoration = RecyclerViewHeaderDecoration(requireContext(), adapter)
binding.contactsList.addItemDecoration(headerItemDecoration)
- viewModel.conversationsContactsAndSuggestionsList.observe(
+ viewModel.modelsList.observe(
viewLifecycleOwner
) {
Log.i(
diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/StartConversationFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/StartConversationFragment.kt
index 951431d91..8e7340dca 100644
--- a/app/src/main/java/org/linphone/ui/main/chat/fragment/StartConversationFragment.kt
+++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/StartConversationFragment.kt
@@ -79,7 +79,7 @@ class StartConversationFragment : GenericAddressPickerFragment() {
setupRecyclerView(binding.contactsList)
- viewModel.contactsAndSuggestionsList.observe(
+ viewModel.modelsList.observe(
viewLifecycleOwner
) {
Log.i("$TAG Contacts & suggestions list is ready with [${it.size}] items")
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 501cd60e4..c228c4d56 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
@@ -101,7 +101,7 @@ class MessageModel @WorkerThread constructor(
val time = TimestampUtils.toString(timestamp)
val chatRoomIsReadOnly = chatMessage.chatRoom.isReadOnly ||
- (!chatMessage.chatRoom.hasCapability(ChatRoom.Capabilities.Encrypted.toInt()) && isEndToEndEncryptionMandatory() == true)
+ (!chatMessage.chatRoom.hasCapability(ChatRoom.Capabilities.Encrypted.toInt()) && isEndToEndEncryptionMandatory())
val groupedWithNextMessage = MutableLiveData()
diff --git a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationForwardMessageViewModel.kt b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationForwardMessageViewModel.kt
index e9d7ff0b1..5169f778a 100644
--- a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationForwardMessageViewModel.kt
+++ b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationForwardMessageViewModel.kt
@@ -22,49 +22,29 @@ package org.linphone.ui.main.chat.viewmodel
import androidx.annotation.UiThread
import androidx.annotation.WorkerThread
import androidx.lifecycle.MutableLiveData
-import java.text.Collator
-import java.util.Locale
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
-import org.linphone.contacts.ContactsManager
import org.linphone.contacts.getListOfSipAddressesAndPhoneNumbers
import org.linphone.core.Address
import org.linphone.core.ChatRoom
import org.linphone.core.ChatRoomListenerStub
import org.linphone.core.ChatRoomParams
-import org.linphone.core.MagicSearch
-import org.linphone.core.MagicSearchListenerStub
-import org.linphone.core.SearchResult
import org.linphone.core.tools.Log
-import org.linphone.ui.GenericViewModel
-import org.linphone.ui.main.chat.model.ConversationContactOrSuggestionModel
-import org.linphone.ui.main.contacts.model.ContactAvatarModel
import org.linphone.ui.main.contacts.model.ContactNumberOrAddressClickListener
import org.linphone.ui.main.contacts.model.ContactNumberOrAddressModel
+import org.linphone.ui.main.model.ConversationContactOrSuggestionModel
import org.linphone.ui.main.model.isEndToEndEncryptionMandatory
+import org.linphone.ui.main.viewmodel.AddressSelectionViewModel
import org.linphone.utils.AppUtils
import org.linphone.utils.Event
import org.linphone.utils.LinphoneUtils
-class ConversationForwardMessageViewModel @UiThread constructor() : GenericViewModel() {
+class ConversationForwardMessageViewModel @UiThread constructor() : AddressSelectionViewModel() {
companion object {
private const val TAG = "[Conversation Forward Message ViewModel]"
}
- protected var magicSearchSourceFlags = MagicSearch.Source.All.toInt()
-
- private var currentFilter = ""
- private var previousFilter = "NotSet"
-
- val searchFilter = MutableLiveData()
-
- val conversationsContactsAndSuggestionsList = MutableLiveData>()
-
- private var limitSearchToLinphoneAccounts = true
-
- private lateinit var magicSearch: MagicSearch
-
val operationInProgress = MutableLiveData()
val chatRoomCreatedEvent: MutableLiveData>> by lazy {
@@ -79,26 +59,6 @@ class ConversationForwardMessageViewModel @UiThread constructor() : GenericViewM
MutableLiveData>()
}
- private val magicSearchListener = object : MagicSearchListenerStub() {
- @WorkerThread
- override fun onSearchResultsReceived(magicSearch: MagicSearch) {
- Log.i("$TAG Magic search contacts available")
- processMagicSearchResults(magicSearch.lastSearch)
- }
- }
-
- private val contactsListener = object : ContactsManager.ContactsListener {
- @WorkerThread
- override fun onContactsLoaded() {
- Log.i("$TAG Contacts have been (re)loaded, updating list")
- applyFilter(
- currentFilter,
- if (limitSearchToLinphoneAccounts) corePreferences.defaultDomain else "",
- magicSearchSourceFlags
- )
- }
- }
-
private val listener = object : ContactNumberOrAddressClickListener {
@UiThread
override fun onClicked(model: ContactNumberOrAddressModel) {
@@ -152,182 +112,7 @@ class ConversationForwardMessageViewModel @UiThread constructor() : GenericViewM
}
init {
- coreContext.postOnCoreThread { core ->
- limitSearchToLinphoneAccounts = isEndToEndEncryptionMandatory()
-
- coreContext.contactsManager.addListener(contactsListener)
- magicSearch = core.createMagicSearch()
- magicSearch.limitedSearch = false
- magicSearch.addListener(magicSearchListener)
- }
-
- applyFilter(currentFilter)
- }
-
- @UiThread
- override fun onCleared() {
- coreContext.postOnCoreThread {
- magicSearch.removeListener(magicSearchListener)
- coreContext.contactsManager.removeListener(contactsListener)
- }
- super.onCleared()
- }
-
- @UiThread
- fun clearFilter() {
- if (searchFilter.value.orEmpty().isNotEmpty()) {
- searchFilter.value = ""
- }
- }
-
- @UiThread
- fun applyFilter(filter: String) {
- coreContext.postOnCoreThread {
- applyFilter(
- filter,
- if (limitSearchToLinphoneAccounts) corePreferences.defaultDomain else "",
- magicSearchSourceFlags
- )
- }
- }
-
- @WorkerThread
- private fun applyFilter(
- filter: String,
- domain: String,
- sources: Int
- ) {
- if (previousFilter.isNotEmpty() && (
- previousFilter.length > filter.length ||
- (previousFilter.length == filter.length && previousFilter != filter)
- )
- ) {
- magicSearch.resetSearchCache()
- }
- currentFilter = filter
- previousFilter = filter
-
- Log.i(
- "$TAG Asking Magic search for contacts matching filter [$filter], domain [$domain] and in sources [$sources]"
- )
- magicSearch.getContactsListAsync(
- filter,
- domain,
- sources,
- MagicSearch.Aggregation.Friend
- )
- }
-
- @WorkerThread
- private fun processMagicSearchResults(results: Array) {
- Log.i("$TAG Processing [${results.size}] results")
-
- val conversationsList = arrayListOf()
- for (chatRoom in LinphoneUtils.getDefaultAccount()?.chatRooms.orEmpty()) {
- // Only get group conversations
- if (!chatRoom.currentParams.isGroupEnabled) {
- continue
- }
-
- val found = if (currentFilter.isEmpty()) {
- null
- } else {
- chatRoom.participants.find {
- // Search in address but also in contact name if exists
- val model =
- coreContext.contactsManager.getContactAvatarModelForAddress(it.address)
- model.contactName?.contains(
- currentFilter,
- ignoreCase = true
- ) == true || it.address.asStringUriOnly().contains(
- currentFilter,
- ignoreCase = true
- )
- }
- }
- if (
- currentFilter.isEmpty() ||
- found != null ||
- chatRoom.peerAddress.asStringUriOnly().contains(currentFilter, ignoreCase = true) ||
- chatRoom.subject.orEmpty().contains(currentFilter, ignoreCase = true)
- ) {
- val localAddress = chatRoom.localAddress
- val remoteAddress = chatRoom.peerAddress
- val model = ConversationContactOrSuggestionModel(
- remoteAddress,
- localAddress,
- chatRoom.subject
- )
-
- val fakeFriend = coreContext.core.createFriend()
- fakeFriend.name = chatRoom.subject
- val avatarModel = ContactAvatarModel(fakeFriend)
- avatarModel.defaultToConversationIcon.postValue(true)
-
- model.avatarModel.postValue(avatarModel)
- conversationsList.add(model)
- }
- }
-
- val contactsList = arrayListOf()
- val suggestionsList = arrayListOf()
-
- for (result in results) {
- val address = result.address
- if (address != null) {
- val friend = coreContext.contactsManager.findContactByAddress(address)
- if (friend != null) {
- val model = ConversationContactOrSuggestionModel(address, friend = friend)
- val avatarModel = coreContext.contactsManager.getContactAvatarModelForAddress(
- address
- )
- model.avatarModel.postValue(avatarModel)
-
- contactsList.add(model)
- } else {
- // If user-input generated result (always last) already exists, don't show it again
- if (result.sourceFlags == MagicSearch.Source.Request.toInt()) {
- val found = suggestionsList.find {
- it.address.weakEqual(address)
- }
- if (found != null) {
- Log.i(
- "$TAG Result generated from user input is a duplicate of an existing solution, preventing double"
- )
- continue
- }
- }
- val defaultAccountAddress = coreContext.core.defaultAccount?.params?.identityAddress
- if (defaultAccountAddress != null && address.weakEqual(defaultAccountAddress)) {
- Log.i("$TAG Removing from suggestions current default account address")
- continue
- }
-
- val model = ConversationContactOrSuggestionModel(address) {
- coreContext.startAudioCall(address)
- }
-
- suggestionsList.add(model)
- }
- }
- }
-
- val collator = Collator.getInstance(Locale.getDefault())
- contactsList.sortWith { model1, model2 ->
- collator.compare(model1.name, model2.name)
- }
- suggestionsList.sortWith { model1, model2 ->
- collator.compare(model1.name, model2.name)
- }
-
- val list = arrayListOf()
- list.addAll(conversationsList)
- list.addAll(contactsList)
- list.addAll(suggestionsList)
- conversationsContactsAndSuggestionsList.postValue(list)
- Log.i(
- "$TAG Processed [${results.size}] results, including [${conversationsList.size}] conversations, [${contactsList.size}] contacts and [${suggestionsList.size}] suggestions"
- )
+ skipConversation = false
}
@WorkerThread
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 ed6c26e32..3182ee7f9 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
@@ -498,7 +498,7 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
@WorkerThread
fun checkIfConversationShouldBeDisabledForSecurityReasons() {
if (!chatRoom.hasCapability(ChatRoom.Capabilities.Encrypted.toInt())) {
- if (isEndToEndEncryptionMandatory() == true) {
+ if (isEndToEndEncryptionMandatory()) {
Log.w(
"$TAG Conversation with subject [${chatRoom.subject}] has been disabled because it isn't encrypted and default account is in secure mode"
)
diff --git a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactViewModel.kt b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactViewModel.kt
index 5c200f243..e368dd456 100644
--- a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactViewModel.kt
+++ b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactViewModel.kt
@@ -250,7 +250,7 @@ class ContactViewModel @UiThread constructor() : GenericViewModel() {
)
// Only expand contacts' devices & trust by default if in E2E encrypted mode
expandDevicesTrust.postValue(
- isEndToEndEncryptionMandatory() == true
+ isEndToEndEncryptionMandatory()
)
coreContext.contactsManager.addListener(contactsListener)
}
@@ -427,7 +427,7 @@ class ContactViewModel @UiThread constructor() : GenericViewModel() {
val numbersCount = friend.phoneNumbers.size
// Do not consider phone numbers if default account is in secure mode
- val enablePhoneNumbers = isEndToEndEncryptionMandatory() != true
+ val enablePhoneNumbers = !isEndToEndEncryptionMandatory()
if (addressesCount == 1 && (numbersCount == 0 || !enablePhoneNumbers)) {
Log.i(
@@ -464,7 +464,7 @@ class ContactViewModel @UiThread constructor() : GenericViewModel() {
val numbersCount = friend.phoneNumbers.size
// Do not consider phone numbers if default account is in secure mode
- val enablePhoneNumbers = isEndToEndEncryptionMandatory() != true
+ val enablePhoneNumbers = !isEndToEndEncryptionMandatory()
if (addressesCount == 1 && (numbersCount == 0 || !enablePhoneNumbers)) {
Log.i(
@@ -501,7 +501,7 @@ class ContactViewModel @UiThread constructor() : GenericViewModel() {
val numbersCount = friend.phoneNumbers.size
// Do not consider phone numbers if default account is in secure mode
- val enablePhoneNumbers = isEndToEndEncryptionMandatory() != true
+ val enablePhoneNumbers = !isEndToEndEncryptionMandatory()
if (addressesCount == 1 && (numbersCount == 0 || !enablePhoneNumbers)) {
Log.i(
diff --git a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactsListViewModel.kt b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactsListViewModel.kt
index 11e31b7d7..967537c6f 100644
--- a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactsListViewModel.kt
+++ b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactsListViewModel.kt
@@ -163,7 +163,7 @@ class ContactsListViewModel @UiThread constructor() : AbstractMainViewModel() {
val defaultAccount = coreContext.core.defaultAccount
val defaultDomain = defaultAccount?.params?.domain == corePreferences.defaultDomain
isDefaultAccountLinphone.postValue(defaultDomain)
- domainFilter = if (isEndToEndEncryptionMandatory() == true) {
+ domainFilter = if (isEndToEndEncryptionMandatory()) {
corePreferences.defaultDomain
} else {
"*"
diff --git a/app/src/main/java/org/linphone/ui/main/fragment/AddParticipantsFragment.kt b/app/src/main/java/org/linphone/ui/main/fragment/AddParticipantsFragment.kt
index 706f54255..125b650b3 100644
--- a/app/src/main/java/org/linphone/ui/main/fragment/AddParticipantsFragment.kt
+++ b/app/src/main/java/org/linphone/ui/main/fragment/AddParticipantsFragment.kt
@@ -85,7 +85,7 @@ class AddParticipantsFragment : GenericAddressPickerFragment() {
viewModel.addSelectedParticipants(participants)
}
- viewModel.contactsAndSuggestionsList.observe(
+ viewModel.modelsList.observe(
viewLifecycleOwner
) {
Log.i("$TAG Contacts & suggestions list is ready with [${it.size}] items")
diff --git a/app/src/main/java/org/linphone/ui/main/fragment/GenericAddressPickerFragment.kt b/app/src/main/java/org/linphone/ui/main/fragment/GenericAddressPickerFragment.kt
index c199afa30..c3e88f410 100644
--- a/app/src/main/java/org/linphone/ui/main/fragment/GenericAddressPickerFragment.kt
+++ b/app/src/main/java/org/linphone/ui/main/fragment/GenericAddressPickerFragment.kt
@@ -31,11 +31,11 @@ import org.linphone.contacts.getListOfSipAddressesAndPhoneNumbers
import org.linphone.core.Address
import org.linphone.core.Friend
import org.linphone.core.tools.Log
+import org.linphone.ui.adapter.ConversationsContactsAndSuggestionsListAdapter
import org.linphone.ui.main.contacts.model.ContactNumberOrAddressClickListener
import org.linphone.ui.main.contacts.model.ContactNumberOrAddressModel
import org.linphone.ui.main.contacts.model.NumberOrAddressPickerDialogModel
-import org.linphone.ui.main.history.adapter.ContactsAndSuggestionsListAdapter
-import org.linphone.ui.main.history.model.ContactOrSuggestionModel
+import org.linphone.ui.main.model.ConversationContactOrSuggestionModel
import org.linphone.ui.main.model.SelectedAddressModel
import org.linphone.ui.main.model.isEndToEndEncryptionMandatory
import org.linphone.ui.main.viewmodel.AddressSelectionViewModel
@@ -51,7 +51,7 @@ abstract class GenericAddressPickerFragment : GenericMainFragment() {
private var numberOrAddressPickerDialog: Dialog? = null
- protected lateinit var adapter: ContactsAndSuggestionsListAdapter
+ protected lateinit var adapter: ConversationsContactsAndSuggestionsListAdapter
protected abstract val viewModel: AddressSelectionViewModel
@@ -85,13 +85,13 @@ abstract class GenericAddressPickerFragment : GenericMainFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- adapter = ContactsAndSuggestionsListAdapter()
+ adapter = ConversationsContactsAndSuggestionsListAdapter()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- adapter.contactClickedEvent.observe(viewLifecycleOwner) {
+ adapter.onClickedEvent.observe(viewLifecycleOwner) {
it.consume { model ->
handleClickOnContactModel(model)
}
@@ -147,7 +147,7 @@ abstract class GenericAddressPickerFragment : GenericMainFragment() {
}
}
- private fun handleClickOnContactModel(model: ContactOrSuggestionModel) {
+ private fun handleClickOnContactModel(model: ConversationContactOrSuggestionModel) {
coreContext.postOnCoreThread { core ->
val friend = model.friend
if (friend == null) {
@@ -162,7 +162,7 @@ abstract class GenericAddressPickerFragment : GenericMainFragment() {
val numbersCount = friend.phoneNumbers.size
// Do not consider phone numbers if default account is in secure mode
- val enablePhoneNumbers = isEndToEndEncryptionMandatory() != true
+ val enablePhoneNumbers = !isEndToEndEncryptionMandatory()
if (addressesCount == 1 && (numbersCount == 0 || !enablePhoneNumbers)) {
val address = friend.addresses.first()
diff --git a/app/src/main/java/org/linphone/ui/main/history/adapter/ContactsAndSuggestionsListAdapter.kt b/app/src/main/java/org/linphone/ui/main/history/adapter/ContactsAndSuggestionsListAdapter.kt
deleted file mode 100644
index f4278f33a..000000000
--- a/app/src/main/java/org/linphone/ui/main/history/adapter/ContactsAndSuggestionsListAdapter.kt
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * 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 .
- */
-package org.linphone.ui.main.history.adapter
-
-import android.content.Context
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.annotation.UiThread
-import androidx.databinding.DataBindingUtil
-import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.findViewTreeLifecycleOwner
-import androidx.recyclerview.widget.DiffUtil
-import androidx.recyclerview.widget.ListAdapter
-import androidx.recyclerview.widget.RecyclerView
-import org.linphone.R
-import org.linphone.databinding.ContactListCellBinding
-import org.linphone.databinding.StartCallSuggestionListCellBinding
-import org.linphone.databinding.StartCallSuggestionListDecorationBinding
-import org.linphone.ui.main.history.model.ContactOrSuggestionModel
-import org.linphone.utils.AppUtils
-import org.linphone.utils.Event
-import org.linphone.utils.HeaderAdapter
-
-class ContactsAndSuggestionsListAdapter :
- ListAdapter(
- ContactOrSuggestionDiffCallback()
- ),
- HeaderAdapter {
- companion object {
- private const val CONTACT_TYPE = 0
- private const val SUGGESTION_TYPE = 1
- }
-
- val contactClickedEvent: MutableLiveData> by lazy {
- MutableLiveData>()
- }
-
- override fun displayHeaderForPosition(position: Int): Boolean {
- val model = getItem(position)
- if (position == 0) {
- return true
- } else if (model.friend == null) {
- val previousModel = getItem(position - 1)
- return previousModel.friend != null
- }
- return false
- }
-
- override fun getHeaderViewForPosition(context: Context, position: Int): View {
- val binding = StartCallSuggestionListDecorationBinding.inflate(LayoutInflater.from(context))
- binding.header.text = if (position == 0) {
- if (getItemViewType(0) == SUGGESTION_TYPE) {
- AppUtils.getString(R.string.history_call_start_suggestions_list_title)
- } else {
- AppUtils.getString(R.string.history_call_start_contacts_list_title)
- }
- } else {
- AppUtils.getString(R.string.history_call_start_suggestions_list_title)
- }
- return binding.root
- }
-
- override fun getItemViewType(position: Int): Int {
- val model = getItem(position)
- return if (model.friend == null) SUGGESTION_TYPE else CONTACT_TYPE
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
- return when (viewType) {
- CONTACT_TYPE -> {
- val binding: ContactListCellBinding = DataBindingUtil.inflate(
- LayoutInflater.from(parent.context),
- R.layout.contact_list_cell,
- parent,
- false
- )
- binding.lifecycleOwner = parent.findViewTreeLifecycleOwner()
- ContactViewHolder(binding)
- }
- else -> {
- val binding: StartCallSuggestionListCellBinding = DataBindingUtil.inflate(
- LayoutInflater.from(parent.context),
- R.layout.start_call_suggestion_list_cell,
- parent,
- false
- )
- binding.apply {
- lifecycleOwner = parent.findViewTreeLifecycleOwner()
-
- setOnClickListener {
- contactClickedEvent.value = Event(model!!)
- }
- }
- SuggestionViewHolder(binding)
- }
- }
- }
-
- override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
- when (getItemViewType(position)) {
- CONTACT_TYPE -> (holder as ContactViewHolder).bind(getItem(position))
- else -> (holder as SuggestionViewHolder).bind(getItem(position))
- }
- }
-
- inner class ContactViewHolder(
- val binding: ContactListCellBinding
- ) : RecyclerView.ViewHolder(binding.root) {
- @UiThread
- fun bind(contactOrSuggestionModel: ContactOrSuggestionModel) {
- with(binding) {
- model = contactOrSuggestionModel.avatarModel.value
-
- setOnClickListener {
- contactClickedEvent.value = Event(contactOrSuggestionModel)
- }
-
- val previousItem = bindingAdapterPosition - 1
- val previousLetter = if (previousItem >= 0) {
- getItem(previousItem).name[0].toString()
- } else {
- ""
- }
-
- val currentLetter = contactOrSuggestionModel.name[0].toString()
- val displayLetter = previousLetter.isEmpty() || currentLetter != previousLetter
- firstContactStartingByThatLetter = displayLetter
-
- executePendingBindings()
- }
- }
- }
-
- inner class SuggestionViewHolder(
- val binding: StartCallSuggestionListCellBinding
- ) : RecyclerView.ViewHolder(binding.root) {
- @UiThread
- fun bind(contactOrSuggestionModel: ContactOrSuggestionModel) {
- with(binding) {
- model = contactOrSuggestionModel
- executePendingBindings()
- }
- }
- }
-
- private class ContactOrSuggestionDiffCallback : DiffUtil.ItemCallback() {
- override fun areItemsTheSame(
- oldItem: ContactOrSuggestionModel,
- newItem: ContactOrSuggestionModel
- ): Boolean {
- return oldItem.id == newItem.id
- }
-
- override fun areContentsTheSame(
- oldItem: ContactOrSuggestionModel,
- newItem: ContactOrSuggestionModel
- ): Boolean {
- return false
- }
- }
-}
diff --git a/app/src/main/java/org/linphone/ui/main/history/fragment/StartCallFragment.kt b/app/src/main/java/org/linphone/ui/main/history/fragment/StartCallFragment.kt
index e59f753f1..8f964e234 100644
--- a/app/src/main/java/org/linphone/ui/main/history/fragment/StartCallFragment.kt
+++ b/app/src/main/java/org/linphone/ui/main/history/fragment/StartCallFragment.kt
@@ -91,7 +91,7 @@ class StartCallFragment : GenericAddressPickerFragment() {
setupRecyclerView(binding.contactsAndSuggestionsList)
- viewModel.contactsAndSuggestionsList.observe(
+ viewModel.modelsList.observe(
viewLifecycleOwner
) {
Log.i("$TAG Contacts & suggestions list is ready with [${it.size}] items")
diff --git a/app/src/main/java/org/linphone/ui/main/history/model/ContactOrSuggestionModel.kt b/app/src/main/java/org/linphone/ui/main/history/model/ContactOrSuggestionModel.kt
deleted file mode 100644
index 9100408d6..000000000
--- a/app/src/main/java/org/linphone/ui/main/history/model/ContactOrSuggestionModel.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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 .
- */
-package org.linphone.ui.main.history.model
-
-import androidx.annotation.UiThread
-import androidx.annotation.WorkerThread
-import androidx.lifecycle.MutableLiveData
-import org.linphone.core.Address
-import org.linphone.core.Friend
-import org.linphone.ui.main.contacts.model.ContactAvatarModel
-import org.linphone.utils.AppUtils
-import org.linphone.utils.LinphoneUtils
-
-class ContactOrSuggestionModel @WorkerThread constructor(
- val address: Address,
- val friend: Friend? = null,
- private val onClicked: ((Address) -> Unit)? = null
-) {
- val id = friend?.refKey ?: address.asStringUriOnly().hashCode()
-
- val name = if (friend != null) {
- friend.name ?: LinphoneUtils.getDisplayName(address)
- } else {
- address.username.orEmpty()
- }
-
- val sipUri = address.asStringUriOnly()
-
- val initials = AppUtils.getInitials(name)
-
- val avatarModel = MutableLiveData()
-
- @UiThread
- fun onClicked() {
- onClicked?.invoke(address)
- }
-}
diff --git a/app/src/main/java/org/linphone/ui/main/chat/model/ConversationContactOrSuggestionModel.kt b/app/src/main/java/org/linphone/ui/main/model/ConversationContactOrSuggestionModel.kt
similarity index 95%
rename from app/src/main/java/org/linphone/ui/main/chat/model/ConversationContactOrSuggestionModel.kt
rename to app/src/main/java/org/linphone/ui/main/model/ConversationContactOrSuggestionModel.kt
index 71ee77e62..419bff3d9 100644
--- a/app/src/main/java/org/linphone/ui/main/chat/model/ConversationContactOrSuggestionModel.kt
+++ b/app/src/main/java/org/linphone/ui/main/model/ConversationContactOrSuggestionModel.kt
@@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package org.linphone.ui.main.chat.model
+package org.linphone.ui.main.model
import androidx.annotation.UiThread
import androidx.annotation.WorkerThread
@@ -31,7 +31,7 @@ import org.linphone.utils.LinphoneUtils
class ConversationContactOrSuggestionModel @WorkerThread constructor(
val address: Address,
val localAddress: Address? = null,
- private val conversationSubject: String? = null,
+ conversationSubject: String? = null,
val friend: Friend? = null,
private val onClicked: ((Address) -> Unit)? = null
) {
diff --git a/app/src/main/java/org/linphone/ui/main/settings/model/CodecModel.kt b/app/src/main/java/org/linphone/ui/main/settings/model/CodecModel.kt
index 9ea8bb89f..cc2237609 100644
--- a/app/src/main/java/org/linphone/ui/main/settings/model/CodecModel.kt
+++ b/app/src/main/java/org/linphone/ui/main/settings/model/CodecModel.kt
@@ -25,9 +25,9 @@ import androidx.lifecycle.MutableLiveData
class CodecModel @WorkerThread constructor(
val mimeType: String,
- val clockRate: Int,
- val recvFmtp: String?,
- val isAudioCodec: Boolean,
+ clockRate: Int,
+ recvFmtp: String?,
+ private val isAudioCodec: Boolean,
enabled: Boolean,
val onEnabledChanged: ((enabled: Boolean) -> Unit)
) {
diff --git a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/SettingsViewModel.kt b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/SettingsViewModel.kt
index 311634269..a9b81e065 100644
--- a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/SettingsViewModel.kt
+++ b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/SettingsViewModel.kt
@@ -79,7 +79,6 @@ class SettingsViewModel @UiThread constructor() : GenericViewModel() {
val showConversationsSettings = MutableLiveData()
val autoDownloadEnabled = MutableLiveData()
- val exportMediaEnabled = MutableLiveData()
// Contacts settings
val showContactsSettings = MutableLiveData()
diff --git a/app/src/main/java/org/linphone/ui/main/viewmodel/AddressSelectionViewModel.kt b/app/src/main/java/org/linphone/ui/main/viewmodel/AddressSelectionViewModel.kt
index 939c79ed1..0ba5aa32e 100644
--- a/app/src/main/java/org/linphone/ui/main/viewmodel/AddressSelectionViewModel.kt
+++ b/app/src/main/java/org/linphone/ui/main/viewmodel/AddressSelectionViewModel.kt
@@ -32,10 +32,12 @@ import org.linphone.core.MagicSearch
import org.linphone.core.MagicSearchListenerStub
import org.linphone.core.SearchResult
import org.linphone.mediastream.Log
-import org.linphone.ui.main.history.model.ContactOrSuggestionModel
+import org.linphone.ui.main.contacts.model.ContactAvatarModel
+import org.linphone.ui.main.model.ConversationContactOrSuggestionModel
import org.linphone.ui.main.model.SelectedAddressModel
import org.linphone.ui.main.model.isEndToEndEncryptionMandatory
import org.linphone.utils.AppUtils
+import org.linphone.utils.LinphoneUtils
abstract class AddressSelectionViewModel @UiThread constructor() : DefaultAccountChangedViewModel() {
companion object {
@@ -48,15 +50,19 @@ abstract class AddressSelectionViewModel @UiThread constructor() : DefaultAccoun
val selectionCount = MutableLiveData()
+ val searchFilter = MutableLiveData()
+
+ val modelsList = MutableLiveData>()
+
+ val isEmpty = MutableLiveData()
+
protected var magicSearchSourceFlags = MagicSearch.Source.All.toInt()
+ protected var skipConversation: Boolean = true
+
private var currentFilter = ""
private var previousFilter = "NotSet"
- val searchFilter = MutableLiveData()
-
- val contactsAndSuggestionsList = MutableLiveData>()
-
private var limitSearchToLinphoneAccounts = true
private lateinit var magicSearch: MagicSearch
@@ -83,6 +89,7 @@ abstract class AddressSelectionViewModel @UiThread constructor() : DefaultAccoun
init {
multipleSelectionMode.value = false
+ isEmpty.value = true
coreContext.postOnCoreThread { core ->
limitSearchToLinphoneAccounts = isEndToEndEncryptionMandatory()
@@ -221,15 +228,67 @@ abstract class AddressSelectionViewModel @UiThread constructor() : DefaultAccoun
private fun processMagicSearchResults(results: Array) {
Log.i("$TAG Processing [${results.size}] results")
- val contactsList = arrayListOf()
- val suggestionsList = arrayListOf()
+ val conversationsList = arrayListOf()
+ if (!skipConversation) {
+ for (chatRoom in LinphoneUtils.getDefaultAccount()?.chatRooms.orEmpty()) {
+ // Only get group conversations
+ if (!chatRoom.currentParams.isGroupEnabled) {
+ continue
+ }
+
+ val found = if (currentFilter.isEmpty()) {
+ null
+ } else {
+ chatRoom.participants.find {
+ // Search in address but also in contact name if exists
+ val model =
+ coreContext.contactsManager.getContactAvatarModelForAddress(it.address)
+ model.contactName?.contains(
+ currentFilter,
+ ignoreCase = true
+ ) == true || it.address.asStringUriOnly().contains(
+ currentFilter,
+ ignoreCase = true
+ )
+ }
+ }
+ if (
+ currentFilter.isEmpty() ||
+ found != null ||
+ chatRoom.peerAddress.asStringUriOnly().contains(
+ currentFilter,
+ ignoreCase = true
+ ) ||
+ chatRoom.subject.orEmpty().contains(currentFilter, ignoreCase = true)
+ ) {
+ val localAddress = chatRoom.localAddress
+ val remoteAddress = chatRoom.peerAddress
+ val model = ConversationContactOrSuggestionModel(
+ remoteAddress,
+ localAddress,
+ chatRoom.subject
+ )
+
+ val fakeFriend = coreContext.core.createFriend()
+ fakeFriend.name = chatRoom.subject
+ val avatarModel = ContactAvatarModel(fakeFriend)
+ avatarModel.defaultToConversationIcon.postValue(true)
+
+ model.avatarModel.postValue(avatarModel)
+ conversationsList.add(model)
+ }
+ }
+ }
+
+ val contactsList = arrayListOf()
+ val suggestionsList = arrayListOf()
for (result in results) {
val address = result.address
if (address != null) {
val friend = coreContext.contactsManager.findContactByAddress(address)
if (friend != null) {
- val model = ContactOrSuggestionModel(address, friend)
+ val model = ConversationContactOrSuggestionModel(address, friend = friend)
val avatarModel = coreContext.contactsManager.getContactAvatarModelForAddress(
address
)
@@ -255,7 +314,7 @@ abstract class AddressSelectionViewModel @UiThread constructor() : DefaultAccoun
continue
}
- val model = ContactOrSuggestionModel(address) {
+ val model = ConversationContactOrSuggestionModel(address) {
coreContext.startAudioCall(address)
}
@@ -272,12 +331,14 @@ abstract class AddressSelectionViewModel @UiThread constructor() : DefaultAccoun
collator.compare(model1.name, model2.name)
}
- val list = arrayListOf()
+ val list = arrayListOf()
+ list.addAll(conversationsList)
list.addAll(contactsList)
list.addAll(suggestionsList)
- contactsAndSuggestionsList.postValue(list)
+ modelsList.postValue(list)
+ isEmpty.postValue(list.isEmpty())
Log.i(
- "$TAG Processed [${results.size}] results, extracted [${suggestionsList.size}] suggestions"
+ "$TAG Processed [${results.size}] results: [${conversationsList.size}] conversations, [${contactsList.size}] contacts and [${suggestionsList.size}] suggestions"
)
}
}
diff --git a/app/src/main/res/layout/chat_message_forward_fragment.xml b/app/src/main/res/layout/chat_message_forward_fragment.xml
index f47fc0124..0321671b9 100644
--- a/app/src/main/res/layout/chat_message_forward_fragment.xml
+++ b/app/src/main/res/layout/chat_message_forward_fragment.xml
@@ -93,7 +93,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
- android:visibility="@{viewModel.conversationsContactsAndSuggestionsList.size() == 0 ? View.GONE : View.VISIBLE}"
+ android:visibility="@{viewModel.isEmpty ? View.GONE : View.VISIBLE}"
app:layout_constraintTop_toBottomOf="@id/search_bar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
diff --git a/app/src/main/res/layout/chat_message_forward_suggestion_list_cell.xml b/app/src/main/res/layout/chat_message_forward_suggestion_list_cell.xml
deleted file mode 100644
index 96ed2e62c..000000000
--- a/app/src/main/res/layout/chat_message_forward_suggestion_list_cell.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/generic_add_participants_fragment.xml b/app/src/main/res/layout/generic_add_participants_fragment.xml
index 65963fced..313a280ea 100644
--- a/app/src/main/res/layout/generic_add_participants_fragment.xml
+++ b/app/src/main/res/layout/generic_add_participants_fragment.xml
@@ -134,7 +134,7 @@
android:layout_margin="10dp"
android:src="@drawable/illu"
android:contentDescription="@null"
- android:visibility="@{viewModel.contactsAndSuggestionsList.size() == 0 ? View.VISIBLE : View.GONE}"
+ android:visibility="@{viewModel.isEmpty ? View.VISIBLE : View.GONE}"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_max="200dp"
@@ -150,7 +150,7 @@
android:layout_height="wrap_content"
android:text="@{viewModel.searchFilter.length() > 0 ? @string/new_conversation_no_matching_contact : @string/new_conversation_no_contact, default=@string/new_conversation_no_contact}"
android:gravity="center"
- android:visibility="@{viewModel.contactsAndSuggestionsList.size() == 0 ? View.VISIBLE : View.GONE}"
+ android:visibility="@{viewModel.isEmpty ? View.VISIBLE : View.GONE}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/no_contact_image" />
@@ -160,7 +160,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
- android:visibility="@{viewModel.contactsAndSuggestionsList.size() == 0 ? View.GONE : View.VISIBLE}"
+ android:visibility="@{viewModel.isEmpty ? View.GONE : View.VISIBLE}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/search_bar"
diff --git a/app/src/main/res/layout/chat_message_forward_contact_list_cell.xml b/app/src/main/res/layout/generic_address_picker_contact_list_cell.xml
similarity index 94%
rename from app/src/main/res/layout/chat_message_forward_contact_list_cell.xml
rename to app/src/main/res/layout/generic_address_picker_contact_list_cell.xml
index 7ebdc0022..33567f776 100644
--- a/app/src/main/res/layout/chat_message_forward_contact_list_cell.xml
+++ b/app/src/main/res/layout/generic_address_picker_contact_list_cell.xml
@@ -6,15 +6,15 @@
-
+
diff --git a/app/src/main/res/layout/chat_message_forward_conversation_list_cell.xml b/app/src/main/res/layout/generic_address_picker_conversation_list_cell.xml
similarity index 96%
rename from app/src/main/res/layout/chat_message_forward_conversation_list_cell.xml
rename to app/src/main/res/layout/generic_address_picker_conversation_list_cell.xml
index 6ca96de31..03108152c 100644
--- a/app/src/main/res/layout/chat_message_forward_conversation_list_cell.xml
+++ b/app/src/main/res/layout/generic_address_picker_conversation_list_cell.xml
@@ -11,7 +11,7 @@
type="View.OnClickListener" />
+ type="org.linphone.ui.main.model.ConversationContactOrSuggestionModel" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/start_call_suggestion_list_cell.xml b/app/src/main/res/layout/generic_address_picker_suggestion_list_cell.xml
similarity index 96%
rename from app/src/main/res/layout/start_call_suggestion_list_cell.xml
rename to app/src/main/res/layout/generic_address_picker_suggestion_list_cell.xml
index 8288a89e3..b42081728 100644
--- a/app/src/main/res/layout/start_call_suggestion_list_cell.xml
+++ b/app/src/main/res/layout/generic_address_picker_suggestion_list_cell.xml
@@ -10,7 +10,7 @@
type="View.OnClickListener" />
+ type="org.linphone.ui.main.model.ConversationContactOrSuggestionModel" />
@@ -242,7 +242,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
- android:visibility="@{viewModel.contactsAndSuggestionsList.size() == 0 ? View.GONE : View.VISIBLE}"
+ android:visibility="@{viewModel.isEmpty ? View.GONE : View.VISIBLE}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/group_call_icon"
diff --git a/app/src/main/res/layout/start_chat_fragment.xml b/app/src/main/res/layout/start_chat_fragment.xml
index 9f623afae..83883bc74 100644
--- a/app/src/main/res/layout/start_chat_fragment.xml
+++ b/app/src/main/res/layout/start_chat_fragment.xml
@@ -198,7 +198,7 @@
android:layout_margin="10dp"
android:src="@drawable/illu"
android:contentDescription="@null"
- android:visibility="@{viewModel.contactsAndSuggestionsList.size() == 0 ? View.VISIBLE : View.GONE}"
+ android:visibility="@{viewModel.isEmpty ? View.VISIBLE : View.GONE}"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_max="200dp"
@@ -214,7 +214,7 @@
android:layout_height="wrap_content"
android:text="@{viewModel.searchFilter.length() > 0 ? @string/new_conversation_no_matching_contact : @string/new_conversation_no_contact, default=@string/new_conversation_no_contact}"
android:gravity="center"
- android:visibility="@{viewModel.contactsAndSuggestionsList.size() == 0 ? View.VISIBLE : View.GONE}"
+ android:visibility="@{viewModel.isEmpty ? View.VISIBLE : View.GONE}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/no_contact_image" />
@@ -224,7 +224,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
- android:visibility="@{viewModel.contactsAndSuggestionsList.size() == 0 ? View.GONE : View.VISIBLE}"
+ android:visibility="@{viewModel.isEmpty ? View.GONE : View.VISIBLE}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/group_chat_icon"
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 66d56747a..bb857aa28 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -36,7 +36,6 @@
OK
Appeler
Supprimer
- Fermer
Installer
Ne plus me montrer ce message
Non
@@ -183,7 +182,6 @@
Appels
Utiliser l\'annulateur d\'écho
Évite que de l\'écho soit entendu par votre correspondant
- Utiliser le périphérique Bluetooth si possible
Activer la vidéo
Activer la FEC vidéo
Vibrer lors de la réception d\'un appel
@@ -306,8 +304,6 @@
Cherchez un contact ou une suggestion
Démarrer un appel de groupe
Aucun contact ni suggestion pour le moment…
- Contacts
- Suggestions
Nommer l\'appel de groupe
Nom de l\'appel de groupe
Aucun appel dans votre historique…
@@ -379,7 +375,6 @@
Aucune conversation pour le moment…
En cours de suppression…
%s :
- Message en attente de transfert
- %s fichier en attente de partage
- %s fichiers en attente de partage
@@ -495,7 +490,6 @@
Transférer à…
Le message a été transféré
Transfert du message abandonné
- Conversations
Lu %s
Reçu %s
@@ -691,6 +685,9 @@
Vous n\'êtes pas connecté à internet
Opération en cours, merci de patienter…
+ Conversations
+ Contacts
+ Suggestions
Passer
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ec3502469..17775d160 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -72,7 +72,6 @@
OK
Call
Delete
- Close
Install
Do not show this dialog anymore
No
@@ -219,7 +218,6 @@
Calls
Use echo canceller
Prevents echo from being heard by remote end
- Route audio to bluetooth device, if any
Enable video
Enable video FEC
Vibrate while incoming call is ringing
@@ -343,8 +341,6 @@
Search contact or history call
Create a group call
No suggestion and no contact for the moment…
- Contacts
- Suggestions
Set group call subject
Group call subject
No call for the moment…
@@ -416,7 +412,6 @@
No conversation for the moment…
Removal in progress…
%s:
- A message is waiting to be forwarded
- %s file waiting to be shared
- %s files waiting to be shared
@@ -532,7 +527,6 @@
Forward message to…
Message was forwarded
Message forward was cancelled
- Conversations
Read %s
Received %s
@@ -728,6 +722,9 @@
You aren\'t connected to internet
Operation in progress, please wait
+ Conversations
+ Contacts
+ Suggestions
Skip