Same rework applied to other classes
This commit is contained in:
parent
1eabce5220
commit
b1ee757c0b
30 changed files with 197 additions and 149 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
|
@ -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>()
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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" />
|
||||||
|
|
Loading…
Reference in a new issue