Only fetch vcards contacts when displaying contacts view or doing swipe refresh on it

This commit is contained in:
Christophe Deschamps 2024-12-04 08:48:16 +01:00
parent ab4e5068af
commit 1ee6f6b2ef
8 changed files with 90 additions and 4 deletions

View file

@ -36,6 +36,7 @@ enable_basic_to_client_group_chat_room_migration=0
enable_simple_group_chat_message_state=0
aggregate_imdn=1
notify_each_friend_individually_when_presence_received=0
fetch_contacts_vcard_list_at_startup=0
[app]
activation_code_length=4

View file

@ -335,6 +335,26 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
requestPermissions(arrayOf(android.Manifest.permission.READ_CONTACTS), 0)
}
}
listViewModel.vcardsFetchSuccesfull.observe(viewLifecycleOwner) { success ->
binding.swiperefresh.isRefreshing = false
if (!success) {
val activity = requireActivity() as MainActivity
activity.showSnackBar(R.string.vcard_sync_failed)
} else {
listViewModel.updateContactsList(true)
}
}
binding.swiperefresh.setOnRefreshListener {
if (!coreContext.core.isNetworkReachable) {
binding.swiperefresh.isRefreshing = false
val activity = requireActivity() as MainActivity
activity.showSnackBar(R.string.call_error_network_unreachable)
} else {
listViewModel.refreshVCards()
}
}
}
override fun deleteItems(indexesOfItemToDelete: ArrayList<Int>) {
@ -362,6 +382,7 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
override fun onResume() {
super.onResume()
listViewModel.refreshVCards()
listViewModel.updateContactsList(true)
}

View file

@ -57,6 +57,24 @@ class ContactsListViewModel : ViewModel() {
MutableLiveData<Event<Boolean>>()
}
var vcardsFetchInProgress = MutableLiveData<Boolean>()
var vcardsFetchSuccesfull = MutableLiveData<Boolean>()
val friendListListener: FriendListListenerStub = object : FriendListListenerStub() {
override fun onSyncStatusChanged(
friendList: FriendList,
status: FriendList.SyncStatus?,
message: String?
) {
if (status == FriendList.SyncStatus.Successful || status == FriendList.SyncStatus.Failure) {
vcardsFetchSuccesfull.value = status == FriendList.SyncStatus.Successful
vcardsFetchInProgress.value = false
friendList.removeListener(this)
coreContext.contactsManager.prepareVCardContacts()
}
}
}
private val contactsUpdatedListener = object : ContactsUpdatedListenerStub() {
override fun onContactsUpdated() {
Log.i("[Contacts] Contacts have changed")
@ -126,6 +144,7 @@ class ContactsListViewModel : ViewModel() {
Log.i(
"[Contacts] Asking Magic search for contacts matching filter [$filterValue], domain [$domain] and in sources [$sources]"
)
coreContext.contactsManager.prepareVCardContacts()
coreContext.contactsManager.magicSearch.getContactsListAsync(
filterValue,
domain,
@ -229,4 +248,14 @@ class ContactsListViewModel : ViewModel() {
}
}
}
fun refreshVCards() {
corePreferences.contactsVCardList?.also { contactsVcardListName ->
coreContext.core.getFriendListByName(contactsVcardListName)?.also { contactsVcardList ->
contactsVcardList.addListener(friendListListener)
vcardsFetchInProgress.value = true
contactsVcardList.synchronizeFriendsFromServer()
}
}
}
}

View file

@ -379,6 +379,29 @@ class ContactsManager(private val context: Context) {
return friend
}
fun prepareVCardContacts() {
coreContext.core.friendsLists.forEach { list ->
if (list.displayName == coreContext.core.config?.getString(
"misc",
"contacts-vcard-list",
"no-contacts-vcard-list"
)
) {
coreContext.core.defaultAccount?.params?.domain?.also { domain ->
list.friends.forEach { friend ->
if (friend.address == null && friend.phoneNumbers.size > 0) {
friend.phoneNumbers.first()?.also { phoneNumber ->
Factory.instance()
.createAddress("sip:" + phoneNumber + "@" + domain)?.also {
friend.setAddress(it)
}
}
}
}
}
}
}
}
}
fun Friend.getContactForPhoneNumberOrAddress(value: String): String? {

View file

@ -97,6 +97,7 @@ open class ContactsSelectionViewModel : MessageNotifierViewModel() {
val domain = if (sipContactsSelected.value == true) coreContext.core.defaultAccount?.params?.domain ?: "" else ""
searchResultsPending = true
fastFetchJob?.cancel()
coreContext.contactsManager.prepareVCardContacts()
coreContext.contactsManager.magicSearch.getContactsListAsync(
filterValue,
domain,

View file

@ -239,6 +239,9 @@ class CorePreferences constructor(private val context: Context) {
/* Contacts */
val contactsVCardList: String?
get() = config.getString("misc", "contacts-vcard-list", null)
var storePresenceInNativeContact: Boolean
get() = config.getBool("app", "store_presence_in_native_contact", false)
set(value) {

View file

@ -156,12 +156,19 @@
android:layout_below="@id/searchBar"
android:background="?attr/dividerColor" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/contactsList"
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swiperefresh"
android:layout_below="@id/searchBar"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/contactsList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<RelativeLayout
android:layout_width="match_parent"
@ -188,7 +195,7 @@
<include
layout="@layout/wait_layout"
app:visibility="@{viewModel.fetchInProgress}"/>
app:visibility="@{viewModel.fetchInProgress || viewModel.vcardsFetchInProgress}"/>
</RelativeLayout>

View file

@ -117,6 +117,7 @@
<string name="contact_cant_be_deleted">This contact can\'t be deleted</string>
<string name="contacts_ldap_query_more_results_available">More results are available, refine your search</string>
<string name="contacts_new_contact_wont_be_visible_warning_dialog">You are about to create a new contact without a SIP URI nor a phone number, thus it won\'t be visible in &appName;.\n\nDo you want to create it anyway?</string>
<string name="vcard_sync_failed">an error occured fetching vcard contacts.</string>
<!-- Dialer -->
<string name="dialer_address_bar_hint">Enter a number or an address</string>