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
* 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 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<ArrayList<StatItemViewModel>>()
class CallStatisticsData(val call: Call) : GenericContactData(call.remoteAddress) {
val audioStats = MutableLiveData<ArrayList<StatItemData>>()
val videoStats = MutableLiveData<ArrayList<StatItemViewModel>>()
val videoStats = MutableLiveData<ArrayList<StatItemData>>()
val isVideoEnabled = MutableLiveData<Boolean>()
@ -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<StatItemViewModel>()
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<StatItemData>()
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<StatItemViewModel>()
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<StatItemData>()
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
}

View file

@ -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<String>()
fun update(call: Call, stats: CallStats) {

View file

@ -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)
}

View file

@ -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<ArrayList<CallStatisticsViewModel>>()
val callStatsList = MutableLiveData<ArrayList<CallStatisticsData>>()
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<CallStatisticsViewModel>()
val newList = arrayListOf<CallStatisticsData>()
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<CallStatisticsViewModel>()
val list = arrayListOf<CallStatisticsData>()
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()

View file

@ -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) {

View file

@ -17,13 +17,12 @@
* You should have received a copy of the GNU General Public License
* 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.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

View file

@ -17,11 +17,11 @@
* You should have received a copy of the GNU General Public License
* 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
class NumberOrAddressEditorViewModel(val currentValue: String, val isSipAddress: Boolean) {
class NumberOrAddressEditorData(val currentValue: String, val isSipAddress: Boolean) {
val newValue = MutableLiveData<String>()
val toRemove = MutableLiveData<Boolean>()

View file

@ -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<ContactEditorFragmentBinding>(), 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<NumberOrAddressEditorViewModel>()
val list = arrayListOf<NumberOrAddressEditorData>()
list.addAll(viewModel.addresses.value.orEmpty())
list.add(newSipUri)
viewModel.addresses.value = list

View file

@ -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<String>()
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 syncAccountType: String? = null
@ -177,35 +178,35 @@ class ContactEditorViewModel(val c: Contact?) : ViewModel(), ContactDataInterfac
}
fun addEmptySipAddress() {
val list = arrayListOf<NumberOrAddressEditorViewModel>()
val list = arrayListOf<NumberOrAddressEditorData>()
list.addAll(addresses.value.orEmpty())
list.add(NumberOrAddressEditorViewModel("", true))
list.add(NumberOrAddressEditorData("", true))
addresses.value = list
}
fun addEmptyPhoneNumber() {
val list = arrayListOf<NumberOrAddressEditorViewModel>()
val list = arrayListOf<NumberOrAddressEditorData>()
list.addAll(numbers.value.orEmpty())
list.add(NumberOrAddressEditorViewModel("", false))
list.add(NumberOrAddressEditorData("", false))
numbers.value = list
}
private fun updateNumbersAndAddresses() {
val phoneNumbers = arrayListOf<NumberOrAddressEditorViewModel>()
val phoneNumbers = arrayListOf<NumberOrAddressEditorData>()
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<NumberOrAddressEditorViewModel>()
val sipAddresses = arrayListOf<NumberOrAddressEditorData>()
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
}

View file

@ -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<ArrayList<ContactNumberOrAddressViewModel>>()
val numbersAndAddresses = MutableLiveData<ArrayList<ContactNumberOrAddressData>>()
val sendSmsToEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>()
@ -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<ContentProviderOperation>()
@ -164,7 +170,7 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont
}
private fun updateNumbersAndAddresses(contact: Contact) {
val list = arrayListOf<ContactNumberOrAddressViewModel>()
val list = arrayListOf<ContactNumberOrAddressData>()
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

View file

@ -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<GroupedCallLogViewModel, RecyclerView.ViewHolder>(selectionVM, CallLogDiffCallback()), HeaderAdapter {
val selectedCallLogEvent: MutableLiveData<Event<GroupedCallLogViewModel>> by lazy {
MutableLiveData<Event<GroupedCallLogViewModel>>()
) : SelectionListAdapter<GroupedCallLogData, RecyclerView.ViewHolder>(selectionVM, CallLogDiffCallback()), HeaderAdapter {
val selectedCallLogEvent: MutableLiveData<Event<GroupedCallLogData>> by lazy {
MutableLiveData<Event<GroupedCallLogData>>()
}
val startCallToEvent: MutableLiveData<Event<Address>> 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<GroupedCallLogViewModel>() {
private class CallLogDiffCallback : DiffUtil.ItemCallback<GroupedCallLogData>() {
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
}

View file

@ -17,11 +17,11 @@
* You should have received a copy of the GNU General Public License
* 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
class GroupedCallLogViewModel(callLog: CallLog) {
class GroupedCallLogData(callLog: CallLog) {
var lastCallLog: CallLog = callLog
val callLogs = arrayListOf(callLog)
}

View file

@ -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<HistoryMasterFragmentBinding, Call
}
override fun deleteItems(indexesOfItemToDelete: ArrayList<Int>) {
val list = ArrayList<GroupedCallLogViewModel>()
val list = ArrayList<GroupedCallLogData>()
for (index in indexesOfItemToDelete) {
val callLogGroup = adapter.currentList[index]
list.add(callLogGroup)

View file

@ -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)
}

View file

@ -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<ArrayList<GroupedCallLogViewModel>>()
val missedCallLogs = MutableLiveData<ArrayList<GroupedCallLogViewModel>>()
val callLogs = MutableLiveData<ArrayList<GroupedCallLogData>>()
val missedCallLogs = MutableLiveData<ArrayList<GroupedCallLogData>>()
val missedCallLogsSelected = MutableLiveData<Boolean>()
@ -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<GroupedCallLogViewModel>) {
fun deleteCallLogGroups(listToDelete: ArrayList<GroupedCallLogData>) {
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<GroupedCallLogViewModel>()
val missedList = arrayListOf<GroupedCallLogViewModel>()
val list = arrayListOf<GroupedCallLogData>()
val missedList = arrayListOf<GroupedCallLogData>()
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)
}
}
}

View file

@ -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<RecordingViewModel, RecyclerView.ViewHolder>(selectionVM, RecordingDiffCallback()), HeaderAdapter {
) : SelectionListAdapter<RecordingData, RecyclerView.ViewHolder>(selectionVM, RecordingDiffCallback()), HeaderAdapter {
val isVideoRecordingPlayingEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}
@ -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<RecordingViewModel>() {
private class RecordingDiffCallback : DiffUtil.ItemCallback<RecordingData>() {
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
}

View file

@ -17,21 +17,17 @@
* You should have received a copy of the GNU General Public License
* 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.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<RecordingViewModel> {
class RecordingData(val path: String) : Comparable<RecordingData> {
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<RecordingVi
}
}
private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
init {
val m = RECORD_PATTERN.matcher(path)
if (m.matches() && m.groupCount() >= 2) {
@ -101,17 +99,18 @@ class RecordingViewModel(val path: String) : ViewModel(), Comparable<RecordingVi
initPlayer()
}
override fun onCleared() {
tickerChannel.cancel()
player.setWindowId(null)
if (!isClosed()) player.close()
player.removeListener(listener)
super.onCleared()
override fun compareTo(other: RecordingData): Int {
return -date.compareTo(other.date)
}
override fun compareTo(other: RecordingViewModel): Int {
return -date.compareTo(other.date)
fun destroy() {
scope.cancel()
tickerChannel.cancel()
player.setWindowId(null)
if (!isClosed()) player.close()
player.removeListener(listener)
}
fun play() {
@ -122,7 +121,7 @@ class RecordingViewModel(val path: String) : ViewModel(), Comparable<RecordingVi
player.start()
isPlaying.value = true
viewModelScope.launch {
scope.launch {
withContext(Dispatchers.IO) {
for (tick in tickerChannel) {
if (player.state == Player.State.Playing) {

View file

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

View file

@ -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<ArrayList<RecordingViewModel>>()
val recordingsList = MutableLiveData<ArrayList<RecordingData>>()
val isVideoVisible = MutableLiveData<Boolean>()
@ -35,7 +36,7 @@ class RecordingsViewModel : ViewModel() {
isVideoVisible.value = false
}
fun deleteRecordings(list: ArrayList<RecordingViewModel>) {
fun deleteRecordings(list: ArrayList<RecordingData>) {
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<RecordingViewModel>()
val list = arrayListOf<RecordingData>()
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
)
)

View file

@ -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

View file

@ -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<AccountSettingsViewModel>()
if (coreContext.core.accountList.isNotEmpty()) {
for (account in coreContext.core.accountList) {
@ -77,6 +84,7 @@ class SettingsViewModel : ViewModel() {
list.add(viewModel)
}
}
accounts.value = list
}
}

View file

@ -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<GroupedCallLogViewModel>()
val selectedCallLogGroup = MutableLiveData<GroupedCallLogData>()
/* Chat */

View file

@ -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<NumberOrAddressEditorViewModel>): NativeContactEditor {
fun setPhoneNumbers(value: List<NumberOrAddressEditorData>): 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<NumberOrAddressEditorViewModel>): NativeContactEditor {
fun setSipAddresses(value: List<NumberOrAddressEditorData>): NativeContactEditor {
var addCount = 0
var removeCount = 0
var editCount = 0

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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