Update local friend & refresh UI after making a change in UI profile

This commit is contained in:
Sylvain Berfini 2023-08-21 10:34:40 +02:00
parent 8b1057b97d
commit cd3a4e0e63
11 changed files with 119 additions and 23 deletions

View file

@ -69,21 +69,17 @@ class ContactsManager {
manager.restartLoader(0, null, ContactLoader()) manager.restartLoader(0, null, ContactLoader())
} }
@UiThread @WorkerThread
fun addListener(listener: ContactsListener) { fun addListener(listener: ContactsListener) {
if (coreContext.isReady()) { if (coreContext.isReady()) {
coreContext.postOnCoreThread { listeners.add(listener)
listeners.add(listener)
}
} }
} }
@UiThread @WorkerThread
fun removeListener(listener: ContactsListener) { fun removeListener(listener: ContactsListener) {
if (coreContext.isReady()) { if (coreContext.isReady()) {
coreContext.postOnCoreThread { listeners.remove(listener)
listeners.remove(listener)
}
} }
} }
@ -124,6 +120,15 @@ class ContactsManager {
) )
localFriends.add(friend) localFriends.add(friend)
} }
notifyLocalContactsUpdated()
}
@WorkerThread
fun notifyLocalContactsUpdated() {
for (listener in listeners) {
listener.onLocalContactsUpdated()
}
} }
@WorkerThread @WorkerThread
@ -149,4 +154,6 @@ class ContactsManager {
interface ContactsListener { interface ContactsListener {
fun onContactsLoaded() fun onContactsLoaded()
fun onLocalContactsUpdated()
} }

View file

@ -66,6 +66,9 @@ class SuggestionsListViewModel : ViewModel() {
MagicSearch.Aggregation.Friend MagicSearch.Aggregation.Friend
) )
} }
@WorkerThread
override fun onLocalContactsUpdated() { }
} }
init { init {

View file

@ -72,6 +72,9 @@ class ContactsListViewModel : ViewModel() {
MagicSearch.Aggregation.Friend MagicSearch.Aggregation.Friend
) )
} }
@WorkerThread
override fun onLocalContactsUpdated() { }
} }
init { init {

View file

@ -19,6 +19,7 @@
*/ */
package org.linphone.ui.main.conversations.viewmodel package org.linphone.ui.main.conversations.viewmodel
import androidx.annotation.WorkerThread
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
@ -49,10 +50,14 @@ class ConversationViewModel : ViewModel() {
val isOneToOne = MutableLiveData<Boolean>() val isOneToOne = MutableLiveData<Boolean>()
private val contactsListener = object : ContactsListener { private val contactsListener = object : ContactsListener {
@WorkerThread
override fun onContactsLoaded() { override fun onContactsLoaded() {
contactLookup() contactLookup()
events.value.orEmpty().forEach(EventLogData::contactLookup) events.value.orEmpty().forEach(EventLogData::contactLookup)
} }
@WorkerThread
override fun onLocalContactsUpdated() { }
} }
private val chatRoomListener = object : ChatRoomListenerStub() { private val chatRoomListener = object : ChatRoomListenerStub() {
@ -84,12 +89,13 @@ class ConversationViewModel : ViewModel() {
} }
init { init {
// Core thread
coreContext.contactsManager.addListener(contactsListener) coreContext.contactsManager.addListener(contactsListener)
} }
override fun onCleared() { override fun onCleared() {
coreContext.contactsManager.removeListener(contactsListener)
coreContext.postOnCoreThread { coreContext.postOnCoreThread {
coreContext.contactsManager.removeListener(contactsListener)
if (::chatRoom.isInitialized) { if (::chatRoom.isInitialized) {
chatRoom.removeListener(chatRoomListener) chatRoom.removeListener(chatRoomListener)
} }

View file

@ -19,6 +19,7 @@
*/ */
package org.linphone.ui.main.conversations.viewmodel package org.linphone.ui.main.conversations.viewmodel
import androidx.annotation.WorkerThread
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import java.util.ArrayList import java.util.ArrayList
@ -39,11 +40,15 @@ class ConversationsListViewModel : ViewModel() {
val notifyItemChangedEvent = MutableLiveData<Event<Int>>() val notifyItemChangedEvent = MutableLiveData<Event<Int>>()
private val contactsListener = object : ContactsListener { private val contactsListener = object : ContactsListener {
@WorkerThread
override fun onContactsLoaded() { override fun onContactsLoaded() {
for (chatRoomData in chatRoomsList.value.orEmpty()) { for (chatRoomData in chatRoomsList.value.orEmpty()) {
chatRoomData.contactLookup() chatRoomData.contactLookup()
} }
} }
@WorkerThread
override fun onLocalContactsUpdated() { }
} }
private val coreListener = object : CoreListenerStub() { private val coreListener = object : CoreListenerStub() {
@ -94,18 +99,17 @@ class ConversationsListViewModel : ViewModel() {
init { init {
coreContext.postOnCoreThread { core -> coreContext.postOnCoreThread { core ->
core.addListener(coreListener) core.addListener(coreListener)
coreContext.contactsManager.addListener(contactsListener)
} }
coreContext.contactsManager.addListener(contactsListener)
coreContext.postOnCoreThread { core -> coreContext.postOnCoreThread { core ->
updateChatRoomsList() updateChatRoomsList()
} }
} }
override fun onCleared() { override fun onCleared() {
coreContext.contactsManager.removeListener(contactsListener)
coreContext.postOnCoreThread { core -> coreContext.postOnCoreThread { core ->
coreContext.contactsManager.removeListener(contactsListener)
core.removeListener(coreListener) core.removeListener(coreListener)
} }
super.onCleared() super.onCleared()

View file

@ -56,24 +56,29 @@ class NewConversationViewModel : ViewModel() {
} }
private val contactsListener = object : ContactsListener { private val contactsListener = object : ContactsListener {
@WorkerThread
override fun onContactsLoaded() { override fun onContactsLoaded() {
applyFilter(filter.value.orEmpty().trim()) applyFilter(filter.value.orEmpty().trim())
} }
@WorkerThread
override fun onLocalContactsUpdated() { }
} }
init { init {
coreContext.postOnCoreThread { coreContext.postOnCoreThread {
magicSearch.addListener(magicSearchListener) magicSearch.addListener(magicSearchListener)
coreContext.contactsManager.addListener(contactsListener)
applyFilter("") applyFilter("")
} }
coreContext.contactsManager.addListener(contactsListener)
} }
override fun onCleared() { override fun onCleared() {
coreContext.postOnCoreThread { coreContext.postOnCoreThread {
coreContext.contactsManager.removeListener(contactsListener)
magicSearch.removeListener(magicSearchListener) magicSearch.removeListener(magicSearchListener)
} }
coreContext.contactsManager.removeListener(contactsListener)
super.onCleared() super.onCleared()
} }

View file

@ -60,6 +60,7 @@ class AccountModel(
init { init {
// Core thread // Core thread
account.addListener(accountListener) account.addListener(accountListener)
isDefault.postValue(coreContext.core.defaultAccount == account) isDefault.postValue(coreContext.core.defaultAccount == account)
friend = coreContext.contactsManager.localFriends.find { friend = coreContext.contactsManager.localFriends.find {

View file

@ -13,6 +13,7 @@ import androidx.navigation.navGraphViewModels
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R import org.linphone.R
import org.linphone.core.tools.Log import org.linphone.core.tools.Log
import org.linphone.databinding.AccountProfileFragmentBinding import org.linphone.databinding.AccountProfileFragmentBinding
@ -93,6 +94,7 @@ class AccountProfileFragment : GenericFragment() {
if (found) { if (found) {
startPostponedEnterTransition() startPostponedEnterTransition()
} else { } else {
Log.e("$TAG Failed to find an account matching this identity address [$identity]")
// TODO Error // TODO Error
goBack() goBack()
} }
@ -103,7 +105,11 @@ class AccountProfileFragment : GenericFragment() {
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
Log.i("$TAG Leaving account profile, saving changes")
viewModel.saveDisplayNameChanges() viewModel.saveDisplayNameChanges()
coreContext.postOnCoreThread {
coreContext.contactsManager.updateLocalContacts()
}
} }
private fun pickImage() { private fun pickImage() {

View file

@ -6,9 +6,14 @@ import androidx.lifecycle.ViewModel
import java.io.File import java.io.File
import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.core.Account import org.linphone.core.Account
import org.linphone.core.tools.Log
import org.linphone.utils.Event import org.linphone.utils.Event
class AccountProfileViewModel : ViewModel() { class AccountProfileViewModel : ViewModel() {
companion object {
const val TAG = "[Account Profile ViewModel]"
}
val picturePath = MutableLiveData<String>() val picturePath = MutableLiveData<String>()
val displayName = MutableLiveData<String>() val displayName = MutableLiveData<String>()
@ -24,6 +29,7 @@ class AccountProfileViewModel : ViewModel() {
it.params.identityAddress?.asStringUriOnly() == identity it.params.identityAddress?.asStringUriOnly() == identity
} }
if (found != null) { if (found != null) {
Log.i("$TAG Found matching local friend [$found]")
account = found account = found
displayName.postValue(account.params.identityAddress?.displayName) displayName.postValue(account.params.identityAddress?.displayName)
@ -50,10 +56,16 @@ class AccountProfileViewModel : ViewModel() {
if (::account.isInitialized) { if (::account.isInitialized) {
val params = account.params val params = account.params
val copy = params.clone() val copy = params.clone()
val address = params.identityAddress val address = params.identityAddress?.clone()
address?.displayName = displayName.value.orEmpty().trim() if (address != null) {
copy.identityAddress = address val newValue = displayName.value.orEmpty().trim()
account.params = copy address.displayName = newValue
copy.identityAddress = address
account.params = copy
Log.i(
"$TAG Updated account [$account] identity address display name [$newValue]"
)
}
} }
} }
} }
@ -73,6 +85,7 @@ class AccountProfileViewModel : ViewModel() {
friend.edit() friend.edit()
friend.photo = path friend.photo = path
friend.done() friend.done()
Log.i("$TAG Updated account [$account] picture path [$path]")
} }
} }
} }

View file

@ -25,14 +25,20 @@ import androidx.annotation.WorkerThread
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.contacts.ContactsListener
import org.linphone.core.Account import org.linphone.core.Account
import org.linphone.core.Core import org.linphone.core.Core
import org.linphone.core.CoreListenerStub import org.linphone.core.CoreListenerStub
import org.linphone.core.RegistrationState import org.linphone.core.RegistrationState
import org.linphone.core.tools.Log
import org.linphone.ui.main.model.AccountModel import org.linphone.ui.main.model.AccountModel
import org.linphone.utils.Event import org.linphone.utils.Event
class DrawerMenuViewModel : ViewModel() { class DrawerMenuViewModel : ViewModel() {
companion object {
const val TAG = "[Drawer Menu ViewModel]"
}
val accounts = MutableLiveData<ArrayList<AccountModel>>() val accounts = MutableLiveData<ArrayList<AccountModel>>()
val startAssistantEvent: MutableLiveData<Event<Boolean>> by lazy { val startAssistantEvent: MutableLiveData<Event<Boolean>> by lazy {
@ -59,8 +65,20 @@ class DrawerMenuViewModel : ViewModel() {
} }
} }
private val localContactListener = object : ContactsListener {
@WorkerThread
override fun onContactsLoaded() {}
@WorkerThread
override fun onLocalContactsUpdated() {
Log.i("$TAG Local contact have been updated")
computeAccountsList()
}
}
init { init {
coreContext.postOnCoreThread { core -> coreContext.postOnCoreThread { core ->
coreContext.contactsManager.addListener(localContactListener)
core.addListener(coreListener) core.addListener(coreListener)
computeAccountsList() computeAccountsList()
} }
@ -72,6 +90,7 @@ class DrawerMenuViewModel : ViewModel() {
coreContext.postOnCoreThread { core -> coreContext.postOnCoreThread { core ->
core.removeListener(coreListener) core.removeListener(coreListener)
coreContext.contactsManager.removeListener(localContactListener)
} }
} }
@ -87,6 +106,7 @@ class DrawerMenuViewModel : ViewModel() {
@WorkerThread @WorkerThread
private fun computeAccountsList() { private fun computeAccountsList() {
Log.i("$TAG Updating accounts list")
accounts.value.orEmpty().forEach(AccountModel::destroy) accounts.value.orEmpty().forEach(AccountModel::destroy)
val list = arrayListOf<AccountModel>() val list = arrayListOf<AccountModel>()

View file

@ -20,13 +20,20 @@
package org.linphone.ui.main.viewmodel package org.linphone.ui.main.viewmodel
import androidx.annotation.UiThread import androidx.annotation.UiThread
import androidx.annotation.WorkerThread
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.contacts.ContactsListener
import org.linphone.core.tools.Log
import org.linphone.ui.main.model.AccountModel import org.linphone.ui.main.model.AccountModel
import org.linphone.utils.Event import org.linphone.utils.Event
class TopBarViewModel : ViewModel() { class TopBarViewModel : ViewModel() {
companion object {
const val TAG = "[Top Bar ViewModel]"
}
val title = MutableLiveData<String>() val title = MutableLiveData<String>()
val account = MutableLiveData<AccountModel>() val account = MutableLiveData<AccountModel>()
@ -43,14 +50,23 @@ class TopBarViewModel : ViewModel() {
MutableLiveData<Event<Boolean>>() MutableLiveData<Event<Boolean>>()
} }
private val localContactListener = object : ContactsListener {
@WorkerThread
override fun onContactsLoaded() {}
@WorkerThread
override fun onLocalContactsUpdated() {
Log.i("$TAG Local contact have been updated")
updateDefaultAccount()
}
}
init { init {
searchBarVisible.value = false searchBarVisible.value = false
coreContext.postOnCoreThread { core -> coreContext.postOnCoreThread {
if (core.accountList.isNotEmpty()) { coreContext.contactsManager.addListener(localContactListener)
val defaultAccount = core.defaultAccount ?: core.accountList.first() updateDefaultAccount()
account.postValue(AccountModel(defaultAccount))
}
} }
} }
@ -59,6 +75,7 @@ class TopBarViewModel : ViewModel() {
super.onCleared() super.onCleared()
coreContext.postOnCoreThread { coreContext.postOnCoreThread {
coreContext.contactsManager.removeListener(localContactListener)
account.value?.destroy() account.value?.destroy()
} }
} }
@ -85,4 +102,15 @@ class TopBarViewModel : ViewModel() {
fun clearFilter() { fun clearFilter() {
searchFilter.value = "" searchFilter.value = ""
} }
@WorkerThread
private fun updateDefaultAccount() {
Log.i("$TAG Updating displayed default account")
val core = coreContext.core
if (core.accountList.isNotEmpty()) {
val defaultAccount = core.defaultAccount ?: core.accountList.first()
account.postValue(AccountModel(defaultAccount))
}
}
} }