Reworked proxy/outbound proxy settings in account advanced settings

This commit is contained in:
Sylvain Berfini 2025-10-02 15:51:27 +02:00
parent 416cc6ea7f
commit 2ea38abdfe
12 changed files with 330 additions and 127 deletions

View file

@ -41,6 +41,7 @@ import org.linphone.ui.GenericActivity
import org.linphone.ui.GenericFragment
import org.linphone.ui.assistant.viewmodel.ThirdPartySipAccountLoginViewModel
import org.linphone.ui.main.sso.fragment.SingleSignOnFragmentDirections
import org.linphone.utils.DialogUtils
import org.linphone.utils.PhoneNumberUtils
@UiThread
@ -98,6 +99,10 @@ class ThirdPartySipAccountLoginFragment : GenericFragment() {
goBack()
}
binding.setOutboundProxyTooltipClickListener {
showOutboundProxyInfoDialog()
}
viewModel.showPassword.observe(viewLifecycleOwner) {
lifecycleScope.launch {
delay(50)
@ -159,4 +164,9 @@ class ThirdPartySipAccountLoginFragment : GenericFragment() {
private fun goBack() {
findNavController().popBackStack()
}
private fun showOutboundProxyInfoDialog() {
val dialog = DialogUtils.getAccountOutboundProxyHelpDialog(requireActivity())
dialog.show()
}
}

View file

@ -67,6 +67,8 @@ class ThirdPartySipAccountLoginViewModel
val expandAdvancedSettings = MutableLiveData<Boolean>()
val proxy = MutableLiveData<String>()
val outboundProxy = MutableLiveData<String>()
val loginEnabled = MediatorLiveData<Boolean>()
@ -236,8 +238,27 @@ class ThirdPartySipAccountLoginViewModel
}
accountParams.identityAddress = identityAddress
val proxyServerValue = proxy.value.orEmpty().trim()
val proxyServerAddress = if (proxyServerValue.isNotEmpty()) {
val server = if (proxyServerValue.startsWith("sip:")) {
proxyServerValue
} else {
"sip:$proxyServerValue"
}
Factory.instance().createAddress(server)
} else {
domainAddress ?: Factory.instance().createAddress("sip:$domainWithoutSip")
}
proxyServerAddress?.transport = when (transport.value.orEmpty().trim()) {
TransportType.Tcp.name.uppercase(Locale.getDefault()) -> TransportType.Tcp
TransportType.Tls.name.uppercase(Locale.getDefault()) -> TransportType.Tls
else -> TransportType.Udp
}
Log.i("$TAG Created proxy server SIP address [${proxyServerAddress?.asStringUriOnly()}]")
accountParams.serverAddress = proxyServerAddress
val outboundProxyValue = outboundProxy.value.orEmpty().trim()
val serverAddress = if (outboundProxyValue.isNotEmpty()) {
val outboundProxyAddress = if (outboundProxyValue.isNotEmpty()) {
val server = if (outboundProxyValue.startsWith("sip:")) {
outboundProxyValue
} else {
@ -245,16 +266,17 @@ class ThirdPartySipAccountLoginViewModel
}
Factory.instance().createAddress(server)
} else {
domainAddress ?: Factory.instance().createAddress("sip:$domainWithoutSip")
null
}
serverAddress?.transport = when (transport.value.orEmpty().trim()) {
TransportType.Tcp.name.uppercase(Locale.getDefault()) -> TransportType.Tcp
TransportType.Tls.name.uppercase(Locale.getDefault()) -> TransportType.Tls
else -> TransportType.Udp
if (outboundProxyAddress != null) {
outboundProxyAddress.transport = when (transport.value.orEmpty().trim()) {
TransportType.Tcp.name.uppercase(Locale.getDefault()) -> TransportType.Tcp
TransportType.Tls.name.uppercase(Locale.getDefault()) -> TransportType.Tls
else -> TransportType.Udp
}
Log.i("$TAG Created outbound proxy server SIP address [${outboundProxyAddress?.asStringUriOnly()}]")
accountParams.setRoutesAddresses(arrayOf(outboundProxyAddress))
}
Log.i("$TAG Created proxy server SIP address [${serverAddress?.asStringUriOnly()}]")
accountParams.serverAddress = serverAddress
val prefix = internationalPrefix.value.orEmpty().trim()
val isoCountryCode = internationalPrefixIsoCountryCode.value.orEmpty()

View file

@ -23,16 +23,12 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import androidx.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import java.util.Locale
import org.linphone.R
import org.linphone.core.TransportType
import org.linphone.core.tools.Log
import org.linphone.databinding.AccountSettingsFragmentBinding
import org.linphone.ui.GenericActivity
@ -54,22 +50,6 @@ class AccountSettingsFragment : GenericMainFragment() {
private lateinit var viewModel: AccountSettingsViewModel
private val transportDropdownListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
val transport = viewModel.availableTransports[position]
val transportType = when (transport) {
TransportType.Tcp.name.uppercase(Locale.getDefault()) -> TransportType.Tcp
TransportType.Tls.name.uppercase(Locale.getDefault()) -> TransportType.Tls
else -> TransportType.Udp
}
Log.i("$TAG Selected transport updated [$transport] -> [${transportType.name}]")
viewModel.selectedTransport.value = transportType
}
override fun onNothingSelected(parent: AdapterView<*>?) {
}
}
override fun goBack(): Boolean {
try {
return findNavController().popBackStack()
@ -110,13 +90,15 @@ class AccountSettingsFragment : GenericMainFragment() {
showUpdatePasswordDialog()
}
binding.setOutboundProxyTooltipClickListener {
showOutboundProxyInfoDialog()
}
viewModel.accountFoundEvent.observe(viewLifecycleOwner) {
it.consume { found ->
if (found) {
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
setupTransportDropdown()
}
} else {
Log.e(
@ -159,20 +141,8 @@ class AccountSettingsFragment : GenericMainFragment() {
dialog.show()
}
private fun setupTransportDropdown() {
val adapter = ArrayAdapter(
requireContext(),
R.layout.drop_down_item,
viewModel.availableTransports
)
adapter.setDropDownViewResource(R.layout.generic_dropdown_cell)
val currentTransport = viewModel.selectedTransport.value?.name?.uppercase(
Locale.getDefault()
)
binding.accountAdvancedSettings.transportSpinner.adapter = adapter
binding.accountAdvancedSettings.transportSpinner.setSelection(
viewModel.availableTransports.indexOf(currentTransport)
)
binding.accountAdvancedSettings.transportSpinner.onItemSelectedListener = transportDropdownListener
private fun showOutboundProxyInfoDialog() {
val dialog = DialogUtils.getAccountOutboundProxyHelpDialog(requireActivity())
dialog.show()
}
}

View file

@ -62,7 +62,7 @@ class AccountSettingsViewModel
val sipProxyServer = MutableLiveData<String>()
val outboundProxyEnabled = MutableLiveData<Boolean>()
val outboundProxyServer = MutableLiveData<String>()
val stunServer = MutableLiveData<String>()
@ -155,7 +155,7 @@ class AccountSettingsViewModel
selectedTransport.postValue(transportType)
sipProxyServer.postValue(params.serverAddress?.asStringUriOnly())
outboundProxyEnabled.postValue(params.isOutboundProxyEnabled)
outboundProxyServer.postValue(params.routesAddresses.first().asStringUriOnly())
natPolicy = params.natPolicy ?: core.createNatPolicy()
stunServer.postValue(natPolicy.stunServer)
@ -222,13 +222,28 @@ class AccountSettingsViewModel
val server = sipProxyServer.value.orEmpty()
if (server.isNotEmpty()) {
Log.i("$TAG Proxy server set to [$server]")
val serverAddress = core.interpretUrl(server, false)
if (serverAddress != null) {
serverAddress.transport = selectedTransport.value
newParams.serverAddress = serverAddress
} else {
Log.e("$TAG Failed to parse proxy server!")
}
}
newParams.isOutboundProxyEnabled = outboundProxyEnabled.value == true
val outboundProxy = outboundProxyServer.value.orEmpty()
if (outboundProxy.isNotEmpty()) {
Log.i("$TAG Outbound proxy server set to [$outboundProxy]")
val outboundProxyAddress = core.interpretUrl(outboundProxy, false)
if (outboundProxyAddress != null) {
outboundProxyAddress.transport = selectedTransport.value
newParams.setRoutesAddresses(arrayOf(outboundProxyAddress))
} else {
Log.e("$TAG Failed to parse outbound proxy server!")
}
} else {
newParams.setRoutesAddresses(null)
}
if (::natPolicy.isInitialized) {
Log.i("$TAG Also applying changes to NAT policy")

View file

@ -68,6 +68,7 @@ import org.linphone.ui.main.contacts.model.NumberOrAddressPickerDialogModel
import org.linphone.ui.main.model.GroupSetOrEditSubjectDialogModel
import androidx.core.graphics.drawable.toDrawable
import org.linphone.databinding.DialogDeleteChatMessageBinding
import org.linphone.databinding.DialogManageAccountOutboundProxyHelpBinding
import org.linphone.ui.main.chat.model.MessageDeleteDialogModel
class DialogUtils {
@ -122,6 +123,23 @@ class DialogUtils {
return dialog
}
@UiThread
fun getAccountOutboundProxyHelpDialog(context: Context): Dialog {
val binding: DialogManageAccountOutboundProxyHelpBinding = DataBindingUtil.inflate(
LayoutInflater.from(context),
R.layout.dialog_manage_account_outbound_proxy_help,
null,
false
)
val dialog = getDialog(context, binding)
binding.setDismissClickListener {
dialog.dismiss()
}
return dialog
}
@UiThread
fun getConfirmAccountRemovalDialog(
context: Context,

View file

@ -9,6 +9,9 @@
<variable
name="backClickListener"
type="View.OnClickListener" />
<variable
name="outboundProxyTooltipClickListener"
type="View.OnClickListener" />
<variable
name="viewModel"
type="org.linphone.ui.assistant.viewmodel.ThirdPartySipAccountLoginViewModel" />
@ -312,7 +315,7 @@
android:id="@+id/advanced_settings_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="authentication_id_label, authentication_id, outbound_proxy_label, outbound_proxy"
app:constraint_referenced_ids="authentication_id_label, authentication_id, proxy, proxy_label, outbound_proxy_label, outbound_proxy, outbound_proxy_tooltip"
android:visibility="@{viewModel.expandAdvancedSettings ? View.VISIBLE : View.GONE, default=gone}" />
<androidx.appcompat.widget.AppCompatTextView
@ -350,7 +353,7 @@
<androidx.appcompat.widget.AppCompatTextView
style="@style/header_style"
android:id="@+id/outbound_proxy_label"
android:id="@+id/proxy_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
@ -359,8 +362,54 @@
android:labelFor="@id/outbound_proxy"
android:text="@string/account_settings_sip_proxy_url_title"
app:layout_constraintTop_toBottomOf="@id/authentication_id"
app:layout_constraintStart_toStartOf="@id/proxy"/>
<androidx.appcompat.widget.AppCompatEditText
style="@style/default_text_style"
android:id="@+id/proxy"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:text="@={viewModel.outboundProxy, default=`sip12.example.net`}"
android:textSize="14sp"
android:textColor="?attr/color_main2_600"
android:background="@drawable/edit_text_background"
android:inputType="text|textUri"
android:hint="@string/account_settings_sip_proxy_url_title"
app:layout_constraintWidth_max="@dimen/text_input_max_width"
app:layout_constraintTop_toBottomOf="@id/proxy_label"
app:layout_constraintStart_toStartOf="@id/advanced_settings"
app:layout_constraintEnd_toEndOf="@id/advanced_settings"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/header_style"
android:id="@+id/outbound_proxy_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:labelFor="@id/outbound_proxy"
android:text="@string/account_settings_outbound_proxy_title"
app:layout_constraintTop_toBottomOf="@id/proxy"
app:layout_constraintStart_toStartOf="@id/outbound_proxy"/>
<ImageView
android:id="@+id/outbound_proxy_tooltip"
android:onClick="@{outboundProxyTooltipClickListener}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:src="@drawable/info"
android:contentDescription="@string/content_description_click_for_more_info"
app:tint="?attr/color_main2_600"
app:layout_constraintTop_toTopOf="@id/outbound_proxy_label"
app:layout_constraintBottom_toBottomOf="@id/outbound_proxy_label"
app:layout_constraintEnd_toEndOf="@id/outbound_proxy" />
<androidx.appcompat.widget.AppCompatEditText
style="@style/default_text_style"
android:id="@+id/outbound_proxy"
@ -375,7 +424,7 @@
android:textColor="?attr/color_main2_600"
android:background="@drawable/edit_text_background"
android:inputType="text|textUri"
android:hint="@string/account_settings_sip_proxy_url_title"
android:hint="@string/account_settings_outbound_proxy_title"
app:layout_constraintWidth_max="@dimen/text_input_max_width"
app:layout_constraintTop_toBottomOf="@id/outbound_proxy_label"
app:layout_constraintStart_toStartOf="@id/advanced_settings"

View file

@ -8,6 +8,9 @@
<variable
name="updatePasswordClickListener"
type="View.OnClickListener" />
<variable
name="outboundProxyTooltipClickListener"
type="View.OnClickListener" />
<variable
name="viewModel"
type="org.linphone.ui.main.settings.viewmodel.AccountSettingsViewModel" />
@ -18,55 +21,6 @@
android:layout_height="wrap_content"
android:background="@drawable/shape_squircle_white_background">
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_title_padding_style"
android:id="@+id/transport_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/assistant_sip_account_transport_protocol"
android:maxLines="2"
android:ellipsize="end"
android:labelFor="@id/transport_spinner"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<androidx.appcompat.widget.AppCompatSpinner
style="@style/default_text_style"
android:id="@+id/transport_spinner"
android:layout_width="0dp"
android:layout_height="50dp"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:textSize="14sp"
android:textColor="@color/gray_main2_600"
android:gravity="center_vertical"
android:overlapAnchor="false"
android:dropDownVerticalOffset="25dp"
android:spinnerMode="dropdown"
android:popupBackground="@drawable/shape_squircle_white_background"
android:background="@drawable/edit_text_background"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintWidth_max="@dimen/text_input_max_width"
app:layout_constraintTop_toBottomOf="@id/transport_title"
app:layout_constraintStart_toStartOf="@id/transport_title"
app:layout_constraintEnd_toEndOf="@id/transport_title" />
<ImageView
android:id="@+id/transport_spinner_caret"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spinner_caret_end_margin"
android:src="@drawable/caret_down"
android:contentDescription="@null"
app:tint="?attr/color_main2_600"
app:layout_constraintTop_toTopOf="@id/transport_spinner"
app:layout_constraintBottom_toBottomOf="@id/transport_spinner"
app:layout_constraintEnd_toEndOf="@id/transport_spinner"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_title_padding_style"
android:id="@+id/sip_proxy_title"
@ -79,7 +33,7 @@
android:maxLines="2"
android:ellipsize="end"
android:labelFor="@id/sip_proxy"
app:layout_constraintTop_toBottomOf="@id/transport_spinner"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
@ -102,32 +56,53 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/sip_proxy_title"/>
<com.google.android.material.materialswitch.MaterialSwitch
style="@style/material_switch_style"
android:id="@+id/outbound_proxy_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginEnd="16dp"
android:checked="@={viewModel.outboundProxyEnabled}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/sip_proxy" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_title_style"
style="@style/settings_title_padding_style"
android:id="@+id/outbound_proxy_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="10dp"
android:layout_marginEnd="16dp"
android:text="@string/account_settings_outbound_proxy_title"
android:maxLines="2"
android:ellipsize="end"
android:labelFor="@id/outbound_proxy_switch"
app:layout_constraintTop_toTopOf="@id/outbound_proxy_switch"
app:layout_constraintBottom_toBottomOf="@id/outbound_proxy_switch"
android:labelFor="@id/sip_proxy"
app:layout_constraintTop_toBottomOf="@id/sip_proxy"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/outbound_proxy_switch"/>
app:layout_constraintEnd_toEndOf="parent"/>
<ImageView
android:id="@+id/outbound_proxy_tooltip"
android:onClick="@{outboundProxyTooltipClickListener}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:src="@drawable/info"
android:contentDescription="@string/content_description_click_for_more_info"
app:tint="?attr/color_main2_600"
app:layout_constraintTop_toTopOf="@id/outbound_proxy_title"
app:layout_constraintBottom_toBottomOf="@id/outbound_proxy_title"
app:layout_constraintEnd_toEndOf="@id/outbound_proxy_title" />
<androidx.appcompat.widget.AppCompatEditText
style="@style/default_text_style"
android:id="@+id/outbound_proxy"
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.outboundProxyServer}"
android:inputType="text|textUri"
android:hint="@string/account_settings_outbound_proxy_title"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintWidth_max="@dimen/text_input_max_width"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/outbound_proxy_title"/>
<com.google.android.material.materialswitch.MaterialSwitch
style="@style/material_switch_style"
@ -138,7 +113,7 @@
android:layout_marginEnd="16dp"
android:checked="@={viewModel.avpfEnabled}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/outbound_proxy_switch" />
app:layout_constraintTop_toBottomOf="@id/outbound_proxy" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_title_style"

View file

@ -11,6 +11,9 @@
<variable
name="updatePasswordClickListener"
type="View.OnClickListener" />
<variable
name="outboundProxyTooltipClickListener"
type="View.OnClickListener" />
<variable
name="viewModel"
type="org.linphone.ui.main.settings.viewmodel.AccountSettingsViewModel" />
@ -310,6 +313,7 @@
android:visibility="@{viewModel.expandAdvancedSettings ? View.VISIBLE : View.GONE}"
layout="@layout/account_advanced_settings"
bind:updatePasswordClickListener="@{updatePasswordClickListener}"
bind:outboundProxyTooltipClickListener="@{outboundProxyTooltipClickListener}"
bind:viewModel="@{viewModel}"/>
</LinearLayout>

View file

@ -9,6 +9,9 @@
<variable
name="backClickListener"
type="View.OnClickListener" />
<variable
name="outboundProxyTooltipClickListener"
type="View.OnClickListener" />
<variable
name="viewModel"
type="org.linphone.ui.assistant.viewmodel.ThirdPartySipAccountLoginViewModel" />
@ -261,7 +264,7 @@
android:id="@+id/advanced_settings_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="authentication_id_label, authentication_id, outbound_proxy_label, outbound_proxy"
app:constraint_referenced_ids="authentication_id_label, authentication_id, proxy_label, proxy, outbound_proxy_label, outbound_proxy, outbound_proxy_tooltip"
android:visibility="@{viewModel.expandAdvancedSettings ? View.VISIBLE : View.GONE, default=gone}" />
<androidx.appcompat.widget.AppCompatTextView
@ -299,7 +302,7 @@
<androidx.appcompat.widget.AppCompatTextView
style="@style/header_style"
android:id="@+id/outbound_proxy_label"
android:id="@+id/proxy_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
@ -308,8 +311,54 @@
android:labelFor="@id/outbound_proxy"
android:text="@string/account_settings_sip_proxy_url_title"
app:layout_constraintTop_toBottomOf="@id/authentication_id"
app:layout_constraintStart_toStartOf="@id/proxy"/>
<androidx.appcompat.widget.AppCompatEditText
style="@style/default_text_style"
android:id="@+id/proxy"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:text="@={viewModel.proxy, default=`sip.example.net`}"
android:textSize="14sp"
android:textColor="?attr/color_main2_600"
android:background="@drawable/edit_text_background"
android:inputType="text|textUri"
android:hint="@string/account_settings_sip_proxy_url_title"
app:layout_constraintWidth_max="@dimen/text_input_max_width"
app:layout_constraintTop_toBottomOf="@id/proxy_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/header_style"
android:id="@+id/outbound_proxy_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:labelFor="@id/outbound_proxy"
android:text="@string/account_settings_outbound_proxy_title"
app:layout_constraintTop_toBottomOf="@id/proxy"
app:layout_constraintStart_toStartOf="@id/outbound_proxy"/>
<ImageView
android:id="@+id/outbound_proxy_tooltip"
android:onClick="@{outboundProxyTooltipClickListener}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:src="@drawable/info"
android:contentDescription="@string/content_description_click_for_more_info"
app:tint="?attr/color_main2_600"
app:layout_constraintTop_toTopOf="@id/outbound_proxy_label"
app:layout_constraintBottom_toBottomOf="@id/outbound_proxy_label"
app:layout_constraintEnd_toEndOf="@id/outbound_proxy" />
<androidx.appcompat.widget.AppCompatEditText
style="@style/default_text_style"
android:id="@+id/outbound_proxy"
@ -324,7 +373,7 @@
android:textColor="?attr/color_main2_600"
android:background="@drawable/edit_text_background"
android:inputType="text|textUri"
android:hint="@string/account_settings_sip_proxy_url_title"
android:hint="@string/account_settings_outbound_proxy_title"
app:layout_constraintWidth_max="@dimen/text_input_max_width"
app:layout_constraintTop_toBottomOf="@id/outbound_proxy_label"
app:layout_constraintStart_toStartOf="parent"

View file

@ -0,0 +1,87 @@
<?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" />
<variable
name="dismissClickListener"
type="View.OnClickListener" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:onClick="@{dismissClickListener}"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/dialog_background"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="2dp"
android:src="@drawable/shape_dialog_background"
android:contentDescription="@null"
app:layout_constraintWidth_max="@dimen/dialog_max_width"
app:layout_constraintBottom_toBottomOf="@id/anchor"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/title" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:paddingTop="@dimen/dialog_top_bottom_margin"
android:text="@string/manage_account_outbound_proxy"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintBottom_toTopOf="@id/message"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style"
android:id="@+id/message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:layout_marginTop="10dp"
android:text="@string/manage_account_dialog_outbound_proxy_help_message"
android:textSize="14sp"
app:layout_constraintBottom_toTopOf="@id/confirm"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintTop_toBottomOf="@id/title" />
<androidx.appcompat.widget.AppCompatTextView
android:onClick="@{dismissClickListener}"
style="@style/primary_dialog_button_label_style"
android:id="@+id/confirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:text="@string/dialog_understood"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintTop_toBottomOf="@id/message"
app:layout_constraintBottom_toTopOf="@id/anchor"/>
<View
android:id="@+id/anchor"
android:layout_width="wrap_content"
android:layout_height="@dimen/dialog_top_bottom_margin"
app:layout_constraintTop_toBottomOf="@id/confirm"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -357,13 +357,15 @@
<string name="manage_account_device_last_connection">Dernière connexion :</string>
<string name="manage_account_dialog_remove_account_title">Se déconnecter du compte ?</string>
<string name="manage_account_dialog_remove_account_message">Si vous souhaitez supprimer définitivement votre compte rendez-vous sur : https://sip.linphone.org</string>
<string name="manage_account_outbound_proxy">Proxy SIP sortant</string>
<string name="manage_account_dialog_outbound_proxy_help_message">Si ce champ est rempli, l\'outbound proxy sera activé automatiquement. Laissez-le vide pour le désactiver.</string>
<string name="account_settings_title">Paramètres de compte</string>
<string name="account_settings_push_notification_title">Activer les notifications push</string>
<string name="account_settings_push_notification_not_available_title">Notifications push non disponibles</string>
<string name="account_settings_im_encryption_mandatory_title">Chiffrement obligatoire des conversations</string>
<string name="account_settings_sip_proxy_url_title">URL du serveur mandataire</string>
<string name="account_settings_outbound_proxy_title">Serveur mandataire sortant</string>
<string name="account_settings_sip_proxy_url_title">Registrar URI</string>
<string name="account_settings_outbound_proxy_title">URI du proxy SIP sortant</string>
<string name="account_settings_nat_policy_title">Paramètres de politique NAT</string>
<string name="account_settings_stun_server_url_title">URL du serveur STUN/TURN</string>
<string name="account_settings_enable_ice_title">Activer ICE</string>

View file

@ -399,13 +399,15 @@
<string name="manage_account_device_last_connection">Last connection:</string>
<string name="manage_account_dialog_remove_account_title">Sign out of your account?</string>
<string name="manage_account_dialog_remove_account_message">If you wish to delete your account permanently, go to: https://sip.linphone.org</string>
<string name="manage_account_outbound_proxy">Outbound SIP Proxy</string>
<string name="manage_account_dialog_outbound_proxy_help_message">If this field is filled, the outbound proxy will be enabled automatically. Leave it empty to disable it.</string>
<string name="account_settings_title">Account settings</string>
<string name="account_settings_push_notification_title">Allow push notifications</string>
<string name="account_settings_push_notification_not_available_title">Push notifications aren\'t available!</string>
<string name="account_settings_im_encryption_mandatory_title">IM encryption mandatory</string>
<string name="account_settings_sip_proxy_url_title">SIP proxy server URL</string>
<string name="account_settings_outbound_proxy_title">Outbound proxy</string>
<string name="account_settings_sip_proxy_url_title">Registrar URI</string>
<string name="account_settings_outbound_proxy_title">Outbound SIP Proxy URI</string>
<string name="account_settings_nat_policy_title">NAT policy settings</string>
<string name="account_settings_stun_server_url_title">STUN/TURN server URL</string>
<string name="account_settings_enable_ice_title">Enable ICE</string>