Added LDAP settings, using MagicSearch in contacts list + updated CHANGELOG from 4.6.2 release
This commit is contained in:
parent
e34965d524
commit
62e2fb580f
20 changed files with 993 additions and 34 deletions
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -10,10 +10,18 @@ Group changes to describe their impact on the project, as follows:
|
|||
Fixed for any bug fixes.
|
||||
Security to invite users to upgrade in case of vulnerabilities.
|
||||
|
||||
|
||||
## [4.7.0] - Unreleased
|
||||
|
||||
## [4.6.2] - Unreleased
|
||||
### Added
|
||||
-
|
||||
|
||||
### Changed
|
||||
-
|
||||
|
||||
### Fixed
|
||||
-
|
||||
|
||||
## [4.6.2] - 2022-03-01
|
||||
|
||||
### Added
|
||||
- Request BLUETOOTH_CONNECT permission on Android 12+ devices, if not we won't be notified when a BT device is being connected/disconnected while app is alive.
|
||||
|
@ -23,13 +31,15 @@ Group changes to describe their impact on the project, as follows:
|
|||
- Prevent screen to turn off while recording a voice message
|
||||
|
||||
### Changed
|
||||
- Contacts lists now show LDAP contacts if any, as well as "generated" contacts from SIP addresses you have interacted with
|
||||
- Contacts lists now show LDAP contacts if any
|
||||
|
||||
### Fixed
|
||||
- Negative gain in audio settings is allowed again
|
||||
- STUN server URL setting not enabling it for non sip.linphone.org accounts
|
||||
- Contacts list header case comparison
|
||||
- Stop voice recording playback when sending chat message
|
||||
- Call activity not finishing when hanging up sometimes
|
||||
- Auto start setting disabled not working if background mode setting was enabled
|
||||
|
||||
## [4.6.1] - 2022-02-14
|
||||
|
||||
|
|
|
@ -866,6 +866,17 @@ internal fun navigateToEmptySetting(navController: NavController) {
|
|||
)
|
||||
}
|
||||
|
||||
internal fun ContactsSettingsFragment.navigateToLdapSettings(configIndex: Int) {
|
||||
if (findNavController().currentDestination?.id == R.id.contactsSettingsFragment) {
|
||||
val bundle = bundleOf("LdapConfigIndex" to configIndex)
|
||||
findNavController().navigate(
|
||||
R.id.action_contactsSettingsFragment_to_ldapSettingsFragment,
|
||||
bundle,
|
||||
popupTo()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun AccountSettingsFragment.navigateToEmptySetting() {
|
||||
navigateToEmptySetting(findNavController())
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import com.google.android.material.transition.MaterialSharedAxis
|
|||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.LinphoneApplication.Companion.corePreferences
|
||||
import org.linphone.R
|
||||
import org.linphone.activities.SnackBarActivity
|
||||
import org.linphone.activities.clearDisplayedContact
|
||||
import org.linphone.activities.main.MainActivity
|
||||
import org.linphone.activities.main.contact.adapters.ContactsListAdapter
|
||||
|
@ -172,6 +173,14 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
|
|||
val viewModel = DialogViewModel(getString(R.string.contact_delete_one_dialog))
|
||||
val dialog: Dialog = DialogUtils.getDialog(requireContext(), viewModel)
|
||||
|
||||
val contactViewModel = adapter.currentList[viewHolder.bindingAdapterPosition]
|
||||
if (contactViewModel.isNativeContact.value == false) {
|
||||
adapter.notifyItemChanged(viewHolder.bindingAdapterPosition)
|
||||
val activity = requireActivity() as MainActivity
|
||||
activity.showSnackBar(R.string.contact_cant_be_deleted)
|
||||
return
|
||||
}
|
||||
|
||||
viewModel.showCancelButton {
|
||||
adapter.notifyItemChanged(viewHolder.bindingAdapterPosition)
|
||||
dialog.dismiss()
|
||||
|
@ -211,6 +220,7 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
|
|||
it.consume { contact ->
|
||||
Log.i("[Contacts] Selected item in list changed: $contact")
|
||||
sharedViewModel.selectedContact.value = contact
|
||||
(requireActivity() as MainActivity).hideKeyboard()
|
||||
|
||||
if (editOnClick) {
|
||||
navigateToContactEditor(sipUriToAdd, binding.slidingPane)
|
||||
|
@ -237,6 +247,14 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
|
|||
adapter.submitList(it)
|
||||
}
|
||||
|
||||
listViewModel.moreResultsAvailableEvent.observe(
|
||||
viewLifecycleOwner
|
||||
) {
|
||||
it.consume {
|
||||
(requireActivity() as SnackBarActivity).showSnackBar(R.string.contacts_ldap_query_more_results_available)
|
||||
}
|
||||
}
|
||||
|
||||
binding.setAllContactsToggleClickListener {
|
||||
listViewModel.sipContactsSelected.value = false
|
||||
}
|
||||
|
@ -247,13 +265,13 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
|
|||
listViewModel.sipContactsSelected.observe(
|
||||
viewLifecycleOwner
|
||||
) {
|
||||
listViewModel.updateContactsList()
|
||||
listViewModel.updateContactsList(true)
|
||||
}
|
||||
|
||||
listViewModel.filter.observe(
|
||||
viewLifecycleOwner
|
||||
) {
|
||||
listViewModel.updateContactsList()
|
||||
listViewModel.updateContactsList(false)
|
||||
}
|
||||
|
||||
binding.setNewContactClickListener {
|
||||
|
|
|
@ -74,6 +74,8 @@ class ContactViewModel(val contactInternal: Contact) : MessageNotifierViewModel(
|
|||
|
||||
val waitForChatRoomCreation = MutableLiveData<Boolean>()
|
||||
|
||||
val isNativeContact = MutableLiveData<Boolean>()
|
||||
|
||||
private val contactsUpdatedListener = object : ContactsUpdatedListenerStub() {
|
||||
override fun onContactUpdated(contact: Contact) {
|
||||
if (contact is NativeContact && contactInternal is NativeContact && contact.nativeId == contactInternal.nativeId) {
|
||||
|
@ -127,6 +129,7 @@ class ContactViewModel(val contactInternal: Contact) : MessageNotifierViewModel(
|
|||
init {
|
||||
contact.value = contactInternal
|
||||
displayName.value = contactInternal.fullName ?: contactInternal.firstName + " " + contactInternal.lastName
|
||||
isNativeContact.value = contactInternal is NativeContact
|
||||
|
||||
updateNumbersAndAddresses(contactInternal)
|
||||
coreContext.contactsManager.addListener(contactsUpdatedListener)
|
||||
|
@ -172,7 +175,7 @@ class ContactViewModel(val contactInternal: Contact) : MessageNotifierViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
private fun updateNumbersAndAddresses(contact: Contact) {
|
||||
fun updateNumbersAndAddresses(contact: Contact) {
|
||||
val list = arrayListOf<ContactNumberOrAddressData>()
|
||||
for (address in contact.sipAddresses) {
|
||||
val value = address.asStringUriOnly()
|
||||
|
|
|
@ -23,61 +23,125 @@ import android.content.ContentProviderOperation
|
|||
import android.provider.ContactsContract
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import java.util.*
|
||||
import kotlinx.coroutines.*
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.contact.Contact
|
||||
import org.linphone.contact.ContactsUpdatedListenerStub
|
||||
import org.linphone.contact.NativeContact
|
||||
import org.linphone.core.*
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.utils.Event
|
||||
|
||||
class ContactsListViewModel : ViewModel() {
|
||||
val sipContactsSelected = MutableLiveData<Boolean>()
|
||||
|
||||
val contactsList = MutableLiveData<ArrayList<ContactViewModel>>()
|
||||
|
||||
val fetchInProgress = MutableLiveData<Boolean>()
|
||||
private var searchResultsPending: Boolean = false
|
||||
private var fastFetchJob: Job? = null
|
||||
|
||||
val filter = MutableLiveData<String>()
|
||||
private var previousFilter = "NotSet"
|
||||
|
||||
val moreResultsAvailableEvent: MutableLiveData<Event<Boolean>> by lazy {
|
||||
MutableLiveData<Event<Boolean>>()
|
||||
}
|
||||
|
||||
private val contactsUpdatedListener = object : ContactsUpdatedListenerStub() {
|
||||
override fun onContactsUpdated() {
|
||||
Log.i("[Contacts] Contacts have changed")
|
||||
updateContactsList()
|
||||
updateContactsList(true)
|
||||
}
|
||||
}
|
||||
|
||||
private val magicSearchListener = object : MagicSearchListenerStub() {
|
||||
override fun onSearchResultsReceived(magicSearch: MagicSearch) {
|
||||
searchResultsPending = false
|
||||
processMagicSearchResults(magicSearch.lastSearch)
|
||||
fetchInProgress.value = false
|
||||
}
|
||||
|
||||
override fun onLdapHaveMoreResults(magicSearch: MagicSearch, ldap: Ldap) {
|
||||
moreResultsAvailableEvent.value = Event(true)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
sipContactsSelected.value = coreContext.contactsManager.shouldDisplaySipContactsList()
|
||||
fetchInProgress.value = false
|
||||
|
||||
coreContext.contactsManager.addListener(contactsUpdatedListener)
|
||||
coreContext.contactsManager.magicSearch.addListener(magicSearchListener)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
contactsList.value.orEmpty().forEach(ContactViewModel::destroy)
|
||||
coreContext.contactsManager.magicSearch.removeListener(magicSearchListener)
|
||||
coreContext.contactsManager.removeListener(contactsUpdatedListener)
|
||||
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
private fun getSelectedContactsList(): ArrayList<ContactViewModel> {
|
||||
val list = arrayListOf<ContactViewModel>()
|
||||
val source =
|
||||
if (sipContactsSelected.value == true) coreContext.contactsManager.sipContacts
|
||||
else coreContext.contactsManager.contacts
|
||||
for (contact in source) {
|
||||
list.add(ContactViewModel(contact))
|
||||
fun updateContactsList(clearCache: Boolean) {
|
||||
val filterValue = filter.value.orEmpty()
|
||||
contactsList.value.orEmpty().forEach(ContactViewModel::destroy)
|
||||
|
||||
if (clearCache || (
|
||||
previousFilter.isNotEmpty() && (
|
||||
previousFilter.length > filterValue.length ||
|
||||
(previousFilter.length == filterValue.length && previousFilter != filterValue)
|
||||
)
|
||||
)
|
||||
) {
|
||||
coreContext.contactsManager.magicSearch.resetSearchCache()
|
||||
}
|
||||
previousFilter = filterValue
|
||||
|
||||
val domain = if (sipContactsSelected.value == true) coreContext.core.defaultAccount?.params?.domain ?: "" else ""
|
||||
val filter = MagicSearchSource.Friends.toInt() or MagicSearchSource.LdapServers.toInt()
|
||||
searchResultsPending = true
|
||||
fastFetchJob?.cancel()
|
||||
coreContext.contactsManager.magicSearch.getContactsAsync(filterValue, domain, filter)
|
||||
|
||||
fastFetchJob = viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
delay(200)
|
||||
withContext(Dispatchers.Main) {
|
||||
if (searchResultsPending) {
|
||||
fetchInProgress.value = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
fun updateContactsList() {
|
||||
val list: ArrayList<ContactViewModel>
|
||||
|
||||
val filterValue = filter.value.orEmpty()
|
||||
list = if (filterValue.isNotEmpty()) {
|
||||
getSelectedContactsList().filter { contact ->
|
||||
contact.name.contains(filterValue, true)
|
||||
} as ArrayList<ContactViewModel>
|
||||
} else {
|
||||
getSelectedContactsList()
|
||||
private fun processMagicSearchResults(results: Array<SearchResult>) {
|
||||
val list = arrayListOf<ContactViewModel>()
|
||||
for (result in results) {
|
||||
val contact = searchMatchingContact(result) ?: Contact(searchResult = result)
|
||||
if (contact is NativeContact) {
|
||||
val found = list.find { contactViewModel ->
|
||||
contactViewModel.contactInternal is NativeContact && contactViewModel.contactInternal.nativeId == contact.nativeId
|
||||
}
|
||||
if (found != null) {
|
||||
Log.d("[Contacts] Found a search result that matches a native contact [$contact] we already have, skipping")
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
val found = list.find { contactViewModel ->
|
||||
contactViewModel.displayName.value == contact.fullName
|
||||
}
|
||||
if (found != null) {
|
||||
Log.i("[Contacts] Found a search result that matches a contact [$contact] we already have, updating it with the new information")
|
||||
found.contactInternal.addAddressAndPhoneNumberFromSearchResult(result)
|
||||
found.updateNumbersAndAddresses(found.contactInternal)
|
||||
continue
|
||||
}
|
||||
}
|
||||
list.add(ContactViewModel(contact))
|
||||
}
|
||||
|
||||
contactsList.postValue(list)
|
||||
|
@ -146,4 +210,19 @@ class ContactsListViewModel : ViewModel() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun searchMatchingContact(searchResult: SearchResult): Contact? {
|
||||
val address = searchResult.address
|
||||
|
||||
if (address != null) {
|
||||
val contact = coreContext.contactsManager.findContactByAddress(address, ignoreLocalContact = true)
|
||||
if (contact != null) return contact
|
||||
}
|
||||
|
||||
if (searchResult.phoneNumber != null) {
|
||||
return coreContext.contactsManager.findContactByPhoneNumber(searchResult.phoneNumber.orEmpty())
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,10 @@ import androidx.lifecycle.ViewModelProvider
|
|||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.LinphoneApplication.Companion.corePreferences
|
||||
import org.linphone.R
|
||||
import org.linphone.activities.main.settings.SettingListenerStub
|
||||
import org.linphone.activities.main.settings.viewmodels.ContactsSettingsViewModel
|
||||
import org.linphone.activities.navigateToEmptySetting
|
||||
import org.linphone.activities.navigateToLdapSettings
|
||||
import org.linphone.compatibility.Compatibility
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.databinding.SettingsContactsFragmentBinding
|
||||
|
@ -74,6 +76,22 @@ class ContactsSettingsFragment : GenericSettingFragment<SettingsContactsFragment
|
|||
}
|
||||
}
|
||||
|
||||
viewModel.ldapNewSettingsListener = object : SettingListenerStub() {
|
||||
override fun onClicked() {
|
||||
Log.i("[Contacts Settings] Clicked on new LDAP config")
|
||||
navigateToLdapSettings(-1)
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.ldapSettingsClickedEvent.observe(
|
||||
viewLifecycleOwner
|
||||
) {
|
||||
it.consume { index ->
|
||||
Log.i("[Contacts Settings] Clicked on LDAP config with index: $index")
|
||||
navigateToLdapSettings(index)
|
||||
}
|
||||
}
|
||||
|
||||
if (!PermissionHelper.required(requireContext()).hasReadContactsPermission()) {
|
||||
Log.i("[Contacts Settings] Asking for READ_CONTACTS permission")
|
||||
requestPermissions(arrayOf(android.Manifest.permission.READ_CONTACTS), 0)
|
||||
|
@ -117,4 +135,9 @@ class ContactsSettingsFragment : GenericSettingFragment<SettingsContactsFragment
|
|||
navigateToEmptySetting()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
viewModel.updateLdapConfigurationsList()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2022 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-android
|
||||
* (see https://www.linphone.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.linphone.activities.main.settings.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import org.linphone.R
|
||||
import org.linphone.activities.main.settings.viewmodels.LdapSettingsViewModel
|
||||
import org.linphone.activities.main.settings.viewmodels.LdapSettingsViewModelFactory
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.databinding.SettingsLdapFragmentBinding
|
||||
|
||||
class LdapSettingsFragment : GenericSettingFragment<SettingsLdapFragmentBinding>() {
|
||||
private lateinit var viewModel: LdapSettingsViewModel
|
||||
|
||||
override fun getLayoutId(): Int = R.layout.settings_ldap_fragment
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.lifecycleOwner = viewLifecycleOwner
|
||||
binding.sharedMainViewModel = sharedViewModel
|
||||
|
||||
val configIndex = arguments?.getInt("LdapConfigIndex")
|
||||
if (configIndex == null) {
|
||||
Log.e("[LDAP Settings] Config index not specified!")
|
||||
goBack()
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
viewModel = ViewModelProvider(this, LdapSettingsViewModelFactory(configIndex))[LdapSettingsViewModel::class.java]
|
||||
} catch (nsee: NoSuchElementException) {
|
||||
Log.e("[LDAP Settings] Failed to find LDAP object, aborting!")
|
||||
goBack()
|
||||
return
|
||||
}
|
||||
binding.viewModel = viewModel
|
||||
|
||||
viewModel.ldapConfigDeletedEvent.observe(
|
||||
viewLifecycleOwner
|
||||
) {
|
||||
it.consume {
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
|
||||
binding.setBackClickListener { goBack() }
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
package org.linphone.activities.main.settings.viewmodels
|
||||
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.activities.main.settings.SettingListenerStub
|
||||
import org.linphone.utils.Event
|
||||
import org.linphone.utils.PermissionHelper
|
||||
|
@ -76,6 +77,20 @@ class ContactsSettingsViewModel : GenericSettingsViewModel() {
|
|||
val launcherShortcuts = MutableLiveData<Boolean>()
|
||||
val launcherShortcutsEvent = MutableLiveData<Event<Boolean>>()
|
||||
|
||||
val ldapAvailable = MutableLiveData<Boolean>()
|
||||
|
||||
val ldapConfigurations = MutableLiveData<ArrayList<LdapSettingsViewModel>>()
|
||||
|
||||
lateinit var ldapNewSettingsListener: SettingListenerStub
|
||||
val ldapSettingsClickedEvent: MutableLiveData<Event<Int>> by lazy {
|
||||
MutableLiveData<Event<Int>>()
|
||||
}
|
||||
private var ldapSettingsListener = object : SettingListenerStub() {
|
||||
override fun onAccountClicked(identity: String) {
|
||||
ldapSettingsClickedEvent.value = Event(identity.toInt())
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
readContactsPermissionGranted.value = PermissionHelper.get().hasReadContactsPermission()
|
||||
|
||||
|
@ -84,5 +99,23 @@ class ContactsSettingsViewModel : GenericSettingsViewModel() {
|
|||
nativePresence.value = prefs.storePresenceInNativeContact
|
||||
showOrganization.value = prefs.displayOrganization
|
||||
launcherShortcuts.value = prefs.contactsShortcuts
|
||||
|
||||
ldapAvailable.value = core.ldapAvailable()
|
||||
ldapConfigurations.value = arrayListOf()
|
||||
|
||||
updateLdapConfigurationsList()
|
||||
}
|
||||
|
||||
fun updateLdapConfigurationsList() {
|
||||
val list = arrayListOf<LdapSettingsViewModel>()
|
||||
var index = 0
|
||||
for (ldap in coreContext.core.ldapList) {
|
||||
val viewModel = LdapSettingsViewModel(ldap, index.toString())
|
||||
viewModel.ldapSettingsListener = ldapSettingsListener
|
||||
list.add(viewModel)
|
||||
index += 1
|
||||
}
|
||||
|
||||
ldapConfigurations.value = list
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,296 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2022 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-android
|
||||
* (see https://www.linphone.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.linphone.activities.main.settings.viewmodels
|
||||
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import java.lang.NumberFormatException
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.R
|
||||
import org.linphone.activities.main.settings.SettingListenerStub
|
||||
import org.linphone.core.Ldap
|
||||
import org.linphone.core.LdapAuthMethod
|
||||
import org.linphone.core.LdapCertVerificationMode
|
||||
import org.linphone.core.LdapDebugLevel
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.utils.Event
|
||||
|
||||
class LdapSettingsViewModelFactory(private val index: Int) :
|
||||
ViewModelProvider.NewInstanceFactory() {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
if (index >= 0 && index <= coreContext.core.ldapList.size) {
|
||||
val ldap = coreContext.core.ldapList[index]
|
||||
return LdapSettingsViewModel(ldap, index.toString()) as T
|
||||
}
|
||||
|
||||
val ldapParams = coreContext.core.createLdapParams()
|
||||
val ldap = coreContext.core.createLdapWithParams(ldapParams)
|
||||
return LdapSettingsViewModel(ldap, "-1") as T
|
||||
}
|
||||
}
|
||||
|
||||
class LdapSettingsViewModel(private val ldap: Ldap, val index: String) : GenericSettingsViewModel() {
|
||||
lateinit var ldapSettingsListener: SettingListenerStub
|
||||
|
||||
val ldapConfigDeletedEvent: MutableLiveData<Event<Boolean>> by lazy {
|
||||
MutableLiveData<Event<Boolean>>()
|
||||
}
|
||||
|
||||
val ldapEnableListener = object : SettingListenerStub() {
|
||||
override fun onBoolValueChanged(newValue: Boolean) {
|
||||
val params = ldap.params.clone()
|
||||
params.enabled = newValue
|
||||
ldap.params = params
|
||||
}
|
||||
}
|
||||
val ldapEnable = MutableLiveData<Boolean>()
|
||||
|
||||
val deleteListener = object : SettingListenerStub() {
|
||||
override fun onClicked() {
|
||||
coreContext.core.removeLdap(ldap)
|
||||
ldapConfigDeletedEvent.value = Event(true)
|
||||
}
|
||||
}
|
||||
|
||||
val ldapServerListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
val params = ldap.params.clone()
|
||||
params.server = newValue
|
||||
ldap.params = params
|
||||
}
|
||||
}
|
||||
val ldapServer = MutableLiveData<String>()
|
||||
|
||||
val ldapBindDnListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
val params = ldap.params.clone()
|
||||
params.bindDn = newValue
|
||||
ldap.params = params
|
||||
}
|
||||
}
|
||||
val ldapBindDn = MutableLiveData<String>()
|
||||
|
||||
val ldapPasswordListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
val params = ldap.params.clone()
|
||||
params.password = newValue
|
||||
ldap.params = params
|
||||
}
|
||||
}
|
||||
val ldapPassword = MutableLiveData<String>()
|
||||
|
||||
val ldapAuthMethodListener = object : SettingListenerStub() {
|
||||
override fun onListValueChanged(position: Int) {
|
||||
val params = ldap.params.clone()
|
||||
params.authMethod = LdapAuthMethod.fromInt(ldapAuthMethodValues[position])
|
||||
ldap.params = params
|
||||
ldapAuthMethodIndex.value = position
|
||||
}
|
||||
}
|
||||
val ldapAuthMethodIndex = MutableLiveData<Int>()
|
||||
val ldapAuthMethodLabels = MutableLiveData<ArrayList<String>>()
|
||||
private val ldapAuthMethodValues = arrayListOf<Int>()
|
||||
|
||||
val ldapTlsListener = object : SettingListenerStub() {
|
||||
override fun onBoolValueChanged(newValue: Boolean) {
|
||||
val params = ldap.params.clone()
|
||||
params.isTlsEnabled = newValue
|
||||
ldap.params = params
|
||||
}
|
||||
}
|
||||
val ldapTls = MutableLiveData<Boolean>()
|
||||
|
||||
val ldapCertCheckListener = object : SettingListenerStub() {
|
||||
override fun onListValueChanged(position: Int) {
|
||||
val params = ldap.params.clone()
|
||||
params.serverCertificatesVerificationMode = LdapCertVerificationMode.fromInt(ldapCertCheckValues[position])
|
||||
ldap.params = params
|
||||
ldapCertCheckIndex.value = position
|
||||
}
|
||||
}
|
||||
val ldapCertCheckIndex = MutableLiveData<Int>()
|
||||
val ldapCertCheckLabels = MutableLiveData<ArrayList<String>>()
|
||||
private val ldapCertCheckValues = arrayListOf<Int>()
|
||||
|
||||
val ldapSearchBaseListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
val params = ldap.params.clone()
|
||||
params.baseObject = newValue
|
||||
ldap.params = params
|
||||
}
|
||||
}
|
||||
val ldapSearchBase = MutableLiveData<String>()
|
||||
|
||||
val ldapSearchFilterListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
val params = ldap.params.clone()
|
||||
params.filter = newValue
|
||||
ldap.params = params
|
||||
}
|
||||
}
|
||||
val ldapSearchFilter = MutableLiveData<String>()
|
||||
|
||||
val ldapSearchMaxResultsListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
try {
|
||||
val intValue = newValue.toInt()
|
||||
val params = ldap.params.clone()
|
||||
params.maxResults = intValue
|
||||
ldap.params = params
|
||||
} catch (nfe: NumberFormatException) {
|
||||
Log.e("[LDAP Settings] Failed to set max results ($newValue): $nfe")
|
||||
}
|
||||
}
|
||||
}
|
||||
val ldapSearchMaxResults = MutableLiveData<Int>()
|
||||
|
||||
val ldapSearchTimeoutListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
try {
|
||||
val intValue = newValue.toInt()
|
||||
val params = ldap.params.clone()
|
||||
params.timeout = intValue
|
||||
ldap.params = params
|
||||
} catch (nfe: NumberFormatException) {
|
||||
Log.e("[LDAP Settings] Failed to set timeout ($newValue): $nfe")
|
||||
}
|
||||
}
|
||||
}
|
||||
val ldapSearchTimeout = MutableLiveData<Int>()
|
||||
|
||||
val ldapRequestDelayListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
try {
|
||||
val intValue = newValue.toInt()
|
||||
val params = ldap.params.clone()
|
||||
params.delay = intValue
|
||||
ldap.params = params
|
||||
} catch (nfe: NumberFormatException) {
|
||||
Log.e("[LDAP Settings] Failed to set request delay ($newValue): $nfe")
|
||||
}
|
||||
}
|
||||
}
|
||||
val ldapRequestDelay = MutableLiveData<Int>()
|
||||
|
||||
val ldapMinimumCharactersListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
try {
|
||||
val intValue = newValue.toInt()
|
||||
val params = ldap.params.clone()
|
||||
params.minChars = intValue
|
||||
ldap.params = params
|
||||
} catch (nfe: NumberFormatException) {
|
||||
Log.e("[LDAP Settings] Failed to set minimum characters ($newValue): $nfe")
|
||||
}
|
||||
}
|
||||
}
|
||||
val ldapMinimumCharacters = MutableLiveData<Int>()
|
||||
|
||||
val ldapNameAttributeListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
val params = ldap.params.clone()
|
||||
params.nameAttribute = newValue
|
||||
ldap.params = params
|
||||
}
|
||||
}
|
||||
val ldapNameAttribute = MutableLiveData<String>()
|
||||
|
||||
val ldapSipAttributeListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
val params = ldap.params.clone()
|
||||
params.sipAttribute = newValue
|
||||
ldap.params = params
|
||||
}
|
||||
}
|
||||
val ldapSipAttribute = MutableLiveData<String>()
|
||||
|
||||
val ldapSipDomainListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
val params = ldap.params.clone()
|
||||
params.sipDomain = newValue
|
||||
ldap.params = params
|
||||
}
|
||||
}
|
||||
val ldapSipDomain = MutableLiveData<String>()
|
||||
|
||||
val ldapDebugListener = object : SettingListenerStub() {
|
||||
override fun onBoolValueChanged(newValue: Boolean) {
|
||||
val params = ldap.params.clone()
|
||||
params.debugLevel = if (newValue) LdapDebugLevel.Verbose else LdapDebugLevel.Off
|
||||
ldap.params = params
|
||||
}
|
||||
}
|
||||
val ldapDebug = MutableLiveData<Boolean>()
|
||||
|
||||
init {
|
||||
val params = ldap.params
|
||||
|
||||
ldapEnable.value = params.enabled
|
||||
ldapServer.value = params.server
|
||||
ldapBindDn.value = params.bindDn
|
||||
ldapPassword.value = params.password
|
||||
ldapTls.value = params.isTlsEnabled
|
||||
ldapSearchBase.value = params.baseObject
|
||||
ldapSearchFilter.value = params.filter
|
||||
ldapSearchMaxResults.value = params.maxResults
|
||||
ldapSearchTimeout.value = params.timeout
|
||||
ldapRequestDelay.value = params.delay
|
||||
ldapMinimumCharacters.value = params.minChars
|
||||
ldapNameAttribute.value = params.nameAttribute
|
||||
ldapSipAttribute.value = params.sipAttribute
|
||||
ldapSipDomain.value = params.sipDomain
|
||||
ldapDebug.value = params.debugLevel == LdapDebugLevel.Verbose
|
||||
|
||||
initAuthMethodList()
|
||||
initTlsCertCheckList()
|
||||
}
|
||||
|
||||
private fun initAuthMethodList() {
|
||||
val labels = arrayListOf<String>()
|
||||
|
||||
labels.add(prefs.getString(R.string.contacts_settings_ldap_auth_method_anonymous))
|
||||
ldapAuthMethodValues.add(LdapAuthMethod.Anonymous.toInt())
|
||||
|
||||
labels.add(prefs.getString(R.string.contacts_settings_ldap_auth_method_simple))
|
||||
ldapAuthMethodValues.add(LdapAuthMethod.Simple.toInt())
|
||||
|
||||
ldapAuthMethodLabels.value = labels
|
||||
ldapAuthMethodIndex.value = ldapAuthMethodValues.indexOf(ldap.params.authMethod.toInt())
|
||||
}
|
||||
|
||||
private fun initTlsCertCheckList() {
|
||||
val labels = arrayListOf<String>()
|
||||
|
||||
labels.add(prefs.getString(R.string.contacts_settings_ldap_cert_check_auto))
|
||||
ldapCertCheckValues.add(LdapCertVerificationMode.Default.toInt())
|
||||
|
||||
labels.add(prefs.getString(R.string.contacts_settings_ldap_cert_check_disabled))
|
||||
ldapCertCheckValues.add(LdapCertVerificationMode.Disabled.toInt())
|
||||
|
||||
labels.add(prefs.getString(R.string.contacts_settings_ldap_cert_check_enabled))
|
||||
ldapCertCheckValues.add(LdapCertVerificationMode.Enabled.toInt())
|
||||
|
||||
ldapCertCheckLabels.value = labels
|
||||
ldapCertCheckIndex.value = ldapCertCheckValues.indexOf(ldap.params.serverCertificatesVerificationMode.toInt())
|
||||
}
|
||||
}
|
|
@ -29,8 +29,10 @@ import org.linphone.R
|
|||
import org.linphone.core.Address
|
||||
import org.linphone.core.Friend
|
||||
import org.linphone.core.PresenceBasicStatus
|
||||
import org.linphone.core.SearchResult
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.utils.ImageUtils
|
||||
import org.linphone.utils.LinphoneUtils
|
||||
|
||||
data class PhoneNumber(val value: String, val typeLabel: String) : Comparable<PhoneNumber> {
|
||||
override fun compareTo(other: PhoneNumber): Int {
|
||||
|
@ -38,7 +40,7 @@ data class PhoneNumber(val value: String, val typeLabel: String) : Comparable<Ph
|
|||
}
|
||||
}
|
||||
|
||||
open class Contact : Comparable<Contact> {
|
||||
open class Contact() : Comparable<Contact> {
|
||||
var fullName: String? = null
|
||||
var firstName: String? = null
|
||||
var lastName: String? = null
|
||||
|
@ -55,6 +57,31 @@ open class Contact : Comparable<Contact> {
|
|||
|
||||
private var thumbnailUri: Uri? = null
|
||||
|
||||
constructor(searchResult: SearchResult) : this() {
|
||||
friend = searchResult.friend
|
||||
addAddressAndPhoneNumberFromSearchResult(searchResult)
|
||||
}
|
||||
|
||||
fun addAddressAndPhoneNumberFromSearchResult(searchResult: SearchResult) {
|
||||
val address = searchResult.address
|
||||
if (address != null) {
|
||||
if (fullName == null) {
|
||||
fullName = friend?.name ?: LinphoneUtils.getDisplayName(address)
|
||||
}
|
||||
|
||||
sipAddresses.add(address)
|
||||
}
|
||||
|
||||
val phoneNumber = searchResult.phoneNumber
|
||||
if (phoneNumber != null) {
|
||||
if (address == null && fullName == null) {
|
||||
fullName = friend?.name ?: phoneNumber.orEmpty()
|
||||
}
|
||||
|
||||
phoneNumbers.add(PhoneNumber(phoneNumber, ""))
|
||||
}
|
||||
}
|
||||
|
||||
override fun compareTo(other: Contact): Int {
|
||||
val fn = fullName ?: ""
|
||||
val otherFn = other.fullName ?: ""
|
||||
|
|
|
@ -238,13 +238,15 @@ class ContactsManager(private val context: Context) {
|
|||
}
|
||||
|
||||
@Synchronized
|
||||
fun findContactByAddress(address: Address): Contact? {
|
||||
val localContact = localAccountsContacts.find { localContact ->
|
||||
localContact.sipAddresses.find { localAddress ->
|
||||
address.weakEqual(localAddress)
|
||||
} != null
|
||||
fun findContactByAddress(address: Address, ignoreLocalContact: Boolean = false): Contact? {
|
||||
if (!ignoreLocalContact) {
|
||||
val localContact = localAccountsContacts.find { localContact ->
|
||||
localContact.sipAddresses.find { localAddress ->
|
||||
address.weakEqual(localAddress)
|
||||
} != null
|
||||
}
|
||||
if (localContact != null) return localContact
|
||||
}
|
||||
if (localContact != null) return localContact
|
||||
|
||||
val cleanAddress = address.clone()
|
||||
cleanAddress.clean() // To remove gruu if any
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
|
||||
<ImageView
|
||||
android:onClick="@{editClickListener}"
|
||||
android:visibility="@{viewModel.isNativeContact ? View.VISIBLE : View.INVISIBLE}"
|
||||
android:contentDescription="@string/content_description_edit_contact"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -62,6 +63,7 @@
|
|||
|
||||
<ImageView
|
||||
android:onClick="@{deleteClickListener}"
|
||||
android:visibility="@{viewModel.isNativeContact ? View.VISIBLE : View.INVISIBLE}"
|
||||
android:contentDescription="@string/content_description_delete_contact"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
|
||||
<CheckBox
|
||||
android:onClick="@{() -> selectionListViewModel.onToggleSelect(position)}"
|
||||
android:visibility="@{selectionListViewModel.isEditionEnabled ? View.VISIBLE : View.GONE, default=gone}"
|
||||
android:visibility="@{selectionListViewModel.isEditionEnabled && viewModel.isNativeContact ? View.VISIBLE : View.GONE, default=gone}"
|
||||
android:checked="@{selectionListViewModel.selectedItems.contains(position)}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
|
|
|
@ -175,6 +175,10 @@
|
|||
android:text="@string/no_contact"
|
||||
android:visibility="@{!viewModel.sipContactsSelected && viewModel.contactsList.empty ? View.VISIBLE : View.GONE}" />
|
||||
|
||||
<include
|
||||
layout="@layout/wait_layout"
|
||||
app:visibility="@{viewModel.fetchInProgress}"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<View
|
||||
|
|
|
@ -107,6 +107,35 @@
|
|||
linphone:checked="@={viewModel.launcherShortcuts}"
|
||||
linphone:enabled="@{viewModel.readContactsPermissionGranted}"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="@{viewModel.ldapAvailable ? View.VISIBLE : View.GONE}"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
style="@style/settings_category_font"
|
||||
android:text="@string/contacts_settings_ldap_title"
|
||||
android:paddingTop="15dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
linphone:entries="@{viewModel.ldapConfigurations}"
|
||||
linphone:layout="@{@layout/settings_ldap_cell}"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_basic"
|
||||
linphone:listener="@{viewModel.ldapNewSettingsListener}"
|
||||
linphone:title="@{@string/contacts_settings_create_new_ldap_config_title}" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
|
37
app/src/main/res/layout/settings_ldap_cell.xml
Normal file
37
app/src/main/res/layout/settings_ldap_cell.xml
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<data>
|
||||
<import type="android.view.View" />
|
||||
<variable
|
||||
name="data"
|
||||
type="org.linphone.activities.main.settings.viewmodels.LdapSettingsViewModel" />
|
||||
</data>
|
||||
|
||||
<RelativeLayout
|
||||
android:onClick="@{() -> data.ldapSettingsListener.onAccountClicked(data.index)}"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical|left">
|
||||
|
||||
<org.linphone.views.MarqueeTextView
|
||||
android:id="@+id/settings_title"
|
||||
style="@style/settings_item_font"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginTop="15dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:singleLine="true"
|
||||
android:text="@{data.ldapServer, default=`ldap://ldap.example.org`}" />
|
||||
|
||||
<View
|
||||
android:layout_marginTop="15dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_below="@id/settings_title"
|
||||
android:background="?attr/dividerColor" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</layout>
|
238
app/src/main/res/layout/settings_ldap_fragment.xml
Normal file
238
app/src/main/res/layout/settings_ldap_fragment.xml
Normal file
|
@ -0,0 +1,238 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:linphone="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<data>
|
||||
<import type="android.view.View"/>
|
||||
<import type="android.text.InputType"/>
|
||||
<variable
|
||||
name="backClickListener"
|
||||
type="android.view.View.OnClickListener"/>
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="org.linphone.activities.main.settings.viewmodels.LdapSettingsViewModel"/>
|
||||
<variable
|
||||
name="sharedMainViewModel"
|
||||
type="org.linphone.activities.main.viewmodels.SharedMainViewModel" />
|
||||
</data>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/top_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/main_activity_top_bar_size"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:background="?attr/lightToolbarBackgroundColor"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/back"
|
||||
android:onClick="@{backClickListener}"
|
||||
android:visibility="@{sharedMainViewModel.isSlidingPaneSlideable ? View.VISIBLE : View.GONE}"
|
||||
android:contentDescription="@string/content_description_go_back"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0.2"
|
||||
android:background="?attr/button_background_drawable"
|
||||
android:padding="18dp"
|
||||
android:src="@drawable/back" />
|
||||
|
||||
<TextView
|
||||
style="@style/accent_colored_title_font"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0.6"
|
||||
android:gravity="center"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:padding="15dp"
|
||||
android:text="@string/contacts_settings_ldap_title"/>
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0.2"
|
||||
android:visibility="@{sharedMainViewModel.isSlidingPaneSlideable ? View.INVISIBLE : View.GONE}" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/top_bar">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_switch"
|
||||
linphone:title="@{@string/contacts_settings_ldap_enable_title}"
|
||||
linphone:listener="@{viewModel.ldapEnableListener}"
|
||||
linphone:checked="@={viewModel.ldapEnable}"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_basic"
|
||||
linphone:title="@{@string/contacts_settings_ldap_delete_title}"
|
||||
linphone:listener="@{viewModel.deleteListener}"/>
|
||||
|
||||
<TextView
|
||||
style="@style/settings_category_font"
|
||||
android:text="@string/contacts_settings_ldap_connection_title"
|
||||
android:paddingTop="5dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_text"
|
||||
linphone:title="@{@string/contacts_settings_ldap_server_title}"
|
||||
linphone:listener="@{viewModel.ldapServerListener}"
|
||||
linphone:defaultValue="@{viewModel.ldapServer}"
|
||||
linphone:inputType="@{InputType.TYPE_TEXT_VARIATION_URI}"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_text"
|
||||
linphone:title="@{@string/contacts_settings_ldap_bind_dn_title}"
|
||||
linphone:listener="@{viewModel.ldapBindDnListener}"
|
||||
linphone:defaultValue="@{viewModel.ldapBindDn}"
|
||||
linphone:inputType="@{InputType.TYPE_CLASS_TEXT}"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_text"
|
||||
linphone:title="@{@string/contacts_settings_ldap_password_title}"
|
||||
linphone:listener="@{viewModel.ldapPasswordListener}"
|
||||
linphone:defaultValue="@{viewModel.ldapPassword}"
|
||||
linphone:inputType="@{InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD}"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_list"
|
||||
linphone:title="@{@string/contacts_settings_ldap_auth_method_title}"
|
||||
linphone:listener="@{viewModel.ldapAuthMethodListener}"
|
||||
linphone:selectedIndex="@{viewModel.ldapAuthMethodIndex}"
|
||||
linphone:labels="@{viewModel.ldapAuthMethodLabels}"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_switch"
|
||||
linphone:title="@{@string/contacts_settings_ldap_tls_title}"
|
||||
linphone:listener="@{viewModel.ldapTlsListener}"
|
||||
linphone:checked="@={viewModel.ldapTls}"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_list"
|
||||
linphone:title="@{@string/contacts_settings_ldap_cert_check_title}"
|
||||
linphone:listener="@{viewModel.ldapCertCheckListener}"
|
||||
linphone:selectedIndex="@{viewModel.ldapCertCheckIndex}"
|
||||
linphone:labels="@{viewModel.ldapCertCheckLabels}"/>
|
||||
|
||||
<TextView
|
||||
style="@style/settings_category_font"
|
||||
android:text="@string/contacts_settings_ldap_search_title"
|
||||
android:paddingTop="5dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_text"
|
||||
linphone:title="@{@string/contacts_settings_ldap_search_base_title}"
|
||||
linphone:subtitle="@{@string/contacts_settings_ldap_search_base_subtitle}"
|
||||
linphone:listener="@{viewModel.ldapSearchBaseListener}"
|
||||
linphone:defaultValue="@{viewModel.ldapSearchBase}"
|
||||
linphone:inputType="@{InputType.TYPE_CLASS_TEXT}"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_text"
|
||||
linphone:title="@{@string/contacts_settings_ldap_search_filter_title}"
|
||||
linphone:listener="@{viewModel.ldapSearchFilterListener}"
|
||||
linphone:defaultValue="@{viewModel.ldapSearchFilter}"
|
||||
linphone:inputType="@{InputType.TYPE_CLASS_TEXT}"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_text"
|
||||
linphone:title="@{@string/contacts_settings_ldap_search_max_results_title}"
|
||||
linphone:listener="@{viewModel.ldapSearchMaxResultsListener}"
|
||||
linphone:defaultValue="@{viewModel.ldapSearchMaxResults.toString()}"
|
||||
linphone:inputType="@{InputType.TYPE_CLASS_NUMBER}"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_text"
|
||||
linphone:title="@{@string/contacts_settings_ldap_search_timeout_title}"
|
||||
linphone:subtitle="@{@string/contacts_settings_ldap_search_timeout_subtitle}"
|
||||
linphone:listener="@{viewModel.ldapSearchTimeoutListener}"
|
||||
linphone:defaultValue="@{viewModel.ldapSearchTimeout.toString()}"
|
||||
linphone:inputType="@{InputType.TYPE_CLASS_NUMBER}"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_text"
|
||||
linphone:title="@{@string/contacts_settings_ldap_request_delay_title}"
|
||||
linphone:subtitle="@{@string/contacts_settings_ldap_request_delay_subtitle}"
|
||||
linphone:listener="@{viewModel.ldapRequestDelayListener}"
|
||||
linphone:defaultValue="@{viewModel.ldapRequestDelay.toString()}"
|
||||
linphone:inputType="@{InputType.TYPE_CLASS_NUMBER}"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_text"
|
||||
linphone:title="@{@string/contacts_settings_ldap_minimum_characters_title}"
|
||||
linphone:listener="@{viewModel.ldapMinimumCharactersListener}"
|
||||
linphone:defaultValue="@{viewModel.ldapMinimumCharacters.toString()}"
|
||||
linphone:inputType="@{InputType.TYPE_CLASS_NUMBER}"/>
|
||||
|
||||
<TextView
|
||||
style="@style/settings_category_font"
|
||||
android:text="@string/contacts_settings_ldap_parsing_title"
|
||||
android:paddingTop="5dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_text"
|
||||
linphone:title="@{@string/contacts_settings_ldap_name_attribute_title}"
|
||||
linphone:listener="@{viewModel.ldapNameAttributeListener}"
|
||||
linphone:defaultValue="@{viewModel.ldapNameAttribute}"
|
||||
linphone:inputType="@{InputType.TYPE_CLASS_TEXT}"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_text"
|
||||
linphone:title="@{@string/contacts_settings_ldap_sip_attribute_title}"
|
||||
linphone:listener="@{viewModel.ldapSipAttributeListener}"
|
||||
linphone:defaultValue="@{viewModel.ldapSipAttribute}"
|
||||
linphone:inputType="@{InputType.TYPE_CLASS_TEXT}"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_text"
|
||||
linphone:title="@{@string/contacts_settings_ldap_sip_domain_title}"
|
||||
linphone:listener="@{viewModel.ldapSipDomainListener}"
|
||||
linphone:defaultValue="@{viewModel.ldapSipDomain}"
|
||||
linphone:inputType="@{InputType.TYPE_CLASS_TEXT}"/>
|
||||
|
||||
<TextView
|
||||
style="@style/settings_category_font"
|
||||
android:text="@string/contacts_settings_ldap_misc_title"
|
||||
android:paddingTop="5dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_switch"
|
||||
linphone:title="@{@string/contacts_settings_ldap_debug_title}"
|
||||
linphone:listener="@{viewModel.ldapDebugListener}"
|
||||
linphone:checked="@={viewModel.ldapDebug}"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</layout>
|
|
@ -49,7 +49,11 @@
|
|||
android:id="@+id/contactsSettingsFragment"
|
||||
android:name="org.linphone.activities.main.settings.fragments.ContactsSettingsFragment"
|
||||
tools:layout="@layout/settings_contacts_fragment"
|
||||
android:label="ContactsSettingsFragment" />
|
||||
android:label="ContactsSettingsFragment" >
|
||||
<action
|
||||
android:id="@+id/action_contactsSettingsFragment_to_ldapSettingsFragment"
|
||||
app:destination="@id/ldapSettingsFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/networkSettingsFragment"
|
||||
android:name="org.linphone.activities.main.settings.fragments.NetworkSettingsFragment"
|
||||
|
@ -136,6 +140,11 @@
|
|||
android:name="IsLinking"
|
||||
app:argType="boolean" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/ldapSettingsFragment"
|
||||
android:name="org.linphone.activities.main.settings.fragments.LdapSettingsFragment"
|
||||
tools:layout="@layout/settings_ldap_fragment"
|
||||
android:label="LdapSettingsFragment" />
|
||||
<fragment
|
||||
android:id="@+id/conferencesSettingsFragment"
|
||||
tools:layout="@layout/settings_conferences_fragment"
|
||||
|
|
|
@ -589,4 +589,38 @@
|
|||
<string name="about_weblate_translation">Contribuer aux traductions</string>
|
||||
<string name="assistant_generic_account_warning">Certaines fonctionnalités avancées comme les messages de groupe ou les messages éphémères nécessitent un compte &appName;.\n\nElles seront masquées dans l\'application si vous configurez un compte SIP tiers.\n\nSi vous souhaitez les activer pour un projet professionnel, contactez-nous.</string>
|
||||
<string name="assistant_generic_account_warning_continue_button_text">J\'ai compris</string>
|
||||
<string name="contacts_settings_create_new_ldap_config_title">Nouvelle configuration LDAP</string>
|
||||
<string name="contacts_settings_ldap_title">LDAP</string>
|
||||
<string name="contacts_settings_ldap_enable_title">Activer</string>
|
||||
<string name="contacts_settings_ldap_delete_title">Supprimer</string>
|
||||
<string name="contacts_settings_ldap_connection_title">Connexion</string>
|
||||
<string name="contacts_settings_ldap_server_title">URL du serveur</string>
|
||||
<string name="contacts_settings_ldap_bind_dn_title">Bind DN</string>
|
||||
<string name="contacts_settings_ldap_password_title">Mot de passe</string>
|
||||
<string name="contacts_settings_ldap_auth_method_title">Méthode d\'authentification</string>
|
||||
<string name="contacts_settings_ldap_auth_method_anonymous">Anonyme</string>
|
||||
<string name="contacts_settings_ldap_auth_method_simple">Simple</string>
|
||||
<string name="contacts_settings_ldap_tls_title">Utiliser TLS</string>
|
||||
<string name="contacts_settings_ldap_cert_check_title">Vérifier les certificats</string>
|
||||
<string name="contacts_settings_ldap_cert_check_auto">Auto</string>
|
||||
<string name="contacts_settings_ldap_cert_check_disabled">Désactivé</string>
|
||||
<string name="contacts_settings_ldap_cert_check_enabled">Activé</string>
|
||||
<string name="contacts_settings_ldap_search_title">Recherche</string>
|
||||
<string name="contacts_settings_ldap_search_base_title">Base de recherche</string>
|
||||
<string name="contacts_settings_ldap_search_base_subtitle">Ne doit pas être vide !</string>
|
||||
<string name="contacts_settings_ldap_search_filter_title">Filtre</string>
|
||||
<string name="contacts_settings_ldap_search_max_results_title">Résultats maximum</string>
|
||||
<string name="contacts_settings_ldap_search_timeout_title">Durée max</string>
|
||||
<string name="contacts_settings_ldap_search_timeout_subtitle">En secondes</string>
|
||||
<string name="contacts_settings_ldap_request_delay_title">Délai entre 2 requêtes</string>
|
||||
<string name="contacts_settings_ldap_request_delay_subtitle">En millisecondes</string>
|
||||
<string name="contacts_settings_ldap_minimum_characters_title">Nombre minimum de caractères pour lancer la requête</string>
|
||||
<string name="contacts_settings_ldap_parsing_title">Analyse</string>
|
||||
<string name="contacts_settings_ldap_name_attribute_title">Attributs de nom</string>
|
||||
<string name="contacts_settings_ldap_sip_attribute_title">Attributs SIP</string>
|
||||
<string name="contacts_settings_ldap_sip_domain_title">Domaine</string>
|
||||
<string name="contacts_settings_ldap_misc_title">Divers</string>
|
||||
<string name="contacts_settings_ldap_debug_title">Débogage</string>
|
||||
<string name="contact_cant_be_deleted">Ce contact ne peut être supprimé</string>
|
||||
<string name="contacts_ldap_query_more_results_available">Plus de résultats sont disponibles, affinez votre recherche</string>
|
||||
</resources>
|
|
@ -111,6 +111,8 @@
|
|||
</plurals>
|
||||
<string name="contact_new_choose_sync_account">Choose where to save the contact</string>
|
||||
<string name="contact_local_sync_account">Store locally</string>
|
||||
<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>
|
||||
|
||||
<!-- Dialer -->
|
||||
<string name="dialer_address_bar_hint">Enter a number or an address</string>
|
||||
|
@ -543,6 +545,40 @@
|
|||
<string name="contacts_settings_launcher_shortcuts_summary">Will replace chat room shortcuts if any</string>
|
||||
<string name="contacts_settings_show_new_contact_account_dialog_title">Always ask in which account save newly created contact</string>
|
||||
<string name="contacts_settings_show_new_contact_account_dialog_summary">If disabled contact will be stored locally</string>
|
||||
<string name="contacts_settings_create_new_ldap_config_title">New LDAP configuration</string>
|
||||
|
||||
<!-- LDAP Contacts settings -->
|
||||
<string name="contacts_settings_ldap_title">LDAP</string>
|
||||
<string name="contacts_settings_ldap_enable_title">Enable</string>
|
||||
<string name="contacts_settings_ldap_delete_title">Delete</string>
|
||||
<string name="contacts_settings_ldap_connection_title">Connection</string>
|
||||
<string name="contacts_settings_ldap_server_title">Server URL</string>
|
||||
<string name="contacts_settings_ldap_bind_dn_title">Bind DN</string>
|
||||
<string name="contacts_settings_ldap_password_title">Password</string>
|
||||
<string name="contacts_settings_ldap_auth_method_title">Authentication method</string>
|
||||
<string name="contacts_settings_ldap_auth_method_anonymous">Anonymous</string>
|
||||
<string name="contacts_settings_ldap_auth_method_simple">Simple</string>
|
||||
<string name="contacts_settings_ldap_tls_title">Use TLS</string>
|
||||
<string name="contacts_settings_ldap_cert_check_title">Check certificates</string>
|
||||
<string name="contacts_settings_ldap_cert_check_auto">Auto</string>
|
||||
<string name="contacts_settings_ldap_cert_check_disabled">Disabled</string>
|
||||
<string name="contacts_settings_ldap_cert_check_enabled">Enabled</string>
|
||||
<string name="contacts_settings_ldap_search_title">Search</string>
|
||||
<string name="contacts_settings_ldap_search_base_title">Search base</string>
|
||||
<string name="contacts_settings_ldap_search_base_subtitle">Must not be empty!</string>
|
||||
<string name="contacts_settings_ldap_search_filter_title">Filter</string>
|
||||
<string name="contacts_settings_ldap_search_max_results_title">Max results</string>
|
||||
<string name="contacts_settings_ldap_search_timeout_title">Timeout</string>
|
||||
<string name="contacts_settings_ldap_search_timeout_subtitle">In seconds</string>
|
||||
<string name="contacts_settings_ldap_request_delay_title">Delay between two requests</string>
|
||||
<string name="contacts_settings_ldap_request_delay_subtitle">In milliseconds</string>
|
||||
<string name="contacts_settings_ldap_minimum_characters_title">Minimum characters to start query</string>
|
||||
<string name="contacts_settings_ldap_parsing_title">Parsing</string>
|
||||
<string name="contacts_settings_ldap_name_attribute_title">Name attributes</string>
|
||||
<string name="contacts_settings_ldap_sip_attribute_title">SIP attributes</string>
|
||||
<string name="contacts_settings_ldap_sip_domain_title">Domain</string>
|
||||
<string name="contacts_settings_ldap_misc_title">Misc</string>
|
||||
<string name="contacts_settings_ldap_debug_title">Debug</string>
|
||||
|
||||
<!-- Advanced settings -->
|
||||
<string name="advanced_settings_debug_mode_title">Debug logs</string>
|
||||
|
|
Loading…
Reference in a new issue