diff --git a/app/src/main/java/org/linphone/contacts/ContactData.kt b/app/src/main/java/org/linphone/contacts/ContactData.kt
deleted file mode 100644
index e85492229..000000000
--- a/app/src/main/java/org/linphone/contacts/ContactData.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2010-2020 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.contacts
-
-import android.content.ContentUris
-import android.net.Uri
-import android.provider.ContactsContract
-import androidx.annotation.WorkerThread
-import androidx.lifecycle.MutableLiveData
-import org.linphone.core.*
-
-class ContactData(val friend: Friend) {
- val presenceStatus = MutableLiveData()
-
- val name = MutableLiveData()
-
- val avatar = getAvatarUri()
-
- private val friendListener = object : FriendListenerStub() {
- @WorkerThread
- override fun onPresenceReceived(fr: Friend) {
- presenceStatus.postValue(fr.consolidatedPresence)
- }
- }
-
- init {
- name.postValue(friend.name)
- presenceStatus.postValue(friend.consolidatedPresence)
-
- friend.addListener(friendListener)
-
- presenceStatus.postValue(ConsolidatedPresence.Offline)
- }
-
- @WorkerThread
- fun onDestroy() {
- friend.removeListener(friendListener)
- }
-
- @WorkerThread
- private fun getAvatarUri(): Uri? {
- val refKey = friend.refKey
- if (refKey != null) {
- val lookupUri = ContentUris.withAppendedId(
- ContactsContract.Contacts.CONTENT_URI,
- refKey.toLong()
- )
- return Uri.withAppendedPath(
- lookupUri,
- ContactsContract.Contacts.Photo.CONTENT_DIRECTORY
- )
- }
-
- return null
- }
-}
diff --git a/app/src/main/java/org/linphone/contacts/ContactsSelectionAdapter.kt b/app/src/main/java/org/linphone/contacts/ContactsSelectionAdapter.kt
deleted file mode 100644
index a50c1b119..000000000
--- a/app/src/main/java/org/linphone/contacts/ContactsSelectionAdapter.kt
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2010-2020 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.contacts
-
-import android.view.LayoutInflater
-import android.view.ViewGroup
-import androidx.databinding.DataBindingUtil
-import androidx.lifecycle.LifecycleOwner
-import androidx.recyclerview.widget.DiffUtil
-import androidx.recyclerview.widget.ListAdapter
-import androidx.recyclerview.widget.RecyclerView
-import org.linphone.R
-import org.linphone.databinding.ContactSelectionCellBinding
-
-class ContactsSelectionAdapter(
- private val viewLifecycleOwner: LifecycleOwner
-) : ListAdapter(ContactDataDiffCallback()) {
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
- val binding: ContactSelectionCellBinding = DataBindingUtil.inflate(
- LayoutInflater.from(parent.context),
- R.layout.contact_selection_cell,
- parent,
- false
- )
- return ViewHolder(binding)
- }
-
- override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
- (holder as ViewHolder).bind(getItem(position))
- }
-
- inner class ViewHolder(
- private val binding: ContactSelectionCellBinding
- ) : RecyclerView.ViewHolder(binding.root) {
- fun bind(contactData: ContactData) {
- with(binding) {
- data = contactData
-
- lifecycleOwner = viewLifecycleOwner
-
- executePendingBindings()
- }
- }
- }
-}
-
-private class ContactDataDiffCallback : DiffUtil.ItemCallback() {
- override fun areItemsTheSame(
- oldItem: ContactData,
- newItem: ContactData
- ): Boolean {
- return oldItem.friend.refKey == newItem.friend.refKey
- }
-
- override fun areContentsTheSame(
- oldItem: ContactData,
- newItem: ContactData
- ): Boolean {
- return true
- }
-}
diff --git a/app/src/main/java/org/linphone/core/CoreContext.kt b/app/src/main/java/org/linphone/core/CoreContext.kt
index 0af11a69c..ec0273b32 100644
--- a/app/src/main/java/org/linphone/core/CoreContext.kt
+++ b/app/src/main/java/org/linphone/core/CoreContext.kt
@@ -335,8 +335,8 @@ class CoreContext @UiThread constructor(val context: Context) : HandlerThread("C
val appName = context.getString(org.linphone.R.string.app_name)
val androidVersion = BuildConfig.VERSION_NAME
val userAgent = "$appName/$androidVersion ($deviceName) LinphoneSDK"
- val sdkVersion = context.getString(org.linphone.core.R.string.linphone_sdk_version)
- val sdkBranch = context.getString(org.linphone.core.R.string.linphone_sdk_branch)
+ val sdkVersion = context.getString(R.string.linphone_sdk_version)
+ val sdkBranch = context.getString(R.string.linphone_sdk_branch)
val sdkUserAgent = "$sdkVersion ($sdkBranch)"
core.setUserAgent(userAgent, sdkUserAgent)
}
diff --git a/app/src/main/java/org/linphone/ui/main/calls/fragment/CallsFragment.kt b/app/src/main/java/org/linphone/ui/main/calls/fragment/CallsFragment.kt
index 55b227e40..6e4831e4a 100644
--- a/app/src/main/java/org/linphone/ui/main/calls/fragment/CallsFragment.kt
+++ b/app/src/main/java/org/linphone/ui/main/calls/fragment/CallsFragment.kt
@@ -124,19 +124,6 @@ class CallsFragment : GenericFragment() {
}
}
- sharedViewModel.navigateToConversationsEvent.observe(viewLifecycleOwner) {
- it.consume {
- if (findNavController().currentDestination?.id == R.id.callsFragment) {
- // To prevent any previously seen contact to show up when navigating back to here later
- binding.callsNavContainer.findNavController().popBackStack()
-
- val action =
- CallsFragmentDirections.actionCallsFragmentToConversationsFragment()
- findNavController().navigate(action)
- }
- }
- }
-
sharedViewModel.navigateToContactsEvent.observe(viewLifecycleOwner) {
it.consume {
if (findNavController().currentDestination?.id == R.id.callsFragment) {
diff --git a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsFragment.kt b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsFragment.kt
index a9984000a..80704974b 100644
--- a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsFragment.kt
+++ b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsFragment.kt
@@ -134,18 +134,6 @@ class ContactsFragment : GenericFragment() {
}
}
- sharedViewModel.navigateToConversationsEvent.observe(viewLifecycleOwner) {
- it.consume {
- if (findNavController().currentDestination?.id == R.id.contactsFragment) {
- // To prevent any previously seen contact to show up when navigating back to here later
- binding.contactsNavContainer.findNavController().popBackStack()
-
- val action = ContactsFragmentDirections.actionContactsFragmentToConversationsFragment()
- findNavController().navigate(action)
- }
- }
- }
-
sharedViewModel.navigateToCallsEvent.observe(viewLifecycleOwner) {
it.consume {
if (findNavController().currentDestination?.id == R.id.contactsFragment) {
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 45c388287..135e22365 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
@@ -134,11 +134,11 @@ class ContactViewModel @UiThread constructor() : ViewModel() {
val organization = friend.organization
if (!organization.isNullOrEmpty()) {
- company.postValue(organization!!)
+ company.postValue(organization)
}
val jobTitle = friend.jobTitle
if (!jobTitle.isNullOrEmpty()) {
- title.postValue(jobTitle!!)
+ title.postValue(jobTitle)
}
val addressesAndNumbers = friend.getListOfSipAddressesAndPhoneNumbers(listener)
@@ -208,7 +208,7 @@ class ContactViewModel @UiThread constructor() : ViewModel() {
val vCard = friend.vcard?.asVcard4String()
if (!vCard.isNullOrEmpty()) {
Log.i("$TAG Friend has been successfully dumped as vCard string")
- val fileName = friend.name.orEmpty().replace(" ", "_").toLowerCase(
+ val fileName = friend.name.orEmpty().replace(" ", "_").lowercase(
Locale.getDefault()
)
val file = FileUtils.getFileStorageCacheDir(
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 3895251e9..3241485fa 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
@@ -192,7 +192,7 @@ class ContactsListViewModel @UiThread constructor() : AbstractTopBarViewModel()
val vCard = friend.vcard?.asVcard4String()
if (!vCard.isNullOrEmpty()) {
Log.i("$TAG Friend has been successfully dumped as vCard string")
- val fileName = friend.name.orEmpty().replace(" ", "_").toLowerCase(
+ val fileName = friend.name.orEmpty().replace(" ", "_").lowercase(
Locale.getDefault()
)
val file = FileUtils.getFileStorageCacheDir(
diff --git a/app/src/main/java/org/linphone/ui/main/conversations/ConversationFragment.kt b/app/src/main/java/org/linphone/ui/main/conversations/ConversationFragment.kt
deleted file mode 100644
index b50b525cb..000000000
--- a/app/src/main/java/org/linphone/ui/main/conversations/ConversationFragment.kt
+++ /dev/null
@@ -1,100 +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.conversations
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.core.view.doOnPreDraw
-import androidx.fragment.app.Fragment
-import androidx.navigation.navGraphViewModels
-import androidx.recyclerview.widget.LinearLayoutManager
-import org.linphone.R
-import org.linphone.databinding.ConversationFragmentBinding
-import org.linphone.ui.main.conversations.adapter.ChatEventLogsListAdapter
-import org.linphone.ui.main.conversations.viewmodel.ConversationViewModel
-
-class ConversationFragment : Fragment() {
- private lateinit var binding: ConversationFragmentBinding
- private val viewModel: ConversationViewModel by navGraphViewModels(
- R.id.main_nav_graph
- )
- private lateinit var adapter: ChatEventLogsListAdapter
-
- override fun onDestroyView() {
- binding.messagesList.adapter = null
- super.onDestroyView()
- }
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View {
- binding = ConversationFragmentBinding.inflate(layoutInflater)
- return binding.root
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- postponeEnterTransition()
-
- 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
- (view.parent as? ViewGroup)?.doOnPreDraw {
- requireActivity().onBackPressedDispatcher.onBackPressed()
- }
- }
- arguments?.clear()
-
- adapter = ChatEventLogsListAdapter(viewLifecycleOwner)
- binding.messagesList.setHasFixedSize(false)
- binding.messagesList.adapter = adapter
-
- val layoutManager = LinearLayoutManager(requireContext())
- binding.messagesList.layoutManager = layoutManager
-
- viewModel.events.observe(
- viewLifecycleOwner
- ) {
- adapter.submitList(it)
-
- (view.parent as? ViewGroup)?.doOnPreDraw {
- startPostponedEnterTransition()
- binding.messagesList.scrollToPosition(adapter.itemCount - 1)
- }
- }
-
- binding.setBackClickListener {
- requireActivity().onBackPressedDispatcher.onBackPressed()
- }
- }
-}
diff --git a/app/src/main/java/org/linphone/ui/main/conversations/ConversationMenuDialogFragment.kt b/app/src/main/java/org/linphone/ui/main/conversations/ConversationMenuDialogFragment.kt
deleted file mode 100644
index 24ad25cec..000000000
--- a/app/src/main/java/org/linphone/ui/main/conversations/ConversationMenuDialogFragment.kt
+++ /dev/null
@@ -1,90 +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.conversations
-
-import android.content.DialogInterface
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import com.google.android.material.bottomsheet.BottomSheetDialogFragment
-import org.linphone.LinphoneApplication.Companion.coreContext
-import org.linphone.core.ChatRoom
-import org.linphone.databinding.ChatRoomMenuBinding
-
-class ConversationMenuDialogFragment(
- private val chatRoom: ChatRoom,
- private val onDismiss: (() -> Unit)? = null
-) : BottomSheetDialogFragment() {
- companion object {
- const val TAG = "ConversationMenuDialogFragment"
- }
-
- override fun onCancel(dialog: DialogInterface) {
- onDismiss?.invoke()
- super.onCancel(dialog)
- }
-
- override fun onDismiss(dialog: DialogInterface) {
- onDismiss?.invoke()
- super.onDismiss(dialog)
- }
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View {
- val view = ChatRoomMenuBinding.inflate(layoutInflater)
-
- view.isMuted = chatRoom.muted
- view.isRead = chatRoom.unreadMessagesCount == 0
-
- view.setMarkAsReadClickListener {
- coreContext.postOnCoreThread {
- chatRoom.markAsRead()
- }
- dismiss()
- }
-
- view.setMuteClickListener {
- coreContext.postOnCoreThread {
- chatRoom.muted = true
- }
- dismiss()
- }
-
- view.setUnMuteClickListener {
- coreContext.postOnCoreThread {
- chatRoom.muted = false
- }
- dismiss()
- }
-
- view.setDeleteClickListener {
- coreContext.postOnCoreThread { core ->
- core.deleteChatRoom(chatRoom)
- }
- dismiss()
- }
-
- return view.root
- }
-}
diff --git a/app/src/main/java/org/linphone/ui/main/conversations/ConversationsFragment.kt b/app/src/main/java/org/linphone/ui/main/conversations/ConversationsFragment.kt
deleted file mode 100644
index d7b2b7938..000000000
--- a/app/src/main/java/org/linphone/ui/main/conversations/ConversationsFragment.kt
+++ /dev/null
@@ -1,174 +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.conversations
-
-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.os.bundleOf
-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 androidx.recyclerview.widget.RecyclerView
-import androidx.transition.AutoTransition
-import org.linphone.R
-import org.linphone.databinding.ConversationsFragmentBinding
-import org.linphone.ui.main.conversations.adapter.ConversationsListAdapter
-import org.linphone.ui.main.conversations.viewmodel.ConversationsListViewModel
-
-class ConversationsFragment : Fragment() {
- private lateinit var binding: ConversationsFragmentBinding
- private val listViewModel: ConversationsListViewModel by navGraphViewModels(
- R.id.main_nav_graph
- )
- private lateinit var adapter: ConversationsListAdapter
-
- private val observer = object : RecyclerView.AdapterDataObserver() {
- override fun onChanged() {
- scrollToTop()
- }
-
- override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
- if (positionStart == 0 && itemCount == 1) {
- scrollToTop()
- }
- }
-
- override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
- scrollToTop()
- }
- }
-
- override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
- if (findNavController().currentDestination?.id == R.id.newConversationFragment ||
- findNavController().currentDestination?.id == R.id.conversationFragment
- ) {
- // Holds fragment in place while (new) conversation fragment slides over it
- return AnimationUtils.loadAnimation(activity, R.anim.hold)
- }
- return super.onCreateAnimation(transit, enter, nextAnim)
- }
-
- override fun onDestroyView() {
- binding.conversationsList.adapter = null
- adapter.unregisterAdapterDataObserver(observer)
- super.onDestroyView()
- }
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View {
- binding = ConversationsFragmentBinding.inflate(layoutInflater)
- sharedElementEnterTransition = AutoTransition()
- return binding.root
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- postponeEnterTransition()
-
- binding.lifecycleOwner = viewLifecycleOwner
- binding.viewModel = listViewModel
-
- adapter = ConversationsListAdapter(viewLifecycleOwner)
- adapter.registerAdapterDataObserver(observer)
- binding.conversationsList.setHasFixedSize(true)
- binding.conversationsList.adapter = adapter
-
- adapter.chatRoomClickedEvent.observe(viewLifecycleOwner) {
- it.consume { data ->
- val bundle = bundleOf()
- bundle.putString("localSipUri", data.localSipUri)
- bundle.putString("remoteSipUri", data.remoteSipUri)
-
- if (findNavController().currentDestination?.id == R.id.conversationsFragment) {
- findNavController().navigate(
- R.id.action_conversationsFragment_to_conversationFragment,
- bundle
- )
- }
- }
- }
-
- adapter.chatRoomLongClickedEvent.observe(viewLifecycleOwner) {
- it.consume { data ->
- val modalBottomSheet = ConversationMenuDialogFragment(data.chatRoom) {
- adapter.resetSelection()
- }
- modalBottomSheet.show(parentFragmentManager, ConversationMenuDialogFragment.TAG)
- }
- }
-
- val layoutManager = LinearLayoutManager(requireContext())
- binding.conversationsList.layoutManager = layoutManager
-
- listViewModel.chatRoomsList.observe(
- viewLifecycleOwner
- ) {
- adapter.submitList(it)
-
- (view.parent as? ViewGroup)?.doOnPreDraw {
- startPostponedEnterTransition()
- }
- }
-
- listViewModel.notifyItemChangedEvent.observe(viewLifecycleOwner) {
- it.consume { index ->
- adapter.notifyItemChanged(index)
- }
- }
-
- /*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 {
- if (findNavController().currentDestination?.id == R.id.conversationsFragment) {
- val action = ConversationsFragmentDirections.actionConversationsFragmentToNewConversationFragment()
- findNavController().navigate(action)
- }
- }
-
- binding.setOnContactsClicked {
- if (findNavController().currentDestination?.id == R.id.conversationsFragment) {
- val action = ConversationsFragmentDirections.actionConversationsFragmentToContactsFragment()
- findNavController().navigate(action)
- }
- }
- }
-
- private fun scrollToTop() {
- binding.conversationsList.scrollToPosition(0)
- }
-}
diff --git a/app/src/main/java/org/linphone/ui/main/conversations/NewConversationFragment.kt b/app/src/main/java/org/linphone/ui/main/conversations/NewConversationFragment.kt
deleted file mode 100644
index 16bd5166d..000000000
--- a/app/src/main/java/org/linphone/ui/main/conversations/NewConversationFragment.kt
+++ /dev/null
@@ -1,110 +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.conversations
-
-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
-import org.linphone.R
-import org.linphone.contacts.ContactsSelectionAdapter
-import org.linphone.databinding.ConversationStartFragmentBinding
-import org.linphone.ui.main.conversations.viewmodel.NewConversationViewModel
-
-class NewConversationFragment : Fragment() {
- private lateinit var binding: ConversationStartFragmentBinding
- private lateinit var adapter: ContactsSelectionAdapter
- private val viewModel: NewConversationViewModel by navGraphViewModels(
- R.id.main_nav_graph
- )
-
- 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?,
- savedInstanceState: Bundle?
- ): View {
- binding = ConversationStartFragmentBinding.inflate(layoutInflater)
- return binding.root
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- postponeEnterTransition()
-
- binding.lifecycleOwner = viewLifecycleOwner
- binding.viewModel = viewModel
-
- adapter = ContactsSelectionAdapter(viewLifecycleOwner)
- binding.contactsList.adapter = adapter
- binding.contactsList.setHasFixedSize(true)
-
- val layoutManager = LinearLayoutManager(requireContext())
- binding.contactsList.layoutManager = layoutManager
-
- viewModel.contactsList.observe(
- viewLifecycleOwner
- ) {
- adapter.submitList(it)
-
- (view.parent as? ViewGroup)?.doOnPreDraw {
- startPostponedEnterTransition()
- }
- }
-
- viewModel.filter.observe(
- viewLifecycleOwner
- ) {
- val filter = it.orEmpty().trim()
- coreContext.postOnCoreThread {
- viewModel.applyFilter(filter)
- }
- }
-
- binding.setBackClickListener {
- requireActivity().onBackPressedDispatcher.onBackPressed()
- }
-
- viewModel.goToChatRoom.observe(viewLifecycleOwner) {
- it.consume {
- if (findNavController().currentDestination?.id == R.id.newConversationFragment) {
- findNavController().navigate(
- R.id.action_newConversationFragment_to_conversationFragment
- )
- }
- }
- }
- }
-}
diff --git a/app/src/main/java/org/linphone/ui/main/conversations/adapter/ChatEventLogsListAdapter.kt b/app/src/main/java/org/linphone/ui/main/conversations/adapter/ChatEventLogsListAdapter.kt
deleted file mode 100644
index a963ad1bd..000000000
--- a/app/src/main/java/org/linphone/ui/main/conversations/adapter/ChatEventLogsListAdapter.kt
+++ /dev/null
@@ -1,152 +0,0 @@
-package org.linphone.ui.main.conversations.adapter
-
-import android.view.LayoutInflater
-import android.view.ViewGroup
-import androidx.databinding.DataBindingUtil
-import androidx.lifecycle.LifecycleOwner
-import androidx.recyclerview.widget.DiffUtil
-import androidx.recyclerview.widget.ListAdapter
-import androidx.recyclerview.widget.RecyclerView
-import org.linphone.R
-import org.linphone.core.ChatMessage
-import org.linphone.databinding.ChatBubbleIncomingBinding
-import org.linphone.databinding.ChatBubbleOutgoingBinding
-import org.linphone.databinding.ChatEventBinding
-import org.linphone.ui.main.conversations.data.ChatMessageData
-import org.linphone.ui.main.conversations.data.EventData
-import org.linphone.ui.main.conversations.data.EventLogData
-
-class ChatEventLogsListAdapter(
- private val viewLifecycleOwner: LifecycleOwner
-) : ListAdapter(EventLogDiffCallback()) {
- companion object {
- const val INCOMING_CHAT_MESSAGE = 1
- const val OUTGOING_CHAT_MESSAGE = 2
- const val EVENT = 3
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
- return when (viewType) {
- INCOMING_CHAT_MESSAGE -> createIncomingChatBubble(parent)
- OUTGOING_CHAT_MESSAGE -> createOutgoingChatBubble(parent)
- else -> createEvent(parent)
- }
- }
-
- override fun getItemViewType(position: Int): Int {
- val data = getItem(position)
- if (data.data is ChatMessageData) {
- if (data.data.isOutgoing) {
- return OUTGOING_CHAT_MESSAGE
- }
- return INCOMING_CHAT_MESSAGE
- }
- return EVENT
- }
-
- private fun createIncomingChatBubble(parent: ViewGroup): IncomingBubbleViewHolder {
- val binding: ChatBubbleIncomingBinding = DataBindingUtil.inflate(
- LayoutInflater.from(parent.context),
- R.layout.chat_bubble_incoming,
- parent,
- false
- )
- return IncomingBubbleViewHolder(binding)
- }
-
- private fun createOutgoingChatBubble(parent: ViewGroup): OutgoingBubbleViewHolder {
- val binding: ChatBubbleOutgoingBinding = DataBindingUtil.inflate(
- LayoutInflater.from(parent.context),
- R.layout.chat_bubble_outgoing,
- parent,
- false
- )
- return OutgoingBubbleViewHolder(binding)
- }
-
- private fun createEvent(parent: ViewGroup): EventViewHolder {
- val binding: ChatEventBinding = DataBindingUtil.inflate(
- LayoutInflater.from(parent.context),
- R.layout.chat_event,
- parent,
- false
- )
- return EventViewHolder(binding)
- }
-
- override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
- val eventLog = getItem(position)
- when (holder) {
- is IncomingBubbleViewHolder -> holder.bind(eventLog.data as ChatMessageData)
- is OutgoingBubbleViewHolder -> holder.bind(eventLog.data as ChatMessageData)
- is EventViewHolder -> holder.bind(eventLog.data as EventData)
- }
- }
-
- inner class IncomingBubbleViewHolder(
- val binding: ChatBubbleIncomingBinding
- ) : RecyclerView.ViewHolder(binding.root) {
- fun bind(chatMessageData: ChatMessageData) {
- with(binding) {
- data = chatMessageData
-
- lifecycleOwner = viewLifecycleOwner
- executePendingBindings()
-
- // To ensure the measure is right since we do some computation for proper multi-line wrap_content
- text.forceLayout()
- }
- }
- }
-
- inner class OutgoingBubbleViewHolder(
- val binding: ChatBubbleOutgoingBinding
- ) : RecyclerView.ViewHolder(binding.root) {
- fun bind(chatMessageData: ChatMessageData) {
- with(binding) {
- data = chatMessageData
-
- lifecycleOwner = viewLifecycleOwner
- executePendingBindings()
-
- // To ensure the measure is right since we do some computation for proper multi-line wrap_content
- text.forceLayout()
- }
- }
- }
- inner class EventViewHolder(
- val binding: ChatEventBinding
- ) : RecyclerView.ViewHolder(binding.root) {
- fun bind(eventData: EventData) {
- with(binding) {
- data = eventData
-
- lifecycleOwner = viewLifecycleOwner
- executePendingBindings()
- }
- }
- }
-}
-
-private class EventLogDiffCallback : DiffUtil.ItemCallback() {
- override fun areItemsTheSame(oldItem: EventLogData, newItem: EventLogData): Boolean {
- return if (oldItem.isEvent && newItem.isEvent) {
- oldItem.notifyId == newItem.notifyId
- } else if (!oldItem.isEvent && !newItem.isEvent) {
- val oldData = (oldItem.data as ChatMessageData)
- val newData = (newItem.data as ChatMessageData)
- oldData.id.isNotEmpty() && oldData.id == newData.id
- } else {
- false
- }
- }
-
- override fun areContentsTheSame(oldItem: EventLogData, newItem: EventLogData): Boolean {
- return if (oldItem.isEvent && newItem.isEvent) {
- true
- } else {
- val newData = (newItem.data as ChatMessageData)
- newData.state.value == ChatMessage.State.Displayed
- }
- }
-}
diff --git a/app/src/main/java/org/linphone/ui/main/conversations/adapter/ConversationsListAdapter.kt b/app/src/main/java/org/linphone/ui/main/conversations/adapter/ConversationsListAdapter.kt
deleted file mode 100644
index 497e37b81..000000000
--- a/app/src/main/java/org/linphone/ui/main/conversations/adapter/ConversationsListAdapter.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-package org.linphone.ui.main.conversations.adapter
-
-import android.view.LayoutInflater
-import android.view.ViewGroup
-import androidx.databinding.DataBindingUtil
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.MutableLiveData
-import androidx.recyclerview.widget.DiffUtil
-import androidx.recyclerview.widget.ListAdapter
-import androidx.recyclerview.widget.RecyclerView
-import org.linphone.R
-import org.linphone.databinding.ChatRoomListCellBinding
-import org.linphone.ui.main.conversations.data.ChatRoomData
-import org.linphone.ui.main.conversations.data.ChatRoomDataListener
-import org.linphone.utils.Event
-
-class ConversationsListAdapter(
- private val viewLifecycleOwner: LifecycleOwner
-) : ListAdapter(ConversationDiffCallback()) {
- val chatRoomClickedEvent: MutableLiveData> by lazy {
- MutableLiveData>()
- }
-
- val chatRoomLongClickedEvent: MutableLiveData> by lazy {
- MutableLiveData>()
- }
-
- var selectedAdapterPosition = -1
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
- val binding: ChatRoomListCellBinding = DataBindingUtil.inflate(
- LayoutInflater.from(parent.context),
- R.layout.chat_room_list_cell,
- parent,
- false
- )
- return ViewHolder(binding)
- }
-
- override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
- (holder as ViewHolder).bind(getItem(position))
- }
-
- fun resetSelection() {
- notifyItemChanged(selectedAdapterPosition)
- selectedAdapterPosition = -1
- }
-
- inner class ViewHolder(
- val binding: ChatRoomListCellBinding
- ) : RecyclerView.ViewHolder(binding.root) {
- fun bind(chatRoomData: ChatRoomData) {
- with(binding) {
- data = chatRoomData
-
- lifecycleOwner = viewLifecycleOwner
-
- binding.root.isSelected = bindingAdapterPosition == selectedAdapterPosition
-
- chatRoomData.chatRoomDataListener = object : ChatRoomDataListener() {
- override fun onClicked() {
- chatRoomClickedEvent.value = Event(chatRoomData)
- }
-
- override fun onLongClicked() {
- selectedAdapterPosition = bindingAdapterPosition
- binding.root.isSelected = true
- chatRoomLongClickedEvent.value = Event(chatRoomData)
- }
- }
-
- executePendingBindings()
- }
- }
- }
-}
-
-private class ConversationDiffCallback : DiffUtil.ItemCallback() {
- override fun areItemsTheSame(oldItem: ChatRoomData, newItem: ChatRoomData): Boolean {
- return oldItem.id == newItem.id
- }
-
- override fun areContentsTheSame(oldItem: ChatRoomData, newItem: ChatRoomData): Boolean {
- return false
- }
-}
diff --git a/app/src/main/java/org/linphone/ui/main/conversations/data/ChatMessageData.kt b/app/src/main/java/org/linphone/ui/main/conversations/data/ChatMessageData.kt
deleted file mode 100644
index 119f3b2ef..000000000
--- a/app/src/main/java/org/linphone/ui/main/conversations/data/ChatMessageData.kt
+++ /dev/null
@@ -1,89 +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.conversations.data
-
-import androidx.lifecycle.MutableLiveData
-import org.linphone.R
-import org.linphone.contacts.ContactData
-import org.linphone.core.ChatMessage
-import org.linphone.core.ChatMessageListenerStub
-import org.linphone.utils.TimestampUtils
-
-class ChatMessageData(private val chatMessage: ChatMessage) {
- val id = chatMessage.messageId
-
- val isOutgoing = chatMessage.isOutgoing
-
- val contactData = MutableLiveData()
-
- val state = MutableLiveData()
-
- val text = MutableLiveData()
-
- val time = MutableLiveData()
-
- val imdnIcon = MutableLiveData()
-
- private val chatMessageListener = object : ChatMessageListenerStub() {
- override fun onMsgStateChanged(message: ChatMessage, state: ChatMessage.State) {
- this@ChatMessageData.state.postValue(state)
- computeImdnIcon()
- }
- }
-
- init {
- state.postValue(chatMessage.state)
- chatMessage.addListener(chatMessageListener)
-
- computeImdnIcon()
- time.postValue(TimestampUtils.toString(chatMessage.time))
- for (content in chatMessage.contents) {
- if (content.isText) {
- text.postValue(content.utf8Text)
- }
- // TODO FIXME
- }
- contactLookup()
- }
-
- fun destroy() {
- chatMessage.removeListener(chatMessageListener)
- }
-
- fun contactLookup() {
- val remoteAddress = chatMessage.fromAddress
- val friend = chatMessage.chatRoom.core.findFriend(remoteAddress)
- if (friend != null) {
- contactData.postValue(ContactData(friend))
- }
- }
-
- private fun computeImdnIcon() {
- imdnIcon.postValue(
- when (chatMessage.state) {
- ChatMessage.State.DeliveredToUser -> R.drawable.imdn_delivered
- ChatMessage.State.Displayed -> R.drawable.imdn_read
- ChatMessage.State.InProgress -> R.drawable.imdn_sent
- // TODO FIXME
- else -> R.drawable.imdn_sent
- }
- )
- }
-}
diff --git a/app/src/main/java/org/linphone/ui/main/conversations/data/ChatRoomData.kt b/app/src/main/java/org/linphone/ui/main/conversations/data/ChatRoomData.kt
deleted file mode 100644
index 42c999a30..000000000
--- a/app/src/main/java/org/linphone/ui/main/conversations/data/ChatRoomData.kt
+++ /dev/null
@@ -1,248 +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.conversations.data
-
-import androidx.lifecycle.MutableLiveData
-import java.lang.StringBuilder
-import org.linphone.LinphoneApplication.Companion.coreContext
-import org.linphone.R
-import org.linphone.contacts.ContactData
-import org.linphone.core.*
-import org.linphone.core.tools.Log
-import org.linphone.utils.LinphoneUtils
-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 isOneToOne = chatRoom.hasCapability(ChatRoom.Capabilities.OneToOne.toInt())
-
- val contactName = MutableLiveData()
-
- val subject = MutableLiveData()
-
- val lastMessage = MutableLiveData()
-
- val unreadChatCount = MutableLiveData()
-
- val isComposing = MutableLiveData()
-
- val isSecure = MutableLiveData()
-
- val isSecureVerified = MutableLiveData()
-
- val isEphemeral = MutableLiveData()
-
- val isMuted = MutableLiveData()
-
- val lastUpdate = MutableLiveData()
-
- val showLastMessageImdnIcon = MutableLiveData()
-
- val lastMessageImdnIcon = MutableLiveData()
-
- val contactData = MutableLiveData()
-
- var chatRoomDataListener: ChatRoomDataListener? = null
-
- private val coreListener = object : CoreListenerStub() {
- override fun onChatRoomRead(core: Core, chatRoom: ChatRoom) {
- if (chatRoom == this@ChatRoomData.chatRoom) {
- unreadChatCount.postValue(chatRoom.unreadMessagesCount)
- }
- }
- }
-
- private val chatRoomListener = object : ChatRoomListenerStub() {
- override fun onIsComposingReceived(
- chatRoom: ChatRoom,
- remoteAddress: Address,
- composing: Boolean
- ) {
- isComposing.postValue(composing)
- }
-
- override fun onMessagesReceived(chatRoom: ChatRoom, chatMessages: Array) {
- unreadChatCount.postValue(chatRoom.unreadMessagesCount)
- computeLastMessage()
- }
-
- override fun onChatMessageSent(chatRoom: ChatRoom, eventLog: EventLog) {
- computeLastMessage()
- }
-
- override fun onEphemeralMessageDeleted(chatRoom: ChatRoom, eventLog: EventLog) {
- computeLastMessage()
- }
-
- override fun onSubjectChanged(chatRoom: ChatRoom, eventLog: EventLog) {
- subject.postValue(
- chatRoom.subject ?: LinphoneUtils.getDisplayName(chatRoom.peerAddress)
- )
- }
- }
-
- init {
- chatRoom.addListener(chatRoomListener)
- coreContext.core.addListener(coreListener)
-
- lastMessageImdnIcon.postValue(R.drawable.imdn_sent)
- showLastMessageImdnIcon.postValue(false)
-
- contactLookup()
- subject.postValue(
- chatRoom.subject ?: LinphoneUtils.getDisplayName(chatRoom.peerAddress)
- )
- computeLastMessage()
-
- unreadChatCount.postValue(chatRoom.unreadMessagesCount)
- isComposing.postValue(chatRoom.isRemoteComposing)
- isSecure.postValue(chatRoom.securityLevel == ChatRoom.SecurityLevel.Encrypted)
- isSecureVerified.postValue(chatRoom.securityLevel == ChatRoom.SecurityLevel.Safe)
- isEphemeral.postValue(chatRoom.isEphemeralEnabled)
- isMuted.postValue(chatRoom.muted)
- }
-
- fun onCleared() {
- coreContext.postOnCoreThread { core ->
- chatRoom.removeListener(chatRoomListener)
- core.removeListener(coreListener)
- }
- }
-
- fun onClicked() {
- chatRoomDataListener?.onClicked()
- }
-
- fun onLongClicked(): Boolean {
- chatRoomDataListener?.onLongClicked()
- return true
- }
-
- 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("[Chat Room Data] No participant in the chat room!")
- }
- }
- }
- computeLastMessage()
- }
-
- private fun computeLastMessageImdnIcon(message: ChatMessage) {
- val state = message.state
- showLastMessageImdnIcon.postValue(
- if (message.isOutgoing) {
- when (state) {
- ChatMessage.State.DeliveredToUser, ChatMessage.State.Displayed,
- ChatMessage.State.NotDelivered, ChatMessage.State.FileTransferError -> true
- else -> false
- }
- } else {
- false
- }
- )
-
- lastMessageImdnIcon.postValue(
- when (state) {
- ChatMessage.State.DeliveredToUser -> R.drawable.imdn_delivered
- ChatMessage.State.Displayed -> R.drawable.imdn_read
- ChatMessage.State.InProgress -> R.drawable.imdn_sent
- // TODO FIXME
- else -> R.drawable.imdn_sent
- }
- )
- }
-
- private fun computeLastMessage() {
- val lastUpdateTime = chatRoom.lastUpdateTime
- lastUpdate.postValue(TimestampUtils.toString(lastUpdateTime, true))
-
- val builder = StringBuilder()
-
- val message = chatRoom.lastMessageInHistory
- if (message != null) {
- val senderAddress = message.fromAddress.clone()
- senderAddress.clean()
-
- if (message.isOutgoing && message.state != ChatMessage.State.Displayed) {
- message.addListener(object : ChatMessageListenerStub() {
- override fun onMsgStateChanged(message: ChatMessage, state: ChatMessage.State) {
- computeLastMessageImdnIcon(message)
-
- if (state == ChatMessage.State.Displayed) {
- message.removeListener(this)
- }
- }
- })
- }
- computeLastMessageImdnIcon(message)
-
- if (!isOneToOne) {
- val sender = chatRoom.core.findFriend(senderAddress)
- builder.append(sender?.name ?: LinphoneUtils.getDisplayName(senderAddress))
- builder.append(": ")
- }
-
- for (content in message.contents) {
- if (content.isFile || content.isFileTransfer) {
- builder.append(content.name + " ")
- } else if (content.isText) {
- builder.append(content.utf8Text + " ")
- }
- }
- builder.trim()
- }
-
- val text = builder.toString()
- if (text.length > 128) { // This brings a huge performance improvement when scrolling
- lastMessage.postValue(text.substring(0, 128))
- } else {
- lastMessage.postValue(text)
- }
- }
-}
-
-abstract class ChatRoomDataListener {
- abstract fun onClicked()
-
- abstract fun onLongClicked()
-}
diff --git a/app/src/main/java/org/linphone/ui/main/conversations/data/EventData.kt b/app/src/main/java/org/linphone/ui/main/conversations/data/EventData.kt
deleted file mode 100644
index 164928b17..000000000
--- a/app/src/main/java/org/linphone/ui/main/conversations/data/EventData.kt
+++ /dev/null
@@ -1,32 +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.conversations.data
-
-import org.linphone.core.EventLog
-
-class EventData(val eventLog: EventLog) {
- fun destroy() {
- // TODO
- }
-
- fun contactLookup() {
- // TODO
- }
-}
diff --git a/app/src/main/java/org/linphone/ui/main/conversations/data/EventLogData.kt b/app/src/main/java/org/linphone/ui/main/conversations/data/EventLogData.kt
deleted file mode 100644
index 8c52799da..000000000
--- a/app/src/main/java/org/linphone/ui/main/conversations/data/EventLogData.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2010-2021 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.conversations.data
-
-import org.linphone.core.EventLog
-
-class EventLogData(val eventLog: EventLog) {
- val type: EventLog.Type = eventLog.type
-
- val isEvent = type != EventLog.Type.ConferenceChatMessage
-
- val data = if (isEvent) {
- EventData(eventLog)
- } else {
- ChatMessageData(eventLog.chatMessage!!)
- }
-
- val notifyId = eventLog.notifyId
-
- fun destroy() {
- when (data) {
- is EventData -> data.destroy()
- is ChatMessageData -> data.destroy()
- }
- }
-
- fun contactLookup() {
- when (data) {
- is EventData -> data.contactLookup()
- is ChatMessageData -> data.contactLookup()
- }
- }
-}
diff --git a/app/src/main/java/org/linphone/ui/main/conversations/view/MultiLineWrapContentWidthTextView.kt b/app/src/main/java/org/linphone/ui/main/conversations/view/MultiLineWrapContentWidthTextView.kt
deleted file mode 100644
index f91068ccf..000000000
--- a/app/src/main/java/org/linphone/ui/main/conversations/view/MultiLineWrapContentWidthTextView.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2010-2020 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.conversations.view
-
-import android.content.Context
-import android.text.Layout
-import android.text.method.LinkMovementMethod
-import android.util.AttributeSet
-import androidx.appcompat.widget.AppCompatTextView
-import kotlin.math.ceil
-import kotlin.math.max
-import kotlin.math.round
-
-/**
- * The purpose of this class is to have a TextView declared with wrap_content as width that won't
- * fill it's parent if it is multi line.
- */
-class MultiLineWrapContentWidthTextView : AppCompatTextView {
- constructor(context: Context) : super(context)
-
- constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
-
- constructor(
- context: Context,
- attrs: AttributeSet?,
- defStyleAttr: Int
- ) : super(context, attrs, defStyleAttr)
-
- override fun setText(text: CharSequence?, type: BufferType?) {
- super.setText(text, type)
- // Required for PatternClickableSpan
- movementMethod = LinkMovementMethod.getInstance()
- }
-
- override fun onMeasure(widthSpec: Int, heightSpec: Int) {
- super.onMeasure(widthSpec, heightSpec)
-
- if (layout != null && layout.lineCount >= 2) {
- val maxLineWidth = ceil(getMaxLineWidth(layout)).toInt() - paddingStart - paddingEnd
- if (maxLineWidth < measuredWidth) {
- super.onMeasure(
- MeasureSpec.makeMeasureSpec(
- maxLineWidth,
- MeasureSpec.getMode(widthSpec)
- ),
- heightSpec
- )
- }
- }
- }
-
- private fun getMaxLineWidth(layout: Layout): Float {
- var maxWidth = 0.0f
- val lines = layout.lineCount
- for (i in 0 until lines) {
- maxWidth = max(maxWidth, layout.getLineWidth(i))
- }
- return round(maxWidth)
- }
-}
diff --git a/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/ConversationViewModel.kt b/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/ConversationViewModel.kt
deleted file mode 100644
index c213c6a9e..000000000
--- a/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/ConversationViewModel.kt
+++ /dev/null
@@ -1,194 +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.conversations.viewmodel
-
-import androidx.annotation.WorkerThread
-import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.ViewModel
-import org.linphone.LinphoneApplication.Companion.coreContext
-import org.linphone.contacts.ContactData
-import org.linphone.contacts.ContactsManager.ContactsListener
-import org.linphone.core.Address
-import org.linphone.core.ChatRoom
-import org.linphone.core.ChatRoomListenerStub
-import org.linphone.core.EventLog
-import org.linphone.core.Factory
-import org.linphone.core.tools.Log
-import org.linphone.ui.main.conversations.data.EventLogData
-import org.linphone.utils.LinphoneUtils
-
-class ConversationViewModel @WorkerThread constructor() : ViewModel() {
- private lateinit var chatRoom: ChatRoom
-
- val events = MutableLiveData>()
-
- val contactName = MutableLiveData()
-
- val contactData = MutableLiveData()
-
- val subject = MutableLiveData()
-
- val isComposing = MutableLiveData()
-
- val isOneToOne = MutableLiveData()
-
- private val contactsListener = object : ContactsListener {
- @WorkerThread
- override fun onContactsLoaded() {
- contactLookup()
- events.value.orEmpty().forEach(EventLogData::contactLookup)
- }
- }
-
- private val chatRoomListener = object : ChatRoomListenerStub() {
- override fun onIsComposingReceived(
- chatRoom: ChatRoom,
- remoteAddress: Address,
- composing: Boolean
- ) {
- isComposing.postValue(composing)
- }
-
- override fun onChatMessagesReceived(chatRoom: ChatRoom, eventLogs: Array) {
- for (eventLog in eventLogs) {
- addChatMessageEventLog(eventLog)
- }
- }
-
- override fun onChatMessageSending(chatRoom: ChatRoom, eventLog: EventLog) {
- val position = events.value.orEmpty().size
-
- if (eventLog.type == EventLog.Type.ConferenceChatMessage) {
- val chatMessage = eventLog.chatMessage
- chatMessage ?: return
- chatMessage.userData = position
- }
-
- addChatMessageEventLog(eventLog)
- }
- }
-
- init {
- coreContext.contactsManager.addListener(contactsListener)
- }
-
- override fun onCleared() {
- coreContext.postOnCoreThread {
- coreContext.contactsManager.removeListener(contactsListener)
- if (::chatRoom.isInitialized) {
- chatRoom.removeListener(chatRoomListener)
- }
- events.value.orEmpty().forEach(EventLogData::destroy)
- }
- }
-
- 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
- chatRoom.addListener(chatRoomListener)
-
- isOneToOne.postValue(chatRoom.hasCapability(ChatRoom.Capabilities.OneToOne.toInt()))
- subject.postValue(chatRoom.subject)
- isComposing.postValue(chatRoom.isRemoteComposing)
- contactLookup()
-
- val list = arrayListOf()
- list.addAll(events.value.orEmpty())
-
- for (eventLog in chatRoom.getHistoryEvents(0)) {
- list.add(EventLogData(eventLog))
- }
-
- events.postValue(list)
- }
- }
- }
-
- 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!")
- }
- }
- }
- }
-
- private fun addEvent(eventLog: EventLog) {
- val list = arrayListOf()
- list.addAll(events.value.orEmpty())
-
- val found = list.find { data -> data.eventLog == eventLog }
- if (found == null) {
- list.add(EventLogData(eventLog))
- }
-
- events.postValue(list)
- }
-
- private fun addChatMessageEventLog(eventLog: EventLog) {
- if (eventLog.type == EventLog.Type.ConferenceChatMessage) {
- val chatMessage = eventLog.chatMessage
- chatMessage ?: return
- chatMessage.userData = events.value.orEmpty().size
-
- val existingEvent = events.value.orEmpty().find { data ->
- data.eventLog.type == EventLog.Type.ConferenceChatMessage && data.eventLog.chatMessage?.messageId == chatMessage.messageId
- }
- if (existingEvent != null) {
- Log.w(
- "[Chat Messages] Found already present chat message, don't add it it's probably the result of an auto download or an aggregated message received before but notified after the conversation was displayed"
- )
- return
- }
- }
-
- addEvent(eventLog)
- }
-}
diff --git a/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/ConversationsListViewModel.kt b/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/ConversationsListViewModel.kt
deleted file mode 100644
index ec317ea06..000000000
--- a/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/ConversationsListViewModel.kt
+++ /dev/null
@@ -1,191 +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.conversations.viewmodel
-
-import androidx.annotation.WorkerThread
-import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.ViewModel
-import java.util.ArrayList
-import org.linphone.LinphoneApplication.Companion.coreContext
-import org.linphone.contacts.ContactsManager.ContactsListener
-import org.linphone.core.ChatMessage
-import org.linphone.core.ChatRoom
-import org.linphone.core.Core
-import org.linphone.core.CoreListenerStub
-import org.linphone.core.tools.Log
-import org.linphone.ui.main.conversations.data.ChatRoomData
-import org.linphone.utils.Event
-import org.linphone.utils.LinphoneUtils
-
-class ConversationsListViewModel : ViewModel() {
- val chatRoomsList = MutableLiveData>()
-
- val notifyItemChangedEvent = MutableLiveData>()
-
- private val contactsListener = object : ContactsListener {
- @WorkerThread
- override fun onContactsLoaded() {
- for (chatRoomData in chatRoomsList.value.orEmpty()) {
- chatRoomData.contactLookup()
- }
- }
- }
-
- private val coreListener = object : CoreListenerStub() {
- override fun onChatRoomStateChanged(
- core: Core,
- chatRoom: ChatRoom,
- state: ChatRoom.State?
- ) {
- Log.i(
- "[Conversations List] Chat room [${LinphoneUtils.getChatRoomId(chatRoom)}] state changed [$state]"
- )
- when (state) {
- ChatRoom.State.Created -> {
- addChatRoomToList(chatRoom)
- }
- ChatRoom.State.Deleted -> {
- removeChatRoomFromList(chatRoom)
- }
- else -> {}
- }
- }
-
- override fun onMessageSent(core: Core, chatRoom: ChatRoom, message: ChatMessage) {
- onChatRoomMessageEvent(chatRoom)
- }
-
- override fun onMessagesReceived(
- core: Core,
- chatRoom: ChatRoom,
- messages: Array
- ) {
- onChatRoomMessageEvent(chatRoom)
- }
-
- override fun onChatRoomRead(core: Core, chatRoom: ChatRoom) {
- notifyChatRoomUpdate(chatRoom)
- }
-
- override fun onChatRoomEphemeralMessageDeleted(core: Core, chatRoom: ChatRoom) {
- notifyChatRoomUpdate(chatRoom)
- }
-
- override fun onChatRoomSubjectChanged(core: Core, chatRoom: ChatRoom) {
- notifyChatRoomUpdate(chatRoom)
- }
- }
-
- init {
- coreContext.postOnCoreThread { core ->
- core.addListener(coreListener)
- coreContext.contactsManager.addListener(contactsListener)
- }
-
- coreContext.postOnCoreThread { core ->
- updateChatRoomsList()
- }
- }
-
- override fun onCleared() {
- coreContext.postOnCoreThread { core ->
- coreContext.contactsManager.removeListener(contactsListener)
- core.removeListener(coreListener)
- }
- super.onCleared()
- }
-
- private fun addChatRoomToList(chatRoom: ChatRoom) {
- val index = findChatRoomIndex(chatRoom)
- if (index != -1) {
- Log.w("[Conversations List] Chat room already exists in list, do not add it again")
- return
- }
-
- val list = arrayListOf()
-
- val data = ChatRoomData(chatRoom)
- list.add(data)
- list.addAll(chatRoomsList.value.orEmpty())
- list.sortByDescending { data -> data.chatRoom.lastUpdateTime }
-
- chatRoomsList.postValue(list)
- }
-
- private fun removeChatRoomFromList(chatRoom: ChatRoom) {
- val list = arrayListOf()
-
- for (data in chatRoomsList.value.orEmpty()) {
- if (LinphoneUtils.getChatRoomId(chatRoom) != LinphoneUtils.getChatRoomId(
- data.chatRoom
- )
- ) {
- list.add(data)
- }
- }
-
- chatRoomsList.postValue(list)
- }
-
- private fun findChatRoomIndex(chatRoom: ChatRoom): Int {
- val id = LinphoneUtils.getChatRoomId(chatRoom)
- for ((index, data) in chatRoomsList.value.orEmpty().withIndex()) {
- if (id == data.id) {
- return index
- }
- }
- return -1
- }
-
- private fun notifyChatRoomUpdate(chatRoom: ChatRoom) {
- when (val index = findChatRoomIndex(chatRoom)) {
- -1 -> updateChatRoomsList()
- else -> notifyItemChangedEvent.postValue(Event(index))
- }
- }
-
- private fun onChatRoomMessageEvent(chatRoom: ChatRoom) {
- when (findChatRoomIndex(chatRoom)) {
- -1 -> updateChatRoomsList()
- 0 -> notifyItemChangedEvent.postValue(Event(0))
- else -> reorderChatRoomsList()
- }
- }
-
- private fun updateChatRoomsList() {
- Log.i("[Conversations List] Updating chat rooms list")
- chatRoomsList.value.orEmpty().forEach(ChatRoomData::onCleared)
-
- val list = arrayListOf()
- val chatRooms = coreContext.core.chatRooms
- for (chatRoom in chatRooms) {
- list.add(ChatRoomData(chatRoom))
- }
- chatRoomsList.postValue(list)
- }
-
- private fun reorderChatRoomsList() {
- Log.i("[Conversations List] Re-ordering chat rooms list")
- val list = arrayListOf()
- list.addAll(chatRoomsList.value.orEmpty())
- list.sortByDescending { data -> data.chatRoom.lastUpdateTime }
- chatRoomsList.postValue(list)
- }
-}
diff --git a/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/NewConversationViewModel.kt b/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/NewConversationViewModel.kt
deleted file mode 100644
index ce63ad676..000000000
--- a/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/NewConversationViewModel.kt
+++ /dev/null
@@ -1,124 +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.conversations.viewmodel
-
-import androidx.annotation.WorkerThread
-import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.ViewModel
-import org.linphone.LinphoneApplication.Companion.coreContext
-import org.linphone.contacts.ContactData
-import org.linphone.contacts.ContactsManager.ContactsListener
-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>()
-
- val groupEnabled = MutableLiveData()
-
- val goToChatRoom: MutableLiveData>> by lazy {
- MutableLiveData>>()
- }
-
- val filter = MutableLiveData()
- private var previousFilter = "NotSet"
-
- private val magicSearch: MagicSearch by lazy {
- val magicSearch = coreContext.core.createMagicSearch()
- magicSearch.limitedSearch = false
- magicSearch
- }
-
- private val magicSearchListener = object : MagicSearchListenerStub() {
- override fun onSearchResultsReceived(magicSearch: MagicSearch) {
- processMagicSearchResults(magicSearch.lastSearch)
- }
- }
-
- private val contactsListener = object : ContactsListener {
- @WorkerThread
- override fun onContactsLoaded() {
- applyFilter(filter.value.orEmpty().trim())
- }
- }
-
- init {
- coreContext.postOnCoreThread {
- magicSearch.addListener(magicSearchListener)
- coreContext.contactsManager.addListener(contactsListener)
-
- applyFilter("")
- }
- }
-
- override fun onCleared() {
- coreContext.postOnCoreThread {
- coreContext.contactsManager.removeListener(contactsListener)
- magicSearch.removeListener(magicSearchListener)
- }
- super.onCleared()
- }
-
- fun applyFilter(filterValue: String) {
- Log.i("[New Conversation ViewModel] Filtering contacts using [$filterValue]")
- if (previousFilter.isNotEmpty() && (
- previousFilter.length > filterValue.length ||
- (previousFilter.length == filterValue.length && previousFilter != filterValue)
- )
- ) {
- magicSearch.resetSearchCache()
- }
- previousFilter = filterValue
-
- magicSearch.getContactsListAsync(
- filterValue,
- "",
- MagicSearch.Source.Friends.toInt(),
- MagicSearch.Aggregation.Friend
- )
- }
-
- fun createGroup() {
- goToChatRoom.value = Event(Pair("", ""))
- }
-
- fun enableGroupSelection() {
- groupEnabled.value = true
- }
-
- @WorkerThread
- private fun processMagicSearchResults(results: Array) {
- Log.i("[New Conversation ViewModel] [${results.size}] matching results")
- contactsList.value.orEmpty().forEach(ContactData::onDestroy)
-
- val list = arrayListOf()
- for (searchResult in results) {
- val friend = searchResult.friend
- if (friend != null) {
- val data = ContactData(friend)
- list.add(data)
- }
- }
- contactsList.postValue(list)
- }
-}
diff --git a/app/src/main/java/org/linphone/ui/main/fragment/BottomNavBarFragment.kt b/app/src/main/java/org/linphone/ui/main/fragment/BottomNavBarFragment.kt
index 1d0b30aaf..feb0e9cf1 100644
--- a/app/src/main/java/org/linphone/ui/main/fragment/BottomNavBarFragment.kt
+++ b/app/src/main/java/org/linphone/ui/main/fragment/BottomNavBarFragment.kt
@@ -83,9 +83,7 @@ class BottomNavBarFragment : Fragment() {
}
binding.setOnConversationsClicked {
- if (sharedViewModel.currentlyDisplayedFragment.value != R.id.conversationsFragment) {
- sharedViewModel.navigateToConversationsEvent.value = Event(true)
- }
+ // TODO
}
binding.setOnMeetingsClicked {
@@ -95,7 +93,6 @@ class BottomNavBarFragment : Fragment() {
sharedViewModel.currentlyDisplayedFragment.observe(viewLifecycleOwner) {
viewModel.contactsSelected.value = it == R.id.contactsFragment
viewModel.callsSelected.value = it == R.id.callsFragment
- viewModel.conversationsSelected.value = it == R.id.conversationsFragment
}
sharedViewModel.resetMissedCallsCountEvent.observe(viewLifecycleOwner) {
diff --git a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt
index 1bf99d394..506fb4c4a 100644
--- a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt
+++ b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt
@@ -52,7 +52,6 @@ import io.getstream.avatarview.AvatarView
import io.getstream.avatarview.coil.loadImage
import org.linphone.BR
import org.linphone.R
-import org.linphone.contacts.ContactData
import org.linphone.core.ConsolidatedPresence
import org.linphone.core.tools.Log
import org.linphone.ui.main.MainActivity
@@ -182,20 +181,6 @@ fun loadPictureWithCoil(imageView: ImageView, file: String?) {
}
}
-@UiThread
-@BindingAdapter("coilContact")
-fun loadContactPictureWithCoil2(imageView: ImageView, contact: ContactData?) {
- Log.i("[Data Binding Utils] Loading contact picture [${contact?.avatar}] with coil")
- if (contact == null) {
- imageView.load(R.drawable.contact_avatar)
- } else {
- imageView.load(contact.avatar) {
- transformations(CircleCropTransformation())
- error(R.drawable.contact_avatar)
- }
- }
-}
-
@UiThread
@BindingAdapter("presenceIcon")
fun ImageView.setPresenceIcon(presence: ConsolidatedPresence?) {
diff --git a/app/src/main/java/org/linphone/utils/TimestampUtils.kt b/app/src/main/java/org/linphone/utils/TimestampUtils.kt
index 22f9068c6..f9de688a3 100644
--- a/app/src/main/java/org/linphone/utils/TimestampUtils.kt
+++ b/app/src/main/java/org/linphone/utils/TimestampUtils.kt
@@ -173,7 +173,8 @@ class TimestampUtils {
}
val millis = if (timestampInSecs) timestamp * 1000 else timestamp
- return dateFormat.format(Date(millis)).capitalize(Locale.getDefault())
+ return dateFormat.format(Date(millis))
+ .replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
}
@AnyThread
diff --git a/app/src/main/res/layout/chat_bubble_incoming.xml b/app/src/main/res/layout/chat_bubble_incoming.xml
deleted file mode 100644
index c140bf6d8..000000000
--- a/app/src/main/res/layout/chat_bubble_incoming.xml
+++ /dev/null
@@ -1,77 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/chat_bubble_outgoing.xml b/app/src/main/res/layout/chat_bubble_outgoing.xml
deleted file mode 100644
index 6d81f5aca..000000000
--- a/app/src/main/res/layout/chat_bubble_outgoing.xml
+++ /dev/null
@@ -1,77 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/chat_event.xml b/app/src/main/res/layout/chat_event.xml
deleted file mode 100644
index 357c59ce3..000000000
--- a/app/src/main/res/layout/chat_event.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/chat_room_list_cell.xml b/app/src/main/res/layout/chat_room_list_cell.xml
deleted file mode 100644
index 938487d0f..000000000
--- a/app/src/main/res/layout/chat_room_list_cell.xml
+++ /dev/null
@@ -1,118 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/chat_room_menu.xml b/app/src/main/res/layout/chat_room_menu.xml
deleted file mode 100644
index 1caca02f9..000000000
--- a/app/src/main/res/layout/chat_room_menu.xml
+++ /dev/null
@@ -1,135 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/contact_selection_cell.xml b/app/src/main/res/layout/contact_selection_cell.xml
deleted file mode 100644
index e5a49ad09..000000000
--- a/app/src/main/res/layout/contact_selection_cell.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/conversation_fragment.xml b/app/src/main/res/layout/conversation_fragment.xml
deleted file mode 100644
index cec8676b7..000000000
--- a/app/src/main/res/layout/conversation_fragment.xml
+++ /dev/null
@@ -1,202 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/conversation_start_fragment.xml b/app/src/main/res/layout/conversation_start_fragment.xml
deleted file mode 100644
index 15f8b52a0..000000000
--- a/app/src/main/res/layout/conversation_start_fragment.xml
+++ /dev/null
@@ -1,145 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/conversations_fragment.xml b/app/src/main/res/layout/conversations_fragment.xml
deleted file mode 100644
index c076f7d83..000000000
--- a/app/src/main/res/layout/conversations_fragment.xml
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/navigation/main_nav_graph.xml b/app/src/main/res/navigation/main_nav_graph.xml
index 1236cbce9..0b9acc53a 100644
--- a/app/src/main/res/navigation/main_nav_graph.xml
+++ b/app/src/main/res/navigation/main_nav_graph.xml
@@ -5,67 +5,11 @@
android:id="@+id/main_nav_graph"
app:startDestination="@id/callsFragment">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-