Same rework applied to other classes

This commit is contained in:
Sylvain Berfini 2021-04-07 10:39:27 +02:00
parent 1eabce5220
commit b1ee757c0b
30 changed files with 197 additions and 149 deletions

View file

@ -17,17 +17,19 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.linphone.activities.call.viewmodels package org.linphone.activities.call.data
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import org.linphone.LinphoneApplication.Companion.coreContext 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.* import org.linphone.core.*
class CallStatisticsViewModel(val call: Call) : GenericContactViewModel(call.remoteAddress) { class CallStatisticsData(val call: Call) : GenericContactData(call.remoteAddress) {
val audioStats = MutableLiveData<ArrayList<StatItemViewModel>>() val audioStats = MutableLiveData<ArrayList<StatItemData>>()
val videoStats = MutableLiveData<ArrayList<StatItemViewModel>>() val videoStats = MutableLiveData<ArrayList<StatItemData>>()
val isVideoEnabled = MutableLiveData<Boolean>() val isVideoEnabled = MutableLiveData<Boolean>()
@ -35,7 +37,7 @@ class CallStatisticsViewModel(val call: Call) : GenericContactViewModel(call.rem
private val listener = object : CoreListenerStub() { private val listener = object : CoreListenerStub() {
override fun onCallStatsUpdated(core: Core, call: Call, stats: CallStats) { override fun onCallStatsUpdated(core: Core, call: Call, stats: CallStats) {
if (call == this@CallStatisticsViewModel.call) { if (call == this@CallStatisticsData.call) {
isVideoEnabled.value = call.currentParams.videoEnabled() isVideoEnabled.value = call.currentParams.videoEnabled()
updateCallStats(stats) updateCallStats(stats)
} }
@ -56,10 +58,9 @@ class CallStatisticsViewModel(val call: Call) : GenericContactViewModel(call.rem
isExpanded.value = coreContext.core.currentCall == call isExpanded.value = coreContext.core.currentCall == call
} }
override fun onCleared() { override fun destroy() {
coreContext.core.removeListener(listener) coreContext.core.removeListener(listener)
super.destroy()
super.onCleared()
} }
fun toggleExpanded() { fun toggleExpanded() {
@ -67,38 +68,38 @@ class CallStatisticsViewModel(val call: Call) : GenericContactViewModel(call.rem
} }
private fun initCallStats() { private fun initCallStats() {
val audioList = arrayListOf<StatItemViewModel>() val audioList = arrayListOf<StatItemData>()
audioList.add(StatItemViewModel(StatType.CAPTURE)) audioList.add(StatItemData(StatType.CAPTURE))
audioList.add(StatItemViewModel(StatType.PLAYBACK)) audioList.add(StatItemData(StatType.PLAYBACK))
audioList.add(StatItemViewModel(StatType.PAYLOAD)) audioList.add(StatItemData(StatType.PAYLOAD))
audioList.add(StatItemViewModel(StatType.ENCODER)) audioList.add(StatItemData(StatType.ENCODER))
audioList.add(StatItemViewModel(StatType.DECODER)) audioList.add(StatItemData(StatType.DECODER))
audioList.add(StatItemViewModel(StatType.DOWNLOAD_BW)) audioList.add(StatItemData(StatType.DOWNLOAD_BW))
audioList.add(StatItemViewModel(StatType.UPLOAD_BW)) audioList.add(StatItemData(StatType.UPLOAD_BW))
audioList.add(StatItemViewModel(StatType.ICE)) audioList.add(StatItemData(StatType.ICE))
audioList.add(StatItemViewModel(StatType.IP_FAM)) audioList.add(StatItemData(StatType.IP_FAM))
audioList.add(StatItemViewModel(StatType.SENDER_LOSS)) audioList.add(StatItemData(StatType.SENDER_LOSS))
audioList.add(StatItemViewModel(StatType.RECEIVER_LOSS)) audioList.add(StatItemData(StatType.RECEIVER_LOSS))
audioList.add(StatItemViewModel(StatType.JITTER)) audioList.add(StatItemData(StatType.JITTER))
audioStats.value = audioList audioStats.value = audioList
val videoList = arrayListOf<StatItemViewModel>() val videoList = arrayListOf<StatItemData>()
videoList.add(StatItemViewModel(StatType.CAPTURE)) videoList.add(StatItemData(StatType.CAPTURE))
videoList.add(StatItemViewModel(StatType.PLAYBACK)) videoList.add(StatItemData(StatType.PLAYBACK))
videoList.add(StatItemViewModel(StatType.PAYLOAD)) videoList.add(StatItemData(StatType.PAYLOAD))
videoList.add(StatItemViewModel(StatType.ENCODER)) videoList.add(StatItemData(StatType.ENCODER))
videoList.add(StatItemViewModel(StatType.DECODER)) videoList.add(StatItemData(StatType.DECODER))
videoList.add(StatItemViewModel(StatType.DOWNLOAD_BW)) videoList.add(StatItemData(StatType.DOWNLOAD_BW))
videoList.add(StatItemViewModel(StatType.UPLOAD_BW)) videoList.add(StatItemData(StatType.UPLOAD_BW))
videoList.add(StatItemViewModel(StatType.ESTIMATED_AVAILABLE_DOWNLOAD_BW)) videoList.add(StatItemData(StatType.ESTIMATED_AVAILABLE_DOWNLOAD_BW))
videoList.add(StatItemViewModel(StatType.ICE)) videoList.add(StatItemData(StatType.ICE))
videoList.add(StatItemViewModel(StatType.IP_FAM)) videoList.add(StatItemData(StatType.IP_FAM))
videoList.add(StatItemViewModel(StatType.SENDER_LOSS)) videoList.add(StatItemData(StatType.SENDER_LOSS))
videoList.add(StatItemViewModel(StatType.RECEIVER_LOSS)) videoList.add(StatItemData(StatType.RECEIVER_LOSS))
videoList.add(StatItemViewModel(StatType.SENT_RESOLUTION)) videoList.add(StatItemData(StatType.SENT_RESOLUTION))
videoList.add(StatItemViewModel(StatType.RECEIVED_RESOLUTION)) videoList.add(StatItemData(StatType.RECEIVED_RESOLUTION))
videoList.add(StatItemViewModel(StatType.SENT_FPS)) videoList.add(StatItemData(StatType.SENT_FPS))
videoList.add(StatItemViewModel(StatType.RECEIVED_FPS)) videoList.add(StatItemData(StatType.RECEIVED_FPS))
videoStats.value = videoList videoStats.value = videoList
} }

View file

@ -20,7 +20,6 @@
package org.linphone.activities.call.viewmodels package org.linphone.activities.call.viewmodels
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import java.text.DecimalFormat import java.text.DecimalFormat
import org.linphone.R import org.linphone.R
import org.linphone.core.AddressFamily 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) ESTIMATED_AVAILABLE_DOWNLOAD_BW(R.string.call_stats_estimated_download)
} }
class StatItemViewModel(val type: StatType) : ViewModel() { class StatItemData(val type: StatType) {
val value = MutableLiveData<String>() val value = MutableLiveData<String>()
fun update(call: Call, stats: CallStats) { fun update(call: Call, stats: CallStats) {

View file

@ -118,11 +118,15 @@ open class CallViewModel(val call: Call) : GenericContactViewModel(call.remoteAd
} }
override fun onCleared() { override fun onCleared() {
call.removeListener(listener) destroy()
super.onCleared() super.onCleared()
} }
fun destroy() {
// TODO: call it from CallsViewModel (after conference rework merge)
call.removeListener(listener)
}
fun terminateCall() { fun terminateCall() {
coreContext.terminateCall(call) coreContext.terminateCall(call)
} }

View file

@ -22,12 +22,13 @@ package org.linphone.activities.call.viewmodels
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.activities.call.data.CallStatisticsData
import org.linphone.core.Call import org.linphone.core.Call
import org.linphone.core.Core import org.linphone.core.Core
import org.linphone.core.CoreListenerStub import org.linphone.core.CoreListenerStub
class StatisticsListViewModel : ViewModel() { class StatisticsListViewModel : ViewModel() {
val callStatsList = MutableLiveData<ArrayList<CallStatisticsViewModel>>() val callStatsList = MutableLiveData<ArrayList<CallStatisticsData>>()
private val listener = object : CoreListenerStub() { private val listener = object : CoreListenerStub() {
override fun onCallStateChanged( override fun onCallStateChanged(
@ -37,10 +38,12 @@ class StatisticsListViewModel : ViewModel() {
message: String message: String
) { ) {
if (state == Call.State.End || state == Call.State.Error) { if (state == Call.State.End || state == Call.State.Error) {
val newList = arrayListOf<CallStatisticsViewModel>() val newList = arrayListOf<CallStatisticsData>()
for (stat in callStatsList.value.orEmpty()) { for (stat in callStatsList.value.orEmpty()) {
if (stat.call != call) { if (stat.call != call) {
newList.add(stat) newList.add(stat)
} else {
stat.destroy()
} }
} }
callStatsList.value = newList callStatsList.value = newList
@ -51,16 +54,17 @@ class StatisticsListViewModel : ViewModel() {
init { init {
coreContext.core.addListener(listener) coreContext.core.addListener(listener)
val list = arrayListOf<CallStatisticsViewModel>() val list = arrayListOf<CallStatisticsData>()
for (call in coreContext.core.calls) { for (call in coreContext.core.calls) {
if (call.state != Call.State.End && call.state != Call.State.Released && call.state != Call.State.Error) { 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 callStatsList.value = list
} }
override fun onCleared() { override fun onCleared() {
callStatsList.value.orEmpty().forEach(CallStatisticsData::destroy)
coreContext.core.removeListener(listener) coreContext.core.removeListener(listener)
super.onCleared() super.onCleared()

View file

@ -59,8 +59,12 @@ class ContactsListAdapter(
(holder as ViewHolder).bind(getItem(position)) (holder as ViewHolder).bind(getItem(position))
} }
override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
(holder as ViewHolder).binding.viewModel?.destroy()
}
inner class ViewHolder( inner class ViewHolder(
private val binding: ContactListCellBinding val binding: ContactListCellBinding
) : RecyclerView.ViewHolder(binding.root) { ) : RecyclerView.ViewHolder(binding.root) {
fun bind(contact: Contact) { fun bind(contact: Contact) {
with(binding) { with(binding) {

View file

@ -17,13 +17,12 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
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.LinphoneApplication.Companion.corePreferences
import org.linphone.core.Address import org.linphone.core.Address
class ContactNumberOrAddressViewModel( class ContactNumberOrAddressData(
val address: Address?, val address: Address?,
val hasPresence: Boolean, val hasPresence: Boolean,
val displayedValue: String, val displayedValue: String,
@ -31,7 +30,7 @@ class ContactNumberOrAddressViewModel(
val showSecureChat: Boolean = false, val showSecureChat: Boolean = false,
val typeLabel: String = "", val typeLabel: String = "",
private val listener: ContactNumberOrAddressClickListener private val listener: ContactNumberOrAddressClickListener
) : ViewModel() { ) {
val showInvite = !hasPresence && !isSip val showInvite = !hasPresence && !isSip
val chatAllowed = !corePreferences.disableChat val chatAllowed = !corePreferences.disableChat

View file

@ -17,11 +17,11 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.linphone.activities.main.contact.viewmodels package org.linphone.activities.main.contact.data
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
class NumberOrAddressEditorViewModel(val currentValue: String, val isSipAddress: Boolean) { class NumberOrAddressEditorData(val currentValue: String, val isSipAddress: Boolean) {
val newValue = MutableLiveData<String>() val newValue = MutableLiveData<String>()
val toRemove = MutableLiveData<Boolean>() val toRemove = MutableLiveData<Boolean>()

View file

@ -35,6 +35,7 @@ import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R import org.linphone.R
import org.linphone.activities.GenericFragment import org.linphone.activities.GenericFragment
import org.linphone.activities.main.MainActivity 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.contact.viewmodels.*
import org.linphone.activities.main.navigateToContact import org.linphone.activities.main.navigateToContact
import org.linphone.activities.main.viewmodels.SharedMainViewModel import org.linphone.activities.main.viewmodels.SharedMainViewModel
@ -90,10 +91,10 @@ class ContactEditorFragment : GenericFragment<ContactEditorFragmentBinding>(), S
val sipUri = arguments?.getString("SipUri") val sipUri = arguments?.getString("SipUri")
if (sipUri != null) { if (sipUri != null) {
Log.i("[Contact Editor] Found SIP URI in arguments: $sipUri") Log.i("[Contact Editor] Found SIP URI in arguments: $sipUri")
val newSipUri = NumberOrAddressEditorViewModel("", true) val newSipUri = NumberOrAddressEditorData("", true)
newSipUri.newValue.value = sipUri newSipUri.newValue.value = sipUri
val list = arrayListOf<NumberOrAddressEditorViewModel>() val list = arrayListOf<NumberOrAddressEditorData>()
list.addAll(viewModel.addresses.value.orEmpty()) list.addAll(viewModel.addresses.value.orEmpty())
list.add(newSipUri) list.add(newSipUri)
viewModel.addresses.value = list viewModel.addresses.value = list

View file

@ -29,6 +29,7 @@ import java.io.ByteArrayOutputStream
import java.io.IOException import java.io.IOException
import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.activities.main.contact.data.NumberOrAddressEditorData
import org.linphone.contact.* import org.linphone.contact.*
import org.linphone.core.tools.Log import org.linphone.core.tools.Log
import org.linphone.utils.ImageUtils import org.linphone.utils.ImageUtils
@ -60,9 +61,9 @@ class ContactEditorViewModel(val c: Contact?) : ViewModel(), ContactDataInterfac
val tempPicturePath = MutableLiveData<String>() val tempPicturePath = MutableLiveData<String>()
private var picture: ByteArray? = null private var picture: ByteArray? = null
val numbers = MutableLiveData<ArrayList<NumberOrAddressEditorViewModel>>() val numbers = MutableLiveData<ArrayList<NumberOrAddressEditorData>>()
val addresses = MutableLiveData<ArrayList<NumberOrAddressEditorViewModel>>() val addresses = MutableLiveData<ArrayList<NumberOrAddressEditorData>>()
var syncAccountName: String? = null var syncAccountName: String? = null
var syncAccountType: String? = null var syncAccountType: String? = null
@ -177,35 +178,35 @@ class ContactEditorViewModel(val c: Contact?) : ViewModel(), ContactDataInterfac
} }
fun addEmptySipAddress() { fun addEmptySipAddress() {
val list = arrayListOf<NumberOrAddressEditorViewModel>() val list = arrayListOf<NumberOrAddressEditorData>()
list.addAll(addresses.value.orEmpty()) list.addAll(addresses.value.orEmpty())
list.add(NumberOrAddressEditorViewModel("", true)) list.add(NumberOrAddressEditorData("", true))
addresses.value = list addresses.value = list
} }
fun addEmptyPhoneNumber() { fun addEmptyPhoneNumber() {
val list = arrayListOf<NumberOrAddressEditorViewModel>() val list = arrayListOf<NumberOrAddressEditorData>()
list.addAll(numbers.value.orEmpty()) list.addAll(numbers.value.orEmpty())
list.add(NumberOrAddressEditorViewModel("", false)) list.add(NumberOrAddressEditorData("", false))
numbers.value = list numbers.value = list
} }
private fun updateNumbersAndAddresses() { private fun updateNumbersAndAddresses() {
val phoneNumbers = arrayListOf<NumberOrAddressEditorViewModel>() val phoneNumbers = arrayListOf<NumberOrAddressEditorData>()
for (number in c?.rawPhoneNumbers.orEmpty()) { for (number in c?.rawPhoneNumbers.orEmpty()) {
phoneNumbers.add(NumberOrAddressEditorViewModel(number, false)) phoneNumbers.add(NumberOrAddressEditorData(number, false))
} }
if (phoneNumbers.isEmpty()) { if (phoneNumbers.isEmpty()) {
phoneNumbers.add(NumberOrAddressEditorViewModel("", false)) phoneNumbers.add(NumberOrAddressEditorData("", false))
} }
numbers.value = phoneNumbers numbers.value = phoneNumbers
val sipAddresses = arrayListOf<NumberOrAddressEditorViewModel>() val sipAddresses = arrayListOf<NumberOrAddressEditorData>()
for (address in c?.rawSipAddresses.orEmpty()) { for (address in c?.rawSipAddresses.orEmpty()) {
sipAddresses.add(NumberOrAddressEditorViewModel(address, true)) sipAddresses.add(NumberOrAddressEditorData(address, true))
} }
if (sipAddresses.isEmpty()) { if (sipAddresses.isEmpty()) {
sipAddresses.add(NumberOrAddressEditorViewModel("", true)) sipAddresses.add(NumberOrAddressEditorData("", true))
} }
addresses.value = sipAddresses addresses.value = sipAddresses
} }

View file

@ -27,6 +27,8 @@ import androidx.lifecycle.ViewModelProvider
import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R 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.activities.main.viewmodels.ErrorReportingViewModel
import org.linphone.contact.Contact import org.linphone.contact.Contact
import org.linphone.contact.ContactDataInterface import org.linphone.contact.ContactDataInterface
@ -55,7 +57,7 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont
val displayOrganization = corePreferences.displayOrganization val displayOrganization = corePreferences.displayOrganization
val numbersAndAddresses = MutableLiveData<ArrayList<ContactNumberOrAddressViewModel>>() val numbersAndAddresses = MutableLiveData<ArrayList<ContactNumberOrAddressData>>()
val sendSmsToEvent: MutableLiveData<Event<String>> by lazy { val sendSmsToEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>() MutableLiveData<Event<String>>()
@ -129,10 +131,14 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont
} }
override fun onCleared() { override fun onCleared() {
coreContext.contactsManager.removeListener(contactsUpdatedListener) destroy()
super.onCleared() super.onCleared()
} }
fun destroy() {
coreContext.contactsManager.removeListener(contactsUpdatedListener)
}
fun deleteContact() { fun deleteContact() {
val select = ContactsContract.Data.CONTACT_ID + " = ?" val select = ContactsContract.Data.CONTACT_ID + " = ?"
val ops = java.util.ArrayList<ContentProviderOperation>() val ops = java.util.ArrayList<ContentProviderOperation>()
@ -164,7 +170,7 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont
} }
private fun updateNumbersAndAddresses(contact: Contact) { private fun updateNumbersAndAddresses(contact: Contact) {
val list = arrayListOf<ContactNumberOrAddressViewModel>() val list = arrayListOf<ContactNumberOrAddressData>()
for (address in contact.sipAddresses) { for (address in contact.sipAddresses) {
val value = address.asStringUriOnly() val value = address.asStringUriOnly()
val presenceModel = contact.friend?.getPresenceModelForUriOrTel(value) 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 isMe = coreContext.core.defaultAccount?.params?.identityAddress?.weakEqual(address) ?: false
val secureChatAllowed = !isMe && contact.friend?.getPresenceModelForUriOrTel(value)?.hasCapability(FriendCapability.LimeX3Dh) ?: 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 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) list.add(noa)
} }
for (phoneNumber in contact.phoneNumbers) { for (phoneNumber in contact.phoneNumbers) {
@ -183,7 +189,7 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont
val address = coreContext.core.interpretUrl(contactAddress) val address = coreContext.core.interpretUrl(contactAddress)
val isMe = if (address != null) coreContext.core.defaultAccount?.params?.identityAddress?.weakEqual(address) ?: false else false 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 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) list.add(noa)
} }
numbersAndAddresses.value = list numbersAndAddresses.value = list

View file

@ -30,8 +30,8 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import org.linphone.R import org.linphone.R
import org.linphone.activities.main.adapters.SelectionListAdapter 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.CallLogViewModel
import org.linphone.activities.main.history.viewmodels.GroupedCallLogViewModel
import org.linphone.activities.main.viewmodels.ListTopBarViewModel import org.linphone.activities.main.viewmodels.ListTopBarViewModel
import org.linphone.core.Address import org.linphone.core.Address
import org.linphone.databinding.GenericListHeaderBinding import org.linphone.databinding.GenericListHeaderBinding
@ -41,9 +41,9 @@ import org.linphone.utils.*
class CallLogsListAdapter( class CallLogsListAdapter(
selectionVM: ListTopBarViewModel, selectionVM: ListTopBarViewModel,
private val viewLifecycleOwner: LifecycleOwner private val viewLifecycleOwner: LifecycleOwner
) : SelectionListAdapter<GroupedCallLogViewModel, RecyclerView.ViewHolder>(selectionVM, CallLogDiffCallback()), HeaderAdapter { ) : SelectionListAdapter<GroupedCallLogData, RecyclerView.ViewHolder>(selectionVM, CallLogDiffCallback()), HeaderAdapter {
val selectedCallLogEvent: MutableLiveData<Event<GroupedCallLogViewModel>> by lazy { val selectedCallLogEvent: MutableLiveData<Event<GroupedCallLogData>> by lazy {
MutableLiveData<Event<GroupedCallLogViewModel>>() MutableLiveData<Event<GroupedCallLogData>>()
} }
val startCallToEvent: MutableLiveData<Event<Address>> by lazy { val startCallToEvent: MutableLiveData<Event<Address>> by lazy {
@ -62,10 +62,14 @@ class CallLogsListAdapter(
(holder as ViewHolder).bind(getItem(position)) (holder as ViewHolder).bind(getItem(position))
} }
override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
(holder as ViewHolder).binding.viewModel?.destroy()
}
inner class ViewHolder( inner class ViewHolder(
private val binding: HistoryListCellBinding val binding: HistoryListCellBinding
) : RecyclerView.ViewHolder(binding.root) { ) : RecyclerView.ViewHolder(binding.root) {
fun bind(callLogGroup: GroupedCallLogViewModel) { fun bind(callLogGroup: GroupedCallLogData) {
with(binding) { with(binding) {
val callLogViewModel = CallLogViewModel(callLogGroup.lastCallLog) val callLogViewModel = CallLogViewModel(callLogGroup.lastCallLog)
viewModel = callLogViewModel viewModel = callLogViewModel
@ -140,17 +144,17 @@ class CallLogsListAdapter(
} }
} }
private class CallLogDiffCallback : DiffUtil.ItemCallback<GroupedCallLogViewModel>() { private class CallLogDiffCallback : DiffUtil.ItemCallback<GroupedCallLogData>() {
override fun areItemsTheSame( override fun areItemsTheSame(
oldItem: GroupedCallLogViewModel, oldItem: GroupedCallLogData,
newItem: GroupedCallLogViewModel newItem: GroupedCallLogData
): Boolean { ): Boolean {
return oldItem.lastCallLog.callId == newItem.lastCallLog.callId return oldItem.lastCallLog.callId == newItem.lastCallLog.callId
} }
override fun areContentsTheSame( override fun areContentsTheSame(
oldItem: GroupedCallLogViewModel, oldItem: GroupedCallLogData,
newItem: GroupedCallLogViewModel newItem: GroupedCallLogData
): Boolean { ): Boolean {
return false // For headers return false // For headers
} }

View file

@ -17,11 +17,11 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.linphone.activities.main.history.viewmodels package org.linphone.activities.main.history.data
import org.linphone.core.CallLog import org.linphone.core.CallLog
class GroupedCallLogViewModel(callLog: CallLog) { class GroupedCallLogData(callLog: CallLog) {
var lastCallLog: CallLog = callLog var lastCallLog: CallLog = callLog
val callLogs = arrayListOf(callLog) val callLogs = arrayListOf(callLog)
} }

View file

@ -31,8 +31,8 @@ import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R import org.linphone.R
import org.linphone.activities.main.fragments.MasterFragment import org.linphone.activities.main.fragments.MasterFragment
import org.linphone.activities.main.history.adapters.CallLogsListAdapter 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.CallLogsListViewModel
import org.linphone.activities.main.history.viewmodels.GroupedCallLogViewModel
import org.linphone.activities.main.navigateToCallHistory import org.linphone.activities.main.navigateToCallHistory
import org.linphone.activities.main.navigateToDialer import org.linphone.activities.main.navigateToDialer
import org.linphone.activities.main.viewmodels.DialogViewModel import org.linphone.activities.main.viewmodels.DialogViewModel
@ -194,7 +194,7 @@ class MasterCallLogsFragment : MasterFragment<HistoryMasterFragmentBinding, Call
} }
override fun deleteItems(indexesOfItemToDelete: ArrayList<Int>) { override fun deleteItems(indexesOfItemToDelete: ArrayList<Int>) {
val list = ArrayList<GroupedCallLogViewModel>() val list = ArrayList<GroupedCallLogData>()
for (index in indexesOfItemToDelete) { for (index in indexesOfItemToDelete) {
val callLogGroup = adapter.currentList[index] val callLogGroup = adapter.currentList[index]
list.add(callLogGroup) list.add(callLogGroup)

View file

@ -129,6 +129,14 @@ class CallLogViewModel(val callLog: CallLog) : GenericContactViewModel(callLog.r
waitForChatRoomCreation.value = false waitForChatRoomCreation.value = false
} }
override fun onCleared() {
destroy()
super.onCleared()
}
fun destroy() {
}
fun startCall() { fun startCall() {
startCallEvent.value = Event(callLog.remoteAddress) startCallEvent.value = Event(callLog.remoteAddress)
} }

View file

@ -22,6 +22,7 @@ package org.linphone.activities.main.history.viewmodels
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.activities.main.history.data.GroupedCallLogData
import org.linphone.contact.ContactsUpdatedListenerStub import org.linphone.contact.ContactsUpdatedListenerStub
import org.linphone.core.* import org.linphone.core.*
import org.linphone.core.tools.Log import org.linphone.core.tools.Log
@ -30,8 +31,8 @@ import org.linphone.utils.LinphoneUtils
import org.linphone.utils.TimestampUtils import org.linphone.utils.TimestampUtils
class CallLogsListViewModel : ViewModel() { class CallLogsListViewModel : ViewModel() {
val callLogs = MutableLiveData<ArrayList<GroupedCallLogViewModel>>() val callLogs = MutableLiveData<ArrayList<GroupedCallLogData>>()
val missedCallLogs = MutableLiveData<ArrayList<GroupedCallLogViewModel>>() val missedCallLogs = MutableLiveData<ArrayList<GroupedCallLogData>>()
val missedCallLogsSelected = MutableLiveData<Boolean>() val missedCallLogsSelected = MutableLiveData<Boolean>()
@ -72,7 +73,7 @@ class CallLogsListViewModel : ViewModel() {
super.onCleared() super.onCleared()
} }
fun deleteCallLogGroup(callLog: GroupedCallLogViewModel?) { fun deleteCallLogGroup(callLog: GroupedCallLogData?) {
if (callLog != null) { if (callLog != null) {
for (log in callLog.callLogs) { for (log in callLog.callLogs) {
coreContext.core.removeCallLog(log) coreContext.core.removeCallLog(log)
@ -82,7 +83,7 @@ class CallLogsListViewModel : ViewModel() {
updateCallLogs() updateCallLogs()
} }
fun deleteCallLogGroups(listToDelete: ArrayList<GroupedCallLogViewModel>) { fun deleteCallLogGroups(listToDelete: ArrayList<GroupedCallLogData>) {
for (callLog in listToDelete) { for (callLog in listToDelete) {
for (log in callLog.callLogs) { for (log in callLog.callLogs) {
coreContext.core.removeCallLog(log) coreContext.core.removeCallLog(log)
@ -93,41 +94,41 @@ class CallLogsListViewModel : ViewModel() {
} }
private fun updateCallLogs() { private fun updateCallLogs() {
val list = arrayListOf<GroupedCallLogViewModel>() val list = arrayListOf<GroupedCallLogData>()
val missedList = arrayListOf<GroupedCallLogViewModel>() val missedList = arrayListOf<GroupedCallLogData>()
var previousCallLogGroup: GroupedCallLogViewModel? = null var previousCallLogGroup: GroupedCallLogData? = null
var previousMissedCallLogGroup: GroupedCallLogViewModel? = null var previousMissedCallLogGroup: GroupedCallLogData? = null
for (callLog in coreContext.core.callLogs) { for (callLog in coreContext.core.callLogs) {
if (previousCallLogGroup == null) { if (previousCallLogGroup == null) {
previousCallLogGroup = GroupedCallLogViewModel(callLog) previousCallLogGroup = GroupedCallLogData(callLog)
} else if (previousCallLogGroup.lastCallLog.localAddress.weakEqual(callLog.localAddress) && previousCallLogGroup.lastCallLog.remoteAddress.weakEqual(callLog.remoteAddress)) { } else if (previousCallLogGroup.lastCallLog.localAddress.weakEqual(callLog.localAddress) && previousCallLogGroup.lastCallLog.remoteAddress.weakEqual(callLog.remoteAddress)) {
if (TimestampUtils.isSameDay(previousCallLogGroup.lastCallLog.startDate, callLog.startDate)) { if (TimestampUtils.isSameDay(previousCallLogGroup.lastCallLog.startDate, callLog.startDate)) {
previousCallLogGroup.callLogs.add(callLog) previousCallLogGroup.callLogs.add(callLog)
previousCallLogGroup.lastCallLog = callLog previousCallLogGroup.lastCallLog = callLog
} else { } else {
list.add(previousCallLogGroup) list.add(previousCallLogGroup)
previousCallLogGroup = GroupedCallLogViewModel(callLog) previousCallLogGroup = GroupedCallLogData(callLog)
} }
} else { } else {
list.add(previousCallLogGroup) list.add(previousCallLogGroup)
previousCallLogGroup = GroupedCallLogViewModel(callLog) previousCallLogGroup = GroupedCallLogData(callLog)
} }
if (LinphoneUtils.isCallLogMissed(callLog)) { if (LinphoneUtils.isCallLogMissed(callLog)) {
if (previousMissedCallLogGroup == null) { if (previousMissedCallLogGroup == null) {
previousMissedCallLogGroup = GroupedCallLogViewModel(callLog) previousMissedCallLogGroup = GroupedCallLogData(callLog)
} else if (previousMissedCallLogGroup.lastCallLog.localAddress.weakEqual(callLog.localAddress) && previousMissedCallLogGroup.lastCallLog.remoteAddress.weakEqual(callLog.remoteAddress)) { } else if (previousMissedCallLogGroup.lastCallLog.localAddress.weakEqual(callLog.localAddress) && previousMissedCallLogGroup.lastCallLog.remoteAddress.weakEqual(callLog.remoteAddress)) {
if (TimestampUtils.isSameDay(previousMissedCallLogGroup.lastCallLog.startDate, callLog.startDate)) { if (TimestampUtils.isSameDay(previousMissedCallLogGroup.lastCallLog.startDate, callLog.startDate)) {
previousMissedCallLogGroup.callLogs.add(callLog) previousMissedCallLogGroup.callLogs.add(callLog)
previousMissedCallLogGroup.lastCallLog = callLog previousMissedCallLogGroup.lastCallLog = callLog
} else { } else {
missedList.add(previousMissedCallLogGroup) missedList.add(previousMissedCallLogGroup)
previousMissedCallLogGroup = GroupedCallLogViewModel(callLog) previousMissedCallLogGroup = GroupedCallLogData(callLog)
} }
} else { } else {
missedList.add(previousMissedCallLogGroup) missedList.add(previousMissedCallLogGroup)
previousMissedCallLogGroup = GroupedCallLogViewModel(callLog) previousMissedCallLogGroup = GroupedCallLogData(callLog)
} }
} }
} }

View file

@ -31,7 +31,7 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import org.linphone.R import org.linphone.R
import org.linphone.activities.main.adapters.SelectionListAdapter 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.activities.main.viewmodels.ListTopBarViewModel
import org.linphone.databinding.GenericListHeaderBinding import org.linphone.databinding.GenericListHeaderBinding
import org.linphone.databinding.RecordingListCellBinding import org.linphone.databinding.RecordingListCellBinding
@ -40,7 +40,7 @@ import org.linphone.utils.*
class RecordingsListAdapter( class RecordingsListAdapter(
selectionVM: ListTopBarViewModel, selectionVM: ListTopBarViewModel,
private val viewLifecycleOwner: LifecycleOwner private val viewLifecycleOwner: LifecycleOwner
) : SelectionListAdapter<RecordingViewModel, RecyclerView.ViewHolder>(selectionVM, RecordingDiffCallback()), HeaderAdapter { ) : SelectionListAdapter<RecordingData, RecyclerView.ViewHolder>(selectionVM, RecordingDiffCallback()), HeaderAdapter {
val isVideoRecordingPlayingEvent: MutableLiveData<Event<Boolean>> by lazy { val isVideoRecordingPlayingEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>() MutableLiveData<Event<Boolean>>()
} }
@ -63,10 +63,14 @@ class RecordingsListAdapter(
(holder as ViewHolder).bind(getItem(position)) (holder as ViewHolder).bind(getItem(position))
} }
override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
(holder as ViewHolder).binding.viewModel?.destroy()
}
inner class ViewHolder( inner class ViewHolder(
private val binding: RecordingListCellBinding val binding: RecordingListCellBinding
) : RecyclerView.ViewHolder(binding.root) { ) : RecyclerView.ViewHolder(binding.root) {
fun bind(recording: RecordingViewModel) { fun bind(recording: RecordingData) {
with(binding) { with(binding) {
viewModel = recording viewModel = recording
@ -136,17 +140,17 @@ class RecordingsListAdapter(
} }
} }
private class RecordingDiffCallback : DiffUtil.ItemCallback<RecordingViewModel>() { private class RecordingDiffCallback : DiffUtil.ItemCallback<RecordingData>() {
override fun areItemsTheSame( override fun areItemsTheSame(
oldItem: RecordingViewModel, oldItem: RecordingData,
newItem: RecordingViewModel newItem: RecordingData
): Boolean { ): Boolean {
return oldItem.compareTo(newItem) == 0 return oldItem.compareTo(newItem) == 0
} }
override fun areContentsTheSame( override fun areContentsTheSame(
oldItem: RecordingViewModel, oldItem: RecordingData,
newItem: RecordingViewModel newItem: RecordingData
): Boolean { ): Boolean {
return false // for headers return false // for headers
} }

View file

@ -17,21 +17,17 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.linphone.activities.main.recordings.viewmodels package org.linphone.activities.main.recordings.data
import android.graphics.SurfaceTexture import android.graphics.SurfaceTexture
import android.view.TextureView import android.view.TextureView
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import java.text.DateFormat import java.text.DateFormat
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
import java.util.regex.Pattern import java.util.regex.Pattern
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.*
import kotlinx.coroutines.channels.ticker import kotlinx.coroutines.channels.ticker
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.core.AudioDevice import org.linphone.core.AudioDevice
import org.linphone.core.Player import org.linphone.core.Player
@ -39,7 +35,7 @@ import org.linphone.core.PlayerListener
import org.linphone.core.tools.Log import org.linphone.core.tools.Log
import org.linphone.utils.LinphoneUtils import org.linphone.utils.LinphoneUtils
class RecordingViewModel(val path: String) : ViewModel(), Comparable<RecordingViewModel> { class RecordingData(val path: String) : Comparable<RecordingData> {
companion object { companion object {
val RECORD_PATTERN: Pattern = val RECORD_PATTERN: Pattern =
Pattern.compile(".*/(.*)_(\\d{2}-\\d{2}-\\d{4}-\\d{2}-\\d{2}-\\d{2})\\..*") 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<RecordingVi
} }
} }
private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
init { init {
val m = RECORD_PATTERN.matcher(path) val m = RECORD_PATTERN.matcher(path)
if (m.matches() && m.groupCount() >= 2) { if (m.matches() && m.groupCount() >= 2) {
@ -101,17 +99,18 @@ class RecordingViewModel(val path: String) : ViewModel(), Comparable<RecordingVi
initPlayer() initPlayer()
} }
override fun onCleared() { override fun compareTo(other: RecordingData): Int {
tickerChannel.cancel() return -date.compareTo(other.date)
player.setWindowId(null)
if (!isClosed()) player.close()
player.removeListener(listener)
super.onCleared()
} }
override fun compareTo(other: RecordingViewModel): Int { fun destroy() {
return -date.compareTo(other.date) scope.cancel()
tickerChannel.cancel()
player.setWindowId(null)
if (!isClosed()) player.close()
player.removeListener(listener)
} }
fun play() { fun play() {
@ -122,7 +121,7 @@ class RecordingViewModel(val path: String) : ViewModel(), Comparable<RecordingVi
player.start() player.start()
isPlaying.value = true isPlaying.value = true
viewModelScope.launch { scope.launch {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
for (tick in tickerChannel) { for (tick in tickerChannel) {
if (player.state == Player.State.Playing) { if (player.state == Player.State.Playing) {

View file

@ -28,7 +28,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import org.linphone.R import org.linphone.R
import org.linphone.activities.main.fragments.MasterFragment import org.linphone.activities.main.fragments.MasterFragment
import org.linphone.activities.main.recordings.adapters.RecordingsListAdapter import org.linphone.activities.main.recordings.adapters.RecordingsListAdapter
import org.linphone.activities.main.recordings.viewmodels.RecordingViewModel import org.linphone.activities.main.recordings.data.RecordingData
import org.linphone.activities.main.recordings.viewmodels.RecordingsViewModel import org.linphone.activities.main.recordings.viewmodels.RecordingsViewModel
import org.linphone.databinding.RecordingsFragmentBinding import org.linphone.databinding.RecordingsFragmentBinding
import org.linphone.utils.RecyclerViewHeaderDecoration import org.linphone.utils.RecyclerViewHeaderDecoration
@ -104,7 +104,7 @@ class RecordingsFragment : MasterFragment<RecordingsFragmentBinding, RecordingsL
} }
override fun deleteItems(indexesOfItemToDelete: ArrayList<Int>) { override fun deleteItems(indexesOfItemToDelete: ArrayList<Int>) {
val list = ArrayList<RecordingViewModel>() val list = ArrayList<RecordingData>()
for (index in indexesOfItemToDelete) { for (index in indexesOfItemToDelete) {
val recording = adapter.currentList[index] val recording = adapter.currentList[index]
list.add(recording) list.add(recording)

View file

@ -22,11 +22,12 @@ package org.linphone.activities.main.recordings.viewmodels
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
import org.linphone.activities.main.recordings.data.RecordingData
import org.linphone.core.tools.Log import org.linphone.core.tools.Log
import org.linphone.utils.FileUtils import org.linphone.utils.FileUtils
class RecordingsViewModel : ViewModel() { class RecordingsViewModel : ViewModel() {
val recordingsList = MutableLiveData<ArrayList<RecordingViewModel>>() val recordingsList = MutableLiveData<ArrayList<RecordingData>>()
val isVideoVisible = MutableLiveData<Boolean>() val isVideoVisible = MutableLiveData<Boolean>()
@ -35,7 +36,7 @@ class RecordingsViewModel : ViewModel() {
isVideoVisible.value = false isVideoVisible.value = false
} }
fun deleteRecordings(list: ArrayList<RecordingViewModel>) { fun deleteRecordings(list: ArrayList<RecordingData>) {
for (recording in list) { for (recording in list) {
Log.i("[Recordings] Deleting recording ${recording.path}") Log.i("[Recordings] Deleting recording ${recording.path}")
FileUtils.deleteFile(recording.path) FileUtils.deleteFile(recording.path)
@ -44,13 +45,13 @@ class RecordingsViewModel : ViewModel() {
} }
private fun getRecordings() { private fun getRecordings() {
val list = arrayListOf<RecordingViewModel>() val list = arrayListOf<RecordingData>()
for (f in FileUtils.getFileStorageDir().listFiles().orEmpty()) { for (f in FileUtils.getFileStorageDir().listFiles().orEmpty()) {
Log.i("[Recordings] Found file ${f.path}") 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( list.add(
RecordingViewModel( RecordingData(
f.path f.path
) )
) )

View file

@ -372,10 +372,14 @@ class AccountSettingsViewModel(val account: Account) : GenericSettingsViewModel(
} }
override fun onCleared() { override fun onCleared() {
account.removeListener(listener) destroy()
super.onCleared() super.onCleared()
} }
fun destroy() {
account.removeListener(listener)
}
private fun update() { private fun update() {
isDefault.value = core.defaultAccount == account isDefault.value = core.defaultAccount == account
val params = account.params val params = account.params

View file

@ -26,7 +26,7 @@ import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.activities.main.settings.SettingListenerStub import org.linphone.activities.main.settings.SettingListenerStub
class SettingsViewModel : ViewModel() { class SettingsViewModel : ViewModel() {
val tunnelAvailable: Boolean = coreContext.core.tunnelAvailable() private val tunnelAvailable: Boolean = coreContext.core.tunnelAvailable()
val showAccountSettings: Boolean = corePreferences.showAccountSettings val showAccountSettings: Boolean = corePreferences.showAccountSettings
val showTunnelSettings: Boolean = tunnelAvailable && corePreferences.showTunnelSettings val showTunnelSettings: Boolean = tunnelAvailable && corePreferences.showTunnelSettings
@ -68,7 +68,14 @@ class SettingsViewModel : ViewModel() {
updateAccountsList() updateAccountsList()
} }
override fun onCleared() {
accounts.value.orEmpty().forEach(AccountSettingsViewModel::destroy)
super.onCleared()
}
fun updateAccountsList() { fun updateAccountsList() {
accounts.value.orEmpty().forEach(AccountSettingsViewModel::destroy)
val list = arrayListOf<AccountSettingsViewModel>() val list = arrayListOf<AccountSettingsViewModel>()
if (coreContext.core.accountList.isNotEmpty()) { if (coreContext.core.accountList.isNotEmpty()) {
for (account in coreContext.core.accountList) { for (account in coreContext.core.accountList) {
@ -77,6 +84,7 @@ class SettingsViewModel : ViewModel() {
list.add(viewModel) list.add(viewModel)
} }
} }
accounts.value = list accounts.value = list
} }
} }

View file

@ -21,7 +21,7 @@ package org.linphone.activities.main.viewmodels
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel 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.contact.Contact
import org.linphone.core.* import org.linphone.core.*
import org.linphone.utils.Event import org.linphone.utils.Event
@ -31,7 +31,7 @@ class SharedMainViewModel : ViewModel() {
/* Call history */ /* Call history */
val selectedCallLogGroup = MutableLiveData<GroupedCallLogViewModel>() val selectedCallLogGroup = MutableLiveData<GroupedCallLogData>()
/* Chat */ /* Chat */

View file

@ -27,7 +27,7 @@ import android.provider.ContactsContract.CommonDataKinds
import android.provider.ContactsContract.RawContacts import android.provider.ContactsContract.RawContacts
import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R 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.core.tools.Log
import org.linphone.utils.AppUtils import org.linphone.utils.AppUtils
import org.linphone.utils.PermissionHelper import org.linphone.utils.PermissionHelper
@ -170,7 +170,7 @@ class NativeContactEditor(val contact: NativeContact) {
return this return this
} }
fun setPhoneNumbers(value: List<NumberOrAddressEditorViewModel>): NativeContactEditor { fun setPhoneNumbers(value: List<NumberOrAddressEditorData>): NativeContactEditor {
var addCount = 0 var addCount = 0
var removeCount = 0 var removeCount = 0
var editCount = 0 var editCount = 0
@ -205,7 +205,7 @@ class NativeContactEditor(val contact: NativeContact) {
return this return this
} }
fun setSipAddresses(value: List<NumberOrAddressEditorViewModel>): NativeContactEditor { fun setSipAddresses(value: List<NumberOrAddressEditorData>): NativeContactEditor {
var addCount = 0 var addCount = 0
var removeCount = 0 var removeCount = 0
var editCount = 0 var editCount = 0

View file

@ -7,7 +7,7 @@
<import type="android.view.View" /> <import type="android.view.View" />
<variable <variable
name="data" name="data"
type="org.linphone.activities.call.viewmodels.CallStatisticsViewModel" /> type="org.linphone.activities.call.data.CallStatisticsData" />
</data> </data>
<RelativeLayout <RelativeLayout

View file

@ -5,7 +5,7 @@
<import type="android.view.View" /> <import type="android.view.View" />
<variable <variable
name="data" name="data"
type="org.linphone.activities.call.viewmodels.StatItemViewModel" /> type="org.linphone.activities.call.viewmodels.StatItemData" />
</data> </data>
<LinearLayout <LinearLayout

View file

@ -7,7 +7,7 @@
<import type="android.view.View" /> <import type="android.view.View" />
<variable <variable
name="data" name="data"
type="org.linphone.activities.call.viewmodels.CallStatisticsViewModel" /> type="org.linphone.activities.call.data.CallStatisticsData" />
</data> </data>
<LinearLayout <LinearLayout

View file

@ -7,7 +7,7 @@
<import type="android.view.View" /> <import type="android.view.View" />
<variable <variable
name="data" name="data"
type="org.linphone.activities.call.viewmodels.CallStatisticsViewModel" /> type="org.linphone.activities.call.data.CallStatisticsData" />
</data> </data>
<RelativeLayout <RelativeLayout

View file

@ -5,7 +5,7 @@
<import type="android.view.View" /> <import type="android.view.View" />
<variable <variable
name="data" name="data"
type="org.linphone.activities.main.contact.viewmodels.ContactNumberOrAddressViewModel" /> type="org.linphone.activities.main.contact.data.ContactNumberOrAddressData" />
</data> </data>
<LinearLayout <LinearLayout

View file

@ -5,7 +5,7 @@
<import type="android.text.InputType" /> <import type="android.text.InputType" />
<variable <variable
name="data" name="data"
type="org.linphone.activities.main.contact.viewmodels.NumberOrAddressEditorViewModel" /> type="org.linphone.activities.main.contact.data.NumberOrAddressEditorData" />
</data> </data>
<RelativeLayout <RelativeLayout

View file

@ -14,7 +14,7 @@
type="Integer"/> type="Integer"/>
<variable <variable
name="viewModel" name="viewModel"
type="org.linphone.activities.main.recordings.viewmodels.RecordingViewModel" /> type="org.linphone.activities.main.recordings.data.RecordingData" />
<variable <variable
name="selectionListViewModel" name="selectionListViewModel"
type="org.linphone.activities.main.viewmodels.ListTopBarViewModel" /> type="org.linphone.activities.main.viewmodels.ListTopBarViewModel" />