Improved local friends / avatars / etc...

This commit is contained in:
Sylvain Berfini 2023-08-22 10:04:04 +02:00
parent ce2a9b0bde
commit 9e259f02d8
14 changed files with 37 additions and 152 deletions

View file

@ -30,15 +30,12 @@ import org.linphone.core.FriendList
import org.linphone.core.FriendListListenerStub
import org.linphone.core.tools.Log
import org.linphone.ui.main.MainActivity
import org.linphone.utils.LinphoneUtils
class ContactsManager {
companion object {
const val TAG = "[Contacts Manager]"
}
val localFriends = arrayListOf<Friend>()
private val listeners = arrayListOf<ContactsListener>()
private val friendListListener: FriendListListenerStub = object : FriendListListenerStub() {
@ -86,7 +83,6 @@ class ContactsManager {
@UiThread
fun onContactsLoaded() {
coreContext.postOnCoreThread {
updateLocalContacts()
notifyContactsListChanged()
}
}
@ -103,35 +99,6 @@ class ContactsManager {
return coreContext.core.defaultFriendList?.findFriendByRefKey(id)
}
@WorkerThread
fun updateLocalContacts() {
Log.i("$TAG Updating local contact(s)")
localFriends.clear()
for (account in coreContext.core.accountList) {
val friend = coreContext.core.createFriend()
friend.name = LinphoneUtils.getDisplayName(account.params.identityAddress)
val address = account.params.identityAddress ?: continue
friend.address = address
friend.photo = "file:/storage/emulated/0/Android/data/org.linphone/files/Pictures/john.jpg" // TODO REMOVE
Log.i(
"$TAG Local contact created for account [${address.asString()}] and picture [${friend.photo}]"
)
localFriends.add(friend)
}
notifyLocalContactsUpdated()
}
@WorkerThread
fun notifyLocalContactsUpdated() {
for (listener in listeners) {
listener.onLocalContactsUpdated()
}
}
@WorkerThread
fun onCoreStarted() {
val core = coreContext.core
@ -139,8 +106,6 @@ class ContactsManager {
for (list in core.friendsLists) {
list.addListener(friendListListener)
}
updateLocalContacts()
}
@WorkerThread
@ -155,6 +120,4 @@ class ContactsManager {
interface ContactsListener {
fun onContactsLoaded()
fun onLocalContactsUpdated()
}

View file

@ -71,7 +71,6 @@ class AssistantViewModel : ViewModel() {
// Set new account as default
core.defaultAccount = newlyCreatedAccount
coreContext.contactsManager.updateLocalContacts()
accountLoggedInEvent.postValue(Event(true))
} else if (state == RegistrationState.Failed) {
registrationInProgress.postValue(false)

View file

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

View file

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

View file

@ -55,9 +55,6 @@ class ConversationViewModel : ViewModel() {
contactLookup()
events.value.orEmpty().forEach(EventLogData::contactLookup)
}
@WorkerThread
override fun onLocalContactsUpdated() { }
}
private val chatRoomListener = object : ChatRoomListenerStub() {

View file

@ -46,9 +46,6 @@ class ConversationsListViewModel : ViewModel() {
chatRoomData.contactLookup()
}
}
@WorkerThread
override fun onLocalContactsUpdated() { }
}
private val coreListener = object : CoreListenerStub() {

View file

@ -60,9 +60,6 @@ class NewConversationViewModel : ViewModel() {
override fun onContactsLoaded() {
applyFilter(filter.value.orEmpty().trim())
}
@WorkerThread
override fun onLocalContactsUpdated() { }
}
init {

View file

@ -26,17 +26,17 @@ import androidx.lifecycle.MutableLiveData
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.core.Account
import org.linphone.core.AccountListenerStub
import org.linphone.core.Friend
import org.linphone.core.RegistrationState
import org.linphone.ui.main.contacts.model.ContactAvatarModel
import org.linphone.utils.FileUtils
import org.linphone.utils.LinphoneUtils
class AccountModel(
private val account: Account,
private val onMenuClicked: ((view: View, account: Account) -> Unit)? = null
) {
val friend: Friend?
val displayName = MutableLiveData<String>()
val contact = MutableLiveData<ContactAvatarModel>()
val avatar = MutableLiveData<String>()
val registrationState = MutableLiveData<String>()
@ -53,7 +53,7 @@ class AccountModel(
state: RegistrationState?,
message: String
) {
updateRegistrationState()
update()
}
}
@ -61,19 +61,9 @@ class AccountModel(
// Core thread
account.addListener(accountListener)
isDefault.postValue(coreContext.core.defaultAccount == account)
avatar.postValue(account.getPicturePath())
friend = coreContext.contactsManager.localFriends.find {
it.addresses.find { address ->
address.weakEqual(account.params.identityAddress!!)
} != null
}
if (friend != null) {
contact.postValue(ContactAvatarModel(friend))
}
updateRegistrationState()
update()
}
@WorkerThread
@ -102,7 +92,11 @@ class AccountModel(
}
@WorkerThread
private fun updateRegistrationState() {
private fun update() {
displayName.postValue(LinphoneUtils.getDisplayName(account.params.identityAddress))
isDefault.postValue(coreContext.core.defaultAccount == account)
val state = when (account.state) {
RegistrationState.None, RegistrationState.Cleared -> "Disabled"
RegistrationState.Progress -> "Connection..."
@ -111,8 +105,18 @@ class AccountModel(
RegistrationState.Refreshing -> "Refreshing"
else -> "${account.state}"
}
isConnected.postValue(account.state == RegistrationState.Ok)
inError.postValue(account.state == RegistrationState.Failed)
registrationState.postValue(state)
}
}
fun Account.getPicturePath(): String {
// TODO FIXME: get image path from account
return FileUtils.getFileStoragePath(
"john.jpg",
isImage = true,
overrideExisting = true
).absolutePath
}

View file

@ -13,7 +13,6 @@ import androidx.navigation.navGraphViewModels
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.AccountProfileFragmentBinding
@ -37,9 +36,9 @@ class AccountProfileFragment : GenericFragment() {
private val pickMedia = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
if (uri != null) {
val identity = "john" // TODO FIXME
val identity = "john" // TODO FIXME: use account identity
val localFileName = FileUtils.getFileStoragePath(
"$identity.jpg",
"$identity.jpg", // TODO FIXME: use correct file extension
isImage = true,
overrideExisting = true
)
@ -102,7 +101,7 @@ class AccountProfileFragment : GenericFragment() {
Log.e(
"$TAG Failed to find an account matching this identity address [$identity]"
)
// TODO Error
// TODO: show error
goBack()
}
}
@ -114,9 +113,6 @@ class AccountProfileFragment : GenericFragment() {
Log.i("$TAG Leaving account profile, saving changes")
viewModel.saveDisplayNameChanges()
coreContext.postOnCoreThread {
coreContext.contactsManager.updateLocalContacts()
}
}
private fun pickImage() {

View file

@ -7,6 +7,7 @@ import java.io.File
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.core.Account
import org.linphone.core.tools.Log
import org.linphone.ui.main.model.getPicturePath
import org.linphone.utils.Event
import org.linphone.utils.FileUtils
@ -33,17 +34,8 @@ class AccountProfileViewModel : ViewModel() {
Log.i("$TAG Found matching local friend [$found]")
account = found
displayName.postValue(account.params.identityAddress?.displayName)
picturePath.postValue(account.getPicturePath())
val friend = coreContext.contactsManager.localFriends.find {
it.addresses.find { address ->
address.asStringUriOnly() == identity
} != null
}
if (friend != null) {
picturePath.postValue(friend.photo)
} else {
// TODO
}
accountFoundEvent.postValue(Event(true))
} else {
accountFoundEvent.postValue(Event(false))
@ -62,6 +54,8 @@ class AccountProfileViewModel : ViewModel() {
val newValue = displayName.value.orEmpty().trim()
address.displayName = newValue
copy.identityAddress = address
// This will trigger a REGISTER, so account display name will be updated by
// CoreListener.onAccountRegistrationStateChanged everywhere in the app
account.params = copy
Log.i(
"$TAG Updated account [$account] identity address display name [$newValue]"
@ -78,18 +72,7 @@ class AccountProfileViewModel : ViewModel() {
coreContext.postOnCoreThread {
if (::account.isInitialized) {
val friend = coreContext.contactsManager.localFriends.find {
it.addresses.find { address ->
address.asStringUriOnly() == account.params.identityAddress?.asStringUriOnly()
} != null
}
if (friend != null) {
// TODO FIXME: photo must be set on Account not Friend, Friend will be re-created from Account right after this
friend.edit()
friend.photo = path
friend.done()
Log.i("$TAG Updated account [$account] picture path [$path]")
}
// TODO: save image path in account
}
}
}

View file

@ -25,11 +25,7 @@ import androidx.annotation.WorkerThread
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.contacts.ContactsListener
import org.linphone.core.Account
import org.linphone.core.Core
import org.linphone.core.CoreListenerStub
import org.linphone.core.RegistrationState
import org.linphone.core.tools.Log
import org.linphone.ui.main.model.AccountModel
import org.linphone.utils.Event
@ -53,33 +49,9 @@ class DrawerMenuViewModel : ViewModel() {
MutableLiveData<Event<Pair<View, Account>>>()
}
private val coreListener = object : CoreListenerStub() {
@WorkerThread
override fun onAccountRegistrationStateChanged(
core: Core,
account: Account,
state: RegistrationState?,
message: String
) {
computeAccountsList()
}
}
private val localContactListener = object : ContactsListener {
@WorkerThread
override fun onContactsLoaded() {}
@WorkerThread
override fun onLocalContactsUpdated() {
Log.i("$TAG Local contact have been updated")
computeAccountsList()
}
}
init {
coreContext.postOnCoreThread { core ->
coreContext.contactsManager.addListener(localContactListener)
core.addListener(coreListener)
// TODO FIXME: update accounts list when a new account is added or when removing one
coreContext.postOnCoreThread {
computeAccountsList()
}
}
@ -87,11 +59,6 @@ class DrawerMenuViewModel : ViewModel() {
@UiThread
override fun onCleared() {
super.onCleared()
coreContext.postOnCoreThread { core ->
core.removeListener(coreListener)
coreContext.contactsManager.removeListener(localContactListener)
}
}
@UiThread

View file

@ -24,7 +24,6 @@ import androidx.annotation.WorkerThread
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
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.utils.Event
@ -50,22 +49,12 @@ class TopBarViewModel : ViewModel() {
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 {
searchBarVisible.value = false
// TODO FIXME: update default account displayed here when uses clicks on another account
coreContext.postOnCoreThread {
coreContext.contactsManager.addListener(localContactListener)
updateDefaultAccount()
}
}
@ -75,7 +64,6 @@ class TopBarViewModel : ViewModel() {
super.onCleared()
coreContext.postOnCoreThread {
coreContext.contactsManager.removeListener(localContactListener)
account.value?.destroy()
}
}

View file

@ -33,7 +33,7 @@
android:layout_marginBottom="5dp"
android:adjustViewBounds="true"
android:background="@drawable/shape_button_round"
contactAvatar="@{model.contact}"
coil="@{model.avatar}"
app:avatarViewPlaceholder="@drawable/contact_avatar"
app:avatarViewInitialsBackgroundColor="@color/blue_outgoing_message"
app:avatarViewInitialsTextColor="@color/gray_9"
@ -57,7 +57,7 @@
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:text="@{model.contact.name, default=`John Doe`}"
android:text="@{model.displayName, default=`John Doe`}"
android:textSize="14sp"
android:textColor="@color/gray_8"
android:layout_marginStart="10dp"

View file

@ -41,7 +41,7 @@
android:layout_height="@dimen/avatar_list_cell_size"
android:layout_marginStart="15dp"
android:background="@drawable/shape_button_round"
contactAvatar="@{viewModel.account.contact}"
coil="@{viewModel.account.avatar}"
app:avatarViewBorderColor="@color/trusted_blue"
app:avatarViewBorderWidth="2dp"
app:avatarViewIndicatorSizeCriteria="3"