From b1ee757c0ba371d350fcb7741a83edc4b2a44f9b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 7 Apr 2021 10:39:27 +0200 Subject: [PATCH] Same rework applied to other classes --- .../CallStatisticsData.kt} | 79 ++++++++++--------- .../StatItemData.kt} | 3 +- .../call/viewmodels/CallViewModel.kt | 8 +- .../viewmodels/StatisticsListViewModel.kt | 12 ++- .../contact/adapters/ContactsListAdapter.kt | 6 +- .../ContactNumberOrAddressData.kt} | 7 +- .../NumberOrAddressEditorData.kt} | 4 +- .../fragments/ContactEditorFragment.kt | 5 +- .../viewmodels/ContactEditorViewModel.kt | 25 +++--- .../contact/viewmodels/ContactViewModel.kt | 16 ++-- .../history/adapters/CallLogsListAdapter.kt | 26 +++--- .../GroupedCallLogData.kt} | 4 +- .../fragments/MasterCallLogsFragment.kt | 4 +- .../history/viewmodels/CallLogViewModel.kt | 8 ++ .../viewmodels/CallLogsListViewModel.kt | 29 +++---- .../adapters/RecordingsListAdapter.kt | 22 +++--- .../RecordingData.kt} | 33 ++++---- .../fragments/RecordingsFragment.kt | 4 +- .../viewmodels/RecordingsViewModel.kt | 11 +-- .../viewmodels/AccountSettingsViewModel.kt | 6 +- .../settings/viewmodels/SettingsViewModel.kt | 10 ++- .../main/viewmodels/SharedMainViewModel.kt | 4 +- .../linphone/contact/NativeContactEditor.kt | 6 +- .../res/layout-land/call_statistics_cell.xml | 2 +- .../res/layout/call_single_statistic_cell.xml | 2 +- .../main/res/layout/call_statistics_cell.xml | 2 +- .../layout/call_statistics_cell_header.xml | 2 +- .../main/res/layout/contact_detail_cell.xml | 2 +- .../contact_number_address_editor_cell.xml | 2 +- .../main/res/layout/recording_list_cell.xml | 2 +- 30 files changed, 197 insertions(+), 149 deletions(-) rename app/src/main/java/org/linphone/activities/call/{viewmodels/CallStatisticsViewModel.kt => data/CallStatisticsData.kt} (50%) rename app/src/main/java/org/linphone/activities/call/{viewmodels/SingleStatisticViewModel.kt => data/StatItemData.kt} (97%) rename app/src/main/java/org/linphone/activities/main/contact/{viewmodels/ContactNumberOrAddressViewModel.kt => data/ContactNumberOrAddressData.kt} (91%) rename app/src/main/java/org/linphone/activities/main/contact/{viewmodels/NumberOrAddressEditorViewModel.kt => data/NumberOrAddressEditorData.kt} (87%) rename app/src/main/java/org/linphone/activities/main/history/{viewmodels/GroupedCallLogViewModel.kt => data/GroupedCallLogData.kt} (89%) rename app/src/main/java/org/linphone/activities/main/recordings/{viewmodels/RecordingViewModel.kt => data/RecordingData.kt} (92%) diff --git a/app/src/main/java/org/linphone/activities/call/viewmodels/CallStatisticsViewModel.kt b/app/src/main/java/org/linphone/activities/call/data/CallStatisticsData.kt similarity index 50% rename from app/src/main/java/org/linphone/activities/call/viewmodels/CallStatisticsViewModel.kt rename to app/src/main/java/org/linphone/activities/call/data/CallStatisticsData.kt index ab38d079d..0179d9076 100644 --- a/app/src/main/java/org/linphone/activities/call/viewmodels/CallStatisticsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/call/data/CallStatisticsData.kt @@ -17,17 +17,19 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.activities.call.viewmodels +package org.linphone.activities.call.data import androidx.lifecycle.MutableLiveData import org.linphone.LinphoneApplication.Companion.coreContext -import org.linphone.contact.GenericContactViewModel +import org.linphone.activities.call.viewmodels.StatItemData +import org.linphone.activities.call.viewmodels.StatType +import org.linphone.contact.GenericContactData import org.linphone.core.* -class CallStatisticsViewModel(val call: Call) : GenericContactViewModel(call.remoteAddress) { - val audioStats = MutableLiveData>() +class CallStatisticsData(val call: Call) : GenericContactData(call.remoteAddress) { + val audioStats = MutableLiveData>() - val videoStats = MutableLiveData>() + val videoStats = MutableLiveData>() val isVideoEnabled = MutableLiveData() @@ -35,7 +37,7 @@ class CallStatisticsViewModel(val call: Call) : GenericContactViewModel(call.rem private val listener = object : CoreListenerStub() { override fun onCallStatsUpdated(core: Core, call: Call, stats: CallStats) { - if (call == this@CallStatisticsViewModel.call) { + if (call == this@CallStatisticsData.call) { isVideoEnabled.value = call.currentParams.videoEnabled() updateCallStats(stats) } @@ -56,10 +58,9 @@ class CallStatisticsViewModel(val call: Call) : GenericContactViewModel(call.rem isExpanded.value = coreContext.core.currentCall == call } - override fun onCleared() { + override fun destroy() { coreContext.core.removeListener(listener) - - super.onCleared() + super.destroy() } fun toggleExpanded() { @@ -67,38 +68,38 @@ class CallStatisticsViewModel(val call: Call) : GenericContactViewModel(call.rem } private fun initCallStats() { - val audioList = arrayListOf() - audioList.add(StatItemViewModel(StatType.CAPTURE)) - audioList.add(StatItemViewModel(StatType.PLAYBACK)) - audioList.add(StatItemViewModel(StatType.PAYLOAD)) - audioList.add(StatItemViewModel(StatType.ENCODER)) - audioList.add(StatItemViewModel(StatType.DECODER)) - audioList.add(StatItemViewModel(StatType.DOWNLOAD_BW)) - audioList.add(StatItemViewModel(StatType.UPLOAD_BW)) - audioList.add(StatItemViewModel(StatType.ICE)) - audioList.add(StatItemViewModel(StatType.IP_FAM)) - audioList.add(StatItemViewModel(StatType.SENDER_LOSS)) - audioList.add(StatItemViewModel(StatType.RECEIVER_LOSS)) - audioList.add(StatItemViewModel(StatType.JITTER)) + val audioList = arrayListOf() + audioList.add(StatItemData(StatType.CAPTURE)) + audioList.add(StatItemData(StatType.PLAYBACK)) + audioList.add(StatItemData(StatType.PAYLOAD)) + audioList.add(StatItemData(StatType.ENCODER)) + audioList.add(StatItemData(StatType.DECODER)) + audioList.add(StatItemData(StatType.DOWNLOAD_BW)) + audioList.add(StatItemData(StatType.UPLOAD_BW)) + audioList.add(StatItemData(StatType.ICE)) + audioList.add(StatItemData(StatType.IP_FAM)) + audioList.add(StatItemData(StatType.SENDER_LOSS)) + audioList.add(StatItemData(StatType.RECEIVER_LOSS)) + audioList.add(StatItemData(StatType.JITTER)) audioStats.value = audioList - val videoList = arrayListOf() - videoList.add(StatItemViewModel(StatType.CAPTURE)) - videoList.add(StatItemViewModel(StatType.PLAYBACK)) - videoList.add(StatItemViewModel(StatType.PAYLOAD)) - videoList.add(StatItemViewModel(StatType.ENCODER)) - videoList.add(StatItemViewModel(StatType.DECODER)) - videoList.add(StatItemViewModel(StatType.DOWNLOAD_BW)) - videoList.add(StatItemViewModel(StatType.UPLOAD_BW)) - videoList.add(StatItemViewModel(StatType.ESTIMATED_AVAILABLE_DOWNLOAD_BW)) - videoList.add(StatItemViewModel(StatType.ICE)) - videoList.add(StatItemViewModel(StatType.IP_FAM)) - videoList.add(StatItemViewModel(StatType.SENDER_LOSS)) - videoList.add(StatItemViewModel(StatType.RECEIVER_LOSS)) - videoList.add(StatItemViewModel(StatType.SENT_RESOLUTION)) - videoList.add(StatItemViewModel(StatType.RECEIVED_RESOLUTION)) - videoList.add(StatItemViewModel(StatType.SENT_FPS)) - videoList.add(StatItemViewModel(StatType.RECEIVED_FPS)) + val videoList = arrayListOf() + videoList.add(StatItemData(StatType.CAPTURE)) + videoList.add(StatItemData(StatType.PLAYBACK)) + videoList.add(StatItemData(StatType.PAYLOAD)) + videoList.add(StatItemData(StatType.ENCODER)) + videoList.add(StatItemData(StatType.DECODER)) + videoList.add(StatItemData(StatType.DOWNLOAD_BW)) + videoList.add(StatItemData(StatType.UPLOAD_BW)) + videoList.add(StatItemData(StatType.ESTIMATED_AVAILABLE_DOWNLOAD_BW)) + videoList.add(StatItemData(StatType.ICE)) + videoList.add(StatItemData(StatType.IP_FAM)) + videoList.add(StatItemData(StatType.SENDER_LOSS)) + videoList.add(StatItemData(StatType.RECEIVER_LOSS)) + videoList.add(StatItemData(StatType.SENT_RESOLUTION)) + videoList.add(StatItemData(StatType.RECEIVED_RESOLUTION)) + videoList.add(StatItemData(StatType.SENT_FPS)) + videoList.add(StatItemData(StatType.RECEIVED_FPS)) videoStats.value = videoList } diff --git a/app/src/main/java/org/linphone/activities/call/viewmodels/SingleStatisticViewModel.kt b/app/src/main/java/org/linphone/activities/call/data/StatItemData.kt similarity index 97% rename from app/src/main/java/org/linphone/activities/call/viewmodels/SingleStatisticViewModel.kt rename to app/src/main/java/org/linphone/activities/call/data/StatItemData.kt index c3983970f..d24a9a10e 100644 --- a/app/src/main/java/org/linphone/activities/call/viewmodels/SingleStatisticViewModel.kt +++ b/app/src/main/java/org/linphone/activities/call/data/StatItemData.kt @@ -20,7 +20,6 @@ package org.linphone.activities.call.viewmodels import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel import java.text.DecimalFormat import org.linphone.R import org.linphone.core.AddressFamily @@ -48,7 +47,7 @@ enum class StatType(val nameResource: Int) { ESTIMATED_AVAILABLE_DOWNLOAD_BW(R.string.call_stats_estimated_download) } -class StatItemViewModel(val type: StatType) : ViewModel() { +class StatItemData(val type: StatType) { val value = MutableLiveData() fun update(call: Call, stats: CallStats) { diff --git a/app/src/main/java/org/linphone/activities/call/viewmodels/CallViewModel.kt b/app/src/main/java/org/linphone/activities/call/viewmodels/CallViewModel.kt index ad2a0119b..a07d1fe3c 100644 --- a/app/src/main/java/org/linphone/activities/call/viewmodels/CallViewModel.kt +++ b/app/src/main/java/org/linphone/activities/call/viewmodels/CallViewModel.kt @@ -118,11 +118,15 @@ open class CallViewModel(val call: Call) : GenericContactViewModel(call.remoteAd } override fun onCleared() { - call.removeListener(listener) - + destroy() super.onCleared() } + fun destroy() { + // TODO: call it from CallsViewModel (after conference rework merge) + call.removeListener(listener) + } + fun terminateCall() { coreContext.terminateCall(call) } diff --git a/app/src/main/java/org/linphone/activities/call/viewmodels/StatisticsListViewModel.kt b/app/src/main/java/org/linphone/activities/call/viewmodels/StatisticsListViewModel.kt index 08b8def5e..56f8f3f85 100644 --- a/app/src/main/java/org/linphone/activities/call/viewmodels/StatisticsListViewModel.kt +++ b/app/src/main/java/org/linphone/activities/call/viewmodels/StatisticsListViewModel.kt @@ -22,12 +22,13 @@ package org.linphone.activities.call.viewmodels import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import org.linphone.LinphoneApplication.Companion.coreContext +import org.linphone.activities.call.data.CallStatisticsData import org.linphone.core.Call import org.linphone.core.Core import org.linphone.core.CoreListenerStub class StatisticsListViewModel : ViewModel() { - val callStatsList = MutableLiveData>() + val callStatsList = MutableLiveData>() private val listener = object : CoreListenerStub() { override fun onCallStateChanged( @@ -37,10 +38,12 @@ class StatisticsListViewModel : ViewModel() { message: String ) { if (state == Call.State.End || state == Call.State.Error) { - val newList = arrayListOf() + val newList = arrayListOf() for (stat in callStatsList.value.orEmpty()) { if (stat.call != call) { newList.add(stat) + } else { + stat.destroy() } } callStatsList.value = newList @@ -51,16 +54,17 @@ class StatisticsListViewModel : ViewModel() { init { coreContext.core.addListener(listener) - val list = arrayListOf() + val list = arrayListOf() for (call in coreContext.core.calls) { if (call.state != Call.State.End && call.state != Call.State.Released && call.state != Call.State.Error) { - list.add(CallStatisticsViewModel(call)) + list.add(CallStatisticsData(call)) } } callStatsList.value = list } override fun onCleared() { + callStatsList.value.orEmpty().forEach(CallStatisticsData::destroy) coreContext.core.removeListener(listener) super.onCleared() 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 c5a734d25..86d8152fc 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 @@ -59,8 +59,12 @@ class ContactsListAdapter( (holder as ViewHolder).bind(getItem(position)) } + override fun onViewRecycled(holder: RecyclerView.ViewHolder) { + (holder as ViewHolder).binding.viewModel?.destroy() + } + inner class ViewHolder( - private val binding: ContactListCellBinding + val binding: ContactListCellBinding ) : RecyclerView.ViewHolder(binding.root) { fun bind(contact: Contact) { with(binding) { diff --git a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactNumberOrAddressViewModel.kt b/app/src/main/java/org/linphone/activities/main/contact/data/ContactNumberOrAddressData.kt similarity index 91% rename from app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactNumberOrAddressViewModel.kt rename to app/src/main/java/org/linphone/activities/main/contact/data/ContactNumberOrAddressData.kt index 852bdea9b..37560fbc1 100644 --- a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactNumberOrAddressViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/contact/data/ContactNumberOrAddressData.kt @@ -17,13 +17,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.activities.main.contact.viewmodels +package org.linphone.activities.main.contact.data -import androidx.lifecycle.ViewModel import org.linphone.LinphoneApplication.Companion.corePreferences import org.linphone.core.Address -class ContactNumberOrAddressViewModel( +class ContactNumberOrAddressData( val address: Address?, val hasPresence: Boolean, val displayedValue: String, @@ -31,7 +30,7 @@ class ContactNumberOrAddressViewModel( val showSecureChat: Boolean = false, val typeLabel: String = "", private val listener: ContactNumberOrAddressClickListener -) : ViewModel() { +) { val showInvite = !hasPresence && !isSip val chatAllowed = !corePreferences.disableChat diff --git a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/NumberOrAddressEditorViewModel.kt b/app/src/main/java/org/linphone/activities/main/contact/data/NumberOrAddressEditorData.kt similarity index 87% rename from app/src/main/java/org/linphone/activities/main/contact/viewmodels/NumberOrAddressEditorViewModel.kt rename to app/src/main/java/org/linphone/activities/main/contact/data/NumberOrAddressEditorData.kt index 04db7d963..44c22cb39 100644 --- a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/NumberOrAddressEditorViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/contact/data/NumberOrAddressEditorData.kt @@ -17,11 +17,11 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.activities.main.contact.viewmodels +package org.linphone.activities.main.contact.data import androidx.lifecycle.MutableLiveData -class NumberOrAddressEditorViewModel(val currentValue: String, val isSipAddress: Boolean) { +class NumberOrAddressEditorData(val currentValue: String, val isSipAddress: Boolean) { val newValue = MutableLiveData() val toRemove = MutableLiveData() diff --git a/app/src/main/java/org/linphone/activities/main/contact/fragments/ContactEditorFragment.kt b/app/src/main/java/org/linphone/activities/main/contact/fragments/ContactEditorFragment.kt index d4cc6c0ab..df6266720 100644 --- a/app/src/main/java/org/linphone/activities/main/contact/fragments/ContactEditorFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/contact/fragments/ContactEditorFragment.kt @@ -35,6 +35,7 @@ import org.linphone.LinphoneApplication.Companion.corePreferences import org.linphone.R import org.linphone.activities.GenericFragment import org.linphone.activities.main.MainActivity +import org.linphone.activities.main.contact.data.NumberOrAddressEditorData import org.linphone.activities.main.contact.viewmodels.* import org.linphone.activities.main.navigateToContact import org.linphone.activities.main.viewmodels.SharedMainViewModel @@ -90,10 +91,10 @@ class ContactEditorFragment : GenericFragment(), S val sipUri = arguments?.getString("SipUri") if (sipUri != null) { Log.i("[Contact Editor] Found SIP URI in arguments: $sipUri") - val newSipUri = NumberOrAddressEditorViewModel("", true) + val newSipUri = NumberOrAddressEditorData("", true) newSipUri.newValue.value = sipUri - val list = arrayListOf() + val list = arrayListOf() list.addAll(viewModel.addresses.value.orEmpty()) list.add(newSipUri) viewModel.addresses.value = list diff --git a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactEditorViewModel.kt b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactEditorViewModel.kt index 3ee0d2a3c..e6697eb1e 100644 --- a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactEditorViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactEditorViewModel.kt @@ -29,6 +29,7 @@ import java.io.ByteArrayOutputStream import java.io.IOException import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.corePreferences +import org.linphone.activities.main.contact.data.NumberOrAddressEditorData import org.linphone.contact.* import org.linphone.core.tools.Log import org.linphone.utils.ImageUtils @@ -60,9 +61,9 @@ class ContactEditorViewModel(val c: Contact?) : ViewModel(), ContactDataInterfac val tempPicturePath = MutableLiveData() private var picture: ByteArray? = null - val numbers = MutableLiveData>() + val numbers = MutableLiveData>() - val addresses = MutableLiveData>() + val addresses = MutableLiveData>() var syncAccountName: String? = null var syncAccountType: String? = null @@ -177,35 +178,35 @@ class ContactEditorViewModel(val c: Contact?) : ViewModel(), ContactDataInterfac } fun addEmptySipAddress() { - val list = arrayListOf() + val list = arrayListOf() list.addAll(addresses.value.orEmpty()) - list.add(NumberOrAddressEditorViewModel("", true)) + list.add(NumberOrAddressEditorData("", true)) addresses.value = list } fun addEmptyPhoneNumber() { - val list = arrayListOf() + val list = arrayListOf() list.addAll(numbers.value.orEmpty()) - list.add(NumberOrAddressEditorViewModel("", false)) + list.add(NumberOrAddressEditorData("", false)) numbers.value = list } private fun updateNumbersAndAddresses() { - val phoneNumbers = arrayListOf() + val phoneNumbers = arrayListOf() for (number in c?.rawPhoneNumbers.orEmpty()) { - phoneNumbers.add(NumberOrAddressEditorViewModel(number, false)) + phoneNumbers.add(NumberOrAddressEditorData(number, false)) } if (phoneNumbers.isEmpty()) { - phoneNumbers.add(NumberOrAddressEditorViewModel("", false)) + phoneNumbers.add(NumberOrAddressEditorData("", false)) } numbers.value = phoneNumbers - val sipAddresses = arrayListOf() + val sipAddresses = arrayListOf() for (address in c?.rawSipAddresses.orEmpty()) { - sipAddresses.add(NumberOrAddressEditorViewModel(address, true)) + sipAddresses.add(NumberOrAddressEditorData(address, true)) } if (sipAddresses.isEmpty()) { - sipAddresses.add(NumberOrAddressEditorViewModel("", true)) + sipAddresses.add(NumberOrAddressEditorData("", true)) } addresses.value = sipAddresses } 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 f8f54ffb1..971c93b24 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 @@ -27,6 +27,8 @@ import androidx.lifecycle.ViewModelProvider import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.corePreferences import org.linphone.R +import org.linphone.activities.main.contact.data.ContactNumberOrAddressClickListener +import org.linphone.activities.main.contact.data.ContactNumberOrAddressData import org.linphone.activities.main.viewmodels.ErrorReportingViewModel import org.linphone.contact.Contact import org.linphone.contact.ContactDataInterface @@ -55,7 +57,7 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont val displayOrganization = corePreferences.displayOrganization - val numbersAndAddresses = MutableLiveData>() + val numbersAndAddresses = MutableLiveData>() val sendSmsToEvent: MutableLiveData> by lazy { MutableLiveData>() @@ -129,10 +131,14 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont } override fun onCleared() { - coreContext.contactsManager.removeListener(contactsUpdatedListener) + destroy() super.onCleared() } + fun destroy() { + coreContext.contactsManager.removeListener(contactsUpdatedListener) + } + fun deleteContact() { val select = ContactsContract.Data.CONTACT_ID + " = ?" val ops = java.util.ArrayList() @@ -164,7 +170,7 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont } private fun updateNumbersAndAddresses(contact: Contact) { - val list = arrayListOf() + val list = arrayListOf() for (address in contact.sipAddresses) { val value = address.asStringUriOnly() val presenceModel = contact.friend?.getPresenceModelForUriOrTel(value) @@ -172,7 +178,7 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont val isMe = coreContext.core.defaultAccount?.params?.identityAddress?.weakEqual(address) ?: false val secureChatAllowed = !isMe && contact.friend?.getPresenceModelForUriOrTel(value)?.hasCapability(FriendCapability.LimeX3Dh) ?: false val displayValue = if (coreContext.core.defaultAccount?.params?.domain == address.domain) (address.username ?: value) else value - val noa = ContactNumberOrAddressViewModel(address, hasPresence, displayValue, showSecureChat = secureChatAllowed, listener = listener) + val noa = ContactNumberOrAddressData(address, hasPresence, displayValue, showSecureChat = secureChatAllowed, listener = listener) list.add(noa) } for (phoneNumber in contact.phoneNumbers) { @@ -183,7 +189,7 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont val address = coreContext.core.interpretUrl(contactAddress) val isMe = if (address != null) coreContext.core.defaultAccount?.params?.identityAddress?.weakEqual(address) ?: false else false val secureChatAllowed = !isMe && contact.friend?.getPresenceModelForUriOrTel(number)?.hasCapability(FriendCapability.LimeX3Dh) ?: false - val noa = ContactNumberOrAddressViewModel(address, hasPresence, number, isSip = false, showSecureChat = secureChatAllowed, typeLabel = phoneNumber.typeLabel, listener = listener) + val noa = ContactNumberOrAddressData(address, hasPresence, number, isSip = false, showSecureChat = secureChatAllowed, typeLabel = phoneNumber.typeLabel, listener = listener) list.add(noa) } numbersAndAddresses.value = list 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 f1ace7721..abb878d8f 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 @@ -30,8 +30,8 @@ import androidx.recyclerview.widget.DiffUtil 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.history.viewmodels.GroupedCallLogViewModel import org.linphone.activities.main.viewmodels.ListTopBarViewModel import org.linphone.core.Address import org.linphone.databinding.GenericListHeaderBinding @@ -41,9 +41,9 @@ import org.linphone.utils.* class CallLogsListAdapter( selectionVM: ListTopBarViewModel, private val viewLifecycleOwner: LifecycleOwner -) : SelectionListAdapter(selectionVM, CallLogDiffCallback()), HeaderAdapter { - val selectedCallLogEvent: MutableLiveData> by lazy { - MutableLiveData>() +) : SelectionListAdapter(selectionVM, CallLogDiffCallback()), HeaderAdapter { + val selectedCallLogEvent: MutableLiveData> by lazy { + MutableLiveData>() } val startCallToEvent: MutableLiveData> by lazy { @@ -62,10 +62,14 @@ class CallLogsListAdapter( (holder as ViewHolder).bind(getItem(position)) } + override fun onViewRecycled(holder: RecyclerView.ViewHolder) { + (holder as ViewHolder).binding.viewModel?.destroy() + } + inner class ViewHolder( - private val binding: HistoryListCellBinding + val binding: HistoryListCellBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(callLogGroup: GroupedCallLogViewModel) { + fun bind(callLogGroup: GroupedCallLogData) { with(binding) { val callLogViewModel = CallLogViewModel(callLogGroup.lastCallLog) viewModel = callLogViewModel @@ -140,17 +144,17 @@ class CallLogsListAdapter( } } -private class CallLogDiffCallback : DiffUtil.ItemCallback() { +private class CallLogDiffCallback : DiffUtil.ItemCallback() { override fun areItemsTheSame( - oldItem: GroupedCallLogViewModel, - newItem: GroupedCallLogViewModel + oldItem: GroupedCallLogData, + newItem: GroupedCallLogData ): Boolean { return oldItem.lastCallLog.callId == newItem.lastCallLog.callId } override fun areContentsTheSame( - oldItem: GroupedCallLogViewModel, - newItem: GroupedCallLogViewModel + oldItem: GroupedCallLogData, + newItem: GroupedCallLogData ): Boolean { return false // For headers } diff --git a/app/src/main/java/org/linphone/activities/main/history/viewmodels/GroupedCallLogViewModel.kt b/app/src/main/java/org/linphone/activities/main/history/data/GroupedCallLogData.kt similarity index 89% rename from app/src/main/java/org/linphone/activities/main/history/viewmodels/GroupedCallLogViewModel.kt rename to app/src/main/java/org/linphone/activities/main/history/data/GroupedCallLogData.kt index 12272f88d..a9365f2ed 100644 --- a/app/src/main/java/org/linphone/activities/main/history/viewmodels/GroupedCallLogViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/history/data/GroupedCallLogData.kt @@ -17,11 +17,11 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.activities.main.history.viewmodels +package org.linphone.activities.main.history.data import org.linphone.core.CallLog -class GroupedCallLogViewModel(callLog: CallLog) { +class GroupedCallLogData(callLog: CallLog) { var lastCallLog: CallLog = callLog val callLogs = arrayListOf(callLog) } diff --git a/app/src/main/java/org/linphone/activities/main/history/fragments/MasterCallLogsFragment.kt b/app/src/main/java/org/linphone/activities/main/history/fragments/MasterCallLogsFragment.kt index 90b725a90..a4889068d 100644 --- a/app/src/main/java/org/linphone/activities/main/history/fragments/MasterCallLogsFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/history/fragments/MasterCallLogsFragment.kt @@ -31,8 +31,8 @@ import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R import org.linphone.activities.main.fragments.MasterFragment import org.linphone.activities.main.history.adapters.CallLogsListAdapter +import org.linphone.activities.main.history.data.GroupedCallLogData import org.linphone.activities.main.history.viewmodels.CallLogsListViewModel -import org.linphone.activities.main.history.viewmodels.GroupedCallLogViewModel import org.linphone.activities.main.navigateToCallHistory import org.linphone.activities.main.navigateToDialer import org.linphone.activities.main.viewmodels.DialogViewModel @@ -194,7 +194,7 @@ class MasterCallLogsFragment : MasterFragment) { - val list = ArrayList() + val list = ArrayList() for (index in indexesOfItemToDelete) { val callLogGroup = adapter.currentList[index] list.add(callLogGroup) diff --git a/app/src/main/java/org/linphone/activities/main/history/viewmodels/CallLogViewModel.kt b/app/src/main/java/org/linphone/activities/main/history/viewmodels/CallLogViewModel.kt index 19417a808..3aa1dfdb3 100644 --- a/app/src/main/java/org/linphone/activities/main/history/viewmodels/CallLogViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/history/viewmodels/CallLogViewModel.kt @@ -129,6 +129,14 @@ class CallLogViewModel(val callLog: CallLog) : GenericContactViewModel(callLog.r waitForChatRoomCreation.value = false } + override fun onCleared() { + destroy() + super.onCleared() + } + + fun destroy() { + } + fun startCall() { startCallEvent.value = Event(callLog.remoteAddress) } 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 67bcb40d1..b7c9a1185 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 @@ -22,6 +22,7 @@ package org.linphone.activities.main.history.viewmodels import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import org.linphone.LinphoneApplication.Companion.coreContext +import org.linphone.activities.main.history.data.GroupedCallLogData import org.linphone.contact.ContactsUpdatedListenerStub import org.linphone.core.* import org.linphone.core.tools.Log @@ -30,8 +31,8 @@ import org.linphone.utils.LinphoneUtils import org.linphone.utils.TimestampUtils class CallLogsListViewModel : ViewModel() { - val callLogs = MutableLiveData>() - val missedCallLogs = MutableLiveData>() + val callLogs = MutableLiveData>() + val missedCallLogs = MutableLiveData>() val missedCallLogsSelected = MutableLiveData() @@ -72,7 +73,7 @@ class CallLogsListViewModel : ViewModel() { super.onCleared() } - fun deleteCallLogGroup(callLog: GroupedCallLogViewModel?) { + fun deleteCallLogGroup(callLog: GroupedCallLogData?) { if (callLog != null) { for (log in callLog.callLogs) { coreContext.core.removeCallLog(log) @@ -82,7 +83,7 @@ class CallLogsListViewModel : ViewModel() { updateCallLogs() } - fun deleteCallLogGroups(listToDelete: ArrayList) { + fun deleteCallLogGroups(listToDelete: ArrayList) { for (callLog in listToDelete) { for (log in callLog.callLogs) { coreContext.core.removeCallLog(log) @@ -93,41 +94,41 @@ class CallLogsListViewModel : ViewModel() { } private fun updateCallLogs() { - val list = arrayListOf() - val missedList = arrayListOf() + val list = arrayListOf() + val missedList = arrayListOf() - var previousCallLogGroup: GroupedCallLogViewModel? = null - var previousMissedCallLogGroup: GroupedCallLogViewModel? = null + var previousCallLogGroup: GroupedCallLogData? = null + var previousMissedCallLogGroup: GroupedCallLogData? = null for (callLog in coreContext.core.callLogs) { if (previousCallLogGroup == null) { - previousCallLogGroup = GroupedCallLogViewModel(callLog) + previousCallLogGroup = GroupedCallLogData(callLog) } else if (previousCallLogGroup.lastCallLog.localAddress.weakEqual(callLog.localAddress) && previousCallLogGroup.lastCallLog.remoteAddress.weakEqual(callLog.remoteAddress)) { if (TimestampUtils.isSameDay(previousCallLogGroup.lastCallLog.startDate, callLog.startDate)) { previousCallLogGroup.callLogs.add(callLog) previousCallLogGroup.lastCallLog = callLog } else { list.add(previousCallLogGroup) - previousCallLogGroup = GroupedCallLogViewModel(callLog) + previousCallLogGroup = GroupedCallLogData(callLog) } } else { list.add(previousCallLogGroup) - previousCallLogGroup = GroupedCallLogViewModel(callLog) + previousCallLogGroup = GroupedCallLogData(callLog) } if (LinphoneUtils.isCallLogMissed(callLog)) { if (previousMissedCallLogGroup == null) { - previousMissedCallLogGroup = GroupedCallLogViewModel(callLog) + previousMissedCallLogGroup = GroupedCallLogData(callLog) } else if (previousMissedCallLogGroup.lastCallLog.localAddress.weakEqual(callLog.localAddress) && previousMissedCallLogGroup.lastCallLog.remoteAddress.weakEqual(callLog.remoteAddress)) { if (TimestampUtils.isSameDay(previousMissedCallLogGroup.lastCallLog.startDate, callLog.startDate)) { previousMissedCallLogGroup.callLogs.add(callLog) previousMissedCallLogGroup.lastCallLog = callLog } else { missedList.add(previousMissedCallLogGroup) - previousMissedCallLogGroup = GroupedCallLogViewModel(callLog) + previousMissedCallLogGroup = GroupedCallLogData(callLog) } } else { missedList.add(previousMissedCallLogGroup) - previousMissedCallLogGroup = GroupedCallLogViewModel(callLog) + previousMissedCallLogGroup = GroupedCallLogData(callLog) } } } 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 f632b4770..693507eb1 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 @@ -31,7 +31,7 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import org.linphone.R import org.linphone.activities.main.adapters.SelectionListAdapter -import org.linphone.activities.main.recordings.viewmodels.RecordingViewModel +import org.linphone.activities.main.recordings.data.RecordingData import org.linphone.activities.main.viewmodels.ListTopBarViewModel import org.linphone.databinding.GenericListHeaderBinding import org.linphone.databinding.RecordingListCellBinding @@ -40,7 +40,7 @@ import org.linphone.utils.* class RecordingsListAdapter( selectionVM: ListTopBarViewModel, private val viewLifecycleOwner: LifecycleOwner -) : SelectionListAdapter(selectionVM, RecordingDiffCallback()), HeaderAdapter { +) : SelectionListAdapter(selectionVM, RecordingDiffCallback()), HeaderAdapter { val isVideoRecordingPlayingEvent: MutableLiveData> by lazy { MutableLiveData>() } @@ -63,10 +63,14 @@ class RecordingsListAdapter( (holder as ViewHolder).bind(getItem(position)) } + override fun onViewRecycled(holder: RecyclerView.ViewHolder) { + (holder as ViewHolder).binding.viewModel?.destroy() + } + inner class ViewHolder( - private val binding: RecordingListCellBinding + val binding: RecordingListCellBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(recording: RecordingViewModel) { + fun bind(recording: RecordingData) { with(binding) { viewModel = recording @@ -136,17 +140,17 @@ class RecordingsListAdapter( } } -private class RecordingDiffCallback : DiffUtil.ItemCallback() { +private class RecordingDiffCallback : DiffUtil.ItemCallback() { override fun areItemsTheSame( - oldItem: RecordingViewModel, - newItem: RecordingViewModel + oldItem: RecordingData, + newItem: RecordingData ): Boolean { return oldItem.compareTo(newItem) == 0 } override fun areContentsTheSame( - oldItem: RecordingViewModel, - newItem: RecordingViewModel + oldItem: RecordingData, + newItem: RecordingData ): Boolean { return false // for headers } diff --git a/app/src/main/java/org/linphone/activities/main/recordings/viewmodels/RecordingViewModel.kt b/app/src/main/java/org/linphone/activities/main/recordings/data/RecordingData.kt similarity index 92% rename from app/src/main/java/org/linphone/activities/main/recordings/viewmodels/RecordingViewModel.kt rename to app/src/main/java/org/linphone/activities/main/recordings/data/RecordingData.kt index 2f97a8030..b3d51abce 100644 --- a/app/src/main/java/org/linphone/activities/main/recordings/viewmodels/RecordingViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/recordings/data/RecordingData.kt @@ -17,21 +17,17 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.activities.main.recordings.viewmodels +package org.linphone.activities.main.recordings.data import android.graphics.SurfaceTexture import android.view.TextureView import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope import java.text.DateFormat import java.text.SimpleDateFormat import java.util.* import java.util.regex.Pattern -import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.* import kotlinx.coroutines.channels.ticker -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.core.AudioDevice import org.linphone.core.Player @@ -39,7 +35,7 @@ import org.linphone.core.PlayerListener import org.linphone.core.tools.Log import org.linphone.utils.LinphoneUtils -class RecordingViewModel(val path: String) : ViewModel(), Comparable { +class RecordingData(val path: String) : Comparable { companion object { val RECORD_PATTERN: Pattern = Pattern.compile(".*/(.*)_(\\d{2}-\\d{2}-\\d{4}-\\d{2}-\\d{2}-\\d{2})\\..*") @@ -87,6 +83,8 @@ class RecordingViewModel(val path: String) : ViewModel(), Comparable= 2) { @@ -101,17 +99,18 @@ class RecordingViewModel(val path: String) : ViewModel(), Comparable) { - val list = ArrayList() + val list = ArrayList() for (index in indexesOfItemToDelete) { val recording = adapter.currentList[index] list.add(recording) 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 96346a2d7..bbbe84fa9 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 @@ -22,11 +22,12 @@ package org.linphone.activities.main.recordings.viewmodels import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import kotlin.collections.ArrayList +import org.linphone.activities.main.recordings.data.RecordingData import org.linphone.core.tools.Log import org.linphone.utils.FileUtils class RecordingsViewModel : ViewModel() { - val recordingsList = MutableLiveData>() + val recordingsList = MutableLiveData>() val isVideoVisible = MutableLiveData() @@ -35,7 +36,7 @@ class RecordingsViewModel : ViewModel() { isVideoVisible.value = false } - fun deleteRecordings(list: ArrayList) { + fun deleteRecordings(list: ArrayList) { for (recording in list) { Log.i("[Recordings] Deleting recording ${recording.path}") FileUtils.deleteFile(recording.path) @@ -44,13 +45,13 @@ class RecordingsViewModel : ViewModel() { } private fun getRecordings() { - val list = arrayListOf() + val list = arrayListOf() for (f in FileUtils.getFileStorageDir().listFiles().orEmpty()) { Log.i("[Recordings] Found file ${f.path}") - if (RecordingViewModel.RECORD_PATTERN.matcher(f.path).matches()) { + if (RecordingData.RECORD_PATTERN.matcher(f.path).matches()) { list.add( - RecordingViewModel( + RecordingData( f.path ) ) diff --git a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AccountSettingsViewModel.kt b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AccountSettingsViewModel.kt index 362540521..26fa87cd7 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AccountSettingsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AccountSettingsViewModel.kt @@ -372,10 +372,14 @@ class AccountSettingsViewModel(val account: Account) : GenericSettingsViewModel( } override fun onCleared() { - account.removeListener(listener) + destroy() super.onCleared() } + fun destroy() { + account.removeListener(listener) + } + private fun update() { isDefault.value = core.defaultAccount == account val params = account.params diff --git a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/SettingsViewModel.kt b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/SettingsViewModel.kt index 1af8c8b06..59a3fb2da 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/SettingsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/SettingsViewModel.kt @@ -26,7 +26,7 @@ import org.linphone.LinphoneApplication.Companion.corePreferences import org.linphone.activities.main.settings.SettingListenerStub class SettingsViewModel : ViewModel() { - val tunnelAvailable: Boolean = coreContext.core.tunnelAvailable() + private val tunnelAvailable: Boolean = coreContext.core.tunnelAvailable() val showAccountSettings: Boolean = corePreferences.showAccountSettings val showTunnelSettings: Boolean = tunnelAvailable && corePreferences.showTunnelSettings @@ -68,7 +68,14 @@ class SettingsViewModel : ViewModel() { updateAccountsList() } + override fun onCleared() { + accounts.value.orEmpty().forEach(AccountSettingsViewModel::destroy) + super.onCleared() + } + fun updateAccountsList() { + accounts.value.orEmpty().forEach(AccountSettingsViewModel::destroy) + val list = arrayListOf() if (coreContext.core.accountList.isNotEmpty()) { for (account in coreContext.core.accountList) { @@ -77,6 +84,7 @@ class SettingsViewModel : ViewModel() { list.add(viewModel) } } + accounts.value = list } } diff --git a/app/src/main/java/org/linphone/activities/main/viewmodels/SharedMainViewModel.kt b/app/src/main/java/org/linphone/activities/main/viewmodels/SharedMainViewModel.kt index fa0f1ed09..fd41f18a3 100644 --- a/app/src/main/java/org/linphone/activities/main/viewmodels/SharedMainViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/viewmodels/SharedMainViewModel.kt @@ -21,7 +21,7 @@ package org.linphone.activities.main.viewmodels import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import org.linphone.activities.main.history.viewmodels.GroupedCallLogViewModel +import org.linphone.activities.main.history.data.GroupedCallLogData import org.linphone.contact.Contact import org.linphone.core.* import org.linphone.utils.Event @@ -31,7 +31,7 @@ class SharedMainViewModel : ViewModel() { /* Call history */ - val selectedCallLogGroup = MutableLiveData() + val selectedCallLogGroup = MutableLiveData() /* Chat */ diff --git a/app/src/main/java/org/linphone/contact/NativeContactEditor.kt b/app/src/main/java/org/linphone/contact/NativeContactEditor.kt index a47d48d84..84f900e74 100644 --- a/app/src/main/java/org/linphone/contact/NativeContactEditor.kt +++ b/app/src/main/java/org/linphone/contact/NativeContactEditor.kt @@ -27,7 +27,7 @@ import android.provider.ContactsContract.CommonDataKinds import android.provider.ContactsContract.RawContacts import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R -import org.linphone.activities.main.contact.viewmodels.NumberOrAddressEditorViewModel +import org.linphone.activities.main.contact.data.NumberOrAddressEditorData import org.linphone.core.tools.Log import org.linphone.utils.AppUtils import org.linphone.utils.PermissionHelper @@ -170,7 +170,7 @@ class NativeContactEditor(val contact: NativeContact) { return this } - fun setPhoneNumbers(value: List): NativeContactEditor { + fun setPhoneNumbers(value: List): NativeContactEditor { var addCount = 0 var removeCount = 0 var editCount = 0 @@ -205,7 +205,7 @@ class NativeContactEditor(val contact: NativeContact) { return this } - fun setSipAddresses(value: List): NativeContactEditor { + fun setSipAddresses(value: List): NativeContactEditor { var addCount = 0 var removeCount = 0 var editCount = 0 diff --git a/app/src/main/res/layout-land/call_statistics_cell.xml b/app/src/main/res/layout-land/call_statistics_cell.xml index 2b2f80d39..daf66caac 100644 --- a/app/src/main/res/layout-land/call_statistics_cell.xml +++ b/app/src/main/res/layout-land/call_statistics_cell.xml @@ -7,7 +7,7 @@ + type="org.linphone.activities.call.data.CallStatisticsData" /> + type="org.linphone.activities.call.viewmodels.StatItemData" /> + type="org.linphone.activities.call.data.CallStatisticsData" /> + type="org.linphone.activities.call.data.CallStatisticsData" /> + type="org.linphone.activities.main.contact.data.ContactNumberOrAddressData" /> + type="org.linphone.activities.main.contact.data.NumberOrAddressEditorData" /> + type="org.linphone.activities.main.recordings.data.RecordingData" />