From e3022f42ab7d45502ec0ba40b3bbe9e406b10e27 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 11 Sep 2023 16:51:25 +0200 Subject: [PATCH] Removed legacy chat views --- .../java/org/linphone/contacts/ContactData.kt | 73 ------ .../contacts/ContactsSelectionAdapter.kt | 78 ------ .../java/org/linphone/core/CoreContext.kt | 4 +- .../ui/main/calls/fragment/CallsFragment.kt | 13 - .../contacts/fragment/ContactsFragment.kt | 12 - .../contacts/viewmodel/ContactViewModel.kt | 6 +- .../viewmodel/ContactsListViewModel.kt | 2 +- .../conversations/ConversationFragment.kt | 100 ------- .../ConversationMenuDialogFragment.kt | 90 ------- .../conversations/ConversationsFragment.kt | 174 ------------ .../conversations/NewConversationFragment.kt | 110 -------- .../adapter/ChatEventLogsListAdapter.kt | 152 ----------- .../adapter/ConversationsListAdapter.kt | 86 ------ .../conversations/data/ChatMessageData.kt | 89 ------- .../main/conversations/data/ChatRoomData.kt | 248 ------------------ .../ui/main/conversations/data/EventData.kt | 32 --- .../main/conversations/data/EventLogData.kt | 50 ---- .../view/MultiLineWrapContentWidthTextView.kt | 77 ------ .../viewmodel/ConversationViewModel.kt | 194 -------------- .../viewmodel/ConversationsListViewModel.kt | 191 -------------- .../viewmodel/NewConversationViewModel.kt | 124 --------- .../ui/main/fragment/BottomNavBarFragment.kt | 5 +- .../org/linphone/utils/DataBindingUtils.kt | 15 -- .../java/org/linphone/utils/TimestampUtils.kt | 3 +- .../main/res/layout/chat_bubble_incoming.xml | 77 ------ .../main/res/layout/chat_bubble_outgoing.xml | 77 ------ app/src/main/res/layout/chat_event.xml | 53 ---- .../main/res/layout/chat_room_list_cell.xml | 118 --------- app/src/main/res/layout/chat_room_menu.xml | 135 ---------- .../res/layout/contact_selection_cell.xml | 48 ---- .../main/res/layout/conversation_fragment.xml | 202 -------------- .../layout/conversation_start_fragment.xml | 145 ---------- .../res/layout/conversations_fragment.xml | 107 -------- .../main/res/navigation/main_nav_graph.xml | 59 ----- 34 files changed, 9 insertions(+), 2940 deletions(-) delete mode 100644 app/src/main/java/org/linphone/contacts/ContactData.kt delete mode 100644 app/src/main/java/org/linphone/contacts/ContactsSelectionAdapter.kt delete mode 100644 app/src/main/java/org/linphone/ui/main/conversations/ConversationFragment.kt delete mode 100644 app/src/main/java/org/linphone/ui/main/conversations/ConversationMenuDialogFragment.kt delete mode 100644 app/src/main/java/org/linphone/ui/main/conversations/ConversationsFragment.kt delete mode 100644 app/src/main/java/org/linphone/ui/main/conversations/NewConversationFragment.kt delete mode 100644 app/src/main/java/org/linphone/ui/main/conversations/adapter/ChatEventLogsListAdapter.kt delete mode 100644 app/src/main/java/org/linphone/ui/main/conversations/adapter/ConversationsListAdapter.kt delete mode 100644 app/src/main/java/org/linphone/ui/main/conversations/data/ChatMessageData.kt delete mode 100644 app/src/main/java/org/linphone/ui/main/conversations/data/ChatRoomData.kt delete mode 100644 app/src/main/java/org/linphone/ui/main/conversations/data/EventData.kt delete mode 100644 app/src/main/java/org/linphone/ui/main/conversations/data/EventLogData.kt delete mode 100644 app/src/main/java/org/linphone/ui/main/conversations/view/MultiLineWrapContentWidthTextView.kt delete mode 100644 app/src/main/java/org/linphone/ui/main/conversations/viewmodel/ConversationViewModel.kt delete mode 100644 app/src/main/java/org/linphone/ui/main/conversations/viewmodel/ConversationsListViewModel.kt delete mode 100644 app/src/main/java/org/linphone/ui/main/conversations/viewmodel/NewConversationViewModel.kt delete mode 100644 app/src/main/res/layout/chat_bubble_incoming.xml delete mode 100644 app/src/main/res/layout/chat_bubble_outgoing.xml delete mode 100644 app/src/main/res/layout/chat_event.xml delete mode 100644 app/src/main/res/layout/chat_room_list_cell.xml delete mode 100644 app/src/main/res/layout/chat_room_menu.xml delete mode 100644 app/src/main/res/layout/contact_selection_cell.xml delete mode 100644 app/src/main/res/layout/conversation_fragment.xml delete mode 100644 app/src/main/res/layout/conversation_start_fragment.xml delete mode 100644 app/src/main/res/layout/conversations_fragment.xml 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"> - - - - - - - - - - - - - - - - - -