Replaced deprecated ProxyConfig object by Account
This commit is contained in:
parent
4f6b416b7e
commit
daa789e672
25 changed files with 264 additions and 159 deletions
|
@ -102,7 +102,7 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin
|
|||
startActivity(intent)
|
||||
}
|
||||
|
||||
if (coreContext.core.proxyConfigList.isEmpty()) {
|
||||
if (coreContext.core.accountList.isEmpty()) {
|
||||
if (corePreferences.firstStart) {
|
||||
corePreferences.firstStart = false
|
||||
startActivity(Intent(this, AssistantActivity::class.java))
|
||||
|
@ -371,7 +371,7 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin
|
|||
|
||||
val peerAddress = coreContext.core.interpretUrl(addressToIM)?.asStringUriOnly()
|
||||
val localAddress =
|
||||
coreContext.core.defaultProxyConfig?.contact?.asStringUriOnly()
|
||||
coreContext.core.defaultAccount?.params?.identityAddress?.asStringUriOnly()
|
||||
val deepLink = "linphone-android://chat-room/$localAddress/$peerAddress"
|
||||
Log.i("[Main Activity] Starting deep link: $deepLink")
|
||||
findNavController(R.id.nav_host_fragment).navigate(Uri.parse(deepLink))
|
||||
|
|
|
@ -101,7 +101,7 @@ class ChatRoomCreationContactsAdapter(
|
|||
securityEnabled: Boolean
|
||||
) {
|
||||
val searchAddress = searchResult.address
|
||||
val isMyself = securityEnabled && searchAddress != null && coreContext.core.defaultProxyConfig?.identityAddress?.weakEqual(searchAddress) ?: false
|
||||
val isMyself = securityEnabled && searchAddress != null && coreContext.core.defaultAccount?.params?.identityAddress?.weakEqual(searchAddress) ?: false
|
||||
val limeCheck = !securityEnabled || (securityEnabled && searchResult.hasCapability(FriendCapability.LimeX3Dh))
|
||||
val groupCheck = !groupChatEnabled || (groupChatEnabled && searchResult.hasCapability(FriendCapability.GroupChat))
|
||||
val disabled = if (searchResult.friend != null) !limeCheck || !groupCheck || isMyself else false // Generated entry from search filter
|
||||
|
|
|
@ -107,7 +107,7 @@ class ChatRoomCreationViewModel : ErrorReportingViewModel() {
|
|||
}
|
||||
|
||||
fun updateContactsList() {
|
||||
val domain = if (sipContactsSelected.value == true) coreContext.core.defaultProxyConfig?.domain ?: "" else ""
|
||||
val domain = if (sipContactsSelected.value == true) coreContext.core.defaultAccount?.params?.domain ?: "" else ""
|
||||
val results = coreContext.contactsManager.magicSearch.getContactListFromFilter(filter.value.orEmpty(), domain)
|
||||
|
||||
val list = arrayListOf<SearchResult>()
|
||||
|
@ -145,7 +145,7 @@ class ChatRoomCreationViewModel : ErrorReportingViewModel() {
|
|||
|
||||
fun createOneToOneChat(searchResult: SearchResult) {
|
||||
waitForChatRoomCreation.value = true
|
||||
val defaultProxyConfig = coreContext.core.defaultProxyConfig
|
||||
val defaultAccount = coreContext.core.defaultAccount
|
||||
var room: ChatRoom?
|
||||
|
||||
val address = searchResult.address ?: coreContext.core.interpretUrl(searchResult.phoneNumber ?: "")
|
||||
|
@ -167,12 +167,13 @@ class ChatRoomCreationViewModel : ErrorReportingViewModel() {
|
|||
}
|
||||
|
||||
val participants = arrayOf(address)
|
||||
val localAddress = defaultProxyConfig?.identityAddress
|
||||
val localAddress: Address? = defaultAccount?.params?.identityAddress
|
||||
|
||||
room = coreContext.core.searchChatRoom(params, localAddress, null, participants)
|
||||
if (room == null) {
|
||||
Log.w("[Chat Room Creation] Couldn't find existing 1-1 chat room with remote ${address.asStringUriOnly()}, encryption=$encrypted and local identity ${localAddress?.asStringUriOnly()}")
|
||||
room = coreContext.core.createChatRoom(params, localAddress, participants)
|
||||
|
||||
if (encrypted) {
|
||||
room?.addListener(listener)
|
||||
} else {
|
||||
|
|
|
@ -125,7 +125,7 @@ class GroupInfoViewModel(val chatRoom: ChatRoom?) : ErrorReportingViewModel() {
|
|||
index += 1
|
||||
}
|
||||
|
||||
val chatRoom: ChatRoom? = coreContext.core.createChatRoom(params, coreContext.core.defaultProxyConfig?.identityAddress, addresses)
|
||||
val chatRoom: ChatRoom? = coreContext.core.createChatRoom(params, coreContext.core.defaultAccount?.params?.identityAddress, addresses)
|
||||
chatRoom?.addListener(listener)
|
||||
if (chatRoom == null) {
|
||||
Log.e("[Chat Room Group Info] Couldn't create chat room!")
|
||||
|
|
|
@ -169,9 +169,9 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont
|
|||
val value = address.asStringUriOnly()
|
||||
val presenceModel = contact.friend?.getPresenceModelForUriOrTel(value)
|
||||
val hasPresence = presenceModel?.basicStatus == PresenceBasicStatus.Open
|
||||
val isMe = coreContext.core.defaultProxyConfig?.identityAddress?.weakEqual(address) ?: false
|
||||
val isMe = coreContext.core.defaultAccount?.params?.identityAddress?.weakEqual(address) ?: false
|
||||
val secureChatAllowed = !isMe && contact.friend?.getPresenceModelForUriOrTel(value)?.hasCapability(FriendCapability.LimeX3Dh) ?: false
|
||||
val displayValue = if (coreContext.core.defaultProxyConfig?.domain == address.domain) (address.username ?: value) else value
|
||||
val displayValue = if (coreContext.core.defaultAccount?.params?.domain == address.domain) (address.username ?: value) else value
|
||||
val noa = ContactNumberOrAddressViewModel(address, hasPresence, displayValue, showSecureChat = secureChatAllowed, listener = listener)
|
||||
list.add(noa)
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont
|
|||
val hasPresence = presenceModel != null && presenceModel.basicStatus == PresenceBasicStatus.Open
|
||||
val contactAddress = presenceModel?.contact ?: number
|
||||
val address = coreContext.core.interpretUrl(contactAddress)
|
||||
val isMe = if (address != null) coreContext.core.defaultProxyConfig?.identityAddress?.weakEqual(address) ?: false else false
|
||||
val isMe = if (address != null) coreContext.core.defaultAccount?.params?.identityAddress?.weakEqual(address) ?: false else false
|
||||
val secureChatAllowed = !isMe && contact.friend?.getPresenceModelForUriOrTel(number)?.hasCapability(FriendCapability.LimeX3Dh) ?: false
|
||||
val noa = ContactNumberOrAddressViewModel(address, hasPresence, number, isSip = false, showSecureChat = secureChatAllowed, typeLabel = phoneNumber.typeLabel, listener = listener)
|
||||
list.add(noa)
|
||||
|
|
|
@ -48,11 +48,11 @@ class StatusFragment : GenericFragment<StatusFragmentBinding>() {
|
|||
ViewModelProvider(this).get(SharedMainViewModel::class.java)
|
||||
}
|
||||
|
||||
sharedViewModel.proxyConfigRemoved.observe(viewLifecycleOwner, {
|
||||
Log.i("[Status Fragment] A proxy config was removed, update default proxy state")
|
||||
val defaultProxy = coreContext.core.defaultProxyConfig
|
||||
if (defaultProxy != null) {
|
||||
viewModel.updateDefaultProxyConfigRegistrationStatus(defaultProxy.state)
|
||||
sharedViewModel.accountRemoved.observe(viewLifecycleOwner, {
|
||||
Log.i("[Status Fragment] An account was removed, update default account state")
|
||||
val defaultAccount = coreContext.core.defaultAccount
|
||||
if (defaultAccount != null) {
|
||||
viewModel.updateDefaultAccountRegistrationStatus(defaultAccount.state)
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -56,9 +56,9 @@ class AccountSettingsFragment : GenericFragment<SettingsAccountFragmentBinding>(
|
|||
|
||||
viewModel.linkPhoneNumberEvent.observe(viewLifecycleOwner, {
|
||||
it.consume {
|
||||
val authInfo = viewModel.proxyConfig.findAuthInfo()
|
||||
val authInfo = viewModel.account.findAuthInfo()
|
||||
if (authInfo == null) {
|
||||
Log.e("[Account Settings] Failed to find auth info for proxy config ${viewModel.proxyConfig}")
|
||||
Log.e("[Account Settings] Failed to find auth info for account ${viewModel.account}")
|
||||
} else {
|
||||
val args = Bundle()
|
||||
args.putString("Username", authInfo.username)
|
||||
|
@ -69,9 +69,9 @@ class AccountSettingsFragment : GenericFragment<SettingsAccountFragmentBinding>(
|
|||
}
|
||||
})
|
||||
|
||||
viewModel.proxyConfigRemovedEvent.observe(viewLifecycleOwner, {
|
||||
viewModel.accountRemovedEvent.observe(viewLifecycleOwner, {
|
||||
it.consume {
|
||||
sharedViewModel.proxyConfigRemoved.value = true
|
||||
sharedViewModel.accountRemoved.value = true
|
||||
findNavController().navigateUp()
|
||||
}
|
||||
})
|
||||
|
|
|
@ -54,8 +54,8 @@ class SettingsFragment : SecureFragment<SettingsFragmentBinding>() {
|
|||
|
||||
binding.setBackClickListener { findNavController().popBackStack() }
|
||||
|
||||
sharedViewModel.proxyConfigRemoved.observe(viewLifecycleOwner, {
|
||||
Log.i("[Settings] Proxy config removed, update accounts list")
|
||||
sharedViewModel.accountRemoved.observe(viewLifecycleOwner, {
|
||||
Log.i("[Settings] Account removed, update accounts list")
|
||||
viewModel.updateAccountsList()
|
||||
})
|
||||
|
||||
|
@ -68,7 +68,7 @@ class SettingsFragment : SecureFragment<SettingsFragmentBinding>() {
|
|||
|
||||
viewModel.accountsSettingsListener = object : SettingListenerStub() {
|
||||
override fun onAccountClicked(identity: String) {
|
||||
Log.i("[Settings] Navigation to settings for proxy with identity: $identity")
|
||||
Log.i("[Settings] Navigation to settings for account with identity: $identity")
|
||||
navigateToAccountSettings(identity)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,16 +38,16 @@ class AccountSettingsViewModelFactory(private val identity: String) :
|
|||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
||||
for (proxy in coreContext.core.proxyConfigList) {
|
||||
if (proxy.identityAddress?.asStringUriOnly() == identity) {
|
||||
return AccountSettingsViewModel(proxy) as T
|
||||
for (account in coreContext.core.accountList) {
|
||||
if (account.params.identityAddress?.asStringUriOnly() == identity) {
|
||||
return AccountSettingsViewModel(account) as T
|
||||
}
|
||||
}
|
||||
return AccountSettingsViewModel(coreContext.core.defaultProxyConfig!!) as T
|
||||
return AccountSettingsViewModel(coreContext.core.defaultAccount!!) as T
|
||||
}
|
||||
}
|
||||
|
||||
class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsViewModel() {
|
||||
class AccountSettingsViewModel(val account: Account) : GenericSettingsViewModel() {
|
||||
val isDefault = MutableLiveData<Boolean>()
|
||||
|
||||
val displayName = MutableLiveData<String>()
|
||||
|
@ -61,25 +61,24 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi
|
|||
|
||||
val waitForUnregister = MutableLiveData<Boolean>()
|
||||
|
||||
val proxyConfigRemovedEvent: MutableLiveData<Event<Boolean>> by lazy {
|
||||
val accountRemovedEvent: MutableLiveData<Event<Boolean>> by lazy {
|
||||
MutableLiveData<Event<Boolean>>()
|
||||
}
|
||||
|
||||
val displayUsernameInsteadOfIdentity = corePreferences.replaceSipUriByUsername
|
||||
|
||||
private var proxyConfigToDelete: ProxyConfig? = null
|
||||
private var accountToDelete: Account? = null
|
||||
|
||||
val listener: CoreListenerStub = object : CoreListenerStub() {
|
||||
val listener: AccountListenerStub = object : AccountListenerStub() {
|
||||
override fun onRegistrationStateChanged(
|
||||
core: Core,
|
||||
cfg: ProxyConfig,
|
||||
account: Account,
|
||||
state: RegistrationState,
|
||||
message: String
|
||||
) {
|
||||
if (state == RegistrationState.Cleared && cfg == proxyConfigToDelete) {
|
||||
Log.i("[Account Settings] Proxy config to remove registration is now cleared")
|
||||
if (state == RegistrationState.Cleared && account == accountToDelete) {
|
||||
Log.i("[Account Settings] Account to remove registration is now cleared")
|
||||
waitForUnregister.value = false
|
||||
deleteProxyConfig(cfg)
|
||||
deleteAccount(account)
|
||||
} else {
|
||||
update()
|
||||
}
|
||||
|
@ -90,44 +89,94 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi
|
|||
|
||||
val userNameListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
// TODO
|
||||
val params = account.params.clone()
|
||||
val identity = params.identityAddress
|
||||
if (identity != null) {
|
||||
identity.username = newValue
|
||||
params.identityAddress = identity
|
||||
account.params = params
|
||||
} else {
|
||||
Log.e("[Account Settings] Account doesn't have an identity yet")
|
||||
}
|
||||
}
|
||||
}
|
||||
val userName = MutableLiveData<String>()
|
||||
|
||||
val userIdListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
// TODO
|
||||
val authInfo = account.findAuthInfo()
|
||||
if (authInfo != null) {
|
||||
authInfo.userid = newValue
|
||||
} else {
|
||||
Log.e("[Account Settings] Failed to find the matching auth info")
|
||||
}
|
||||
}
|
||||
}
|
||||
val userId = MutableLiveData<String>()
|
||||
|
||||
val passwordListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
// TODO
|
||||
val authInfo = account.findAuthInfo()
|
||||
if (authInfo != null) {
|
||||
authInfo.password = newValue
|
||||
} else {
|
||||
Log.w("[Account Settings] Failed to find the matching auth info")
|
||||
val params = account.params
|
||||
val identity = params.identityAddress
|
||||
if (identity != null && identity.username != null) {
|
||||
val newAuthInfo = Factory.instance()
|
||||
.createAuthInfo(identity.username!!, userId.value, newValue, null, null, identity.domain)
|
||||
core.addAuthInfo(newAuthInfo)
|
||||
} else {
|
||||
Log.e("[Account Settings] Failed to find the user's identity, can't create a new auth info")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val password = MutableLiveData<String>()
|
||||
|
||||
val domainListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
// TODO
|
||||
val params = account.params.clone()
|
||||
val identity = params.identityAddress
|
||||
if (identity != null) {
|
||||
val authInfo = account.findAuthInfo()
|
||||
if (authInfo != null) {
|
||||
authInfo.domain = newValue
|
||||
} else {
|
||||
Log.e("[Account Settings] Failed to find the matching auth info")
|
||||
}
|
||||
|
||||
identity.domain = newValue
|
||||
params.identityAddress = identity
|
||||
account.params = params
|
||||
} else {
|
||||
Log.e("[Account Settings] Account doesn't have an identity yet")
|
||||
}
|
||||
}
|
||||
}
|
||||
val domain = MutableLiveData<String>()
|
||||
|
||||
val displayNameListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
proxyConfig.identityAddress?.displayName = newValue
|
||||
val params = account.params.clone()
|
||||
val identity = params.identityAddress
|
||||
if (identity != null) {
|
||||
identity.displayName = newValue
|
||||
params.identityAddress = identity
|
||||
account.params = params
|
||||
} else {
|
||||
Log.e("[Account Settings] Account doesn't have an identity yet")
|
||||
}
|
||||
}
|
||||
}
|
||||
// displayName mutable is above
|
||||
|
||||
val disableListener = object : SettingListenerStub() {
|
||||
override fun onBoolValueChanged(newValue: Boolean) {
|
||||
proxyConfig.edit()
|
||||
proxyConfig.enableRegister(!newValue)
|
||||
proxyConfig.done()
|
||||
val params = account.params.clone()
|
||||
params.registerEnabled = !newValue
|
||||
account.params = params
|
||||
}
|
||||
}
|
||||
val disable = MutableLiveData<Boolean>()
|
||||
|
@ -135,14 +184,14 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi
|
|||
val isDefaultListener = object : SettingListenerStub() {
|
||||
override fun onBoolValueChanged(newValue: Boolean) {
|
||||
if (newValue) {
|
||||
core.defaultProxyConfig = proxyConfig
|
||||
core.defaultAccount = account
|
||||
}
|
||||
}
|
||||
}
|
||||
// isDefault mutable is above
|
||||
|
||||
private fun deleteProxyConfig(cfg: ProxyConfig) {
|
||||
val authInfo = cfg.findAuthInfo()
|
||||
private fun deleteAccount(account: Account) {
|
||||
val authInfo = account.findAuthInfo()
|
||||
if (authInfo != null) {
|
||||
Log.i("[Account Settings] Found auth info $authInfo, removing it.")
|
||||
core.removeAuthInfo(authInfo)
|
||||
|
@ -150,42 +199,44 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi
|
|||
Log.w("[Account Settings] Couldn't find matching auth info...")
|
||||
}
|
||||
|
||||
core.removeProxyConfig(cfg)
|
||||
proxyConfigRemovedEvent.value = Event(true)
|
||||
core.removeAccount(account)
|
||||
accountRemovedEvent.value = Event(true)
|
||||
}
|
||||
|
||||
val deleteListener = object : SettingListenerStub() {
|
||||
override fun onClicked() {
|
||||
proxyConfigToDelete = proxyConfig
|
||||
accountToDelete = account
|
||||
|
||||
val registered = proxyConfig.state == RegistrationState.Ok
|
||||
val registered = account.state == RegistrationState.Ok
|
||||
waitForUnregister.value = registered
|
||||
|
||||
if (core.defaultProxyConfig == proxyConfig) {
|
||||
Log.i("[Account Settings] Proxy config was default, let's look for a replacement")
|
||||
for (proxyConfigIterator in core.proxyConfigList) {
|
||||
if (proxyConfig != proxyConfigIterator) {
|
||||
core.defaultProxyConfig = proxyConfigIterator
|
||||
Log.i("[Account Settings] New default proxy config is $proxyConfigIterator")
|
||||
if (core.defaultAccount == account) {
|
||||
Log.i("[Account Settings] Account was default, let's look for a replacement")
|
||||
for (accountIterator in core.accountList) {
|
||||
if (account != accountIterator) {
|
||||
core.defaultAccount = accountIterator
|
||||
Log.i("[Account Settings] New default account is $accountIterator")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proxyConfig.edit()
|
||||
proxyConfig.enableRegister(false)
|
||||
proxyConfig.done()
|
||||
val params = account.params.clone()
|
||||
params.registerEnabled = false
|
||||
account.params = params
|
||||
|
||||
if (!registered) {
|
||||
Log.w("[Account Settings] Proxy config isn't registered, don't unregister before removing it")
|
||||
deleteProxyConfig(proxyConfig)
|
||||
Log.w("[Account Settings] Account isn't registered, don't unregister before removing it")
|
||||
deleteAccount(account)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val pushNotificationListener = object : SettingListenerStub() {
|
||||
override fun onBoolValueChanged(newValue: Boolean) {
|
||||
proxyConfig.isPushNotificationAllowed = newValue
|
||||
val params = account.params.clone()
|
||||
params.pushNotificationAllowed = newValue
|
||||
account.params = params
|
||||
}
|
||||
}
|
||||
val pushNotification = MutableLiveData<Boolean>()
|
||||
|
@ -193,7 +244,10 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi
|
|||
|
||||
val transportListener = object : SettingListenerStub() {
|
||||
override fun onListValueChanged(position: Int) {
|
||||
// TODO
|
||||
val params = account.params.clone()
|
||||
params.transport = TransportType.fromInt(position)
|
||||
account.params = params
|
||||
proxy.value = account.params.serverAddr
|
||||
}
|
||||
}
|
||||
val transportIndex = MutableLiveData<Int>()
|
||||
|
@ -201,40 +255,48 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi
|
|||
|
||||
val proxyListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
proxyConfig.serverAddr = newValue
|
||||
if (outboundProxy.value == true) {
|
||||
// TODO
|
||||
}
|
||||
val params = account.params.clone()
|
||||
params.serverAddr = newValue
|
||||
account.params = params
|
||||
transportIndex.value = account.params.transport.toInt()
|
||||
}
|
||||
}
|
||||
val proxy = MutableLiveData<String>()
|
||||
|
||||
val outboundProxyListener = object : SettingListenerStub() {
|
||||
override fun onBoolValueChanged(newValue: Boolean) {
|
||||
// TODO
|
||||
val params = account.params.clone()
|
||||
params.outboundProxyEnabled = newValue
|
||||
account.params = params
|
||||
}
|
||||
}
|
||||
val outboundProxy = MutableLiveData<Boolean>()
|
||||
|
||||
val stunServerListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
proxyConfig.natPolicy?.stunServer = newValue
|
||||
val params = account.params.clone()
|
||||
params.natPolicy?.stunServer = newValue
|
||||
if (newValue.isEmpty()) ice.value = false
|
||||
stunServer.value = newValue
|
||||
account.params = params
|
||||
}
|
||||
}
|
||||
val stunServer = MutableLiveData<String>()
|
||||
|
||||
val iceListener = object : SettingListenerStub() {
|
||||
override fun onBoolValueChanged(newValue: Boolean) {
|
||||
proxyConfig.natPolicy?.enableIce(newValue)
|
||||
val params = account.params.clone()
|
||||
params.natPolicy?.enableIce(newValue)
|
||||
account.params = params
|
||||
}
|
||||
}
|
||||
val ice = MutableLiveData<Boolean>()
|
||||
|
||||
val avpfListener = object : SettingListenerStub() {
|
||||
override fun onBoolValueChanged(newValue: Boolean) {
|
||||
proxyConfig.avpfMode = if (newValue) AVPFMode.Enabled else AVPFMode.Disabled
|
||||
val params = account.params.clone()
|
||||
params.avpfMode = if (newValue) AVPFMode.Enabled else AVPFMode.Disabled
|
||||
account.params = params
|
||||
}
|
||||
}
|
||||
val avpf = MutableLiveData<Boolean>()
|
||||
|
@ -242,8 +304,11 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi
|
|||
val avpfRrIntervalListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
try {
|
||||
proxyConfig.avpfRrInterval = newValue.toInt()
|
||||
val params = account.params.clone()
|
||||
params.avpfRrInterval = newValue.toInt()
|
||||
account.params = params
|
||||
} catch (nfe: NumberFormatException) {
|
||||
Log.e("[Account Settings] Failed to set AVPF RR interval ($newValue): $nfe")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -252,23 +317,39 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi
|
|||
val expiresListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
try {
|
||||
proxyConfig.expires = newValue.toInt()
|
||||
val params = account.params.clone()
|
||||
params.expires = newValue.toInt()
|
||||
account.params = params
|
||||
} catch (nfe: NumberFormatException) {
|
||||
Log.e("[Account Settings] Failed to set expires ($newValue): $nfe")
|
||||
}
|
||||
}
|
||||
}
|
||||
val expires = MutableLiveData<Int>()
|
||||
|
||||
val dialPrefixListener = object : SettingListenerStub() {
|
||||
val prefixListener = object : SettingListenerStub() {
|
||||
override fun onTextValueChanged(newValue: String) {
|
||||
proxyConfig.dialPrefix = newValue
|
||||
val params = account.params.clone()
|
||||
params.internationalPrefix = newValue
|
||||
account.params = params
|
||||
}
|
||||
}
|
||||
val dialPrefix = MutableLiveData<String>()
|
||||
val prefix = MutableLiveData<String>()
|
||||
|
||||
val dialPrefixListener = object : SettingListenerStub() {
|
||||
override fun onBoolValueChanged(newValue: Boolean) {
|
||||
val params = account.params.clone()
|
||||
params.useInternationalPrefixForCallsAndChats = newValue
|
||||
account.params = params
|
||||
}
|
||||
}
|
||||
val dialPrefix = MutableLiveData<Boolean>()
|
||||
|
||||
val escapePlusListener = object : SettingListenerStub() {
|
||||
override fun onBoolValueChanged(newValue: Boolean) {
|
||||
proxyConfig.dialEscapePlus = newValue
|
||||
val params = account.params.clone()
|
||||
params.dialEscapePlusEnabled = newValue
|
||||
account.params = params
|
||||
}
|
||||
}
|
||||
val escapePlus = MutableLiveData<Boolean>()
|
||||
|
@ -282,61 +363,67 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi
|
|||
|
||||
init {
|
||||
update()
|
||||
core.addListener(listener)
|
||||
account.addListener(listener)
|
||||
initTransportList()
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
core.removeListener(listener)
|
||||
account.removeListener(listener)
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
private fun update() {
|
||||
isDefault.value = core.defaultProxyConfig == proxyConfig
|
||||
val identityAddress = proxyConfig.identityAddress
|
||||
isDefault.value = core.defaultAccount == account
|
||||
val params = account.params
|
||||
val identityAddress = params.identityAddress
|
||||
if (identityAddress != null) {
|
||||
displayName.value = identityAddress.displayName ?: ""
|
||||
identity.value = identityAddress.asStringUriOnly()
|
||||
}
|
||||
|
||||
iconResource.value = when (proxyConfig.state) {
|
||||
iconResource.value = when (account.state) {
|
||||
RegistrationState.Ok -> R.drawable.led_registered
|
||||
RegistrationState.Failed -> R.drawable.led_error
|
||||
RegistrationState.Progress -> R.drawable.led_registration_in_progress
|
||||
else -> R.drawable.led_not_registered
|
||||
}
|
||||
iconContentDescription.value = when (proxyConfig.state) {
|
||||
iconContentDescription.value = when (account.state) {
|
||||
RegistrationState.Ok -> R.string.status_connected
|
||||
RegistrationState.Progress -> R.string.status_in_progress
|
||||
RegistrationState.Failed -> R.string.status_error
|
||||
else -> R.string.status_not_connected
|
||||
}
|
||||
|
||||
userName.value = proxyConfig.identityAddress?.username
|
||||
userId.value = proxyConfig.findAuthInfo()?.userid
|
||||
domain.value = proxyConfig.identityAddress?.domain
|
||||
disable.value = !proxyConfig.registerEnabled()
|
||||
pushNotification.value = proxyConfig.isPushNotificationAllowed
|
||||
userName.value = params.identityAddress?.username
|
||||
userId.value = account.findAuthInfo()?.userid
|
||||
domain.value = params.identityAddress?.domain
|
||||
disable.value = !params.registerEnabled
|
||||
pushNotification.value = params.pushNotificationAllowed
|
||||
pushNotificationsAvailable.value = core.isPushNotificationAvailable
|
||||
proxy.value = proxyConfig.serverAddr
|
||||
outboundProxy.value = proxyConfig.serverAddr == proxyConfig.routes.firstOrNull()
|
||||
stunServer.value = proxyConfig.natPolicy?.stunServer
|
||||
ice.value = proxyConfig.natPolicy?.iceEnabled()
|
||||
avpf.value = proxyConfig.avpfEnabled()
|
||||
avpfRrInterval.value = proxyConfig.avpfRrInterval
|
||||
expires.value = proxyConfig.expires
|
||||
dialPrefix.value = proxyConfig.dialPrefix
|
||||
escapePlus.value = proxyConfig.dialEscapePlus
|
||||
proxy.value = params.serverAddr
|
||||
outboundProxy.value = params.outboundProxyEnabled
|
||||
stunServer.value = params.natPolicy?.stunServer
|
||||
ice.value = params.natPolicy?.iceEnabled()
|
||||
avpf.value = params.avpfMode == AVPFMode.Enabled
|
||||
avpfRrInterval.value = params.avpfRrInterval
|
||||
expires.value = params.expires
|
||||
prefix.value = params.internationalPrefix
|
||||
dialPrefix.value = params.useInternationalPrefixForCallsAndChats
|
||||
escapePlus.value = params.dialEscapePlusEnabled
|
||||
}
|
||||
|
||||
private fun initTransportList() {
|
||||
val labels = arrayListOf<String>()
|
||||
|
||||
// Keep following in the same order as TransportType enum
|
||||
labels.add(prefs.getString(R.string.account_settings_transport_udp))
|
||||
labels.add(prefs.getString(R.string.account_settings_transport_tcp))
|
||||
labels.add(prefs.getString(R.string.account_settings_transport_tls))
|
||||
if (corePreferences.allowDtlsTransport) {
|
||||
labels.add(prefs.getString(R.string.account_settings_transport_dtls))
|
||||
}
|
||||
|
||||
transportLabels.value = labels
|
||||
transportIndex.value = labels.indexOf(proxyConfig.transport.toUpperCase(Locale.getDefault()))
|
||||
transportIndex.value = account.params.transport.toInt()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,9 +70,9 @@ class SettingsViewModel : ViewModel() {
|
|||
|
||||
fun updateAccountsList() {
|
||||
val list = arrayListOf<AccountSettingsViewModel>()
|
||||
if (coreContext.core.proxyConfigList.isNotEmpty()) {
|
||||
for (proxy in coreContext.core.proxyConfigList) {
|
||||
val viewModel = AccountSettingsViewModel(proxy)
|
||||
if (coreContext.core.accountList.isNotEmpty()) {
|
||||
for (account in coreContext.core.accountList) {
|
||||
val viewModel = AccountSettingsViewModel(account)
|
||||
viewModel.accountsSettingsListener = accountClickListener
|
||||
list.add(viewModel)
|
||||
}
|
||||
|
|
|
@ -67,8 +67,8 @@ class SideMenuFragment : GenericFragment<SideMenuFragmentBinding>() {
|
|||
ViewModelProvider(this).get(SharedMainViewModel::class.java)
|
||||
}
|
||||
|
||||
sharedViewModel.proxyConfigRemoved.observe(viewLifecycleOwner, {
|
||||
Log.i("[Side Menu] Proxy config removed, update accounts list")
|
||||
sharedViewModel.accountRemoved.observe(viewLifecycleOwner, {
|
||||
Log.i("[Side Menu] Account removed, update accounts list")
|
||||
viewModel.updateAccountsList()
|
||||
})
|
||||
|
||||
|
@ -76,7 +76,7 @@ class SideMenuFragment : GenericFragment<SideMenuFragmentBinding>() {
|
|||
override fun onAccountClicked(identity: String) {
|
||||
val args = Bundle()
|
||||
args.putString("Identity", identity)
|
||||
Log.i("[Side Menu] Navigation to settings for proxy with identity: $identity")
|
||||
Log.i("[Side Menu] Navigation to settings for account with identity: $identity")
|
||||
|
||||
sharedViewModel.toggleDrawerEvent.value = Event(true)
|
||||
navigateToAccountSettings(identity)
|
||||
|
|
|
@ -35,7 +35,7 @@ class SideMenuViewModel : ViewModel() {
|
|||
val showAbout: Boolean = corePreferences.showAboutInSideMenu
|
||||
val showQuit: Boolean = corePreferences.showQuitInSideMenu
|
||||
|
||||
val defaultAccount = MutableLiveData<AccountSettingsViewModel>()
|
||||
val defaultAccountViewModel = MutableLiveData<AccountSettingsViewModel>()
|
||||
val defaultAccountFound = MutableLiveData<Boolean>()
|
||||
val defaultAccountAvatar = MutableLiveData<String>()
|
||||
|
||||
|
@ -50,14 +50,14 @@ class SideMenuViewModel : ViewModel() {
|
|||
}
|
||||
|
||||
private val listener: CoreListenerStub = object : CoreListenerStub() {
|
||||
override fun onRegistrationStateChanged(
|
||||
override fun onAccountRegistrationStateChanged(
|
||||
core: Core,
|
||||
cfg: ProxyConfig,
|
||||
account: Account,
|
||||
state: RegistrationState,
|
||||
message: String
|
||||
) {
|
||||
if (coreContext.core.proxyConfigList.size != accounts.value?.size) {
|
||||
// Only refresh the list if a proxy has been added or removed
|
||||
if (coreContext.core.accountList.size != accounts.value?.size) {
|
||||
// Only refresh the list if an account has been added or removed
|
||||
updateAccountsList()
|
||||
}
|
||||
}
|
||||
|
@ -77,18 +77,18 @@ class SideMenuViewModel : ViewModel() {
|
|||
|
||||
fun updateAccountsList() {
|
||||
val list = arrayListOf<AccountSettingsViewModel>()
|
||||
if (coreContext.core.proxyConfigList.isNotEmpty()) {
|
||||
val defaultProxyConfig = coreContext.core.defaultProxyConfig
|
||||
if (defaultProxyConfig != null) {
|
||||
val defaultViewModel = AccountSettingsViewModel(defaultProxyConfig)
|
||||
if (coreContext.core.accountList.isNotEmpty()) {
|
||||
val defaultAccount = coreContext.core.defaultAccount
|
||||
if (defaultAccount != null) {
|
||||
val defaultViewModel = AccountSettingsViewModel(defaultAccount)
|
||||
defaultViewModel.accountsSettingsListener = accountClickListener
|
||||
defaultAccount.value = defaultViewModel
|
||||
defaultAccountViewModel.value = defaultViewModel
|
||||
defaultAccountFound.value = true
|
||||
}
|
||||
|
||||
for (proxy in coreContext.core.proxyConfigList) {
|
||||
if (proxy != coreContext.core.defaultProxyConfig) {
|
||||
val viewModel = AccountSettingsViewModel(proxy)
|
||||
for (account in coreContext.core.accountList) {
|
||||
if (account != coreContext.core.defaultAccount) {
|
||||
val viewModel = AccountSettingsViewModel(account)
|
||||
viewModel.accountsSettingsListener = accountClickListener
|
||||
list.add(viewModel)
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ class SharedMainViewModel : ViewModel() {
|
|||
|
||||
/* Accounts */
|
||||
|
||||
val proxyConfigRemoved = MutableLiveData<Boolean>()
|
||||
val accountRemoved = MutableLiveData<Boolean>()
|
||||
|
||||
/* Call */
|
||||
|
||||
|
|
|
@ -35,13 +35,15 @@ open class StatusViewModel : ViewModel() {
|
|||
val voiceMailCount = MutableLiveData<Int>()
|
||||
|
||||
private val listener: CoreListenerStub = object : CoreListenerStub() {
|
||||
override fun onRegistrationStateChanged(
|
||||
override fun onAccountRegistrationStateChanged(
|
||||
core: Core,
|
||||
proxyConfig: ProxyConfig,
|
||||
account: Account,
|
||||
state: RegistrationState,
|
||||
message: String
|
||||
) {
|
||||
updateDefaultProxyConfigRegistrationStatus(state)
|
||||
if (account == core.defaultAccount) {
|
||||
updateDefaultAccountRegistrationStatus(state)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNotifyReceived(
|
||||
|
@ -71,11 +73,11 @@ open class StatusViewModel : ViewModel() {
|
|||
core.addListener(listener)
|
||||
|
||||
var state: RegistrationState = RegistrationState.None
|
||||
val defaultProxyConfig = core.defaultProxyConfig
|
||||
if (defaultProxyConfig != null) {
|
||||
state = defaultProxyConfig.state
|
||||
val defaultAccount = core.defaultAccount
|
||||
if (defaultAccount != null) {
|
||||
state = defaultAccount.state
|
||||
}
|
||||
updateDefaultProxyConfigRegistrationStatus(state)
|
||||
updateDefaultAccountRegistrationStatus(state)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
|
@ -87,7 +89,7 @@ open class StatusViewModel : ViewModel() {
|
|||
coreContext.core.refreshRegisters()
|
||||
}
|
||||
|
||||
fun updateDefaultProxyConfigRegistrationStatus(state: RegistrationState) {
|
||||
fun updateDefaultAccountRegistrationStatus(state: RegistrationState) {
|
||||
registrationStatusText.value = getStatusIconText(state)
|
||||
registrationStatusDrawable.value = getStatusIconResource(state)
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ class ContactsManager(private val context: Context) {
|
|||
}
|
||||
|
||||
fun shouldDisplaySipContactsList(): Boolean {
|
||||
return coreContext.core.defaultProxyConfig?.identityAddress?.domain == corePreferences.defaultDomain
|
||||
return coreContext.core.defaultAccount?.params?.identityAddress?.domain == corePreferences.defaultDomain
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
|
|
|
@ -312,15 +312,15 @@ class CoreContext(val context: Context, coreConfig: Config) {
|
|||
|
||||
computeUserAgent()
|
||||
|
||||
for (lpc in core.proxyConfigList) {
|
||||
if (lpc.identityAddress?.domain == corePreferences.defaultDomain) {
|
||||
for (account in core.accountList) {
|
||||
if (account.params.identityAddress?.domain == corePreferences.defaultDomain) {
|
||||
// Ensure conference URI is set on sip.linphone.org proxy configs
|
||||
if (lpc.conferenceFactoryUri == null) {
|
||||
lpc.edit()
|
||||
if (account.params.conferenceFactoryUri == null) {
|
||||
val params = account.params.clone()
|
||||
val uri = corePreferences.conferenceServerUri
|
||||
Log.i("[Context] Setting conference factory on proxy config ${lpc.identityAddress?.asString()} to default value: $uri")
|
||||
lpc.conferenceFactoryUri = uri
|
||||
lpc.done()
|
||||
Log.i("[Context] Setting conference factory on proxy config ${params.identityAddress?.asString()} to default value: $uri")
|
||||
params.conferenceFactoryUri = uri
|
||||
account.params = params
|
||||
}
|
||||
|
||||
// Ensure LIME server URL is set if at least one sip.linphone.org proxy
|
||||
|
|
|
@ -391,6 +391,9 @@ class CorePreferences constructor(private val context: Context) {
|
|||
|
||||
/* Settings */
|
||||
|
||||
val allowDtlsTransport: Boolean
|
||||
get() = config.getBool("app", "allow_dtls_transport", false)
|
||||
|
||||
val showAccountSettings: Boolean
|
||||
get() = config.getBool("app", "settings_accounts", true)
|
||||
|
||||
|
|
|
@ -56,17 +56,17 @@ class LinphoneUtils {
|
|||
val core = coreContext.core
|
||||
return core.limeX3DhAvailable() && core.limeX3DhEnabled() &&
|
||||
core.limeX3DhServerUrl != null &&
|
||||
core.defaultProxyConfig?.conferenceFactoryUri != null
|
||||
core.defaultAccount?.params?.conferenceFactoryUri != null
|
||||
}
|
||||
|
||||
fun isGroupChatAvailable(): Boolean {
|
||||
val core = coreContext.core
|
||||
return core.defaultProxyConfig?.conferenceFactoryUri != null
|
||||
return core.defaultAccount?.params?.conferenceFactoryUri != null
|
||||
}
|
||||
|
||||
fun createOneToOneChatRoom(participant: Address, isSecured: Boolean = false): ChatRoom? {
|
||||
val core: Core = coreContext.core
|
||||
val defaultProxyConfig = core.defaultProxyConfig
|
||||
val defaultAccount = core.defaultAccount
|
||||
|
||||
val params = core.createDefaultChatRoomParams()
|
||||
params.enableGroup(false)
|
||||
|
@ -79,8 +79,8 @@ class LinphoneUtils {
|
|||
|
||||
val participants = arrayOf(participant)
|
||||
|
||||
return core.searchChatRoom(params, defaultProxyConfig?.contact, null, participants)
|
||||
?: core.createChatRoom(params, defaultProxyConfig?.contact, participants)
|
||||
return core.searchChatRoom(params, defaultAccount?.contactAddress, null, participants)
|
||||
?: core.createChatRoom(params, defaultAccount?.contactAddress, participants)
|
||||
}
|
||||
|
||||
fun deleteFilesAttachedToEventLog(eventLog: EventLog) {
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
linphone:subtitle="@{@string/account_settings_password_summary}"
|
||||
linphone:listener="@{viewModel.passwordListener}"
|
||||
linphone:defaultValue="@{viewModel.password}"
|
||||
linphone:inputType="@{InputType.TYPE_TEXT_VARIATION_PASSWORD}"/>
|
||||
linphone:inputType="@{InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD}"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_text"
|
||||
|
@ -224,12 +224,19 @@
|
|||
|
||||
<include
|
||||
layout="@layout/settings_widget_text"
|
||||
linphone:title="@{@string/account_settings_dial_prefix_title}"
|
||||
linphone:subtitle="@{@string/account_settings_dial_prefix_summary}"
|
||||
linphone:listener="@{viewModel.dialPrefixListener}"
|
||||
linphone:defaultValue="@{viewModel.dialPrefix.toString()}"
|
||||
linphone:title="@{@string/account_settings_prefix_title}"
|
||||
linphone:subtitle="@{@string/account_settings_prefix_summary}"
|
||||
linphone:listener="@{viewModel.prefixListener}"
|
||||
linphone:defaultValue="@{viewModel.prefix}"
|
||||
linphone:inputType="@{InputType.TYPE_CLASS_NUMBER}"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_switch"
|
||||
linphone:title="@{@string/account_settings_apply_prefix_for_calls_title}"
|
||||
linphone:subtitle="@{@string/account_settings_apply_prefix_for_calls_summary}"
|
||||
linphone:listener="@{viewModel.dialPrefixListener}"
|
||||
linphone:checked="@={viewModel.dialPrefix}"/>
|
||||
|
||||
<include
|
||||
layout="@layout/settings_widget_switch"
|
||||
linphone:title="@{@string/account_settings_escape_plus_title}"
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
<RelativeLayout
|
||||
android:id="@+id/main_account"
|
||||
android:onClick="@{() -> viewModel.defaultAccount.accountsSettingsListener.onAccountClicked(viewModel.defaultAccount.identity)}"
|
||||
android:onClick="@{() -> viewModel.defaultAccountViewModel.accountsSettingsListener.onAccountClicked(viewModel.defaultAccountViewModel.identity)}"
|
||||
android:enabled="@{viewModel.defaultAccountFound}"
|
||||
android:visibility="@{viewModel.showAccounts ? View.VISIBLE : View.GONE}"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -82,7 +82,7 @@
|
|||
|
||||
<TextView
|
||||
android:visibility="@{viewModel.defaultAccountFound ? View.VISIBLE : View.GONE}"
|
||||
android:text="@{viewModel.defaultAccount.displayName.isEmpty() ? viewModel.defaultAccount.userName : viewModel.defaultAccount.displayName}"
|
||||
android:text="@{viewModel.defaultAccountViewModel.displayName.isEmpty() ? viewModel.defaultAccountViewModel.userName : viewModel.defaultAccountViewModel.displayName}"
|
||||
android:textColor="?attr/lightToolbarTextColor"
|
||||
android:textStyle="bold"
|
||||
android:textSize="18sp"
|
||||
|
@ -91,7 +91,7 @@
|
|||
|
||||
<TextView
|
||||
android:visibility="@{viewModel.defaultAccountFound ? View.VISIBLE : View.GONE}"
|
||||
android:text="@{viewModel.defaultAccount.displayUsernameInsteadOfIdentity ? viewModel.defaultAccount.userName : viewModel.defaultAccount.identity}"
|
||||
android:text="@{viewModel.defaultAccountViewModel.displayUsernameInsteadOfIdentity ? viewModel.defaultAccountViewModel.userName : viewModel.defaultAccountViewModel.identity}"
|
||||
style="@style/sip_uri_small_font"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
@ -100,8 +100,8 @@
|
|||
|
||||
<ImageView
|
||||
android:background="@drawable/led_background"
|
||||
android:src="@{viewModel.defaultAccount.iconResource, default=@drawable/led_not_registered}"
|
||||
android:contentDescription="@{viewModel.defaultAccount.iconContentDescription}"
|
||||
android:src="@{viewModel.defaultAccountViewModel.iconResource, default=@drawable/led_not_registered}"
|
||||
android:contentDescription="@{viewModel.defaultAccountViewModel.iconContentDescription}"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
|
|
|
@ -541,6 +541,7 @@
|
|||
<string name="account_settings_transport_title">Transporte</string>
|
||||
<string name="account_settings_transport_tcp">TCP</string>
|
||||
<string name="account_settings_transport_tls">TLS</string>
|
||||
<string name="account_settings_transport_dtls">DTLS</string>
|
||||
<string name="account_settings_proxy_title">Proxy SIP</string>
|
||||
<string name="account_settings_outbound_proxy_summary">Enruta todas las llamadas a través del proxy SIP de arriba</string>
|
||||
<string name="account_settings_stun_server_title">Servidor STUN / TURN</string>
|
||||
|
@ -549,8 +550,8 @@
|
|||
<string name="account_settings_avpf_rr_interval_title">AVPF de intervalo regular de RTCP</string>
|
||||
<string name="account_settings_expires_title">Caduce</string>
|
||||
<string name="account_settings_expires_summary">en segundos</string>
|
||||
<string name="account_settings_dial_prefix_title">Prefijo de tu país</string>
|
||||
<string name="account_settings_dial_prefix_summary">sin el +</string>
|
||||
<string name="account_settings_prefix_title">Prefijo de tu país</string>
|
||||
<string name="account_settings_prefix_summary">sin el +</string>
|
||||
<string name="account_settings_escape_plus_title">Reemplazar + por 00</string>
|
||||
<string name="notification_channel_incoming_call_name">&appName; notificaciones de llamadas entrantes</string>
|
||||
<string name="notification_channel_chat_name">&appName; notificaciones de mensajes</string>
|
||||
|
|
|
@ -389,6 +389,7 @@
|
|||
<string name="account_settings_transport_udp">UDP</string>
|
||||
<string name="account_settings_transport_tcp">TCP</string>
|
||||
<string name="account_settings_transport_tls">TLS</string>
|
||||
<string name="account_settings_transport_dtls">DTLS</string>
|
||||
<string name="account_settings_proxy_title">Proxy SIP</string>
|
||||
<string name="account_settings_outbound_proxy_title">Outbound proxy</string>
|
||||
<string name="account_settings_stun_server_title">Serveur TURN / STUN</string>
|
||||
|
@ -397,8 +398,8 @@
|
|||
<string name="account_settings_avpf_rr_interval_summary">en secondes (entre 1 et 5)</string>
|
||||
<string name="account_settings_expires_title">Expiration</string>
|
||||
<string name="account_settings_expires_summary">en secondes</string>
|
||||
<string name="account_settings_dial_prefix_summary">(sans le +)</string>
|
||||
<string name="account_settings_dial_prefix_title">Préfixe de votre pays</string>
|
||||
<string name="account_settings_prefix_summary">(sans le +)</string>
|
||||
<string name="account_settings_prefix_title">Préfixe de votre pays</string>
|
||||
<string name="account_settings_escape_plus_title">Remplacer + par 00</string>
|
||||
<string name="notification_channel_incoming_call_name">Notifications d\'appels entrants &appName;</string>
|
||||
<string name="incoming_call_notification_title">Appel entrant</string>
|
||||
|
|
|
@ -160,8 +160,8 @@
|
|||
<string name="account_settings_avpf_rr_interval_summary">以秒为单位(1到5之间)</string>
|
||||
<string name="account_settings_expires_title">到期</string>
|
||||
<string name="account_settings_expires_summary">以秒为单位</string>
|
||||
<string name="account_settings_dial_prefix_title">您所在国家的前缀</string>
|
||||
<string name="account_settings_dial_prefix_summary">不包含 +</string>
|
||||
<string name="account_settings_prefix_title">您所在国家的前缀</string>
|
||||
<string name="account_settings_prefix_summary">不包含 +</string>
|
||||
<string name="account_settings_escape_plus_title">用00代替+</string>
|
||||
<string name="notification_channel_service_name">&appName; 服务通知</string>
|
||||
<string name="notification_channel_chat_name">&appName; 即时通讯通知</string>
|
||||
|
|
|
@ -421,8 +421,8 @@
|
|||
<string name="account_settings_avpf_rr_interval_summary">以秒為單位(1到5之間)</string>
|
||||
<string name="account_settings_expires_title">到期</string>
|
||||
<string name="account_settings_expires_summary">以秒為單位</string>
|
||||
<string name="account_settings_dial_prefix_title">您所在國家的前綴</string>
|
||||
<string name="account_settings_dial_prefix_summary">不包含+</string>
|
||||
<string name="account_settings_prefix_title">您所在國家的前綴</string>
|
||||
<string name="account_settings_prefix_summary">不包含+</string>
|
||||
<string name="account_settings_escape_plus_title">用00代替+</string>
|
||||
<string name="notification_channel_incoming_call_name">&appName;來電通知</string>
|
||||
<string name="notification_channel_chat_name">&appName;即時通訊通知</string>
|
||||
|
|
|
@ -528,6 +528,7 @@
|
|||
<string name="account_settings_transport_udp">UDP</string>
|
||||
<string name="account_settings_transport_tcp">TCP</string>
|
||||
<string name="account_settings_transport_tls">TLS</string>
|
||||
<string name="account_settings_transport_dtls">DTLS</string>
|
||||
<string name="account_settings_proxy_title">SIP proxy</string>
|
||||
<string name="account_settings_proxy_summary"></string>
|
||||
<string name="account_settings_outbound_proxy_title">Outbound proxy</string>
|
||||
|
@ -542,8 +543,10 @@
|
|||
<string name="account_settings_avpf_rr_interval_summary">in seconds (between 1 and 5)</string>
|
||||
<string name="account_settings_expires_title">Expire</string>
|
||||
<string name="account_settings_expires_summary">in seconds</string>
|
||||
<string name="account_settings_dial_prefix_title">Prefix for your country</string>
|
||||
<string name="account_settings_dial_prefix_summary">without the +</string>
|
||||
<string name="account_settings_prefix_title">Prefix for your country</string>
|
||||
<string name="account_settings_prefix_summary">without the +</string>
|
||||
<string name="account_settings_apply_prefix_for_calls_title">Apply prefix for outgoing calls and chat</string>
|
||||
<string name="account_settings_apply_prefix_for_calls_summary">If a number is entered, apply prefix to number</string>
|
||||
<string name="account_settings_escape_plus_title">Replace + by 00</string>
|
||||
<string name="account_settings_escape_plus_summary"></string>
|
||||
|
||||
|
|
Loading…
Reference in a new issue