mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-17 11:28:06 +00:00
Started CardDAV & LDAP configuration fragments
This commit is contained in:
parent
deaf9cd0db
commit
dcca7d6952
16 changed files with 1671 additions and 5 deletions
|
|
@ -157,7 +157,7 @@ dependencies {
|
|||
implementation 'com.google.android.material:material:1.11.0'
|
||||
|
||||
// https://github.com/coil-kt/coil/blob/main/LICENSE.txt Apache v2.0
|
||||
def coil_version = "2.5.0"
|
||||
def coil_version = "2.6.0"
|
||||
implementation("io.coil-kt:coil:$coil_version")
|
||||
implementation("io.coil-kt:coil-gif:$coil_version")
|
||||
implementation("io.coil-kt:coil-svg:$coil_version")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
package org.linphone.ui.main.settings.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.UiThread
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.databinding.SettingsContactsCarddavBinding
|
||||
import org.linphone.ui.main.MainActivity
|
||||
import org.linphone.ui.main.fragment.GenericFragment
|
||||
import org.linphone.ui.main.settings.viewmodel.CardDavViewModel
|
||||
|
||||
@UiThread
|
||||
class CardDavAddressBookConfigurationFragment : GenericFragment() {
|
||||
companion object {
|
||||
private const val TAG = "[CardDAV Address Book Configuration Fragment]"
|
||||
}
|
||||
|
||||
private lateinit var binding: SettingsContactsCarddavBinding
|
||||
|
||||
private lateinit var viewModel: CardDavViewModel
|
||||
|
||||
private val args: CardDavAddressBookConfigurationFragmentArgs by navArgs()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = SettingsContactsCarddavBinding.inflate(layoutInflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
viewModel = ViewModelProvider(this)[CardDavViewModel::class.java]
|
||||
|
||||
binding.lifecycleOwner = viewLifecycleOwner
|
||||
binding.viewModel = viewModel
|
||||
|
||||
val friendListDisplayName = args.displayName
|
||||
if (friendListDisplayName != null) {
|
||||
Log.i("$TAG Found display name in arguments, loading friends list values")
|
||||
viewModel.loadFriendList(friendListDisplayName)
|
||||
} else {
|
||||
Log.i("$TAG No display name found in arguments, starting from scratch")
|
||||
}
|
||||
|
||||
binding.setBackClickListener {
|
||||
goBack()
|
||||
}
|
||||
|
||||
viewModel.cardDavOperationSuccessfulEvent.observe(viewLifecycleOwner) {
|
||||
it.consume {
|
||||
Log.i("$TAG CardDAV friend list operation was successful, going back")
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.showErrorToastEvent.observe(viewLifecycleOwner) {
|
||||
it.consume { pair ->
|
||||
val icon = pair.first
|
||||
val message = pair.second
|
||||
(requireActivity() as MainActivity).showRedToast(message, icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package org.linphone.ui.main.settings.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.UiThread
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.databinding.SettingsContactsLdapBinding
|
||||
import org.linphone.ui.main.MainActivity
|
||||
import org.linphone.ui.main.fragment.GenericFragment
|
||||
import org.linphone.ui.main.settings.viewmodel.LdapViewModel
|
||||
|
||||
@UiThread
|
||||
class LdapServerConfigurationFragment : GenericFragment() {
|
||||
companion object {
|
||||
private const val TAG = "[LDAP Server Configuration Fragment]"
|
||||
}
|
||||
|
||||
private lateinit var binding: SettingsContactsLdapBinding
|
||||
|
||||
private lateinit var viewModel: LdapViewModel
|
||||
|
||||
private val args: LdapServerConfigurationFragmentArgs by navArgs()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = SettingsContactsLdapBinding.inflate(layoutInflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
viewModel = ViewModelProvider(this)[LdapViewModel::class.java]
|
||||
|
||||
binding.lifecycleOwner = viewLifecycleOwner
|
||||
binding.viewModel = viewModel
|
||||
|
||||
val ldapServerUrl = args.serverUrl
|
||||
if (ldapServerUrl != null) {
|
||||
Log.i("$TAG Found server URL in arguments, loading values")
|
||||
viewModel.loadLdap(ldapServerUrl)
|
||||
} else {
|
||||
Log.i("$TAG No server URL found in arguments, starting from scratch")
|
||||
}
|
||||
|
||||
binding.setBackClickListener {
|
||||
goBack()
|
||||
}
|
||||
|
||||
viewModel.ldapServerOperationSuccessfulEvent.observe(viewLifecycleOwner) {
|
||||
it.consume {
|
||||
Log.i("$TAG LDAP server operation was successful, going back")
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.showErrorToastEvent.observe(viewLifecycleOwner) {
|
||||
it.consume { pair ->
|
||||
val icon = pair.first
|
||||
val message = pair.second
|
||||
(requireActivity() as MainActivity).showRedToast(message, icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import android.widget.AdapterView
|
|||
import android.widget.ArrayAdapter
|
||||
import androidx.annotation.UiThread
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.R
|
||||
import org.linphone.compatibility.Compatibility
|
||||
|
|
@ -109,6 +110,42 @@ class SettingsFragment : GenericFragment() {
|
|||
|
||||
binding.callsSettings.deviceRingtoneSpinner.onItemSelectedListener = ringtoneListener
|
||||
|
||||
viewModel.addLdapServerEvent.observe(viewLifecycleOwner) {
|
||||
it.consume {
|
||||
val action = SettingsFragmentDirections.actionSettingsFragmentToLdapServerConfigurationFragment(
|
||||
null
|
||||
)
|
||||
findNavController().navigate(action)
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.editLdapServerEvent.observe(viewLifecycleOwner) {
|
||||
it.consume { name ->
|
||||
val action = SettingsFragmentDirections.actionSettingsFragmentToLdapServerConfigurationFragment(
|
||||
name
|
||||
)
|
||||
findNavController().navigate(action)
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.addCardDavServerEvent.observe(viewLifecycleOwner) {
|
||||
it.consume {
|
||||
val action = SettingsFragmentDirections.actionSettingsFragmentToCardDavAddressBookConfigurationFragment(
|
||||
null
|
||||
)
|
||||
findNavController().navigate(action)
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.editCardDavServerEvent.observe(viewLifecycleOwner) {
|
||||
it.consume { name ->
|
||||
val action = SettingsFragmentDirections.actionSettingsFragmentToCardDavAddressBookConfigurationFragment(
|
||||
name
|
||||
)
|
||||
findNavController().navigate(action)
|
||||
}
|
||||
}
|
||||
|
||||
// Meeting default layout related
|
||||
val layoutAdapter = ArrayAdapter(
|
||||
requireContext(),
|
||||
|
|
@ -152,4 +189,11 @@ class SettingsFragment : GenericFragment() {
|
|||
viewModel.stopRingtonePlayer()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
viewModel.reloadLdapServers()
|
||||
viewModel.reloadConfiguredCardDavServers()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2023 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.ui.main.settings.model
|
||||
|
||||
import androidx.annotation.AnyThread
|
||||
import androidx.annotation.UiThread
|
||||
|
||||
@AnyThread
|
||||
class CardDavLdapModel(val name: String, private val onClicked: (name: String) -> (Unit)) {
|
||||
@UiThread
|
||||
fun clicked() {
|
||||
onClicked.invoke(name)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2023 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.ui.main.settings.viewmodel
|
||||
|
||||
import androidx.annotation.UiThread
|
||||
import androidx.annotation.WorkerThread
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.R
|
||||
import org.linphone.core.Factory
|
||||
import org.linphone.core.FriendList
|
||||
import org.linphone.core.FriendListListenerStub
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.utils.Event
|
||||
|
||||
class CardDavViewModel : ViewModel() {
|
||||
companion object {
|
||||
private const val TAG = "[CardDAV ViewModel]"
|
||||
}
|
||||
|
||||
val isEdit = MutableLiveData<Boolean>()
|
||||
|
||||
val displayName = MutableLiveData<String>()
|
||||
|
||||
val serverUrl = MutableLiveData<String>()
|
||||
|
||||
val username = MutableLiveData<String>()
|
||||
|
||||
val password = MutableLiveData<String>()
|
||||
|
||||
val realm = MutableLiveData<String>()
|
||||
|
||||
val showPassword = MutableLiveData<Boolean>()
|
||||
|
||||
val syncInProgress = MutableLiveData<Boolean>()
|
||||
|
||||
val cardDavOperationSuccessfulEvent: MutableLiveData<Event<Boolean>> by lazy {
|
||||
MutableLiveData<Event<Boolean>>()
|
||||
}
|
||||
|
||||
val showErrorToastEvent: MutableLiveData<Event<Pair<Int, String>>> by lazy {
|
||||
MutableLiveData<Event<Pair<Int, String>>>()
|
||||
}
|
||||
|
||||
private lateinit var friendList: FriendList
|
||||
|
||||
private val friendListListener = object : FriendListListenerStub() {
|
||||
@WorkerThread
|
||||
override fun onSyncStatusChanged(
|
||||
friendList: FriendList,
|
||||
status: FriendList.SyncStatus,
|
||||
message: String?
|
||||
) {
|
||||
Log.i(
|
||||
"$TAG Friend list [${friendList.displayName}] sync status changed to [$status] with message [$message]"
|
||||
)
|
||||
when (status) {
|
||||
FriendList.SyncStatus.Successful -> {
|
||||
syncInProgress.postValue(false)
|
||||
cardDavOperationSuccessfulEvent.postValue(Event(true))
|
||||
}
|
||||
FriendList.SyncStatus.Failure -> {
|
||||
syncInProgress.postValue(false)
|
||||
val icon = R.drawable.x
|
||||
showErrorToastEvent.postValue(Event(Pair(icon, message.orEmpty())))
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
isEdit.value = false
|
||||
showPassword.value = false
|
||||
syncInProgress.value = false
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
if (::friendList.isInitialized) {
|
||||
friendList.removeListener(friendListListener)
|
||||
}
|
||||
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun loadFriendList(name: String) {
|
||||
coreContext.postOnCoreThread { core ->
|
||||
val found = core.getFriendListByName(name)
|
||||
if (found == null) {
|
||||
Log.e("$TAG Failed to find friend list with display name [$name]!")
|
||||
return@postOnCoreThread
|
||||
}
|
||||
|
||||
isEdit.postValue(true)
|
||||
friendList = found
|
||||
friendList.addListener(friendListListener)
|
||||
|
||||
displayName.postValue(name)
|
||||
serverUrl.postValue(friendList.uri)
|
||||
Log.i("$TAG Existing friend list CardDAV values loaded")
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun delete() {
|
||||
coreContext.postOnCoreThread { core ->
|
||||
if (isEdit.value == true && ::friendList.isInitialized) {
|
||||
val name = friendList.displayName
|
||||
core.removeFriendList(friendList)
|
||||
Log.i("$TAG Removed friends list with display name [$name]")
|
||||
cardDavOperationSuccessfulEvent.postValue(Event(true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun toggleShowPassword() {
|
||||
showPassword.value = showPassword.value == false
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun addAddressBook() {
|
||||
val name = displayName.value.orEmpty().trim()
|
||||
val server = serverUrl.value.orEmpty().trim()
|
||||
if (name.isEmpty() || server.isEmpty()) {
|
||||
// TODO FIXME: improve toast
|
||||
showErrorToastEvent.postValue(Event(Pair(R.drawable.x, "Name or Server is empty!")))
|
||||
return
|
||||
}
|
||||
|
||||
val user = username.value.orEmpty().trim()
|
||||
val pwd = password.value.orEmpty().trim()
|
||||
val authRealm = realm.value.orEmpty().trim()
|
||||
|
||||
coreContext.postOnCoreThread { core ->
|
||||
// TODO FIXME: add dialog to ask user before removing existing friend list & auth info ?
|
||||
if (isEdit.value == false) {
|
||||
val foundFriendList = core.getFriendListByName(name)
|
||||
if (foundFriendList != null) {
|
||||
Log.w("$TAG Friend list [$name] already exists, removing it first")
|
||||
core.removeFriendList(foundFriendList)
|
||||
}
|
||||
}
|
||||
|
||||
if (user.isNotEmpty() && authRealm.isNotEmpty()) {
|
||||
val foundAuthInfo = core.findAuthInfo(authRealm, user, null)
|
||||
if (foundAuthInfo != null) {
|
||||
Log.w("$TAG Auth info with username [$user] already exists, removing it first")
|
||||
core.removeAuthInfo(foundAuthInfo)
|
||||
}
|
||||
|
||||
Log.i("$TAG Adding auth info with username [$user]")
|
||||
val authInfo = Factory.instance().createAuthInfo(
|
||||
user,
|
||||
null,
|
||||
pwd,
|
||||
null,
|
||||
authRealm,
|
||||
null
|
||||
)
|
||||
core.addAuthInfo(authInfo)
|
||||
}
|
||||
|
||||
if (isEdit.value == true && ::friendList.isInitialized) {
|
||||
Log.i(
|
||||
"$TAG Changes were made to CardDAV friend list [$name], synchronizing it"
|
||||
)
|
||||
} else {
|
||||
friendList = core.createFriendList()
|
||||
friendList.displayName = name
|
||||
friendList.type = FriendList.Type.CardDAV
|
||||
friendList.uri = server
|
||||
friendList.isDatabaseStorageEnabled = true
|
||||
friendList.addListener(friendListListener)
|
||||
core.addFriendList(friendList)
|
||||
|
||||
Log.i(
|
||||
"$TAG CardDAV friend list [$name] created with server URL [$server], synchronizing it"
|
||||
)
|
||||
}
|
||||
|
||||
syncInProgress.postValue(true)
|
||||
friendList.synchronizeFriendsFromServer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2023 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.ui.main.settings.viewmodel
|
||||
|
||||
import androidx.annotation.UiThread
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.R
|
||||
import org.linphone.core.Ldap
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.utils.Event
|
||||
|
||||
class LdapViewModel : ViewModel() {
|
||||
companion object {
|
||||
private const val TAG = "[LDAP ViewModel]"
|
||||
}
|
||||
|
||||
val isEdit = MutableLiveData<Boolean>()
|
||||
|
||||
val serverUrl = MutableLiveData<String>()
|
||||
|
||||
val bindDn = MutableLiveData<String>()
|
||||
|
||||
val password = MutableLiveData<String>()
|
||||
|
||||
val showPassword = MutableLiveData<Boolean>()
|
||||
|
||||
val useTls = MutableLiveData<Boolean>()
|
||||
|
||||
val searchBase = MutableLiveData<String>()
|
||||
|
||||
val searchFilter = MutableLiveData<String>()
|
||||
|
||||
val maxResults = MutableLiveData<String>()
|
||||
|
||||
val requestTimeout = MutableLiveData<String>()
|
||||
|
||||
val requestDelay = MutableLiveData<String>()
|
||||
|
||||
val minCharacters = MutableLiveData<String>()
|
||||
|
||||
val nameAttributes = MutableLiveData<String>()
|
||||
|
||||
val sipAttributes = MutableLiveData<String>()
|
||||
|
||||
val sipDomain = MutableLiveData<String>()
|
||||
|
||||
val ldapServerOperationSuccessfulEvent: MutableLiveData<Event<Boolean>> by lazy {
|
||||
MutableLiveData<Event<Boolean>>()
|
||||
}
|
||||
|
||||
val showErrorToastEvent: MutableLiveData<Event<Pair<Int, String>>> by lazy {
|
||||
MutableLiveData<Event<Pair<Int, String>>>()
|
||||
}
|
||||
|
||||
private lateinit var ldapToEdit: Ldap
|
||||
|
||||
init {
|
||||
isEdit.value = false
|
||||
showPassword.value = false
|
||||
|
||||
useTls.value = true
|
||||
minCharacters.value = "3"
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun loadLdap(url: String) {
|
||||
coreContext.postOnCoreThread { core ->
|
||||
val found = core.ldapList.find {
|
||||
it.params.server == url
|
||||
}
|
||||
if (found == null) {
|
||||
Log.e("$TAG Failed to find LDAP server with URL [$url]!")
|
||||
return@postOnCoreThread
|
||||
}
|
||||
|
||||
isEdit.postValue(true)
|
||||
ldapToEdit = found
|
||||
val ldapParams = ldapToEdit.params
|
||||
|
||||
serverUrl.postValue(ldapParams.server)
|
||||
bindDn.postValue(ldapParams.bindDn.orEmpty())
|
||||
useTls.postValue(ldapParams.isTlsEnabled)
|
||||
searchBase.postValue(ldapParams.baseObject)
|
||||
searchFilter.postValue(ldapParams.filter.orEmpty())
|
||||
maxResults.postValue(ldapParams.maxResults.toString())
|
||||
requestTimeout.postValue(ldapParams.timeout.toString())
|
||||
requestDelay.postValue(ldapParams.delay.toString())
|
||||
minCharacters.postValue(ldapParams.minChars.toString())
|
||||
nameAttributes.postValue(ldapParams.nameAttribute.orEmpty())
|
||||
sipAttributes.postValue(ldapParams.sipAttribute.orEmpty())
|
||||
sipDomain.postValue(ldapParams.sipDomain.orEmpty())
|
||||
Log.i("$TAG Existing LDAP server values loaded")
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun delete() {
|
||||
coreContext.postOnCoreThread { core ->
|
||||
if (isEdit.value == true && ::ldapToEdit.isInitialized) {
|
||||
val serverUrl = ldapToEdit.params.server
|
||||
core.removeLdap(ldapToEdit)
|
||||
Log.i("$TAG Removed LDAP config for server URL [$serverUrl]")
|
||||
ldapServerOperationSuccessfulEvent.postValue(Event(true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun toggleShowPassword() {
|
||||
showPassword.value = showPassword.value == false
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun toggleTls() {
|
||||
useTls.value = useTls.value == false
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun addServer() {
|
||||
coreContext.postOnCoreThread { core ->
|
||||
try {
|
||||
val ldapParams = core.createLdapParams()
|
||||
|
||||
ldapParams.enabled = true
|
||||
ldapParams.server = serverUrl.value.orEmpty().trim()
|
||||
ldapParams.bindDn = bindDn.value.orEmpty().trim()
|
||||
ldapParams.password = password.value.orEmpty().trim()
|
||||
ldapParams.authMethod = Ldap.AuthMethod.Simple
|
||||
ldapParams.isTlsEnabled = useTls.value == true
|
||||
ldapParams.serverCertificatesVerificationMode = Ldap.CertVerificationMode.Default
|
||||
ldapParams.baseObject = searchBase.value.orEmpty().trim()
|
||||
ldapParams.filter = searchFilter.value.orEmpty().trim()
|
||||
ldapParams.maxResults = maxResults.value.orEmpty().trim().toInt()
|
||||
ldapParams.timeout = requestTimeout.value.orEmpty().trim().toInt()
|
||||
ldapParams.delay = requestDelay.value.orEmpty().trim().toInt()
|
||||
ldapParams.minChars = minCharacters.value.orEmpty().trim().toInt()
|
||||
ldapParams.nameAttribute = nameAttributes.value.orEmpty().trim()
|
||||
ldapParams.sipAttribute = sipAttributes.value.orEmpty().trim()
|
||||
ldapParams.sipDomain = sipDomain.value.orEmpty().trim()
|
||||
ldapParams.debugLevel = Ldap.DebugLevel.Verbose
|
||||
|
||||
if (isEdit.value == true && ::ldapToEdit.isInitialized) {
|
||||
ldapToEdit.params = ldapParams
|
||||
Log.i("$TAG LDAP changes have been applied")
|
||||
} else {
|
||||
val ldap = core.createLdapWithParams(ldapParams)
|
||||
core.addLdap(ldap)
|
||||
Log.i("$TAG New LDAP config created")
|
||||
}
|
||||
ldapServerOperationSuccessfulEvent.postValue(Event(true))
|
||||
} catch (e: Exception) {
|
||||
Log.e("$TAG Exception while creating LDAP: $e")
|
||||
// TODO FIXME: improve toast
|
||||
showErrorToastEvent.postValue(
|
||||
Event(Pair(R.drawable.x, e.toString()))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -35,11 +35,14 @@ import org.linphone.LinphoneApplication.Companion.coreContext
|
|||
import org.linphone.LinphoneApplication.Companion.corePreferences
|
||||
import org.linphone.R
|
||||
import org.linphone.core.Conference
|
||||
import org.linphone.core.FriendList
|
||||
import org.linphone.core.Player
|
||||
import org.linphone.core.PlayerListener
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.ui.main.settings.model.CardDavLdapModel
|
||||
import org.linphone.utils.AppUtils
|
||||
import org.linphone.utils.AudioUtils
|
||||
import org.linphone.utils.Event
|
||||
|
||||
class SettingsViewModel @UiThread constructor() : ViewModel() {
|
||||
companion object {
|
||||
|
|
@ -79,6 +82,25 @@ class SettingsViewModel @UiThread constructor() : ViewModel() {
|
|||
// Contacts settings
|
||||
val showContactsSettings = MutableLiveData<Boolean>()
|
||||
|
||||
val ldapServers = MutableLiveData<List<CardDavLdapModel>>()
|
||||
|
||||
val cardDavFriendsLists = MutableLiveData<List<CardDavLdapModel>>()
|
||||
|
||||
val addLdapServerEvent: MutableLiveData<Event<Boolean>> by lazy {
|
||||
MutableLiveData<Event<Boolean>>()
|
||||
}
|
||||
val editLdapServerEvent: MutableLiveData<Event<String>> by lazy {
|
||||
MutableLiveData<Event<String>>()
|
||||
}
|
||||
|
||||
val addCardDavServerEvent: MutableLiveData<Event<Boolean>> by lazy {
|
||||
MutableLiveData<Event<Boolean>>()
|
||||
}
|
||||
|
||||
val editCardDavServerEvent: MutableLiveData<Event<String>> by lazy {
|
||||
MutableLiveData<Event<String>>()
|
||||
}
|
||||
|
||||
// Meetings settings
|
||||
val showMeetingsSettings = MutableLiveData<Boolean>()
|
||||
|
||||
|
|
@ -336,6 +358,58 @@ class SettingsViewModel @UiThread constructor() : ViewModel() {
|
|||
expandContacts.value = expandContacts.value == false
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun addLdapServer() {
|
||||
addLdapServerEvent.value = Event(true)
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun reloadLdapServers() {
|
||||
coreContext.postOnCoreThread { core ->
|
||||
val list = arrayListOf<CardDavLdapModel>()
|
||||
|
||||
for (ldap in core.ldapList) {
|
||||
val label = ldap.params.server
|
||||
if (label.isNotEmpty()) {
|
||||
list.add(
|
||||
CardDavLdapModel(label) {
|
||||
editLdapServerEvent.postValue(Event(label))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
ldapServers.postValue(list)
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun addCardDavServer() {
|
||||
addCardDavServerEvent.value = Event(true)
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun reloadConfiguredCardDavServers() {
|
||||
coreContext.postOnCoreThread { core ->
|
||||
val list = arrayListOf<CardDavLdapModel>()
|
||||
|
||||
for (friendList in core.friendsLists) {
|
||||
if (friendList.type == FriendList.Type.CardDAV) {
|
||||
val label = friendList.displayName ?: friendList.uri ?: ""
|
||||
if (label.isNotEmpty()) {
|
||||
list.add(
|
||||
CardDavLdapModel(label) {
|
||||
editCardDavServerEvent.postValue(Event(label))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cardDavFriendsLists.postValue(list)
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun toggleMeetingsExpand() {
|
||||
expandMeetings.value = expandMeetings.value == false
|
||||
|
|
|
|||
|
|
@ -107,7 +107,9 @@ fun <T> setEntries(
|
|||
)
|
||||
|
||||
binding.setVariable(BR.model, entry)
|
||||
binding.setVariable(BR.onLongClickListener, onLongClick)
|
||||
if (onLongClick != null) {
|
||||
binding.setVariable(BR.onLongClickListener, onLongClick)
|
||||
}
|
||||
|
||||
// This is a bit hacky...
|
||||
if (viewGroup.context as? LifecycleOwner != null) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<data>
|
||||
<import type="android.view.View" />
|
||||
|
|
@ -15,6 +15,76 @@
|
|||
android:paddingBottom="20dp"
|
||||
android:background="@drawable/shape_squircle_white_background">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:onClick="@{() -> viewModel.addLdapServer()}"
|
||||
android:id="@+id/add_ldap_server"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:padding="5dp"
|
||||
android:text="@string/settings_contacts_add_ldap_server_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
android:drawableEnd="@drawable/caret_right"
|
||||
android:drawableTint="?attr/color_main2_600"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/existing_ldap_servers"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/existing_ldap_servers"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="@{viewModel.ldapServers.size() == 0 ? View.GONE : View.VISIBLE, default=gone}"
|
||||
app:entries="@{viewModel.ldapServers}"
|
||||
app:layout="@{@layout/settings_contacts_carddav_ldap_list_cell}"
|
||||
app:layout_constraintTop_toBottomOf="@id/add_ldap_server"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:onClick="@{() -> viewModel.addCardDavServer()}"
|
||||
android:id="@+id/add_carddav_server"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:padding="5dp"
|
||||
android:text="@string/settings_contacts_add_carddav_server_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
android:drawableEnd="@drawable/caret_right"
|
||||
android:drawableTint="?attr/color_main2_600"
|
||||
app:layout_constraintTop_toBottomOf="@id/existing_ldap_servers"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/existing_carddav_servers"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="@{viewModel.cardDavFriendsLists.size() == 0 ? View.GONE : View.VISIBLE, default=gone}"
|
||||
app:entries="@{viewModel.cardDavFriendsLists}"
|
||||
app:layout="@{@layout/settings_contacts_carddav_ldap_list_cell}"
|
||||
app:layout_constraintTop_toBottomOf="@id/add_carddav_server"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</layout>
|
||||
277
app/src/main/res/layout/settings_contacts_carddav.xml
Normal file
277
app/src/main/res/layout/settings_contacts_carddav.xml
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:bind="http://schemas.android.com/tools">
|
||||
|
||||
<data>
|
||||
<import type="android.view.View" />
|
||||
<import type="android.text.InputType" />
|
||||
<variable
|
||||
name="backClickListener"
|
||||
type="View.OnClickListener" />
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="org.linphone.ui.main.settings.viewmodel.CardDavViewModel" />
|
||||
</data>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/color_main2_000">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/back"
|
||||
android:onClick="@{backClickListener}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:padding="15dp"
|
||||
android:src="@drawable/caret_left"
|
||||
android:contentDescription="@string/content_description_go_back_icon"
|
||||
app:tint="?attr/color_main1_500"
|
||||
app:layout_constraintBottom_toBottomOf="@id/title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/title" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/main_page_title_style"
|
||||
android:id="@+id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/top_bar_height"
|
||||
android:layout_marginStart="10dp"
|
||||
android:text="@{viewModel.isEdit ? @string/settings_contacts_edit_carddav_server_title : @string/settings_contacts_add_carddav_server_title, default=@string/settings_contacts_add_carddav_server_title}"
|
||||
app:layout_constraintEnd_toStartOf="@id/delete"
|
||||
app:layout_constraintStart_toEndOf="@id/back"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/delete"
|
||||
android:onClick="@{() -> viewModel.delete()}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:padding="15dp"
|
||||
android:src="@drawable/trash_simple"
|
||||
android:visibility="@{viewModel.isEdit ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:tint="?attr/color_main1_500"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/title"
|
||||
app:layout_constraintTop_toTopOf="@id/back"
|
||||
app:layout_constraintBottom_toBottomOf="@id/back"/>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:fillViewport="true"
|
||||
android:background="?attr/color_grey_100"
|
||||
app:layout_constraintTop_toBottomOf="@id/title"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/name_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/settings_contacts_carddav_name_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.displayName}"
|
||||
android:inputType="text|textPersonName"
|
||||
android:hint="@string/settings_contacts_carddav_name_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/name_title"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/server_url_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/settings_contacts_carddav_server_url_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@id/name"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/server_url"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.serverUrl}"
|
||||
android:inputType="text|textUri"
|
||||
android:hint="@string/settings_contacts_carddav_server_url_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/server_url_title"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/username_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/settings_contacts_carddav_username_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@id/server_url"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/username"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.username}"
|
||||
android:inputType="text"
|
||||
android:hint="@string/username"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/username_title"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/password_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/settings_contacts_carddav_password_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@id/username"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/password"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.password}"
|
||||
android:hint="@string/password"
|
||||
android:inputType="@{viewModel.showPassword ? InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD : InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD, default=textPassword}"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/password_title" />
|
||||
|
||||
<ImageView
|
||||
android:onClick="@{() -> viewModel.toggleShowPassword()}"
|
||||
android:id="@+id/eye"
|
||||
android:layout_width="@dimen/icon_size"
|
||||
android:layout_height="0dp"
|
||||
android:padding="4dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:src="@{viewModel.showPassword ? @drawable/eye_slash : @drawable/eye, default=@drawable/eye}"
|
||||
app:tint="?attr/color_main2_500"
|
||||
app:layout_constraintEnd_toEndOf="@id/password"
|
||||
app:layout_constraintTop_toTopOf="@id/password"
|
||||
app:layout_constraintBottom_toBottomOf="@id/password" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/realm_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/settings_contacts_carddav_realm_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@id/password"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/realm"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginBottom="@dimen/screen_bottom_margin"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.realm}"
|
||||
android:inputType="text"
|
||||
android:hint="@string/settings_contacts_carddav_realm_title"
|
||||
app:layout_constraintVertical_bias="0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/realm_title"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/add_account"
|
||||
android:onClick="@{() -> viewModel.addAddressBook()}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|bottom"
|
||||
android:layout_margin="16dp"
|
||||
android:src="@{viewModel.isEdit ? @drawable/check : @drawable/plus_circle, default=@drawable/plus_circle}"
|
||||
android:visibility="@{viewModel.syncInProgress ? View.GONE : View.VISIBLE}"
|
||||
app:tint="?attr/color_on_main"
|
||||
app:backgroundTint="?attr/color_main1_500"
|
||||
app:shapeAppearanceOverlay="@style/rounded"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<include
|
||||
layout="@layout/operation_in_progress"
|
||||
bind:visibility="@{viewModel.syncInProgress}" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</layout>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:bind="http://schemas.android.com/tools">
|
||||
|
||||
<data>
|
||||
<import type="android.view.View" />
|
||||
<variable
|
||||
name="model"
|
||||
type="org.linphone.ui.main.settings.model.CardDavLdapModel" />
|
||||
</data>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/name"
|
||||
android:onClick="@{() -> model.clicked()}"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:padding="5dp"
|
||||
android:text="@{model.name, default=`LDAP or CardDAV item`}"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
android:drawableEnd="@drawable/pencil_simple"
|
||||
android:drawableTint="?attr/color_main2_600"
|
||||
app:layout_constraintStart_toEndOf="@id/avatar"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
</layout>
|
||||
523
app/src/main/res/layout/settings_contacts_ldap.xml
Normal file
523
app/src/main/res/layout/settings_contacts_ldap.xml
Normal file
|
|
@ -0,0 +1,523 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<data>
|
||||
<import type="android.view.View" />
|
||||
<import type="android.text.InputType" />
|
||||
<variable
|
||||
name="backClickListener"
|
||||
type="View.OnClickListener" />
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="org.linphone.ui.main.settings.viewmodel.LdapViewModel" />
|
||||
</data>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/color_main2_000">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/back"
|
||||
android:onClick="@{backClickListener}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:padding="15dp"
|
||||
android:src="@drawable/caret_left"
|
||||
android:contentDescription="@string/content_description_go_back_icon"
|
||||
app:tint="?attr/color_main1_500"
|
||||
app:layout_constraintBottom_toBottomOf="@id/title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/title" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/main_page_title_style"
|
||||
android:id="@+id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/top_bar_height"
|
||||
android:layout_marginStart="10dp"
|
||||
android:text="@{viewModel.isEdit ? @string/settings_contacts_edit_ldap_server_title : @string/settings_contacts_add_ldap_server_title, default=@string/settings_contacts_add_ldap_server_title}"
|
||||
app:layout_constraintEnd_toStartOf="@id/delete"
|
||||
app:layout_constraintStart_toEndOf="@id/back"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/delete"
|
||||
android:onClick="@{() -> viewModel.delete()}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:padding="15dp"
|
||||
android:src="@drawable/trash_simple"
|
||||
android:visibility="@{viewModel.isEdit ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:tint="?attr/color_main1_500"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/title"
|
||||
app:layout_constraintTop_toTopOf="@id/back"
|
||||
app:layout_constraintBottom_toBottomOf="@id/back"/>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:fillViewport="true"
|
||||
android:background="?attr/color_grey_100"
|
||||
app:layout_constraintTop_toBottomOf="@id/title"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/server_url_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/settings_contacts_ldap_server_url_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/server_url"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.serverUrl}"
|
||||
android:inputType="text|textUri"
|
||||
android:hint="@string/settings_contacts_ldap_server_url_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/server_url_title"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/bind_dn_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/settings_contacts_ldap_bind_dn_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@id/server_url"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/bind_dn"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.bindDn}"
|
||||
android:inputType="text"
|
||||
android:hint="@string/settings_contacts_ldap_bind_dn_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/bind_dn_title"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/password_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/settings_contacts_ldap_password_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@id/bind_dn"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/password"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.password}"
|
||||
android:hint="@string/password"
|
||||
android:inputType="@{viewModel.showPassword ? InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD : InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD, default=textPassword}"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/password_title" />
|
||||
|
||||
<ImageView
|
||||
android:onClick="@{() -> viewModel.toggleShowPassword()}"
|
||||
android:id="@+id/eye"
|
||||
android:layout_width="@dimen/icon_size"
|
||||
android:layout_height="0dp"
|
||||
android:padding="4dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:src="@{viewModel.showPassword ? @drawable/eye_slash : @drawable/eye, default=@drawable/eye}"
|
||||
app:tint="?attr/color_main2_500"
|
||||
app:layout_constraintEnd_toEndOf="@id/password"
|
||||
app:layout_constraintTop_toTopOf="@id/password"
|
||||
app:layout_constraintBottom_toBottomOf="@id/password" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:onClick="@{() -> viewModel.toggleTls()}"
|
||||
android:id="@+id/tls_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:text="@string/settings_contacts_ldap_use_tls_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toTopOf="@id/tls_switch"
|
||||
app:layout_constraintBottom_toBottomOf="@id/tls_switch"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/tls_switch"/>
|
||||
|
||||
<com.google.android.material.materialswitch.MaterialSwitch
|
||||
style="@style/material_switch_style"
|
||||
android:id="@+id/tls_switch"
|
||||
android:onClick="@{() -> viewModel.toggleTls()}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:checked="@{viewModel.useTls}"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/password" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/search_base_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/settings_contacts_ldap_search_base_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@id/tls_switch"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/search_base"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.searchBase}"
|
||||
android:inputType="text"
|
||||
android:hint="@string/settings_contacts_ldap_search_base_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/search_base_title"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/search_filter_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/settings_contacts_ldap_search_filter_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@id/search_base"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/search_filter"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.searchFilter}"
|
||||
android:inputType="text"
|
||||
android:hint="@string/settings_contacts_ldap_search_filter_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/search_filter_title"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/max_results_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/settings_contacts_ldap_max_results_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@id/search_filter"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/max_results"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.maxResults}"
|
||||
android:inputType="numberSigned"
|
||||
android:hint="@string/settings_contacts_ldap_max_results_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/max_results_title"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/request_timeout_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/settings_contacts_ldap_request_timeout_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@id/max_results"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/request_timeout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.requestTimeout}"
|
||||
android:inputType="numberSigned"
|
||||
android:hint="@string/settings_contacts_ldap_request_timeout_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/request_timeout_title"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/request_delay_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/settings_contacts_ldap_request_delay_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@id/request_timeout"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/request_delay"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.requestDelay}"
|
||||
android:inputType="numberSigned"
|
||||
android:hint="@string/settings_contacts_ldap_request_delay_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/request_delay_title"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/min_chars_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/settings_contacts_ldap_min_characters_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@id/request_delay"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/min_chars"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.minCharacters}"
|
||||
android:inputType="numberSigned"
|
||||
android:hint="@string/settings_contacts_ldap_min_characters_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/min_chars_title"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/name_attributes_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/settings_contacts_ldap_name_attributes_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@id/min_chars"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/name_attributes"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.nameAttributes}"
|
||||
android:inputType="text"
|
||||
android:hint="@string/settings_contacts_ldap_name_attributes_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/name_attributes_title"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/sip_attributes_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/settings_contacts_ldap_sip_attributes_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@id/name_attributes"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/sip_attributes"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.sipAttributes}"
|
||||
android:inputType="text"
|
||||
android:hint="@string/settings_contacts_ldap_sip_attributes_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/sip_attributes_title"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/settings_title_style"
|
||||
android:id="@+id/sip_domain_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/settings_contacts_ldap_sip_domain_title"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@id/sip_attributes"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/sip_domain"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginBottom="@dimen/screen_bottom_margin"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text="@={viewModel.sipDomain}"
|
||||
android:inputType="text"
|
||||
android:hint="@string/settings_contacts_ldap_sip_domain_title"
|
||||
app:layout_constraintVertical_bias="0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/sip_domain_title"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/add_server"
|
||||
android:onClick="@{() -> viewModel.addServer()}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|bottom"
|
||||
android:layout_margin="16dp"
|
||||
android:src="@{viewModel.isEdit ? @drawable/check : @drawable/plus_circle, default=@drawable/plus_circle}"
|
||||
app:tint="?attr/color_on_main"
|
||||
app:backgroundTint="?attr/color_main1_500"
|
||||
app:shapeAppearanceOverlay="@style/rounded"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</layout>
|
||||
|
|
@ -112,7 +112,24 @@
|
|||
android:id="@+id/settingsFragment"
|
||||
android:name="org.linphone.ui.main.settings.fragment.SettingsFragment"
|
||||
android:label="SettingsFragment"
|
||||
tools:layout="@layout/settings_fragment" />
|
||||
tools:layout="@layout/settings_fragment" >
|
||||
<action
|
||||
android:id="@+id/action_settingsFragment_to_ldapServerConfigurationFragment"
|
||||
app:destination="@id/ldapServerConfigurationFragment"
|
||||
app:launchSingleTop="true"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_in_left"
|
||||
app:popExitAnim="@anim/slide_out_right" />
|
||||
<action
|
||||
android:id="@+id/action_settingsFragment_to_cardDavAddressBookConfigurationFragment"
|
||||
app:destination="@id/cardDavAddressBookConfigurationFragment"
|
||||
app:launchSingleTop="true"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_in_left"
|
||||
app:popExitAnim="@anim/slide_out_right" />
|
||||
</fragment>
|
||||
|
||||
<action
|
||||
android:id="@+id/action_global_settingsFragment"
|
||||
|
|
@ -362,4 +379,26 @@
|
|||
app:argType="string" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/ldapServerConfigurationFragment"
|
||||
android:name="org.linphone.ui.main.settings.fragment.LdapServerConfigurationFragment"
|
||||
android:label="LdapServerConfigurationFragment"
|
||||
tools:layout="@layout/settings_contacts_ldap" >
|
||||
<argument
|
||||
android:name="serverUrl"
|
||||
app:argType="string"
|
||||
app:nullable="true" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/cardDavAddressBookConfigurationFragment"
|
||||
android:name="org.linphone.ui.main.settings.fragment.CardDavAddressBookConfigurationFragment"
|
||||
android:label="CardDavAddressBookConfigurationFragment"
|
||||
tools:layout="@layout/settings_contacts_carddav" >
|
||||
<argument
|
||||
android:name="displayName"
|
||||
app:argType="string"
|
||||
app:nullable="true" />
|
||||
</fragment>
|
||||
|
||||
</navigation>
|
||||
|
|
@ -203,6 +203,29 @@
|
|||
<string name="settings_conversations_export_media_title">Exporter les médias dans la gallerie</string>
|
||||
<string name="settings_conversations_export_media_subtitle">Les médias des messages éphémères ne seront jamais exportés</string>
|
||||
<string name="settings_contacts_title">Contacts</string>
|
||||
<string name="settings_contacts_add_ldap_server_title">Ajouter un serveur LDAP</string>
|
||||
<string name="settings_contacts_edit_ldap_server_title">Editer le serveur LDAP</string>
|
||||
<string name="settings_contacts_add_carddav_server_title">Ajouter un carnet d\'adresse CardDAV</string>
|
||||
<string name="settings_contacts_edit_carddav_server_title">Editer le carnet d\'adresse CardDAV</string>
|
||||
<string name="settings_contacts_carddav_name_title">Nom d\'affichage</string>
|
||||
<string name="settings_contacts_carddav_server_url_title">URL du serveur</string>
|
||||
<string name="settings_contacts_carddav_username_title">Nom d\'utilisateur</string>
|
||||
<string name="settings_contacts_carddav_password_title">Mot de passe</string>
|
||||
<string name="settings_contacts_carddav_realm_title">Domaine d\'authentification</string>
|
||||
<string name="settings_contacts_carddav_add_title">Ajouter le carnet d\'adresse</string>
|
||||
<string name="settings_contacts_ldap_server_url_title">URL du serveur</string>
|
||||
<string name="settings_contacts_ldap_bind_dn_title">Bind DN</string>
|
||||
<string name="settings_contacts_ldap_password_title">Mot de passe</string>
|
||||
<string name="settings_contacts_ldap_use_tls_title">Utiliser TLS</string>
|
||||
<string name="settings_contacts_ldap_search_base_title">Base de recherche (ne peut être vide)</string>
|
||||
<string name="settings_contacts_ldap_search_filter_title">Filtre</string>
|
||||
<string name="settings_contacts_ldap_max_results_title">Nombre de résultats maximum</string>
|
||||
<string name="settings_contacts_ldap_request_timeout_title">Durée maximum</string>
|
||||
<string name="settings_contacts_ldap_request_delay_title">Délai entre 2 requêtes (en secondes)</string>
|
||||
<string name="settings_contacts_ldap_min_characters_title">Nombre minimum de caractères pour lancer la requête (en millisecondes)</string>
|
||||
<string name="settings_contacts_ldap_name_attributes_title">Attributs de nom</string>
|
||||
<string name="settings_contacts_ldap_sip_attributes_title">Attributs SIP</string>
|
||||
<string name="settings_contacts_ldap_sip_domain_title">Domaine SIP</string>
|
||||
<string name="settings_meetings_title">Réunions</string>
|
||||
<string name="settings_meetings_default_layout_title">Disposition par défaut</string>
|
||||
<string name="settings_meetings_layout_active_speaker_label">Intervenant actif</string>
|
||||
|
|
|
|||
|
|
@ -247,6 +247,29 @@
|
|||
<string name="settings_conversations_export_media_title">Export media in native gallery</string>
|
||||
<string name="settings_conversations_export_media_subtitle">Media from ephemeral messages will never be exported</string>
|
||||
<string name="settings_contacts_title">Contacts</string>
|
||||
<string name="settings_contacts_add_ldap_server_title">Add LDAP server</string>
|
||||
<string name="settings_contacts_edit_ldap_server_title">Edit LDAP server</string>
|
||||
<string name="settings_contacts_add_carddav_server_title">Add CardDAV address book</string>
|
||||
<string name="settings_contacts_edit_carddav_server_title">Edit CardDAV address book</string>
|
||||
<string name="settings_contacts_carddav_name_title">Display name</string>
|
||||
<string name="settings_contacts_carddav_server_url_title">Server URL</string>
|
||||
<string name="settings_contacts_carddav_username_title">Username</string>
|
||||
<string name="settings_contacts_carddav_password_title">Password</string>
|
||||
<string name="settings_contacts_carddav_realm_title">Auth realm</string>
|
||||
<string name="settings_contacts_carddav_add_title">Add address book</string>
|
||||
<string name="settings_contacts_ldap_server_url_title">Server URL</string>
|
||||
<string name="settings_contacts_ldap_bind_dn_title">Bind DN</string>
|
||||
<string name="settings_contacts_ldap_password_title">Password</string>
|
||||
<string name="settings_contacts_ldap_use_tls_title">Use TLS</string>
|
||||
<string name="settings_contacts_ldap_search_base_title">Search</string>
|
||||
<string name="settings_contacts_ldap_search_filter_title">Search base (can\'t be empty)</string>
|
||||
<string name="settings_contacts_ldap_max_results_title">Filter</string>
|
||||
<string name="settings_contacts_ldap_request_timeout_title">Max results</string>
|
||||
<string name="settings_contacts_ldap_request_delay_title">Timeout (in seconds)</string>
|
||||
<string name="settings_contacts_ldap_min_characters_title">Delay between two requests (in milliseconds)</string>
|
||||
<string name="settings_contacts_ldap_name_attributes_title">Name attributes</string>
|
||||
<string name="settings_contacts_ldap_sip_attributes_title">SIP attributes</string>
|
||||
<string name="settings_contacts_ldap_sip_domain_title">SIP domain</string>
|
||||
<string name="settings_meetings_title">Meetings</string>
|
||||
<string name="settings_meetings_default_layout_title">Default layout</string>
|
||||
<string name="settings_meetings_layout_active_speaker_label">Active speaker</string>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue