diff --git a/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatMessagesListAdapter.kt b/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatMessagesListAdapter.kt index 97463a99a..5808807b9 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatMessagesListAdapter.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatMessagesListAdapter.kt @@ -120,12 +120,6 @@ class ChatMessagesListAdapter( } } - override fun onViewRecycled(holder: RecyclerView.ViewHolder) { - when (holder) { - is ChatMessageViewHolder -> holder.binding.data?.destroy() - } - } - override fun getItemViewType(position: Int): Int { val eventLog = getItem(position) return eventLog.eventLog.type.toInt() diff --git a/app/src/main/java/org/linphone/activities/main/chat/adapters/GroupInfoParticipantsAdapter.kt b/app/src/main/java/org/linphone/activities/main/chat/adapters/GroupInfoParticipantsAdapter.kt index fb1301dab..fb955ee7c 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/adapters/GroupInfoParticipantsAdapter.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/adapters/GroupInfoParticipantsAdapter.kt @@ -36,7 +36,7 @@ import org.linphone.utils.Event class GroupInfoParticipantsAdapter( private val viewLifecycleOwner: LifecycleOwner, private val isEncryptionEnabled: Boolean -) : ListAdapter(ParticipantDiffCallback()) { +) : ListAdapter(ParticipantDiffCallback()) { private var showAdmin: Boolean = false val participantRemovedEvent: MutableLiveData> by lazy { @@ -55,10 +55,6 @@ class GroupInfoParticipantsAdapter( (holder as ViewHolder).bind(getItem(position)) } - override fun onViewRecycled(holder: RecyclerView.ViewHolder) { - (holder as ViewHolder).binding.data?.destroy() - } - fun showAdminControls(show: Boolean) { showAdmin = show notifyDataSetChanged() @@ -67,16 +63,15 @@ class GroupInfoParticipantsAdapter( inner class ViewHolder( val binding: ChatRoomGroupInfoParticipantCellBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(participant: GroupChatRoomMember) { + fun bind(participantViewModel: GroupInfoParticipantData) { with(binding) { - val participantViewModel = GroupInfoParticipantData(participant) participantViewModel.showAdminControls.value = showAdmin data = participantViewModel lifecycleOwner = viewLifecycleOwner setRemoveClickListener { - participantRemovedEvent.value = Event(participant) + participantRemovedEvent.value = Event(participantViewModel.participant) } isEncrypted = isEncryptionEnabled @@ -86,17 +81,17 @@ class GroupInfoParticipantsAdapter( } } -private class ParticipantDiffCallback : DiffUtil.ItemCallback() { +private class ParticipantDiffCallback : DiffUtil.ItemCallback() { override fun areItemsTheSame( - oldItem: GroupChatRoomMember, - newItem: GroupChatRoomMember + oldItem: GroupInfoParticipantData, + newItem: GroupInfoParticipantData ): Boolean { - return oldItem.address.weakEqual(newItem.address) + return oldItem.sipUri == newItem.sipUri } override fun areContentsTheSame( - oldItem: GroupChatRoomMember, - newItem: GroupChatRoomMember + oldItem: GroupInfoParticipantData, + newItem: GroupInfoParticipantData ): Boolean { return false } diff --git a/app/src/main/java/org/linphone/activities/main/chat/adapters/ImdnAdapter.kt b/app/src/main/java/org/linphone/activities/main/chat/adapters/ImdnAdapter.kt index 0827e49b8..63c44d25e 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/adapters/ImdnAdapter.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/adapters/ImdnAdapter.kt @@ -31,14 +31,13 @@ import androidx.recyclerview.widget.RecyclerView import org.linphone.R import org.linphone.activities.main.chat.data.ImdnParticipantData import org.linphone.core.ChatMessage -import org.linphone.core.ParticipantImdnState import org.linphone.databinding.ChatRoomImdnParticipantCellBinding import org.linphone.databinding.ImdnListHeaderBinding import org.linphone.utils.HeaderAdapter class ImdnAdapter( private val viewLifecycleOwner: LifecycleOwner -) : ListAdapter(ParticipantImdnStateDiffCallback()), HeaderAdapter { +) : ListAdapter(ParticipantImdnStateDiffCallback()), HeaderAdapter { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val binding: ChatRoomImdnParticipantCellBinding = DataBindingUtil.inflate( LayoutInflater.from(parent.context), @@ -51,16 +50,12 @@ class ImdnAdapter( (holder as ViewHolder).bind(getItem(position)) } - override fun onViewRecycled(holder: RecyclerView.ViewHolder) { - (holder as ViewHolder).binding.data?.destroy() - } - inner class ViewHolder( val binding: ChatRoomImdnParticipantCellBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(participantImdnState: ParticipantImdnState) { + fun bind(participantImdnData: ImdnParticipantData) { with(binding) { - data = ImdnParticipantData(participantImdnState) + data = participantImdnData lifecycleOwner = viewLifecycleOwner @@ -74,12 +69,12 @@ class ImdnAdapter( val participantImdnState = getItem(position) val previousPosition = position - 1 return if (previousPosition >= 0) { - getItem(previousPosition).state != participantImdnState.state + getItem(previousPosition).imdnState.state != participantImdnState.imdnState.state } else true } override fun getHeaderViewForPosition(context: Context, position: Int): View { - val participantImdnState = getItem(position) + val participantImdnState = getItem(position).imdnState val binding: ImdnListHeaderBinding = DataBindingUtil.inflate( LayoutInflater.from(context), R.layout.imdn_list_header, null, false @@ -111,17 +106,17 @@ class ImdnAdapter( } } -private class ParticipantImdnStateDiffCallback : DiffUtil.ItemCallback() { +private class ParticipantImdnStateDiffCallback : DiffUtil.ItemCallback() { override fun areItemsTheSame( - oldItem: ParticipantImdnState, - newItem: ParticipantImdnState + oldItem: ImdnParticipantData, + newItem: ImdnParticipantData ): Boolean { - return oldItem.participant.address.weakEqual(newItem.participant.address) + return oldItem.sipUri == newItem.sipUri } override fun areContentsTheSame( - oldItem: ParticipantImdnState, - newItem: ParticipantImdnState + oldItem: ImdnParticipantData, + newItem: ImdnParticipantData ): Boolean { return false } diff --git a/app/src/main/java/org/linphone/activities/main/chat/data/EventLogData.kt b/app/src/main/java/org/linphone/activities/main/chat/data/EventLogData.kt index be217ad5a..3730fbc4b 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/data/EventLogData.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/data/EventLogData.kt @@ -28,4 +28,8 @@ class EventLogData(val eventLog: EventLog) { } else { EventData(eventLog) } + + fun destroy() { + data.destroy() + } } diff --git a/app/src/main/java/org/linphone/activities/main/chat/data/GroupInfoParticipantData.kt b/app/src/main/java/org/linphone/activities/main/chat/data/GroupInfoParticipantData.kt index c46f9b499..d87f90437 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/data/GroupInfoParticipantData.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/data/GroupInfoParticipantData.kt @@ -25,7 +25,7 @@ import org.linphone.contact.GenericContactData import org.linphone.core.ChatRoomSecurityLevel import org.linphone.utils.LinphoneUtils -class GroupInfoParticipantData(private val participant: GroupChatRoomMember) : GenericContactData(participant.address) { +class GroupInfoParticipantData(val participant: GroupChatRoomMember) : GenericContactData(participant.address) { override val securityLevel: ChatRoomSecurityLevel get() = participant.securityLevel @@ -44,6 +44,10 @@ class GroupInfoParticipantData(private val participant: GroupChatRoomMember) : G canBeSetAdmin.value = participant.canBeSetAdmin } + override fun destroy() { + super.destroy() + } + fun setAdmin() { isAdmin.value = true participant.isAdmin = true diff --git a/app/src/main/java/org/linphone/activities/main/chat/data/ImdnParticipantData.kt b/app/src/main/java/org/linphone/activities/main/chat/data/ImdnParticipantData.kt index df6854685..2dcfbf0f6 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/data/ImdnParticipantData.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/data/ImdnParticipantData.kt @@ -23,8 +23,12 @@ import org.linphone.contact.GenericContactData import org.linphone.core.ParticipantImdnState import org.linphone.utils.TimestampUtils -class ImdnParticipantData(imdnState: ParticipantImdnState) : GenericContactData(imdnState.participant.address) { +class ImdnParticipantData(val imdnState: ParticipantImdnState) : GenericContactData(imdnState.participant.address) { val sipUri: String = imdnState.participant.address.asStringUriOnly() val time: String = TimestampUtils.toString(imdnState.stateChangeTime) + + override fun destroy() { + super.destroy() + } } diff --git a/app/src/main/java/org/linphone/activities/main/chat/fragments/GroupInfoFragment.kt b/app/src/main/java/org/linphone/activities/main/chat/fragments/GroupInfoFragment.kt index 5c876bacd..f179a6b9f 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/fragments/GroupInfoFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/fragments/GroupInfoFragment.kt @@ -29,6 +29,7 @@ import org.linphone.R import org.linphone.activities.main.MainActivity import org.linphone.activities.main.chat.GroupChatRoomMember import org.linphone.activities.main.chat.adapters.GroupInfoParticipantsAdapter +import org.linphone.activities.main.chat.data.GroupInfoParticipantData import org.linphone.activities.main.chat.viewmodels.GroupInfoViewModel import org.linphone.activities.main.chat.viewmodels.GroupInfoViewModelFactory import org.linphone.activities.main.fragments.SecureFragment @@ -129,7 +130,7 @@ class GroupInfoFragment : SecureFragment() { val list = arrayListOf
() for (participant in viewModel.participants.value.orEmpty()) { - list.add(participant.address) + list.add(participant.participant.address) } sharedViewModel.chatRoomParticipants.value = list @@ -164,17 +165,19 @@ class GroupInfoFragment : SecureFragment() { private fun addParticipantsFromSharedViewModel() { val participants = sharedViewModel.chatRoomParticipants.value if (participants != null && participants.size > 0) { - val list = arrayListOf() + val list = arrayListOf() for (address in participants) { val exists = viewModel.participants.value?.find { - it.address.weakEqual(address) + it.participant.address.weakEqual(address) } if (exists != null) { list.add(exists) } else { - list.add(GroupChatRoomMember(address, false, hasLimeX3DHCapability = viewModel.isEncrypted.value == true)) + list.add(GroupInfoParticipantData( + GroupChatRoomMember(address, false, hasLimeX3DHCapability = viewModel.isEncrypted.value == true) + )) } } diff --git a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessagesListViewModel.kt b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessagesListViewModel.kt index 06d9538ef..c85cd5793 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessagesListViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessagesListViewModel.kt @@ -150,6 +150,7 @@ class ChatMessagesListViewModel(private val chatRoom: ChatRoom) : ViewModel() { } override fun onCleared() { + events.value.orEmpty().forEach(EventLogData::destroy) chatRoom.removeListener(chatRoomListener) super.onCleared() diff --git a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomsListViewModel.kt b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomsListViewModel.kt index 87d685e04..2406fc531 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomsListViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomsListViewModel.kt @@ -96,6 +96,7 @@ class ChatRoomsListViewModel : ErrorReportingViewModel() { } override fun onCleared() { + chatRooms.value.orEmpty().forEach(ChatRoomViewModel::destroy) coreContext.contactsManager.removeListener(contactsUpdatedListener) coreContext.core.removeListener(listener) diff --git a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/GroupInfoViewModel.kt b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/GroupInfoViewModel.kt index 444ce0444..4767964e6 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/GroupInfoViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/GroupInfoViewModel.kt @@ -25,6 +25,7 @@ import androidx.lifecycle.ViewModelProvider import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R import org.linphone.activities.main.chat.GroupChatRoomMember +import org.linphone.activities.main.chat.data.GroupInfoParticipantData import org.linphone.activities.main.viewmodels.ErrorReportingViewModel import org.linphone.core.* import org.linphone.core.tools.Log @@ -44,7 +45,7 @@ class GroupInfoViewModel(val chatRoom: ChatRoom?) : ErrorReportingViewModel() { val subject = MutableLiveData() - val participants = MutableLiveData>() + val participants = MutableLiveData>() val isEncrypted = MutableLiveData() @@ -105,6 +106,7 @@ class GroupInfoViewModel(val chatRoom: ChatRoom?) : ErrorReportingViewModel() { } override fun onCleared() { + participants.value.orEmpty().forEach(GroupInfoParticipantData::destroy) chatRoom?.removeListener(listener) super.onCleared() @@ -120,8 +122,8 @@ class GroupInfoViewModel(val chatRoom: ChatRoom?) : ErrorReportingViewModel() { val addresses = arrayOfNulls
(participants.value.orEmpty().size) var index = 0 for (participant in participants.value.orEmpty()) { - addresses[index] = participant.address - Log.i("[Chat Room Group Info] Participant ${participant.address.asStringUriOnly()} will be added to group") + addresses[index] = participant.participant.address + Log.i("[Chat Room Group Info] Participant ${participant.sipUri} will be added to group") index += 1 } @@ -147,7 +149,7 @@ class GroupInfoViewModel(val chatRoom: ChatRoom?) : ErrorReportingViewModel() { val participantsToRemove = arrayListOf() for (participant in chatRoom.participants) { val member = participants.value.orEmpty().find { member -> - participant.address.weakEqual(member.address) + participant.address.weakEqual(member.participant.address) } if (member == null) { Log.w("[Chat Room Group Info] Participant ${participant.address.asStringUriOnly()} will be removed from group") @@ -162,19 +164,19 @@ class GroupInfoViewModel(val chatRoom: ChatRoom?) : ErrorReportingViewModel() { val participantsToAdd = arrayListOf
() for (member in participants.value.orEmpty()) { val participant = chatRoom.participants.find { participant -> - participant.address.weakEqual(member.address) + participant.address.weakEqual(member.participant.address) } if (participant != null) { // Participant found, check if admin status needs to be updated - if (member.isAdmin != participant.isAdmin) { + if (member.participant.isAdmin != participant.isAdmin) { if (chatRoom.me?.isAdmin == true) { - Log.i("[Chat Room Group Info] Participant ${member.address.asStringUriOnly()} will be admin? ${member.isAdmin}") - chatRoom.setParticipantAdminStatus(participant, member.isAdmin) + Log.i("[Chat Room Group Info] Participant ${member.sipUri} will be admin? ${member.isAdmin}") + chatRoom.setParticipantAdminStatus(participant, member.participant.isAdmin) } } } else { - Log.i("[Chat Room Group Info] Participant ${member.address.asStringUriOnly()} will be added to group") - participantsToAdd.add(member.address) + Log.i("[Chat Room Group Info] Participant ${member.sipUri} will be added to group") + participantsToAdd.add(member.participant.address) } } val toAdd = arrayOfNulls
(participantsToAdd.size) @@ -195,18 +197,23 @@ class GroupInfoViewModel(val chatRoom: ChatRoom?) : ErrorReportingViewModel() { } fun removeParticipant(participant: GroupChatRoomMember) { - val list = arrayListOf() - list.addAll(participants.value.orEmpty()) - list.remove(participant) + val list = arrayListOf() + for (data in participants.value.orEmpty()) { + if (!data.participant.address.weakEqual(participant.address)) { + list.add(data) + } + } participants.value = list } private fun updateParticipants() { - val list = arrayListOf() + val list = arrayListOf() if (chatRoom != null) { for (participant in chatRoom.participants) { - list.add(GroupChatRoomMember(participant.address, participant.isAdmin, participant.securityLevel, canBeSetAdmin = true)) + list.add(GroupInfoParticipantData( + GroupChatRoomMember(participant.address, participant.isAdmin, participant.securityLevel, canBeSetAdmin = true) + )) } } diff --git a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ImdnViewModel.kt b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ImdnViewModel.kt index 9f4403a9e..29c9d6f54 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ImdnViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ImdnViewModel.kt @@ -23,6 +23,7 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import org.linphone.activities.main.chat.data.ChatMessageData +import org.linphone.activities.main.chat.data.ImdnParticipantData import org.linphone.core.ChatMessage import org.linphone.core.ChatMessageListenerStub import org.linphone.core.ParticipantImdnState @@ -37,7 +38,7 @@ class ImdnViewModelFactory(private val chatMessage: ChatMessage) : } class ImdnViewModel(private val chatMessage: ChatMessage) : ViewModel() { - val participants = MutableLiveData>() + val participants = MutableLiveData>() val chatMessageViewModel = ChatMessageData(chatMessage) @@ -56,16 +57,27 @@ class ImdnViewModel(private val chatMessage: ChatMessage) : ViewModel() { } override fun onCleared() { + participants.value.orEmpty().forEach(ImdnParticipantData::destroy) chatMessage.removeListener(listener) super.onCleared() } private fun updateParticipantsLists() { - val list = arrayListOf() - list.addAll(chatMessage.getParticipantsByImdnState(ChatMessage.State.Displayed)) - list.addAll(chatMessage.getParticipantsByImdnState(ChatMessage.State.DeliveredToUser)) - list.addAll(chatMessage.getParticipantsByImdnState(ChatMessage.State.Delivered)) - list.addAll(chatMessage.getParticipantsByImdnState(ChatMessage.State.NotDelivered)) + val list = arrayListOf() + + for (participant in chatMessage.getParticipantsByImdnState(ChatMessage.State.Displayed)) { + list.add(ImdnParticipantData(participant)) + } + for (participant in chatMessage.getParticipantsByImdnState(ChatMessage.State.DeliveredToUser)) { + list.add(ImdnParticipantData(participant)) + } + for (participant in chatMessage.getParticipantsByImdnState(ChatMessage.State.Delivered)) { + list.add(ImdnParticipantData(participant)) + } + for (participant in chatMessage.getParticipantsByImdnState(ChatMessage.State.NotDelivered)) { + list.add(ImdnParticipantData(participant)) + } + participants.value = list } } diff --git a/app/src/main/java/org/linphone/activities/main/contact/adapters/ContactsListAdapter.kt b/app/src/main/java/org/linphone/activities/main/contact/adapters/ContactsListAdapter.kt index 86d8152fc..6d3ebb552 100644 --- a/app/src/main/java/org/linphone/activities/main/contact/adapters/ContactsListAdapter.kt +++ b/app/src/main/java/org/linphone/activities/main/contact/adapters/ContactsListAdapter.kt @@ -42,7 +42,7 @@ import org.linphone.utils.HeaderAdapter class ContactsListAdapter( selectionVM: ListTopBarViewModel, private val viewLifecycleOwner: LifecycleOwner -) : SelectionListAdapter(selectionVM, ContactDiffCallback()), HeaderAdapter { +) : SelectionListAdapter(selectionVM, ContactDiffCallback()), HeaderAdapter { val selectedContactEvent: MutableLiveData> by lazy { MutableLiveData>() } @@ -59,16 +59,11 @@ class ContactsListAdapter( (holder as ViewHolder).bind(getItem(position)) } - override fun onViewRecycled(holder: RecyclerView.ViewHolder) { - (holder as ViewHolder).binding.viewModel?.destroy() - } - inner class ViewHolder( val binding: ContactListCellBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(contact: Contact) { + fun bind(contactViewModel: ContactViewModel) { with(binding) { - val contactViewModel = ContactViewModel(contact) viewModel = contactViewModel lifecycleOwner = viewLifecycleOwner @@ -83,7 +78,7 @@ class ContactsListAdapter( if (selectionViewModel.isEditionEnabled.value == true) { selectionViewModel.onToggleSelect(adapterPosition) } else { - selectedContactEvent.value = Event(contact) + selectedContactEvent.value = Event(contactViewModel.contactInternal) } } @@ -104,17 +99,17 @@ class ContactsListAdapter( override fun displayHeaderForPosition(position: Int): Boolean { if (position >= itemCount) return false val contact = getItem(position) - val firstLetter = contact.fullName?.first().toString() + val firstLetter = contact.displayName.first().toString() val previousPosition = position - 1 return if (previousPosition >= 0) { - val previousItemFirstLetter = getItem(previousPosition).fullName?.first().toString() + val previousItemFirstLetter = getItem(previousPosition).displayName.first().toString() previousItemFirstLetter != firstLetter } else true } override fun getHeaderViewForPosition(context: Context, position: Int): View { val contact = getItem(position) - val firstLetter = AppUtils.getInitials(contact.fullName ?: "", 1) + val firstLetter = AppUtils.getInitials(contact.displayName, 1) val binding: GenericListHeaderBinding = DataBindingUtil.inflate( LayoutInflater.from(context), R.layout.generic_list_header, null, false @@ -125,17 +120,17 @@ class ContactsListAdapter( } } -private class ContactDiffCallback : DiffUtil.ItemCallback() { +private class ContactDiffCallback : DiffUtil.ItemCallback() { override fun areItemsTheSame( - oldItem: Contact, - newItem: Contact + oldItem: ContactViewModel, + newItem: ContactViewModel ): Boolean { - return oldItem.compareTo(newItem) == 0 + return oldItem.contactInternal.compareTo(newItem.contactInternal) == 0 } override fun areContentsTheSame( - oldItem: Contact, - newItem: Contact + oldItem: ContactViewModel, + newItem: ContactViewModel ): Boolean { return false // For headers } diff --git a/app/src/main/java/org/linphone/activities/main/contact/fragments/MasterContactsFragment.kt b/app/src/main/java/org/linphone/activities/main/contact/fragments/MasterContactsFragment.kt index 43c56620a..56ea20bd9 100644 --- a/app/src/main/java/org/linphone/activities/main/contact/fragments/MasterContactsFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/contact/fragments/MasterContactsFragment.kt @@ -110,7 +110,7 @@ class MasterContactsFragment : MasterFragment) { val list = ArrayList() for (index in indexesOfItemToDelete) { - val contact = adapter.currentList[index] + val contact = adapter.currentList[index].contactInternal list.add(contact) } listViewModel.deleteContacts(list) diff --git a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactViewModel.kt b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactViewModel.kt index 971c93b24..d0ba4bebb 100644 --- a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactViewModel.kt @@ -48,11 +48,11 @@ class ContactViewModelFactory(private val contact: Contact) : } } -class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), ContactDataInterface { +class ContactViewModel(val contactInternal: Contact) : ErrorReportingViewModel(), ContactDataInterface { override val contact = MutableLiveData() override val displayName: String by lazy { - c.fullName ?: c.firstName + " " + c.lastName + contactInternal.fullName ?: contactInternal.firstName + " " + contactInternal.lastName } val displayOrganization = corePreferences.displayOrganization @@ -75,7 +75,7 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont private val contactsUpdatedListener = object : ContactsUpdatedListenerStub() { override fun onContactUpdated(contact: Contact) { - if (c is NativeContact && contact is NativeContact && c.nativeId == contact.nativeId) { + if (contact is NativeContact && contactInternal is NativeContact && contact.nativeId == contactInternal.nativeId) { Log.d("[Contact] $contact has changed") updateNumbersAndAddresses(contact) } @@ -124,8 +124,8 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont } init { - contact.value = c - updateNumbersAndAddresses(c) + contact.value = contactInternal + updateNumbersAndAddresses(contactInternal) coreContext.contactsManager.addListener(contactsUpdatedListener) waitForChatRoomCreation.value = false } @@ -143,8 +143,8 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont val select = ContactsContract.Data.CONTACT_ID + " = ?" val ops = java.util.ArrayList() - if (c is NativeContact) { - val nativeContact: NativeContact = c + if (contactInternal is NativeContact) { + val nativeContact: NativeContact = contactInternal Log.i("[Contact] Setting Android contact id ${nativeContact.nativeId} to batch removal") val args = arrayOf(nativeContact.nativeId) ops.add( @@ -154,9 +154,9 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont ) } - if (c.friend != null) { + if (contactInternal.friend != null) { Log.i("[Contact] Removing friend") - c.friend?.remove() + contactInternal.friend?.remove() } if (ops.isNotEmpty()) { diff --git a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactsListViewModel.kt b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactsListViewModel.kt index b4d4f5450..cbcf7b0d7 100644 --- a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactsListViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactsListViewModel.kt @@ -33,7 +33,7 @@ import org.linphone.core.tools.Log class ContactsListViewModel : ViewModel() { val sipContactsSelected = MutableLiveData() - val contactsList = MutableLiveData>() + val contactsList = MutableLiveData>() val filter = MutableLiveData() @@ -51,23 +51,31 @@ class ContactsListViewModel : ViewModel() { } override fun onCleared() { + contactsList.value.orEmpty().forEach(ContactViewModel::destroy) coreContext.contactsManager.removeListener(contactsUpdatedListener) super.onCleared() } - private fun getSelectedContactsList(): ArrayList { - return if (sipContactsSelected.value == true) coreContext.contactsManager.sipContacts else coreContext.contactsManager.contacts + private fun getSelectedContactsList(): ArrayList { + val list = arrayListOf() + val source = + if (sipContactsSelected.value == true) coreContext.contactsManager.sipContacts + else coreContext.contactsManager.contacts + for (contact in source) { + list.add(ContactViewModel(contact)) + } + return list } fun updateContactsList() { - val list: ArrayList + val list: ArrayList val filterValue = filter.value.orEmpty() list = if (filterValue.isNotEmpty()) { getSelectedContactsList().filter { contact -> - contact.fullName?.contains(filterValue, true) ?: false - } as ArrayList + contact.displayName.contains(filterValue, true) ?: false + } as ArrayList } else { getSelectedContactsList() } diff --git a/app/src/main/java/org/linphone/activities/main/history/adapters/CallLogsListAdapter.kt b/app/src/main/java/org/linphone/activities/main/history/adapters/CallLogsListAdapter.kt index b937bb6fa..ee8f91d3b 100644 --- a/app/src/main/java/org/linphone/activities/main/history/adapters/CallLogsListAdapter.kt +++ b/app/src/main/java/org/linphone/activities/main/history/adapters/CallLogsListAdapter.kt @@ -31,7 +31,6 @@ import androidx.recyclerview.widget.RecyclerView import org.linphone.R import org.linphone.activities.main.adapters.SelectionListAdapter import org.linphone.activities.main.history.data.GroupedCallLogData -import org.linphone.activities.main.history.viewmodels.CallLogViewModel import org.linphone.activities.main.viewmodels.ListTopBarViewModel import org.linphone.databinding.GenericListHeaderBinding import org.linphone.databinding.HistoryListCellBinding @@ -61,16 +60,12 @@ class CallLogsListAdapter( (holder as ViewHolder).bind(getItem(position)) } - override fun onViewRecycled(holder: RecyclerView.ViewHolder) { - (holder as ViewHolder).binding.viewModel?.destroy() - } - inner class ViewHolder( val binding: HistoryListCellBinding ) : RecyclerView.ViewHolder(binding.root) { fun bind(callLogGroup: GroupedCallLogData) { with(binding) { - val callLogViewModel = CallLogViewModel(callLogGroup.lastCallLog) + val callLogViewModel = callLogGroup.lastCallLogViewModel viewModel = callLogViewModel lifecycleOwner = viewLifecycleOwner diff --git a/app/src/main/java/org/linphone/activities/main/history/data/GroupedCallLogData.kt b/app/src/main/java/org/linphone/activities/main/history/data/GroupedCallLogData.kt index a9365f2ed..89b0d1716 100644 --- a/app/src/main/java/org/linphone/activities/main/history/data/GroupedCallLogData.kt +++ b/app/src/main/java/org/linphone/activities/main/history/data/GroupedCallLogData.kt @@ -19,9 +19,15 @@ */ package org.linphone.activities.main.history.data +import org.linphone.activities.main.history.viewmodels.CallLogViewModel import org.linphone.core.CallLog class GroupedCallLogData(callLog: CallLog) { var lastCallLog: CallLog = callLog val callLogs = arrayListOf(callLog) + val lastCallLogViewModel = CallLogViewModel(lastCallLog) + + fun destroy() { + lastCallLogViewModel.destroy() + } } diff --git a/app/src/main/java/org/linphone/activities/main/history/viewmodels/CallLogsListViewModel.kt b/app/src/main/java/org/linphone/activities/main/history/viewmodels/CallLogsListViewModel.kt index 0849096be..f1f0719b1 100644 --- a/app/src/main/java/org/linphone/activities/main/history/viewmodels/CallLogsListViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/history/viewmodels/CallLogsListViewModel.kt @@ -67,6 +67,9 @@ class CallLogsListViewModel : ViewModel() { } override fun onCleared() { + callLogs.value.orEmpty().forEach(GroupedCallLogData::destroy) + missedCallLogs.value.orEmpty().forEach(GroupedCallLogData::destroy) + coreContext.contactsManager.removeListener(contactsUpdatedListener) coreContext.core.removeListener(listener) diff --git a/app/src/main/java/org/linphone/activities/main/recordings/adapters/RecordingsListAdapter.kt b/app/src/main/java/org/linphone/activities/main/recordings/adapters/RecordingsListAdapter.kt index 8151bf69f..f108676bf 100644 --- a/app/src/main/java/org/linphone/activities/main/recordings/adapters/RecordingsListAdapter.kt +++ b/app/src/main/java/org/linphone/activities/main/recordings/adapters/RecordingsListAdapter.kt @@ -63,10 +63,6 @@ class RecordingsListAdapter( (holder as ViewHolder).bind(getItem(position)) } - override fun onViewRecycled(holder: RecyclerView.ViewHolder) { - (holder as ViewHolder).binding.data?.destroy() - } - inner class ViewHolder( val binding: RecordingListCellBinding ) : RecyclerView.ViewHolder(binding.root) { diff --git a/app/src/main/java/org/linphone/activities/main/recordings/viewmodels/RecordingsViewModel.kt b/app/src/main/java/org/linphone/activities/main/recordings/viewmodels/RecordingsViewModel.kt index bbbe84fa9..ff483fe2f 100644 --- a/app/src/main/java/org/linphone/activities/main/recordings/viewmodels/RecordingsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/recordings/viewmodels/RecordingsViewModel.kt @@ -36,6 +36,11 @@ class RecordingsViewModel : ViewModel() { isVideoVisible.value = false } + override fun onCleared() { + recordingsList.value.orEmpty().forEach(RecordingData::destroy) + super.onCleared() + } + fun deleteRecordings(list: ArrayList) { for (recording in list) { Log.i("[Recordings] Deleting recording ${recording.path}")