Ran new version of kotlin auto formatter
This commit is contained in:
parent
06a3124ee6
commit
f2a1869a1a
74 changed files with 1776 additions and 1219 deletions
|
@ -448,7 +448,8 @@ internal fun ChatRoomCreationFragment.navigateToEmptyChatRoom() {
|
||||||
|
|
||||||
internal fun GroupInfoFragment.navigateToChatRoomCreation(args: Bundle?) {
|
internal fun GroupInfoFragment.navigateToChatRoomCreation(args: Bundle?) {
|
||||||
if (findNavController().currentDestination?.id == R.id.groupInfoFragment) {
|
if (findNavController().currentDestination?.id == R.id.groupInfoFragment) {
|
||||||
findNavController().navigate(R.id.action_groupInfoFragment_to_chatRoomCreationFragment,
|
findNavController().navigate(
|
||||||
|
R.id.action_groupInfoFragment_to_chatRoomCreationFragment,
|
||||||
args,
|
args,
|
||||||
getLeftToRightAnimationNavOptions(R.id.chatRoomCreationFragment, true)
|
getLeftToRightAnimationNavOptions(R.id.chatRoomCreationFragment, true)
|
||||||
)
|
)
|
||||||
|
|
|
@ -74,16 +74,21 @@ class AccountLoginFragment : AbstractPhoneFragment<AssistantAccountLoginFragment
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.goToSmsValidationEvent.observe(viewLifecycleOwner, {
|
viewModel.goToSmsValidationEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
args.putBoolean("IsLogin", true)
|
args.putBoolean("IsLogin", true)
|
||||||
args.putString("PhoneNumber", viewModel.accountCreator.phoneNumber)
|
args.putString("PhoneNumber", viewModel.accountCreator.phoneNumber)
|
||||||
navigateToPhoneAccountValidation(args)
|
navigateToPhoneAccountValidation(args)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.leaveAssistantEvent.observe(viewLifecycleOwner, {
|
viewModel.leaveAssistantEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
coreContext.contactsManager.updateLocalContacts()
|
coreContext.contactsManager.updateLocalContacts()
|
||||||
|
|
||||||
|
@ -93,9 +98,12 @@ class AccountLoginFragment : AbstractPhoneFragment<AssistantAccountLoginFragment
|
||||||
requireActivity().finish()
|
requireActivity().finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.invalidCredentialsEvent.observe(viewLifecycleOwner, {
|
viewModel.invalidCredentialsEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
val dialogViewModel = DialogViewModel(getString(R.string.assistant_error_invalid_credentials))
|
val dialogViewModel = DialogViewModel(getString(R.string.assistant_error_invalid_credentials))
|
||||||
val dialog: Dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
|
val dialog: Dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
|
||||||
|
@ -105,20 +113,27 @@ class AccountLoginFragment : AbstractPhoneFragment<AssistantAccountLoginFragment
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
dialogViewModel.showDeleteButton({
|
dialogViewModel.showDeleteButton(
|
||||||
|
{
|
||||||
viewModel.continueEvenIfInvalidCredentials()
|
viewModel.continueEvenIfInvalidCredentials()
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}, getString(R.string.assistant_continue_even_if_credentials_invalid))
|
},
|
||||||
|
getString(R.string.assistant_continue_even_if_credentials_invalid)
|
||||||
|
)
|
||||||
|
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(viewLifecycleOwner, {
|
viewModel.onErrorEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { message ->
|
it.consume { message ->
|
||||||
(requireActivity() as AssistantActivity).showSnackBar(message)
|
(requireActivity() as AssistantActivity).showSnackBar(message)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
checkPermission()
|
checkPermission()
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,11 +43,14 @@ class EchoCancellerCalibrationFragment : GenericFragment<AssistantEchoCancellerC
|
||||||
viewModel = ViewModelProvider(this).get(EchoCancellerCalibrationViewModel::class.java)
|
viewModel = ViewModelProvider(this).get(EchoCancellerCalibrationViewModel::class.java)
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
viewModel.echoCalibrationTerminated.observe(viewLifecycleOwner, {
|
viewModel.echoCalibrationTerminated.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
requireActivity().finish()
|
requireActivity().finish()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if (!PermissionHelper.required(requireContext()).hasRecordAudioPermission()) {
|
if (!PermissionHelper.required(requireContext()).hasRecordAudioPermission()) {
|
||||||
Log.i("[Echo Canceller Calibration] Asking for RECORD_AUDIO permission")
|
Log.i("[Echo Canceller Calibration] Asking for RECORD_AUDIO permission")
|
||||||
|
|
|
@ -49,16 +49,22 @@ class EmailAccountCreationFragment : GenericFragment<AssistantEmailAccountCreati
|
||||||
viewModel = ViewModelProvider(this, EmailAccountCreationViewModelFactory(sharedViewModel.getAccountCreator())).get(EmailAccountCreationViewModel::class.java)
|
viewModel = ViewModelProvider(this, EmailAccountCreationViewModelFactory(sharedViewModel.getAccountCreator())).get(EmailAccountCreationViewModel::class.java)
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
viewModel.goToEmailValidationEvent.observe(viewLifecycleOwner, {
|
viewModel.goToEmailValidationEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
navigateToEmailAccountValidation()
|
navigateToEmailAccountValidation()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(viewLifecycleOwner, {
|
viewModel.onErrorEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { message ->
|
it.consume { message ->
|
||||||
(requireActivity() as AssistantActivity).showSnackBar(message)
|
(requireActivity() as AssistantActivity).showSnackBar(message)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,9 @@ class EmailAccountValidationFragment : GenericFragment<AssistantEmailAccountVali
|
||||||
viewModel = ViewModelProvider(this, EmailAccountValidationViewModelFactory(sharedViewModel.getAccountCreator())).get(EmailAccountValidationViewModel::class.java)
|
viewModel = ViewModelProvider(this, EmailAccountValidationViewModelFactory(sharedViewModel.getAccountCreator())).get(EmailAccountValidationViewModel::class.java)
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
viewModel.leaveAssistantEvent.observe(viewLifecycleOwner, {
|
viewModel.leaveAssistantEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
coreContext.contactsManager.updateLocalContacts()
|
coreContext.contactsManager.updateLocalContacts()
|
||||||
|
|
||||||
|
@ -58,12 +60,16 @@ class EmailAccountValidationFragment : GenericFragment<AssistantEmailAccountVali
|
||||||
args.putString("Password", viewModel.accountCreator.password)
|
args.putString("Password", viewModel.accountCreator.password)
|
||||||
navigateToAccountLinking(args)
|
navigateToAccountLinking(args)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(viewLifecycleOwner, {
|
viewModel.onErrorEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { message ->
|
it.consume { message ->
|
||||||
(requireActivity() as AssistantActivity).showSnackBar(message)
|
(requireActivity() as AssistantActivity).showSnackBar(message)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,9 @@ class GenericAccountLoginFragment : GenericFragment<AssistantGenericAccountLogin
|
||||||
viewModel = ViewModelProvider(this, GenericLoginViewModelFactory(sharedViewModel.getAccountCreator(true))).get(GenericLoginViewModel::class.java)
|
viewModel = ViewModelProvider(this, GenericLoginViewModelFactory(sharedViewModel.getAccountCreator(true))).get(GenericLoginViewModel::class.java)
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
viewModel.leaveAssistantEvent.observe(viewLifecycleOwner, {
|
viewModel.leaveAssistantEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
coreContext.contactsManager.updateLocalContacts()
|
coreContext.contactsManager.updateLocalContacts()
|
||||||
|
|
||||||
|
@ -63,9 +65,12 @@ class GenericAccountLoginFragment : GenericFragment<AssistantGenericAccountLogin
|
||||||
requireActivity().finish()
|
requireActivity().finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.invalidCredentialsEvent.observe(viewLifecycleOwner, {
|
viewModel.invalidCredentialsEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
val dialogViewModel = DialogViewModel(getString(R.string.assistant_error_invalid_credentials))
|
val dialogViewModel = DialogViewModel(getString(R.string.assistant_error_invalid_credentials))
|
||||||
val dialog: Dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
|
val dialog: Dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
|
||||||
|
@ -75,19 +80,26 @@ class GenericAccountLoginFragment : GenericFragment<AssistantGenericAccountLogin
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
dialogViewModel.showDeleteButton({
|
dialogViewModel.showDeleteButton(
|
||||||
|
{
|
||||||
viewModel.continueEvenIfInvalidCredentials()
|
viewModel.continueEvenIfInvalidCredentials()
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}, getString(R.string.assistant_continue_even_if_credentials_invalid))
|
},
|
||||||
|
getString(R.string.assistant_continue_even_if_credentials_invalid)
|
||||||
|
)
|
||||||
|
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(viewLifecycleOwner, {
|
viewModel.onErrorEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { message ->
|
it.consume { message ->
|
||||||
(requireActivity() as AssistantActivity).showSnackBar(message)
|
(requireActivity() as AssistantActivity).showSnackBar(message)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,20 +56,26 @@ class PhoneAccountCreationFragment : AbstractPhoneFragment<AssistantPhoneAccount
|
||||||
CountryPickerFragment(viewModel).show(childFragmentManager, "CountryPicker")
|
CountryPickerFragment(viewModel).show(childFragmentManager, "CountryPicker")
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.goToSmsValidationEvent.observe(viewLifecycleOwner, {
|
viewModel.goToSmsValidationEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
args.putBoolean("IsCreation", true)
|
args.putBoolean("IsCreation", true)
|
||||||
args.putString("PhoneNumber", viewModel.accountCreator.phoneNumber)
|
args.putString("PhoneNumber", viewModel.accountCreator.phoneNumber)
|
||||||
navigateToPhoneAccountValidation(args)
|
navigateToPhoneAccountValidation(args)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(viewLifecycleOwner, {
|
viewModel.onErrorEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { message ->
|
it.consume { message ->
|
||||||
(requireActivity() as AssistantActivity).showSnackBar(message)
|
(requireActivity() as AssistantActivity).showSnackBar(message)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
checkPermission()
|
checkPermission()
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,16 +71,21 @@ class PhoneAccountLinkingFragment : AbstractPhoneFragment<AssistantPhoneAccountL
|
||||||
CountryPickerFragment(viewModel).show(childFragmentManager, "CountryPicker")
|
CountryPickerFragment(viewModel).show(childFragmentManager, "CountryPicker")
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.goToSmsValidationEvent.observe(viewLifecycleOwner, {
|
viewModel.goToSmsValidationEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
args.putBoolean("IsLinking", true)
|
args.putBoolean("IsLinking", true)
|
||||||
args.putString("PhoneNumber", viewModel.accountCreator.phoneNumber)
|
args.putString("PhoneNumber", viewModel.accountCreator.phoneNumber)
|
||||||
navigateToPhoneAccountValidation(args)
|
navigateToPhoneAccountValidation(args)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.leaveAssistantEvent.observe(viewLifecycleOwner, {
|
viewModel.leaveAssistantEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
if (LinphoneApplication.coreContext.core.isEchoCancellerCalibrationRequired) {
|
if (LinphoneApplication.coreContext.core.isEchoCancellerCalibrationRequired) {
|
||||||
navigateToEchoCancellerCalibration()
|
navigateToEchoCancellerCalibration()
|
||||||
|
@ -88,13 +93,17 @@ class PhoneAccountLinkingFragment : AbstractPhoneFragment<AssistantPhoneAccountL
|
||||||
requireActivity().finish()
|
requireActivity().finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(viewLifecycleOwner, {
|
viewModel.onErrorEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { message ->
|
it.consume { message ->
|
||||||
(requireActivity() as AssistantActivity).showSnackBar(message)
|
(requireActivity() as AssistantActivity).showSnackBar(message)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
checkPermission()
|
checkPermission()
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,9 @@ class PhoneAccountValidationFragment : GenericFragment<AssistantPhoneAccountVali
|
||||||
viewModel.isCreation.value = arguments?.getBoolean("IsCreation", false)
|
viewModel.isCreation.value = arguments?.getBoolean("IsCreation", false)
|
||||||
viewModel.isLinking.value = arguments?.getBoolean("IsLinking", false)
|
viewModel.isLinking.value = arguments?.getBoolean("IsLinking", false)
|
||||||
|
|
||||||
viewModel.leaveAssistantEvent.observe(viewLifecycleOwner, {
|
viewModel.leaveAssistantEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
when {
|
when {
|
||||||
viewModel.isLogin.value == true || viewModel.isCreation.value == true -> {
|
viewModel.isLogin.value == true || viewModel.isCreation.value == true -> {
|
||||||
|
@ -77,13 +79,17 @@ class PhoneAccountValidationFragment : GenericFragment<AssistantPhoneAccountVali
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(viewLifecycleOwner, {
|
viewModel.onErrorEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { message ->
|
it.consume { message ->
|
||||||
(requireActivity() as AssistantActivity).showSnackBar(message)
|
(requireActivity() as AssistantActivity).showSnackBar(message)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
val clipboard = requireContext().getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
|
val clipboard = requireContext().getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
clipboard.addPrimaryClipChangedListener {
|
clipboard.addPrimaryClipChangedListener {
|
||||||
|
|
|
@ -51,12 +51,15 @@ class QrCodeFragment : GenericFragment<AssistantQrCodeFragmentBinding>() {
|
||||||
viewModel = ViewModelProvider(this).get(QrCodeViewModel::class.java)
|
viewModel = ViewModelProvider(this).get(QrCodeViewModel::class.java)
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
viewModel.qrCodeFoundEvent.observe(viewLifecycleOwner, {
|
viewModel.qrCodeFoundEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { url ->
|
it.consume { url ->
|
||||||
sharedViewModel.remoteProvisioningUrl.value = url
|
sharedViewModel.remoteProvisioningUrl.value = url
|
||||||
findNavController().navigateUp()
|
findNavController().navigateUp()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
viewModel.setBackCamera()
|
viewModel.setBackCamera()
|
||||||
|
|
||||||
if (!PermissionHelper.required(requireContext()).hasCameraPermission()) {
|
if (!PermissionHelper.required(requireContext()).hasCameraPermission()) {
|
||||||
|
|
|
@ -54,7 +54,9 @@ class RemoteProvisioningFragment : GenericFragment<AssistantRemoteProvisioningFr
|
||||||
navigateToQrCode()
|
navigateToQrCode()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.fetchSuccessfulEvent.observe(viewLifecycleOwner, {
|
viewModel.fetchSuccessfulEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { success ->
|
it.consume { success ->
|
||||||
if (success) {
|
if (success) {
|
||||||
if (coreContext.core.isEchoCancellerCalibrationRequired) {
|
if (coreContext.core.isEchoCancellerCalibrationRequired) {
|
||||||
|
@ -67,7 +69,8 @@ class RemoteProvisioningFragment : GenericFragment<AssistantRemoteProvisioningFr
|
||||||
activity.showSnackBar(R.string.assistant_remote_provisioning_failure)
|
activity.showSnackBar(R.string.assistant_remote_provisioning_failure)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.urlToFetch.value = sharedViewModel.remoteProvisioningUrl.value ?: coreContext.core.provisioningUri
|
viewModel.urlToFetch.value = sharedViewModel.remoteProvisioningUrl.value ?: coreContext.core.provisioningUri
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,9 +72,12 @@ class WelcomeFragment : GenericFragment<AssistantWelcomeFragmentBinding>() {
|
||||||
navigateToRemoteProvisioning()
|
navigateToRemoteProvisioning()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.termsAndPrivacyAccepted.observe(viewLifecycleOwner, {
|
viewModel.termsAndPrivacyAccepted.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
if (it) corePreferences.readAndAgreeTermsAndPrivacy = true
|
if (it) corePreferences.readAndAgreeTermsAndPrivacy = true
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
setUpTermsAndPrivacyLinks()
|
setUpTermsAndPrivacyLinks()
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,8 @@ import org.linphone.core.DialPlan
|
||||||
import org.linphone.core.tools.Log
|
import org.linphone.core.tools.Log
|
||||||
import org.linphone.utils.PhoneNumberUtils
|
import org.linphone.utils.PhoneNumberUtils
|
||||||
|
|
||||||
abstract class AbstractPhoneViewModel(val accountCreator: AccountCreator) : ViewModel(),
|
abstract class AbstractPhoneViewModel(val accountCreator: AccountCreator) :
|
||||||
|
ViewModel(),
|
||||||
CountryPickerFragment.CountryPickedListener {
|
CountryPickerFragment.CountryPickedListener {
|
||||||
|
|
||||||
val prefix = MutableLiveData<String>()
|
val prefix = MutableLiveData<String>()
|
||||||
|
|
|
@ -160,9 +160,11 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh
|
||||||
private fun isCreateButtonEnabled(): Boolean {
|
private fun isCreateButtonEnabled(): Boolean {
|
||||||
val usernameRegexp = corePreferences.config.getString("assistant", "username_regex", "^[a-z0-9+_.\\-]*\$")
|
val usernameRegexp = corePreferences.config.getString("assistant", "username_regex", "^[a-z0-9+_.\\-]*\$")
|
||||||
return isPhoneNumberOk() && usernameRegexp != null &&
|
return isPhoneNumberOk() && usernameRegexp != null &&
|
||||||
(useUsername.value == false ||
|
(
|
||||||
|
useUsername.value == false ||
|
||||||
username.value.orEmpty().matches(Regex(usernameRegexp)) &&
|
username.value.orEmpty().matches(Regex(usernameRegexp)) &&
|
||||||
username.value.orEmpty().isNotEmpty() &&
|
username.value.orEmpty().isNotEmpty() &&
|
||||||
usernameError.value.orEmpty().isEmpty())
|
usernameError.value.orEmpty().isEmpty()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,9 @@ class CallActivity : ProximitySensorActivity() {
|
||||||
|
|
||||||
sharedViewModel = ViewModelProvider(this).get(SharedCallViewModel::class.java)
|
sharedViewModel = ViewModelProvider(this).get(SharedCallViewModel::class.java)
|
||||||
|
|
||||||
sharedViewModel.toggleDrawerEvent.observe(this, {
|
sharedViewModel.toggleDrawerEvent.observe(
|
||||||
|
this,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
if (binding.statsMenu.isDrawerOpen(Gravity.LEFT)) {
|
if (binding.statsMenu.isDrawerOpen(Gravity.LEFT)) {
|
||||||
binding.statsMenu.closeDrawer(binding.sideMenuContent, true)
|
binding.statsMenu.closeDrawer(binding.sideMenuContent, true)
|
||||||
|
@ -70,13 +72,17 @@ class CallActivity : ProximitySensorActivity() {
|
||||||
binding.statsMenu.openDrawer(binding.sideMenuContent, true)
|
binding.statsMenu.openDrawer(binding.sideMenuContent, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
sharedViewModel.resetHiddenInterfaceTimerInVideoCallEvent.observe(this, {
|
sharedViewModel.resetHiddenInterfaceTimerInVideoCallEvent.observe(
|
||||||
|
this,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
viewModel.showMomentarily()
|
viewModel.showMomentarily()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
coreContext.core.nativeVideoWindowId = binding.remoteVideoSurface
|
coreContext.core.nativeVideoWindowId = binding.remoteVideoSurface
|
||||||
coreContext.core.nativePreviewWindowId = binding.localPreviewVideoSurface
|
coreContext.core.nativePreviewWindowId = binding.localPreviewVideoSurface
|
||||||
|
@ -104,9 +110,12 @@ class CallActivity : ProximitySensorActivity() {
|
||||||
|
|
||||||
videoZoomHelper = VideoZoomHelper(this, binding.remoteVideoSurface)
|
videoZoomHelper = VideoZoomHelper(this, binding.remoteVideoSurface)
|
||||||
|
|
||||||
viewModel.proximitySensorEnabled.observe(this, {
|
viewModel.proximitySensorEnabled.observe(
|
||||||
|
this,
|
||||||
|
{
|
||||||
enableProximitySensor(it)
|
enableProximitySensor(it)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
|
|
|
@ -78,19 +78,25 @@ class IncomingCallActivity : GenericActivity() {
|
||||||
)[IncomingCallViewModel::class.java]
|
)[IncomingCallViewModel::class.java]
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
viewModel.callEndedEvent.observe(this, {
|
viewModel.callEndedEvent.observe(
|
||||||
|
this,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
Log.i("[Incoming Call Activity] Call ended, finish activity")
|
Log.i("[Incoming Call Activity] Call ended, finish activity")
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.earlyMediaVideoEnabled.observe(this, {
|
viewModel.earlyMediaVideoEnabled.observe(
|
||||||
|
this,
|
||||||
|
{
|
||||||
if (it) {
|
if (it) {
|
||||||
Log.i("[Incoming Call Activity] Early media video being received, set native window id")
|
Log.i("[Incoming Call Activity] Early media video being received, set native window id")
|
||||||
coreContext.core.nativeVideoWindowId = binding.remoteVideoSurface
|
coreContext.core.nativeVideoWindowId = binding.remoteVideoSurface
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
|
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
|
||||||
val keyguardLocked = keyguardManager.isKeyguardLocked
|
val keyguardLocked = keyguardManager.isKeyguardLocked
|
||||||
|
@ -169,7 +175,8 @@ class IncomingCallActivity : GenericActivity() {
|
||||||
private fun findIncomingCall(): Call? {
|
private fun findIncomingCall(): Call? {
|
||||||
for (call in coreContext.core.calls) {
|
for (call in coreContext.core.calls) {
|
||||||
if (call.state == Call.State.IncomingReceived ||
|
if (call.state == Call.State.IncomingReceived ||
|
||||||
call.state == Call.State.IncomingEarlyMedia) {
|
call.state == Call.State.IncomingEarlyMedia
|
||||||
|
) {
|
||||||
return call
|
return call
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,31 +79,45 @@ class OutgoingCallActivity : ProximitySensorActivity() {
|
||||||
controlsViewModel = ViewModelProvider(this).get(ControlsViewModel::class.java)
|
controlsViewModel = ViewModelProvider(this).get(ControlsViewModel::class.java)
|
||||||
binding.controlsViewModel = controlsViewModel
|
binding.controlsViewModel = controlsViewModel
|
||||||
|
|
||||||
viewModel.callEndedEvent.observe(this, {
|
viewModel.callEndedEvent.observe(
|
||||||
|
this,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
Log.i("[Outgoing Call Activity] Call ended, finish activity")
|
Log.i("[Outgoing Call Activity] Call ended, finish activity")
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.callConnectedEvent.observe(this, {
|
viewModel.callConnectedEvent.observe(
|
||||||
|
this,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
Log.i("[Outgoing Call Activity] Call connected, finish activity")
|
Log.i("[Outgoing Call Activity] Call connected, finish activity")
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
controlsViewModel.isSpeakerSelected.observe(this, {
|
controlsViewModel.isSpeakerSelected.observe(
|
||||||
|
this,
|
||||||
|
{
|
||||||
enableProximitySensor(!it)
|
enableProximitySensor(!it)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
controlsViewModel.askPermissionEvent.observe(this, {
|
controlsViewModel.askPermissionEvent.observe(
|
||||||
|
this,
|
||||||
|
{
|
||||||
it.consume { permission ->
|
it.consume { permission ->
|
||||||
requestPermissions(arrayOf(permission), 0)
|
requestPermissions(arrayOf(permission), 0)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
controlsViewModel.toggleNumpadEvent.observe(this, {
|
controlsViewModel.toggleNumpadEvent.observe(
|
||||||
|
this,
|
||||||
|
{
|
||||||
it.consume { open ->
|
it.consume { open ->
|
||||||
if (this::numpadAnimator.isInitialized) {
|
if (this::numpadAnimator.isInitialized) {
|
||||||
if (open) {
|
if (open) {
|
||||||
|
@ -113,7 +127,8 @@ class OutgoingCallActivity : ProximitySensorActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60)) {
|
if (Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60)) {
|
||||||
checkPermissions()
|
checkPermissions()
|
||||||
|
@ -192,7 +207,8 @@ class OutgoingCallActivity : ProximitySensorActivity() {
|
||||||
for (call in coreContext.core.calls) {
|
for (call in coreContext.core.calls) {
|
||||||
if (call.state == Call.State.OutgoingInit ||
|
if (call.state == Call.State.OutgoingInit ||
|
||||||
call.state == Call.State.OutgoingProgress ||
|
call.state == Call.State.OutgoingProgress ||
|
||||||
call.state == Call.State.OutgoingRinging) {
|
call.state == Call.State.OutgoingRinging
|
||||||
|
) {
|
||||||
return call
|
return call
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,9 @@ class VideoZoomHelper(context: Context, private var videoDisplayView: View) : Ge
|
||||||
init {
|
init {
|
||||||
val gestureDetector = GestureDetector(context, this)
|
val gestureDetector = GestureDetector(context, this)
|
||||||
|
|
||||||
scaleDetector = ScaleGestureDetector(context, object :
|
scaleDetector = ScaleGestureDetector(
|
||||||
|
context,
|
||||||
|
object :
|
||||||
ScaleGestureDetector.SimpleOnScaleGestureListener() {
|
ScaleGestureDetector.SimpleOnScaleGestureListener() {
|
||||||
override fun onScale(detector: ScaleGestureDetector): Boolean {
|
override fun onScale(detector: ScaleGestureDetector): Boolean {
|
||||||
zoomFactor *= detector.scaleFactor
|
zoomFactor *= detector.scaleFactor
|
||||||
|
@ -58,7 +60,8 @@ class VideoZoomHelper(context: Context, private var videoDisplayView: View) : Ge
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
videoDisplayView.setOnTouchListener { _, event ->
|
videoDisplayView.setOnTouchListener { _, event ->
|
||||||
val currentZoomFactor = zoomFactor
|
val currentZoomFactor = zoomFactor
|
||||||
|
|
|
@ -80,30 +80,41 @@ class ControlsFragment : GenericFragment<CallControlsFragmentBinding>() {
|
||||||
conferenceViewModel = ViewModelProvider(this).get(ConferenceViewModel::class.java)
|
conferenceViewModel = ViewModelProvider(this).get(ConferenceViewModel::class.java)
|
||||||
binding.conferenceViewModel = conferenceViewModel
|
binding.conferenceViewModel = conferenceViewModel
|
||||||
|
|
||||||
callsViewModel.currentCallViewModel.observe(viewLifecycleOwner, {
|
callsViewModel.currentCallViewModel.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
if (it != null) {
|
if (it != null) {
|
||||||
binding.activeCallTimer.base =
|
binding.activeCallTimer.base =
|
||||||
SystemClock.elapsedRealtime() - (1000 * it.call.duration) // Linphone timestamps are in seconds
|
SystemClock.elapsedRealtime() - (1000 * it.call.duration) // Linphone timestamps are in seconds
|
||||||
binding.activeCallTimer.start()
|
binding.activeCallTimer.start()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
callsViewModel.noMoreCallEvent.observe(viewLifecycleOwner, {
|
callsViewModel.noMoreCallEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
requireActivity().finish()
|
requireActivity().finish()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
callsViewModel.askWriteExternalStoragePermissionEvent.observe(viewLifecycleOwner, {
|
callsViewModel.askWriteExternalStoragePermissionEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
if (!PermissionHelper.get().hasWriteExternalStorage()) {
|
if (!PermissionHelper.get().hasWriteExternalStorage()) {
|
||||||
Log.i("[Controls Fragment] Asking for WRITE_EXTERNAL_STORAGE permission")
|
Log.i("[Controls Fragment] Asking for WRITE_EXTERNAL_STORAGE permission")
|
||||||
requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1)
|
requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
callsViewModel.callUpdateEvent.observe(viewLifecycleOwner, {
|
callsViewModel.callUpdateEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { call ->
|
it.consume { call ->
|
||||||
if (call.state == Call.State.StreamsRunning) {
|
if (call.state == Call.State.StreamsRunning) {
|
||||||
dialog?.dismiss()
|
dialog?.dismiss()
|
||||||
|
@ -117,9 +128,12 @@ class ControlsFragment : GenericFragment<CallControlsFragmentBinding>() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
controlsViewModel.chatClickedEvent.observe(viewLifecycleOwner, {
|
controlsViewModel.chatClickedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
val intent = Intent()
|
val intent = Intent()
|
||||||
intent.setClass(requireContext(), MainActivity::class.java)
|
intent.setClass(requireContext(), MainActivity::class.java)
|
||||||
|
@ -127,9 +141,12 @@ class ControlsFragment : GenericFragment<CallControlsFragmentBinding>() {
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
controlsViewModel.addCallClickedEvent.observe(viewLifecycleOwner, {
|
controlsViewModel.addCallClickedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
val intent = Intent()
|
val intent = Intent()
|
||||||
intent.setClass(requireContext(), MainActivity::class.java)
|
intent.setClass(requireContext(), MainActivity::class.java)
|
||||||
|
@ -138,9 +155,12 @@ class ControlsFragment : GenericFragment<CallControlsFragmentBinding>() {
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
controlsViewModel.transferCallClickedEvent.observe(viewLifecycleOwner, {
|
controlsViewModel.transferCallClickedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
val intent = Intent()
|
val intent = Intent()
|
||||||
intent.setClass(requireContext(), MainActivity::class.java)
|
intent.setClass(requireContext(), MainActivity::class.java)
|
||||||
|
@ -149,16 +169,22 @@ class ControlsFragment : GenericFragment<CallControlsFragmentBinding>() {
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
controlsViewModel.askPermissionEvent.observe(viewLifecycleOwner, {
|
controlsViewModel.askPermissionEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { permission ->
|
it.consume { permission ->
|
||||||
Log.i("[Controls Fragment] Asking for $permission permission")
|
Log.i("[Controls Fragment] Asking for $permission permission")
|
||||||
requestPermissions(arrayOf(permission), 0)
|
requestPermissions(arrayOf(permission), 0)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
controlsViewModel.toggleNumpadEvent.observe(viewLifecycleOwner, {
|
controlsViewModel.toggleNumpadEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { open ->
|
it.consume { open ->
|
||||||
if (this::numpadAnimator.isInitialized) {
|
if (this::numpadAnimator.isInitialized) {
|
||||||
if (open) {
|
if (open) {
|
||||||
|
@ -168,13 +194,17 @@ class ControlsFragment : GenericFragment<CallControlsFragmentBinding>() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
controlsViewModel.somethingClickedEvent.observe(viewLifecycleOwner, {
|
controlsViewModel.somethingClickedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
sharedViewModel.resetHiddenInterfaceTimerInVideoCallEvent.value = Event(true)
|
sharedViewModel.resetHiddenInterfaceTimerInVideoCallEvent.value = Event(true)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60)) {
|
if (Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60)) {
|
||||||
checkPermissions()
|
checkPermissions()
|
||||||
|
@ -245,15 +275,21 @@ class ControlsFragment : GenericFragment<CallControlsFragmentBinding>() {
|
||||||
val viewModel = DialogViewModel(AppUtils.getString(R.string.call_video_update_requested_dialog))
|
val viewModel = DialogViewModel(AppUtils.getString(R.string.call_video_update_requested_dialog))
|
||||||
dialog = DialogUtils.getDialog(requireContext(), viewModel)
|
dialog = DialogUtils.getDialog(requireContext(), viewModel)
|
||||||
|
|
||||||
viewModel.showCancelButton({
|
viewModel.showCancelButton(
|
||||||
|
{
|
||||||
callsViewModel.answerCallVideoUpdateRequest(call, false)
|
callsViewModel.answerCallVideoUpdateRequest(call, false)
|
||||||
dialog?.dismiss()
|
dialog?.dismiss()
|
||||||
}, getString(R.string.dialog_decline))
|
},
|
||||||
|
getString(R.string.dialog_decline)
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.showOkButton({
|
viewModel.showOkButton(
|
||||||
|
{
|
||||||
callsViewModel.answerCallVideoUpdateRequest(call, true)
|
callsViewModel.answerCallVideoUpdateRequest(call, true)
|
||||||
dialog?.dismiss()
|
dialog?.dismiss()
|
||||||
}, getString(R.string.dialog_accept))
|
},
|
||||||
|
getString(R.string.dialog_accept)
|
||||||
|
)
|
||||||
|
|
||||||
dialog?.show()
|
dialog?.show()
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,13 +62,16 @@ class StatusFragment : GenericFragment<CallStatusFragmentBinding>() {
|
||||||
viewModel.refreshRegister()
|
viewModel.refreshRegister()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.showZrtpDialogEvent.observe(viewLifecycleOwner, {
|
viewModel.showZrtpDialogEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { call ->
|
it.consume { call ->
|
||||||
if (call.state == Call.State.Connected || call.state == Call.State.StreamsRunning) {
|
if (call.state == Call.State.Connected || call.state == Call.State.StreamsRunning) {
|
||||||
showZrtpDialog(call)
|
showZrtpDialog(call)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
@ -117,19 +120,25 @@ class StatusFragment : GenericFragment<CallStatusFragmentBinding>() {
|
||||||
|
|
||||||
val dialog: Dialog = DialogUtils.getDialog(requireContext(), viewModel)
|
val dialog: Dialog = DialogUtils.getDialog(requireContext(), viewModel)
|
||||||
|
|
||||||
viewModel.showDeleteButton({
|
viewModel.showDeleteButton(
|
||||||
|
{
|
||||||
call.authenticationTokenVerified = false
|
call.authenticationTokenVerified = false
|
||||||
this@StatusFragment.viewModel.updateEncryptionInfo(call)
|
this@StatusFragment.viewModel.updateEncryptionInfo(call)
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
zrtpDialog = null
|
zrtpDialog = null
|
||||||
}, getString(R.string.zrtp_dialog_deny_button_label))
|
},
|
||||||
|
getString(R.string.zrtp_dialog_deny_button_label)
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.showOkButton({
|
viewModel.showOkButton(
|
||||||
|
{
|
||||||
call.authenticationTokenVerified = true
|
call.authenticationTokenVerified = true
|
||||||
this@StatusFragment.viewModel.updateEncryptionInfo(call)
|
this@StatusFragment.viewModel.updateEncryptionInfo(call)
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
zrtpDialog = null
|
zrtpDialog = null
|
||||||
}, getString(R.string.zrtp_dialog_ok_button_label))
|
},
|
||||||
|
getString(R.string.zrtp_dialog_ok_button_label)
|
||||||
|
)
|
||||||
|
|
||||||
zrtpDialog = dialog
|
zrtpDialog = dialog
|
||||||
dialog.show()
|
dialog.show()
|
||||||
|
|
|
@ -148,7 +148,8 @@ open class CallViewModel(val call: Call) : GenericContactViewModel(call.remoteAd
|
||||||
timer?.cancel()
|
timer?.cancel()
|
||||||
|
|
||||||
timer = Timer("Call update timeout")
|
timer = Timer("Call update timeout")
|
||||||
timer?.schedule(object : TimerTask() {
|
timer?.schedule(
|
||||||
|
object : TimerTask() {
|
||||||
override fun run() {
|
override fun run() {
|
||||||
// Decline call update
|
// Decline call update
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
@ -157,6 +158,8 @@ open class CallViewModel(val call: Call) : GenericContactViewModel(call.remoteAd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 30000)
|
},
|
||||||
|
30000
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,7 +123,8 @@ class ControlsFadingViewModel : ViewModel() {
|
||||||
timer?.cancel()
|
timer?.cancel()
|
||||||
|
|
||||||
timer = Timer("Hide UI controls scheduler")
|
timer = Timer("Hide UI controls scheduler")
|
||||||
timer?.schedule(object : TimerTask() {
|
timer?.schedule(
|
||||||
|
object : TimerTask() {
|
||||||
override fun run() {
|
override fun run() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
@ -132,6 +133,8 @@ class ControlsFadingViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 3000)
|
},
|
||||||
|
3000
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -445,8 +445,10 @@ class ControlsViewModel : ViewModel() {
|
||||||
val core = coreContext.core
|
val core = coreContext.core
|
||||||
val currentCall = core.currentCall
|
val currentCall = core.currentCall
|
||||||
isVideoAvailable.value = (core.videoCaptureEnabled() || core.videoPreviewEnabled()) &&
|
isVideoAvailable.value = (core.videoCaptureEnabled() || core.videoPreviewEnabled()) &&
|
||||||
((currentCall != null && !currentCall.mediaInProgress()) ||
|
(
|
||||||
core.conference?.isIn == true)
|
(currentCall != null && !currentCall.mediaInProgress()) ||
|
||||||
|
core.conference?.isIn == true
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateVideoEnabled() {
|
private fun updateVideoEnabled() {
|
||||||
|
|
|
@ -73,7 +73,8 @@ class ChatBubbleActivity : GenericActivity() {
|
||||||
val localAddress = Factory.instance().createAddress(localSipUri)
|
val localAddress = Factory.instance().createAddress(localSipUri)
|
||||||
val remoteSipAddress = Factory.instance().createAddress(remoteSipUri)
|
val remoteSipAddress = Factory.instance().createAddress(remoteSipUri)
|
||||||
chatRoom = coreContext.core.searchChatRoom(
|
chatRoom = coreContext.core.searchChatRoom(
|
||||||
null, localAddress, remoteSipAddress, arrayOfNulls(
|
null, localAddress, remoteSipAddress,
|
||||||
|
arrayOfNulls(
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -114,7 +115,9 @@ class ChatBubbleActivity : GenericActivity() {
|
||||||
// Disable context menu on each message
|
// Disable context menu on each message
|
||||||
adapter.disableContextMenu()
|
adapter.disableContextMenu()
|
||||||
|
|
||||||
adapter.openContentEvent.observe(this, {
|
adapter.openContentEvent.observe(
|
||||||
|
this,
|
||||||
|
{
|
||||||
it.consume { content ->
|
it.consume { content ->
|
||||||
if (content.isFileEncrypted) {
|
if (content.isFileEncrypted) {
|
||||||
Toast.makeText(this, R.string.chat_bubble_cant_open_enrypted_file, Toast.LENGTH_LONG).show()
|
Toast.makeText(this, R.string.chat_bubble_cant_open_enrypted_file, Toast.LENGTH_LONG).show()
|
||||||
|
@ -122,19 +125,26 @@ class ChatBubbleActivity : GenericActivity() {
|
||||||
FileUtils.openFileInThirdPartyApp(this, content.filePath.orEmpty(), true)
|
FileUtils.openFileInThirdPartyApp(this, content.filePath.orEmpty(), true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
val layoutManager = LinearLayoutManager(this)
|
val layoutManager = LinearLayoutManager(this)
|
||||||
layoutManager.stackFromEnd = true
|
layoutManager.stackFromEnd = true
|
||||||
binding.chatMessagesList.layoutManager = layoutManager
|
binding.chatMessagesList.layoutManager = layoutManager
|
||||||
|
|
||||||
listViewModel.events.observe(this, { events ->
|
listViewModel.events.observe(
|
||||||
|
this,
|
||||||
|
{ events ->
|
||||||
adapter.submitList(events)
|
adapter.submitList(events)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
chatSendingViewModel.textToSend.observe(this, {
|
chatSendingViewModel.textToSend.observe(
|
||||||
|
this,
|
||||||
|
{
|
||||||
chatSendingViewModel.onTextToSendChanged(it)
|
chatSendingViewModel.onTextToSendChanged(it)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
binding.setOpenAppClickListener {
|
binding.setOpenAppClickListener {
|
||||||
val intent = Intent(this, MainActivity::class.java)
|
val intent = Intent(this, MainActivity::class.java)
|
||||||
|
|
|
@ -121,7 +121,9 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin
|
||||||
callOverlayViewModel = ViewModelProvider(this).get(CallOverlayViewModel::class.java)
|
callOverlayViewModel = ViewModelProvider(this).get(CallOverlayViewModel::class.java)
|
||||||
binding.callOverlayViewModel = callOverlayViewModel
|
binding.callOverlayViewModel = callOverlayViewModel
|
||||||
|
|
||||||
sharedViewModel.toggleDrawerEvent.observe(this, {
|
sharedViewModel.toggleDrawerEvent.observe(
|
||||||
|
this,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
if (binding.sideMenu.isDrawerOpen(Gravity.LEFT)) {
|
if (binding.sideMenu.isDrawerOpen(Gravity.LEFT)) {
|
||||||
binding.sideMenu.closeDrawer(binding.sideMenuContent, true)
|
binding.sideMenu.closeDrawer(binding.sideMenuContent, true)
|
||||||
|
@ -129,13 +131,17 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin
|
||||||
binding.sideMenu.openDrawer(binding.sideMenuContent, true)
|
binding.sideMenu.openDrawer(binding.sideMenuContent, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
coreContext.callErrorMessageResourceId.observe(this, {
|
coreContext.callErrorMessageResourceId.observe(
|
||||||
|
this,
|
||||||
|
{
|
||||||
it.consume { message ->
|
it.consume { message ->
|
||||||
showSnackBar(message)
|
showSnackBar(message)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if (coreContext.core.accountList.isEmpty()) {
|
if (coreContext.core.accountList.isEmpty()) {
|
||||||
if (corePreferences.firstStart) {
|
if (corePreferences.firstStart) {
|
||||||
|
@ -486,7 +492,8 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin
|
||||||
}
|
}
|
||||||
MotionEvent.ACTION_UP -> {
|
MotionEvent.ACTION_UP -> {
|
||||||
if (abs(initPosX - view.x) < CorePreferences.OVERLAY_CLICK_SENSITIVITY &&
|
if (abs(initPosX - view.x) < CorePreferences.OVERLAY_CLICK_SENSITIVITY &&
|
||||||
abs(initPosY - view.y) < CorePreferences.OVERLAY_CLICK_SENSITIVITY) {
|
abs(initPosY - view.y) < CorePreferences.OVERLAY_CLICK_SENSITIVITY
|
||||||
|
) {
|
||||||
view.performClick()
|
view.performClick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,9 +153,12 @@ class ChatMessagesListAdapter(
|
||||||
|
|
||||||
// This is for item selection through ListTopBarFragment
|
// This is for item selection through ListTopBarFragment
|
||||||
selectionListViewModel = selectionViewModel
|
selectionListViewModel = selectionViewModel
|
||||||
selectionViewModel.isEditionEnabled.observe(viewLifecycleOwner, {
|
selectionViewModel.isEditionEnabled.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
position = adapterPosition
|
position = adapterPosition
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
setClickListener {
|
setClickListener {
|
||||||
if (selectionViewModel.isEditionEnabled.value == true) {
|
if (selectionViewModel.isEditionEnabled.value == true) {
|
||||||
|
@ -213,7 +216,8 @@ class ChatMessagesListAdapter(
|
||||||
val itemSize = AppUtils.getDimension(R.dimen.chat_message_popup_item_height).toInt()
|
val itemSize = AppUtils.getDimension(R.dimen.chat_message_popup_item_height).toInt()
|
||||||
var totalSize = itemSize * 7
|
var totalSize = itemSize * 7
|
||||||
if (chatMessage.chatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt()) ||
|
if (chatMessage.chatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt()) ||
|
||||||
chatMessage.state == ChatMessage.State.NotDelivered) { // No message id
|
chatMessage.state == ChatMessage.State.NotDelivered
|
||||||
|
) { // No message id
|
||||||
popupView.imdnHidden = true
|
popupView.imdnHidden = true
|
||||||
totalSize -= itemSize
|
totalSize -= itemSize
|
||||||
}
|
}
|
||||||
|
@ -236,7 +240,8 @@ class ChatMessagesListAdapter(
|
||||||
|
|
||||||
// When using WRAP_CONTENT instead of real size, fails to place the
|
// When using WRAP_CONTENT instead of real size, fails to place the
|
||||||
// popup window above if not enough space is available below
|
// popup window above if not enough space is available below
|
||||||
val popupWindow = PopupWindow(popupView.root,
|
val popupWindow = PopupWindow(
|
||||||
|
popupView.root,
|
||||||
AppUtils.getDimension(R.dimen.chat_message_popup_width).toInt(),
|
AppUtils.getDimension(R.dimen.chat_message_popup_width).toInt(),
|
||||||
totalSize,
|
totalSize,
|
||||||
true
|
true
|
||||||
|
@ -354,9 +359,12 @@ class ChatMessagesListAdapter(
|
||||||
|
|
||||||
// This is for item selection through ListTopBarFragment
|
// This is for item selection through ListTopBarFragment
|
||||||
selectionListViewModel = selectionViewModel
|
selectionListViewModel = selectionViewModel
|
||||||
selectionViewModel.isEditionEnabled.observe(viewLifecycleOwner, {
|
selectionViewModel.isEditionEnabled.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
position = adapterPosition
|
position = adapterPosition
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
binding.setClickListener {
|
binding.setClickListener {
|
||||||
if (selectionViewModel.isEditionEnabled.value == true) {
|
if (selectionViewModel.isEditionEnabled.value == true) {
|
||||||
|
@ -376,7 +384,8 @@ private class ChatMessageDiffCallback : DiffUtil.ItemCallback<EventLogData>() {
|
||||||
newItem: EventLogData
|
newItem: EventLogData
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return if (oldItem.eventLog.type == EventLog.Type.ConferenceChatMessage &&
|
return if (oldItem.eventLog.type == EventLog.Type.ConferenceChatMessage &&
|
||||||
newItem.eventLog.type == EventLog.Type.ConferenceChatMessage) {
|
newItem.eventLog.type == EventLog.Type.ConferenceChatMessage
|
||||||
|
) {
|
||||||
oldItem.eventLog.chatMessage?.time == newItem.eventLog.chatMessage?.time &&
|
oldItem.eventLog.chatMessage?.time == newItem.eventLog.chatMessage?.time &&
|
||||||
oldItem.eventLog.chatMessage?.isOutgoing == newItem.eventLog.chatMessage?.isOutgoing
|
oldItem.eventLog.chatMessage?.isOutgoing == newItem.eventLog.chatMessage?.isOutgoing
|
||||||
} else oldItem.eventLog.notifyId == newItem.eventLog.notifyId
|
} else oldItem.eventLog.notifyId == newItem.eventLog.notifyId
|
||||||
|
|
|
@ -72,9 +72,12 @@ class ChatRoomsListAdapter(
|
||||||
|
|
||||||
// This is for item selection through ListTopBarFragment
|
// This is for item selection through ListTopBarFragment
|
||||||
selectionListViewModel = selectionViewModel
|
selectionListViewModel = selectionViewModel
|
||||||
selectionViewModel.isEditionEnabled.observe(viewLifecycleOwner, {
|
selectionViewModel.isEditionEnabled.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
position = adapterPosition
|
position = adapterPosition
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
forwardPending = isForwardPending
|
forwardPending = isForwardPending
|
||||||
|
|
||||||
|
|
|
@ -214,7 +214,7 @@ class ChatMessageContentData(
|
||||||
isVoiceRecording.value = isVoiceRecord
|
isVoiceRecording.value = isVoiceRecord
|
||||||
|
|
||||||
if (isVoiceRecord) {
|
if (isVoiceRecord) {
|
||||||
val duration = content.fileDuration// duration is in ms
|
val duration = content.fileDuration // duration is in ms
|
||||||
voiceRecordDuration.value = duration
|
voiceRecordDuration.value = duration
|
||||||
formattedDuration.value = SimpleDateFormat("mm:ss", Locale.getDefault()).format(duration)
|
formattedDuration.value = SimpleDateFormat("mm:ss", Locale.getDefault()).format(duration)
|
||||||
Log.i("[Voice Recording] Duration is ${voiceRecordDuration.value} ($duration)")
|
Log.i("[Voice Recording] Duration is ${voiceRecordDuration.value} ($duration)")
|
||||||
|
|
|
@ -35,7 +35,8 @@ class EventData(private val eventLog: EventLog) : GenericContactData(
|
||||||
} else {
|
} else {
|
||||||
eventLog.participantAddress!!
|
eventLog.participantAddress!!
|
||||||
}
|
}
|
||||||
}) {
|
}
|
||||||
|
) {
|
||||||
val text = MutableLiveData<String>()
|
val text = MutableLiveData<String>()
|
||||||
|
|
||||||
val isSecurity: Boolean by lazy {
|
val isSecurity: Boolean by lazy {
|
||||||
|
|
|
@ -90,34 +90,54 @@ class ChatRoomCreationFragment : SecureFragment<ChatRoomCreationFragmentBinding>
|
||||||
viewModel.sipContactsSelected.value = true
|
viewModel.sipContactsSelected.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.contactsList.observe(viewLifecycleOwner, {
|
viewModel.contactsList.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
adapter.submitList(it)
|
adapter.submitList(it)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.isEncrypted.observe(viewLifecycleOwner, {
|
viewModel.isEncrypted.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
adapter.updateSecurity(it)
|
adapter.updateSecurity(it)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.sipContactsSelected.observe(viewLifecycleOwner, {
|
viewModel.sipContactsSelected.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
viewModel.updateContactsList()
|
viewModel.updateContactsList()
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.selectedAddresses.observe(viewLifecycleOwner, {
|
viewModel.selectedAddresses.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
adapter.updateSelectedAddresses(it)
|
adapter.updateSelectedAddresses(it)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.chatRoomCreatedEvent.observe(viewLifecycleOwner, {
|
viewModel.chatRoomCreatedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { chatRoom ->
|
it.consume { chatRoom ->
|
||||||
sharedViewModel.selectedChatRoom.value = chatRoom
|
sharedViewModel.selectedChatRoom.value = chatRoom
|
||||||
navigateToChatRoom(AppUtils.createBundleWithSharedTextAndFiles(sharedViewModel))
|
navigateToChatRoom(AppUtils.createBundleWithSharedTextAndFiles(sharedViewModel))
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.filter.observe(viewLifecycleOwner, {
|
viewModel.filter.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
viewModel.applyFilter()
|
viewModel.applyFilter()
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
adapter.selectedContact.observe(viewLifecycleOwner, {
|
adapter.selectedContact.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { searchResult ->
|
it.consume { searchResult ->
|
||||||
if (createGroup) {
|
if (createGroup) {
|
||||||
viewModel.toggleSelectionForSearchResult(searchResult)
|
viewModel.toggleSelectionForSearchResult(searchResult)
|
||||||
|
@ -125,7 +145,8 @@ class ChatRoomCreationFragment : SecureFragment<ChatRoomCreationFragmentBinding>
|
||||||
viewModel.createOneToOneChat(searchResult)
|
viewModel.createOneToOneChat(searchResult)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
addParticipantsFromSharedViewModel()
|
addParticipantsFromSharedViewModel()
|
||||||
|
|
||||||
|
@ -136,11 +157,14 @@ class ChatRoomCreationFragment : SecureFragment<ChatRoomCreationFragmentBinding>
|
||||||
navigateToGroupInfo()
|
navigateToGroupInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(viewLifecycleOwner, {
|
viewModel.onErrorEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { messageResourceId ->
|
it.consume { messageResourceId ->
|
||||||
(activity as MainActivity).showSnackBar(messageResourceId)
|
(activity as MainActivity).showSnackBar(messageResourceId)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if (!PermissionHelper.get().hasReadContactsPermission()) {
|
if (!PermissionHelper.get().hasReadContactsPermission()) {
|
||||||
Log.i("[Chat Room Creation] Asking for READ_CONTACTS permission")
|
Log.i("[Chat Room Creation] Asking for READ_CONTACTS permission")
|
||||||
|
|
|
@ -115,7 +115,8 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
||||||
val localAddress = Factory.instance().createAddress(localSipUri)
|
val localAddress = Factory.instance().createAddress(localSipUri)
|
||||||
val remoteSipAddress = Factory.instance().createAddress(remoteSipUri)
|
val remoteSipAddress = Factory.instance().createAddress(remoteSipUri)
|
||||||
sharedViewModel.selectedChatRoom.value = coreContext.core.searchChatRoom(
|
sharedViewModel.selectedChatRoom.value = coreContext.core.searchChatRoom(
|
||||||
null, localAddress, remoteSipAddress, arrayOfNulls(
|
null, localAddress, remoteSipAddress,
|
||||||
|
arrayOfNulls(
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -189,46 +190,69 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
||||||
}
|
}
|
||||||
binding.chatMessagesList.addOnScrollListener(chatScrollListener)
|
binding.chatMessagesList.addOnScrollListener(chatScrollListener)
|
||||||
|
|
||||||
chatSendingViewModel.textToSend.observe(viewLifecycleOwner, {
|
chatSendingViewModel.textToSend.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
chatSendingViewModel.onTextToSendChanged(it)
|
chatSendingViewModel.onTextToSendChanged(it)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
chatSendingViewModel.requestRecordAudioPermissionEvent.observe(viewLifecycleOwner, {
|
chatSendingViewModel.requestRecordAudioPermissionEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
Log.i("[Chat Room] Asking for RECORD_AUDIO permission")
|
Log.i("[Chat Room] Asking for RECORD_AUDIO permission")
|
||||||
requestPermissions(arrayOf(android.Manifest.permission.RECORD_AUDIO), 2)
|
requestPermissions(arrayOf(android.Manifest.permission.RECORD_AUDIO), 2)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
listViewModel.events.observe(viewLifecycleOwner, { events ->
|
listViewModel.events.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{ events ->
|
||||||
adapter.submitList(events)
|
adapter.submitList(events)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
listViewModel.messageUpdatedEvent.observe(viewLifecycleOwner, {
|
listViewModel.messageUpdatedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { position ->
|
it.consume { position ->
|
||||||
adapter.notifyItemChanged(position)
|
adapter.notifyItemChanged(position)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
listViewModel.requestWriteExternalStoragePermissionEvent.observe(viewLifecycleOwner, {
|
listViewModel.requestWriteExternalStoragePermissionEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
requestPermissions(arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE), 1)
|
requestPermissions(arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE), 1)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
adapter.deleteMessageEvent.observe(viewLifecycleOwner, {
|
adapter.deleteMessageEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { chatMessage ->
|
it.consume { chatMessage ->
|
||||||
listViewModel.deleteMessage(chatMessage)
|
listViewModel.deleteMessage(chatMessage)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
adapter.resendMessageEvent.observe(viewLifecycleOwner, {
|
adapter.resendMessageEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { chatMessage ->
|
it.consume { chatMessage ->
|
||||||
listViewModel.resendMessage(chatMessage)
|
listViewModel.resendMessage(chatMessage)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
adapter.forwardMessageEvent.observe(viewLifecycleOwner, {
|
adapter.forwardMessageEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { chatMessage ->
|
it.consume { chatMessage ->
|
||||||
// Remove observer before setting the message to forward
|
// Remove observer before setting the message to forward
|
||||||
// as we don't want to forward it in this chat room
|
// as we don't want to forward it in this chat room
|
||||||
|
@ -241,32 +265,44 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
||||||
sharedViewModel.closeSlidingPaneEvent.value = Event(true)
|
sharedViewModel.closeSlidingPaneEvent.value = Event(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
adapter.replyMessageEvent.observe(viewLifecycleOwner, {
|
adapter.replyMessageEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { chatMessage ->
|
it.consume { chatMessage ->
|
||||||
chatSendingViewModel.pendingChatMessageToReplyTo.value?.destroy()
|
chatSendingViewModel.pendingChatMessageToReplyTo.value?.destroy()
|
||||||
chatSendingViewModel.pendingChatMessageToReplyTo.value = ChatMessageData(chatMessage)
|
chatSendingViewModel.pendingChatMessageToReplyTo.value = ChatMessageData(chatMessage)
|
||||||
chatSendingViewModel.isPendingAnswer.value = true
|
chatSendingViewModel.isPendingAnswer.value = true
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
adapter.showImdnForMessageEvent.observe(viewLifecycleOwner, {
|
adapter.showImdnForMessageEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { chatMessage ->
|
it.consume { chatMessage ->
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
args.putString("MessageId", chatMessage.messageId)
|
args.putString("MessageId", chatMessage.messageId)
|
||||||
navigateToImdn(args)
|
navigateToImdn(args)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
adapter.addSipUriToContactEvent.observe(viewLifecycleOwner, {
|
adapter.addSipUriToContactEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { sipUri ->
|
it.consume { sipUri ->
|
||||||
Log.i("[Chat Room] Going to contacts list with SIP URI to add: $sipUri")
|
Log.i("[Chat Room] Going to contacts list with SIP URI to add: $sipUri")
|
||||||
navigateToContacts(sipUri)
|
navigateToContacts(sipUri)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
adapter.openContentEvent.observe(viewLifecycleOwner, {
|
adapter.openContentEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { content ->
|
it.consume { content ->
|
||||||
val path = content.filePath.orEmpty()
|
val path = content.filePath.orEmpty()
|
||||||
|
|
||||||
|
@ -311,9 +347,12 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
adapter.scrollToChatMessageEvent.observe(viewLifecycleOwner, {
|
adapter.scrollToChatMessageEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { chatMessage ->
|
it.consume { chatMessage ->
|
||||||
val events = listViewModel.events.value.orEmpty()
|
val events = listViewModel.events.value.orEmpty()
|
||||||
val eventLog = events.find { eventLog ->
|
val eventLog = events.find { eventLog ->
|
||||||
|
@ -328,7 +367,8 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
||||||
Log.e("[Chat Room] Can't scroll to position $index")
|
Log.e("[Chat Room] Can't scroll to position $index")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
binding.setBackClickListener {
|
binding.setBackClickListener {
|
||||||
goBack()
|
goBack()
|
||||||
|
@ -336,7 +376,8 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
||||||
|
|
||||||
binding.setTitleClickListener {
|
binding.setTitleClickListener {
|
||||||
binding.sipUri.visibility = if (!viewModel.oneToOneChatRoom ||
|
binding.sipUri.visibility = if (!viewModel.oneToOneChatRoom ||
|
||||||
binding.sipUri.visibility == View.VISIBLE) View.GONE else View.VISIBLE
|
binding.sipUri.visibility == View.VISIBLE
|
||||||
|
) View.GONE else View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.setMenuClickListener {
|
binding.setMenuClickListener {
|
||||||
|
@ -360,7 +401,8 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
||||||
arrayOf(
|
arrayOf(
|
||||||
android.Manifest.permission.READ_EXTERNAL_STORAGE,
|
android.Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||||
android.Manifest.permission.CAMERA
|
android.Manifest.permission.CAMERA
|
||||||
), 0
|
),
|
||||||
|
0
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,13 +442,16 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sharedViewModel.messageToForwardEvent.observe(viewLifecycleOwner, {
|
sharedViewModel.messageToForwardEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { chatMessage ->
|
it.consume { chatMessage ->
|
||||||
Log.i("[Chat Room] Found message to transfer")
|
Log.i("[Chat Room] Found message to transfer")
|
||||||
showForwardConfirmationDialog(chatMessage)
|
showForwardConfirmationDialog(chatMessage)
|
||||||
sharedViewModel.isPendingMessageForward.value = false
|
sharedViewModel.isPendingMessageForward.value = false
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deleteItems(indexesOfItemToDelete: ArrayList<Int>) {
|
override fun deleteItems(indexesOfItemToDelete: ArrayList<Int>) {
|
||||||
|
@ -464,10 +509,12 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
for (fileToUploadPath in FileUtils.getFilesPathFromPickerIntent(
|
for (
|
||||||
|
fileToUploadPath in FileUtils.getFilesPathFromPickerIntent(
|
||||||
data,
|
data,
|
||||||
chatSendingViewModel.temporaryFileUploadPath
|
chatSendingViewModel.temporaryFileUploadPath
|
||||||
)) {
|
)
|
||||||
|
) {
|
||||||
chatSendingViewModel.addAttachment(fileToUploadPath)
|
chatSendingViewModel.addAttachment(fileToUploadPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -502,7 +549,8 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
||||||
val okLabel = if (viewModel.oneParticipantOneDevice) getString(R.string.dialog_call) else getString(
|
val okLabel = if (viewModel.oneParticipantOneDevice) getString(R.string.dialog_call) else getString(
|
||||||
R.string.dialog_ok
|
R.string.dialog_ok
|
||||||
)
|
)
|
||||||
dialogViewModel.showOkButton({ doNotAskAgain ->
|
dialogViewModel.showOkButton(
|
||||||
|
{ doNotAskAgain ->
|
||||||
if (doNotAskAgain) corePreferences.limeSecurityPopupEnabled = false
|
if (doNotAskAgain) corePreferences.limeSecurityPopupEnabled = false
|
||||||
|
|
||||||
val address = viewModel.onlyParticipantOnlyDeviceAddress
|
val address = viewModel.onlyParticipantOnlyDeviceAddress
|
||||||
|
@ -515,7 +563,9 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}, okLabel)
|
},
|
||||||
|
okLabel
|
||||||
|
)
|
||||||
|
|
||||||
dialog.show()
|
dialog.show()
|
||||||
} else {
|
} else {
|
||||||
|
@ -551,11 +601,14 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.showOkButton({
|
viewModel.showOkButton(
|
||||||
|
{
|
||||||
Log.i("[Chat Room] Transfer confirmed")
|
Log.i("[Chat Room] Transfer confirmed")
|
||||||
chatSendingViewModel.transferMessage(chatMessage)
|
chatSendingViewModel.transferMessage(chatMessage)
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}, getString(R.string.chat_message_context_menu_forward))
|
},
|
||||||
|
getString(R.string.chat_message_context_menu_forward)
|
||||||
|
)
|
||||||
|
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
|
@ -679,7 +732,8 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
||||||
)
|
)
|
||||||
val dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
|
val dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
|
||||||
|
|
||||||
dialogViewModel.showDeleteButton({
|
dialogViewModel.showDeleteButton(
|
||||||
|
{
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
val plainFilePath = content.plainFilePath
|
val plainFilePath = content.plainFilePath
|
||||||
|
@ -692,12 +746,17 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, getString(R.string.chat_message_cant_open_file_in_app_dialog_export_button))
|
},
|
||||||
|
getString(R.string.chat_message_cant_open_file_in_app_dialog_export_button)
|
||||||
|
)
|
||||||
|
|
||||||
dialogViewModel.showOkButton({
|
dialogViewModel.showOkButton(
|
||||||
|
{
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
navigateToTextFileViewer(true)
|
navigateToTextFileViewer(true)
|
||||||
}, getString(R.string.chat_message_cant_open_file_in_app_dialog_open_as_text_button))
|
},
|
||||||
|
getString(R.string.chat_message_cant_open_file_in_app_dialog_open_as_text_button)
|
||||||
|
)
|
||||||
|
|
||||||
dialogViewModel.showCancelButton {
|
dialogViewModel.showCancelButton {
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
|
|
|
@ -83,25 +83,37 @@ class GroupInfoFragment : SecureFragment<ChatRoomGroupInfoFragmentBinding>() {
|
||||||
// Divider between items
|
// Divider between items
|
||||||
binding.participants.addItemDecoration(AppUtils.getDividerDecoration(requireContext(), layoutManager))
|
binding.participants.addItemDecoration(AppUtils.getDividerDecoration(requireContext(), layoutManager))
|
||||||
|
|
||||||
viewModel.participants.observe(viewLifecycleOwner, {
|
viewModel.participants.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
adapter.submitList(it)
|
adapter.submitList(it)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.isMeAdmin.observe(viewLifecycleOwner, { isMeAdmin ->
|
viewModel.isMeAdmin.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{ isMeAdmin ->
|
||||||
adapter.showAdminControls(isMeAdmin && chatRoom != null)
|
adapter.showAdminControls(isMeAdmin && chatRoom != null)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.meAdminChangedEvent.observe(viewLifecycleOwner, {
|
viewModel.meAdminChangedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { isMeAdmin ->
|
it.consume { isMeAdmin ->
|
||||||
showMeAdminStateChanged(isMeAdmin)
|
showMeAdminStateChanged(isMeAdmin)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
adapter.participantRemovedEvent.observe(viewLifecycleOwner, {
|
adapter.participantRemovedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { participant ->
|
it.consume { participant ->
|
||||||
viewModel.removeParticipant(participant)
|
viewModel.removeParticipant(participant)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
addParticipantsFromSharedViewModel()
|
addParticipantsFromSharedViewModel()
|
||||||
|
|
||||||
|
@ -109,12 +121,15 @@ class GroupInfoFragment : SecureFragment<ChatRoomGroupInfoFragmentBinding>() {
|
||||||
goBack()
|
goBack()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.createdChatRoomEvent.observe(viewLifecycleOwner, {
|
viewModel.createdChatRoomEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { chatRoom ->
|
it.consume { chatRoom ->
|
||||||
sharedViewModel.selectedChatRoom.value = chatRoom
|
sharedViewModel.selectedChatRoom.value = chatRoom
|
||||||
navigateToChatRoom(AppUtils.createBundleWithSharedTextAndFiles(sharedViewModel))
|
navigateToChatRoom(AppUtils.createBundleWithSharedTextAndFiles(sharedViewModel))
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
binding.setNextClickListener {
|
binding.setNextClickListener {
|
||||||
if (viewModel.chatRoom != null) {
|
if (viewModel.chatRoom != null) {
|
||||||
|
@ -143,10 +158,13 @@ class GroupInfoFragment : SecureFragment<ChatRoomGroupInfoFragmentBinding>() {
|
||||||
val dialogViewModel = DialogViewModel(getString(R.string.chat_room_group_info_leave_dialog_message))
|
val dialogViewModel = DialogViewModel(getString(R.string.chat_room_group_info_leave_dialog_message))
|
||||||
val dialog: Dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
|
val dialog: Dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
|
||||||
|
|
||||||
dialogViewModel.showDeleteButton({
|
dialogViewModel.showDeleteButton(
|
||||||
|
{
|
||||||
viewModel.leaveGroup()
|
viewModel.leaveGroup()
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}, getString(R.string.chat_room_group_info_leave_dialog_button))
|
},
|
||||||
|
getString(R.string.chat_room_group_info_leave_dialog_button)
|
||||||
|
)
|
||||||
|
|
||||||
dialogViewModel.showCancelButton {
|
dialogViewModel.showCancelButton {
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
|
@ -155,11 +173,14 @@ class GroupInfoFragment : SecureFragment<ChatRoomGroupInfoFragmentBinding>() {
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(viewLifecycleOwner, {
|
viewModel.onErrorEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { messageResourceId ->
|
it.consume { messageResourceId ->
|
||||||
(activity as MainActivity).showSnackBar(messageResourceId)
|
(activity as MainActivity).showSnackBar(messageResourceId)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addParticipantsFromSharedViewModel() {
|
private fun addParticipantsFromSharedViewModel() {
|
||||||
|
@ -175,9 +196,11 @@ class GroupInfoFragment : SecureFragment<ChatRoomGroupInfoFragmentBinding>() {
|
||||||
if (exists != null) {
|
if (exists != null) {
|
||||||
list.add(exists)
|
list.add(exists)
|
||||||
} else {
|
} else {
|
||||||
list.add(GroupInfoParticipantData(
|
list.add(
|
||||||
|
GroupInfoParticipantData(
|
||||||
GroupChatRoomMember(address, false, hasLimeX3DHCapability = viewModel.isEncrypted.value == true)
|
GroupChatRoomMember(address, false, hasLimeX3DHCapability = viewModel.isEncrypted.value == true)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,9 +97,12 @@ class ImdnFragment : SecureFragment<ChatRoomImdnFragmentBinding>() {
|
||||||
val headerItemDecoration = RecyclerViewHeaderDecoration(requireContext(), adapter)
|
val headerItemDecoration = RecyclerViewHeaderDecoration(requireContext(), adapter)
|
||||||
binding.participantsList.addItemDecoration(headerItemDecoration)
|
binding.participantsList.addItemDecoration(headerItemDecoration)
|
||||||
|
|
||||||
viewModel.participants.observe(viewLifecycleOwner, {
|
viewModel.participants.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
adapter.submitList(it)
|
adapter.submitList(it)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
binding.setBackClickListener {
|
binding.setBackClickListener {
|
||||||
goBack()
|
goBack()
|
||||||
|
|
|
@ -92,14 +92,19 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
|
||||||
|
|
||||||
view.doOnPreDraw { sharedViewModel.canSlidingPaneBeClosed.value = binding.slidingPane.isSlideable }
|
view.doOnPreDraw { sharedViewModel.canSlidingPaneBeClosed.value = binding.slidingPane.isSlideable }
|
||||||
|
|
||||||
sharedViewModel.closeSlidingPaneEvent.observe(viewLifecycleOwner, {
|
sharedViewModel.closeSlidingPaneEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
if (!binding.slidingPane.closePane()) {
|
if (!binding.slidingPane.closePane()) {
|
||||||
goBack()
|
goBack()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
sharedViewModel.layoutChangedEvent.observe(viewLifecycleOwner, {
|
)
|
||||||
|
sharedViewModel.layoutChangedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
sharedViewModel.canSlidingPaneBeClosed.value = binding.slidingPane.isSlideable
|
sharedViewModel.canSlidingPaneBeClosed.value = binding.slidingPane.isSlideable
|
||||||
if (binding.slidingPane.isSlideable) {
|
if (binding.slidingPane.isSlideable) {
|
||||||
|
@ -110,7 +115,8 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
binding.slidingPane.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED
|
binding.slidingPane.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED
|
||||||
binding.slidingPane.addPanelSlideListener(object : SlidingPaneLayout.PanelSlideListener {
|
binding.slidingPane.addPanelSlideListener(object : SlidingPaneLayout.PanelSlideListener {
|
||||||
override fun onPanelSlide(panel: View, slideOffset: Float) { }
|
override fun onPanelSlide(panel: View, slideOffset: Float) { }
|
||||||
|
@ -171,16 +177,20 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.showDeleteButton({
|
viewModel.showDeleteButton(
|
||||||
|
{
|
||||||
val deletedChatRoom = adapter.currentList[viewHolder.adapterPosition].chatRoom
|
val deletedChatRoom = adapter.currentList[viewHolder.adapterPosition].chatRoom
|
||||||
listViewModel.deleteChatRoom(deletedChatRoom)
|
listViewModel.deleteChatRoom(deletedChatRoom)
|
||||||
if (!binding.slidingPane.isSlideable &&
|
if (!binding.slidingPane.isSlideable &&
|
||||||
deletedChatRoom == sharedViewModel.selectedChatRoom.value) {
|
deletedChatRoom == sharedViewModel.selectedChatRoom.value
|
||||||
|
) {
|
||||||
Log.i("[Chat] Currently displayed chat room has been deleted, removing detail fragment")
|
Log.i("[Chat] Currently displayed chat room has been deleted, removing detail fragment")
|
||||||
clearDisplayedChatRoom()
|
clearDisplayedChatRoom()
|
||||||
}
|
}
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}, getString(R.string.dialog_delete))
|
},
|
||||||
|
getString(R.string.dialog_delete)
|
||||||
|
)
|
||||||
|
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
|
@ -191,17 +201,25 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
|
||||||
// Divider between items
|
// Divider between items
|
||||||
binding.chatList.addItemDecoration(AppUtils.getDividerDecoration(requireContext(), layoutManager))
|
binding.chatList.addItemDecoration(AppUtils.getDividerDecoration(requireContext(), layoutManager))
|
||||||
|
|
||||||
listViewModel.chatRooms.observe(viewLifecycleOwner, { chatRooms ->
|
listViewModel.chatRooms.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{ chatRooms ->
|
||||||
adapter.submitList(chatRooms)
|
adapter.submitList(chatRooms)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
listViewModel.contactsUpdatedEvent.observe(viewLifecycleOwner, {
|
listViewModel.contactsUpdatedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
adapter.notifyDataSetChanged()
|
adapter.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
adapter.selectedChatRoomEvent.observe(viewLifecycleOwner, {
|
adapter.selectedChatRoomEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { chatRoom ->
|
it.consume { chatRoom ->
|
||||||
if ((requireActivity() as GenericActivity).isDestructionPending) {
|
if ((requireActivity() as GenericActivity).isDestructionPending) {
|
||||||
Log.w("[Chat] Activity is pending destruction, don't start navigating now!")
|
Log.w("[Chat] Activity is pending destruction, don't start navigating now!")
|
||||||
|
@ -212,7 +230,8 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
|
||||||
navigateToChatRoom(AppUtils.createBundleWithSharedTextAndFiles(sharedViewModel))
|
navigateToChatRoom(AppUtils.createBundleWithSharedTextAndFiles(sharedViewModel))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
binding.setEditClickListener {
|
binding.setEditClickListener {
|
||||||
listSelectionViewModel.isEditionEnabled.value = true
|
listSelectionViewModel.isEditionEnabled.value = true
|
||||||
|
@ -268,7 +287,9 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
|
||||||
adapter.selectedChatRoomEvent.value = Event(chatRoom)
|
adapter.selectedChatRoomEvent.value = Event(chatRoom)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sharedViewModel.textToShare.observe(viewLifecycleOwner, {
|
sharedViewModel.textToShare.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
if (it.isNotEmpty()) {
|
if (it.isNotEmpty()) {
|
||||||
Log.i("[Chat] Found text to share")
|
Log.i("[Chat] Found text to share")
|
||||||
// val activity = requireActivity() as MainActivity
|
// val activity = requireActivity() as MainActivity
|
||||||
|
@ -279,8 +300,11 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
|
||||||
listViewModel.textSharingPending.value = false
|
listViewModel.textSharingPending.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
sharedViewModel.filesToShare.observe(viewLifecycleOwner, {
|
)
|
||||||
|
sharedViewModel.filesToShare.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
if (it.isNotEmpty()) {
|
if (it.isNotEmpty()) {
|
||||||
Log.i("[Chat] Found ${it.size} files to share")
|
Log.i("[Chat] Found ${it.size} files to share")
|
||||||
// val activity = requireActivity() as MainActivity
|
// val activity = requireActivity() as MainActivity
|
||||||
|
@ -291,20 +315,27 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
|
||||||
listViewModel.fileSharingPending.value = false
|
listViewModel.fileSharingPending.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
sharedViewModel.isPendingMessageForward.observe(viewLifecycleOwner, {
|
)
|
||||||
|
sharedViewModel.isPendingMessageForward.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
listViewModel.forwardPending.value = it
|
listViewModel.forwardPending.value = it
|
||||||
adapter.forwardPending(it)
|
adapter.forwardPending(it)
|
||||||
if (it) {
|
if (it) {
|
||||||
Log.i("[Chat] Found chat message to transfer")
|
Log.i("[Chat] Found chat message to transfer")
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
listViewModel.onErrorEvent.observe(viewLifecycleOwner, {
|
listViewModel.onErrorEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { messageResourceId ->
|
it.consume { messageResourceId ->
|
||||||
(activity as MainActivity).showSnackBar(messageResourceId)
|
(activity as MainActivity).showSnackBar(messageResourceId)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,9 +149,11 @@ class ChatMessageSendingViewModel(private val chatRoom: ChatRoom) : ViewModel()
|
||||||
fun addAttachment(path: String) {
|
fun addAttachment(path: String) {
|
||||||
val list = arrayListOf<ChatMessageAttachmentData>()
|
val list = arrayListOf<ChatMessageAttachmentData>()
|
||||||
list.addAll(attachments.value.orEmpty())
|
list.addAll(attachments.value.orEmpty())
|
||||||
list.add(ChatMessageAttachmentData(path) {
|
list.add(
|
||||||
|
ChatMessageAttachmentData(path) {
|
||||||
removeAttachment(it)
|
removeAttachment(it)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
attachments.value = list
|
attachments.value = list
|
||||||
|
|
||||||
sendMessageEnabled.value = textToSend.value.orEmpty().isNotEmpty() || list.isNotEmpty() || isPendingVoiceRecord.value == true
|
sendMessageEnabled.value = textToSend.value.orEmpty().isNotEmpty() || list.isNotEmpty() || isPendingVoiceRecord.value == true
|
||||||
|
|
|
@ -211,9 +211,11 @@ class GroupInfoViewModel(val chatRoom: ChatRoom?) : ErrorReportingViewModel() {
|
||||||
|
|
||||||
if (chatRoom != null) {
|
if (chatRoom != null) {
|
||||||
for (participant in chatRoom.participants) {
|
for (participant in chatRoom.participants) {
|
||||||
list.add(GroupInfoParticipantData(
|
list.add(
|
||||||
|
GroupInfoParticipantData(
|
||||||
GroupChatRoomMember(participant.address, participant.isAdmin, participant.securityLevel, canBeSetAdmin = true)
|
GroupChatRoomMember(participant.address, participant.isAdmin, participant.securityLevel, canBeSetAdmin = true)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,9 +47,11 @@ class MultiLineWrapContentWidthTextView : AppCompatTextView {
|
||||||
if (widthMode == MeasureSpec.AT_MOST) {
|
if (widthMode == MeasureSpec.AT_MOST) {
|
||||||
val layout = layout
|
val layout = layout
|
||||||
if (layout != null) {
|
if (layout != null) {
|
||||||
val maxWidth = (ceil(getMaxLineWidth(layout).toDouble()).toInt() +
|
val maxWidth = (
|
||||||
|
ceil(getMaxLineWidth(layout).toDouble()).toInt() +
|
||||||
totalPaddingLeft +
|
totalPaddingLeft +
|
||||||
totalPaddingRight)
|
totalPaddingRight
|
||||||
|
)
|
||||||
wSpec = MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.AT_MOST)
|
wSpec = MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.AT_MOST)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,9 +70,12 @@ class ContactsListAdapter(
|
||||||
|
|
||||||
// This is for item selection through ListTopBarFragment
|
// This is for item selection through ListTopBarFragment
|
||||||
selectionListViewModel = selectionViewModel
|
selectionListViewModel = selectionViewModel
|
||||||
selectionViewModel.isEditionEnabled.observe(viewLifecycleOwner, {
|
selectionViewModel.isEditionEnabled.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
position = adapterPosition
|
position = adapterPosition
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
setClickListener {
|
setClickListener {
|
||||||
if (selectionViewModel.isEditionEnabled.value == true) {
|
if (selectionViewModel.isEditionEnabled.value == true) {
|
||||||
|
|
|
@ -78,13 +78,18 @@ class DetailContactFragment : GenericFragment<ContactDetailFragmentBinding>() {
|
||||||
)[ContactViewModel::class.java]
|
)[ContactViewModel::class.java]
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
viewModel.sendSmsToEvent.observe(viewLifecycleOwner, {
|
viewModel.sendSmsToEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { number ->
|
it.consume { number ->
|
||||||
sendSms(number)
|
sendSms(number)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.startCallToEvent.observe(viewLifecycleOwner, {
|
viewModel.startCallToEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { address ->
|
it.consume { address ->
|
||||||
if (coreContext.core.callsNb > 0) {
|
if (coreContext.core.callsNb > 0) {
|
||||||
Log.i("[Contact] Starting dialer with pre-filled URI ${address.asStringUriOnly()}, is transfer? ${sharedViewModel.pendingCallTransfer}")
|
Log.i("[Contact] Starting dialer with pre-filled URI ${address.asStringUriOnly()}, is transfer? ${sharedViewModel.pendingCallTransfer}")
|
||||||
|
@ -97,16 +102,20 @@ class DetailContactFragment : GenericFragment<ContactDetailFragmentBinding>() {
|
||||||
coreContext.startCall(address)
|
coreContext.startCall(address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.chatRoomCreatedEvent.observe(viewLifecycleOwner, {
|
viewModel.chatRoomCreatedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { chatRoom ->
|
it.consume { chatRoom ->
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
args.putString("LocalSipUri", chatRoom.localAddress.asStringUriOnly())
|
args.putString("LocalSipUri", chatRoom.localAddress.asStringUriOnly())
|
||||||
args.putString("RemoteSipUri", chatRoom.peerAddress.asStringUriOnly())
|
args.putString("RemoteSipUri", chatRoom.peerAddress.asStringUriOnly())
|
||||||
navigateToChatRoom(args)
|
navigateToChatRoom(args)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
binding.setBackClickListener {
|
binding.setBackClickListener {
|
||||||
goBack()
|
goBack()
|
||||||
|
@ -120,11 +129,14 @@ class DetailContactFragment : GenericFragment<ContactDetailFragmentBinding>() {
|
||||||
confirmContactRemoval()
|
confirmContactRemoval()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(viewLifecycleOwner, {
|
viewModel.onErrorEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { messageResourceId ->
|
it.consume { messageResourceId ->
|
||||||
(activity as MainActivity).showSnackBar(messageResourceId)
|
(activity as MainActivity).showSnackBar(messageResourceId)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun goBack() {
|
override fun goBack() {
|
||||||
|
@ -143,11 +155,14 @@ class DetailContactFragment : GenericFragment<ContactDetailFragmentBinding>() {
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
dialogViewModel.showDeleteButton({
|
dialogViewModel.showDeleteButton(
|
||||||
|
{
|
||||||
viewModel.deleteContact()
|
viewModel.deleteContact()
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
goBack()
|
goBack()
|
||||||
}, getString(R.string.dialog_delete))
|
},
|
||||||
|
getString(R.string.dialog_delete)
|
||||||
|
)
|
||||||
|
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,14 +80,19 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
|
||||||
|
|
||||||
view.doOnPreDraw { sharedViewModel.canSlidingPaneBeClosed.value = binding.slidingPane.isSlideable }
|
view.doOnPreDraw { sharedViewModel.canSlidingPaneBeClosed.value = binding.slidingPane.isSlideable }
|
||||||
|
|
||||||
sharedViewModel.closeSlidingPaneEvent.observe(viewLifecycleOwner, {
|
sharedViewModel.closeSlidingPaneEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
if (!binding.slidingPane.closePane()) {
|
if (!binding.slidingPane.closePane()) {
|
||||||
goBack()
|
goBack()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
sharedViewModel.layoutChangedEvent.observe(viewLifecycleOwner, {
|
)
|
||||||
|
sharedViewModel.layoutChangedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
sharedViewModel.canSlidingPaneBeClosed.value = binding.slidingPane.isSlideable
|
sharedViewModel.canSlidingPaneBeClosed.value = binding.slidingPane.isSlideable
|
||||||
if (binding.slidingPane.isSlideable) {
|
if (binding.slidingPane.isSlideable) {
|
||||||
|
@ -98,7 +103,8 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
binding.slidingPane.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED
|
binding.slidingPane.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED
|
||||||
/*binding.slidingPane.addPanelSlideListener(object : SlidingPaneLayout.PanelSlideListener {
|
/*binding.slidingPane.addPanelSlideListener(object : SlidingPaneLayout.PanelSlideListener {
|
||||||
override fun onPanelSlide(panel: View, slideOffset: Float) { }
|
override fun onPanelSlide(panel: View, slideOffset: Float) { }
|
||||||
|
@ -155,16 +161,20 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.showDeleteButton({
|
viewModel.showDeleteButton(
|
||||||
|
{
|
||||||
val deletedContact = adapter.currentList[viewHolder.adapterPosition].contactInternal
|
val deletedContact = adapter.currentList[viewHolder.adapterPosition].contactInternal
|
||||||
listViewModel.deleteContact(deletedContact)
|
listViewModel.deleteContact(deletedContact)
|
||||||
if (!binding.slidingPane.isSlideable &&
|
if (!binding.slidingPane.isSlideable &&
|
||||||
deletedContact == sharedViewModel.selectedContact.value) {
|
deletedContact == sharedViewModel.selectedContact.value
|
||||||
|
) {
|
||||||
Log.i("[Contacts] Currently displayed contact has been deleted, removing detail fragment")
|
Log.i("[Contacts] Currently displayed contact has been deleted, removing detail fragment")
|
||||||
clearDisplayedContact()
|
clearDisplayedContact()
|
||||||
}
|
}
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}, getString(R.string.dialog_delete))
|
},
|
||||||
|
getString(R.string.dialog_delete)
|
||||||
|
)
|
||||||
|
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
|
@ -179,7 +189,9 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
|
||||||
val headerItemDecoration = RecyclerViewHeaderDecoration(requireContext(), adapter)
|
val headerItemDecoration = RecyclerViewHeaderDecoration(requireContext(), adapter)
|
||||||
binding.contactsList.addItemDecoration(headerItemDecoration)
|
binding.contactsList.addItemDecoration(headerItemDecoration)
|
||||||
|
|
||||||
adapter.selectedContactEvent.observe(viewLifecycleOwner, {
|
adapter.selectedContactEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { contact ->
|
it.consume { contact ->
|
||||||
Log.i("[Contacts] Selected item in list changed: $contact")
|
Log.i("[Contacts] Selected item in list changed: $contact")
|
||||||
sharedViewModel.selectedContact.value = contact
|
sharedViewModel.selectedContact.value = contact
|
||||||
|
@ -194,9 +206,12 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
|
||||||
navigateToContact()
|
navigateToContact()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
listViewModel.contactsList.observe(viewLifecycleOwner, {
|
listViewModel.contactsList.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
val id = contactIdToDisplay
|
val id = contactIdToDisplay
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
val contact = coreContext.contactsManager.findContactById(id)
|
val contact = coreContext.contactsManager.findContactById(id)
|
||||||
|
@ -207,7 +222,8 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
adapter.submitList(it)
|
adapter.submitList(it)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
binding.setAllContactsToggleClickListener {
|
binding.setAllContactsToggleClickListener {
|
||||||
listViewModel.sipContactsSelected.value = false
|
listViewModel.sipContactsSelected.value = false
|
||||||
|
@ -216,13 +232,19 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
|
||||||
listViewModel.sipContactsSelected.value = true
|
listViewModel.sipContactsSelected.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
listViewModel.sipContactsSelected.observe(viewLifecycleOwner, {
|
listViewModel.sipContactsSelected.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
listViewModel.updateContactsList()
|
listViewModel.updateContactsList()
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
listViewModel.filter.observe(viewLifecycleOwner, {
|
listViewModel.filter.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
listViewModel.updateContactsList()
|
listViewModel.updateContactsList()
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
binding.setNewContactClickListener {
|
binding.setNewContactClickListener {
|
||||||
// Remove any previously selected contact
|
// Remove any previously selected contact
|
||||||
|
|
|
@ -166,11 +166,14 @@ class ContactEditorViewModel(val c: Contact?) : ViewModel(), ContactDataInterfac
|
||||||
}
|
}
|
||||||
|
|
||||||
when (orientation) {
|
when (orientation) {
|
||||||
ExifInterface.ORIENTATION_ROTATE_90 -> image =
|
ExifInterface.ORIENTATION_ROTATE_90 ->
|
||||||
|
image =
|
||||||
ImageUtils.rotateImage(image, 90f)
|
ImageUtils.rotateImage(image, 90f)
|
||||||
ExifInterface.ORIENTATION_ROTATE_180 -> image =
|
ExifInterface.ORIENTATION_ROTATE_180 ->
|
||||||
|
image =
|
||||||
ImageUtils.rotateImage(image, 180f)
|
ImageUtils.rotateImage(image, 180f)
|
||||||
ExifInterface.ORIENTATION_ROTATE_270 -> image =
|
ExifInterface.ORIENTATION_ROTATE_270 ->
|
||||||
|
image =
|
||||||
ImageUtils.rotateImage(image, 270f)
|
ImageUtils.rotateImage(image, 270f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,14 +95,19 @@ class DialerFragment : SecureFragment<DialerFragmentBinding>() {
|
||||||
}
|
}
|
||||||
arguments?.clear()
|
arguments?.clear()
|
||||||
|
|
||||||
viewModel.enteredUri.observe(viewLifecycleOwner, {
|
viewModel.enteredUri.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
if (it == corePreferences.debugPopupCode) {
|
if (it == corePreferences.debugPopupCode) {
|
||||||
displayDebugPopup()
|
displayDebugPopup()
|
||||||
viewModel.enteredUri.value = ""
|
viewModel.enteredUri.value = ""
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.uploadFinishedEvent.observe(viewLifecycleOwner, {
|
viewModel.uploadFinishedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { url ->
|
it.consume { url ->
|
||||||
// To prevent being trigger when using the Send Logs button in About page
|
// To prevent being trigger when using the Send Logs button in About page
|
||||||
if (uploadLogsInitiatedByUs) {
|
if (uploadLogsInitiatedByUs) {
|
||||||
|
@ -117,13 +122,17 @@ class DialerFragment : SecureFragment<DialerFragmentBinding>() {
|
||||||
AppUtils.shareUploadedLogsUrl(activity, url)
|
AppUtils.shareUploadedLogsUrl(activity, url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.updateAvailableEvent.observe(viewLifecycleOwner, {
|
viewModel.updateAvailableEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { url ->
|
it.consume { url ->
|
||||||
displayNewVersionAvailableDialog(url)
|
displayNewVersionAvailableDialog(url)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
Log.i("[Dialer] Pending call transfer mode = ${sharedViewModel.pendingCallTransfer}")
|
Log.i("[Dialer] Pending call transfer mode = ${sharedViewModel.pendingCallTransfer}")
|
||||||
viewModel.transferVisibility.value = sharedViewModel.pendingCallTransfer
|
viewModel.transferVisibility.value = sharedViewModel.pendingCallTransfer
|
||||||
|
@ -204,11 +213,14 @@ class DialerFragment : SecureFragment<DialerFragmentBinding>() {
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.showOkButton({
|
viewModel.showOkButton(
|
||||||
|
{
|
||||||
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||||
startActivity(browserIntent)
|
startActivity(browserIntent)
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}, getString(R.string.dialog_ok))
|
},
|
||||||
|
getString(R.string.dialog_ok)
|
||||||
|
)
|
||||||
|
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,23 +62,34 @@ abstract class MasterFragment<T : ViewDataBinding, U : SelectionListAdapter<*, *
|
||||||
// List selection
|
// List selection
|
||||||
listSelectionViewModel = ViewModelProvider(this).get(ListTopBarViewModel::class.java)
|
listSelectionViewModel = ViewModelProvider(this).get(ListTopBarViewModel::class.java)
|
||||||
|
|
||||||
listSelectionViewModel.isEditionEnabled.observe(viewLifecycleOwner, {
|
listSelectionViewModel.isEditionEnabled.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
if (!it) listSelectionViewModel.onUnSelectAll()
|
if (!it) listSelectionViewModel.onUnSelectAll()
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
listSelectionViewModel.selectAllEvent.observe(viewLifecycleOwner, {
|
listSelectionViewModel.selectAllEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
listSelectionViewModel.onSelectAll(getItemCount() - 1)
|
listSelectionViewModel.onSelectAll(getItemCount() - 1)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
listSelectionViewModel.unSelectAllEvent.observe(viewLifecycleOwner, {
|
listSelectionViewModel.unSelectAllEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
listSelectionViewModel.onUnSelectAll()
|
listSelectionViewModel.onUnSelectAll()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
listSelectionViewModel.deleteSelectionEvent.observe(viewLifecycleOwner, {
|
listSelectionViewModel.deleteSelectionEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
val confirmationDialog = AppUtils.getStringWithPlural(dialogConfirmationMessageBeforeRemoval, listSelectionViewModel.selectedItems.value.orEmpty().size)
|
val confirmationDialog = AppUtils.getStringWithPlural(dialogConfirmationMessageBeforeRemoval, listSelectionViewModel.selectedItems.value.orEmpty().size)
|
||||||
val viewModel = DialogViewModel(confirmationDialog)
|
val viewModel = DialogViewModel(confirmationDialog)
|
||||||
|
@ -89,15 +100,19 @@ abstract class MasterFragment<T : ViewDataBinding, U : SelectionListAdapter<*, *
|
||||||
listSelectionViewModel.isEditionEnabled.value = false
|
listSelectionViewModel.isEditionEnabled.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.showDeleteButton({
|
viewModel.showDeleteButton(
|
||||||
|
{
|
||||||
delete()
|
delete()
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
listSelectionViewModel.isEditionEnabled.value = false
|
listSelectionViewModel.isEditionEnabled.value = false
|
||||||
}, getString(R.string.dialog_delete))
|
},
|
||||||
|
getString(R.string.dialog_delete)
|
||||||
|
)
|
||||||
|
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun delete() {
|
private fun delete() {
|
||||||
|
|
|
@ -75,7 +75,8 @@ abstract class SecureFragment<T : ViewDataBinding> : GenericFragment<T>() {
|
||||||
|
|
||||||
val flags: Int = window.attributes.flags
|
val flags: Int = window.attributes.flags
|
||||||
if ((enable && flags and WindowManager.LayoutParams.FLAG_SECURE != 0) ||
|
if ((enable && flags and WindowManager.LayoutParams.FLAG_SECURE != 0) ||
|
||||||
(!enable && flags and WindowManager.LayoutParams.FLAG_SECURE == 0)) {
|
(!enable && flags and WindowManager.LayoutParams.FLAG_SECURE == 0)
|
||||||
|
) {
|
||||||
Log.d("[Secure Fragment] Secure flag is already ${if (enable) "enabled" else "disabled"}, skipping...")
|
Log.d("[Secure Fragment] Secure flag is already ${if (enable) "enabled" else "disabled"}, skipping...")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,13 +49,16 @@ class StatusFragment : GenericFragment<StatusFragmentBinding>() {
|
||||||
ViewModelProvider(this).get(SharedMainViewModel::class.java)
|
ViewModelProvider(this).get(SharedMainViewModel::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
sharedViewModel.accountRemoved.observe(viewLifecycleOwner, {
|
sharedViewModel.accountRemoved.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
Log.i("[Status Fragment] An account was removed, update default account state")
|
Log.i("[Status Fragment] An account was removed, update default account state")
|
||||||
val defaultAccount = coreContext.core.defaultAccount
|
val defaultAccount = coreContext.core.defaultAccount
|
||||||
if (defaultAccount != null) {
|
if (defaultAccount != null) {
|
||||||
viewModel.updateDefaultAccountRegistrationStatus(defaultAccount.state)
|
viewModel.updateDefaultAccountRegistrationStatus(defaultAccount.state)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
binding.setMenuClickListener {
|
binding.setMenuClickListener {
|
||||||
sharedViewModel.toggleDrawerEvent.value = Event(true)
|
sharedViewModel.toggleDrawerEvent.value = Event(true)
|
||||||
|
|
|
@ -72,9 +72,12 @@ class CallLogsListAdapter(
|
||||||
|
|
||||||
// This is for item selection through ListTopBarFragment
|
// This is for item selection through ListTopBarFragment
|
||||||
selectionListViewModel = selectionViewModel
|
selectionListViewModel = selectionViewModel
|
||||||
selectionViewModel.isEditionEnabled.observe(viewLifecycleOwner, {
|
selectionViewModel.isEditionEnabled.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
position = adapterPosition
|
position = adapterPosition
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
setClickListener {
|
setClickListener {
|
||||||
if (selectionViewModel.isEditionEnabled.value == true) {
|
if (selectionViewModel.isEditionEnabled.value == true) {
|
||||||
|
|
|
@ -94,7 +94,9 @@ class DetailCallLogFragment : GenericFragment<HistoryDetailFragmentBinding>() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.startCallEvent.observe(viewLifecycleOwner, {
|
viewModel.startCallEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { callLog ->
|
it.consume { callLog ->
|
||||||
val address = callLog.remoteAddress
|
val address = callLog.remoteAddress
|
||||||
if (coreContext.core.callsNb > 0) {
|
if (coreContext.core.callsNb > 0) {
|
||||||
|
@ -112,22 +114,29 @@ class DetailCallLogFragment : GenericFragment<HistoryDetailFragmentBinding>() {
|
||||||
coreContext.startCall(address, localAddress = localAddress)
|
coreContext.startCall(address, localAddress = localAddress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.chatRoomCreatedEvent.observe(viewLifecycleOwner, {
|
viewModel.chatRoomCreatedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { chatRoom ->
|
it.consume { chatRoom ->
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
args.putString("LocalSipUri", chatRoom.localAddress.asStringUriOnly())
|
args.putString("LocalSipUri", chatRoom.localAddress.asStringUriOnly())
|
||||||
args.putString("RemoteSipUri", chatRoom.peerAddress.asStringUriOnly())
|
args.putString("RemoteSipUri", chatRoom.peerAddress.asStringUriOnly())
|
||||||
navigateToChatRoom(args)
|
navigateToChatRoom(args)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(viewLifecycleOwner, {
|
viewModel.onErrorEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { messageResourceId ->
|
it.consume { messageResourceId ->
|
||||||
(activity as MainActivity).showSnackBar(messageResourceId)
|
(activity as MainActivity).showSnackBar(messageResourceId)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun goBack() {
|
override fun goBack() {
|
||||||
|
|
|
@ -83,14 +83,19 @@ class MasterCallLogsFragment : MasterFragment<HistoryMasterFragmentBinding, Call
|
||||||
|
|
||||||
view.doOnPreDraw { sharedViewModel.canSlidingPaneBeClosed.value = binding.slidingPane.isSlideable }
|
view.doOnPreDraw { sharedViewModel.canSlidingPaneBeClosed.value = binding.slidingPane.isSlideable }
|
||||||
|
|
||||||
sharedViewModel.closeSlidingPaneEvent.observe(viewLifecycleOwner, {
|
sharedViewModel.closeSlidingPaneEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
if (!binding.slidingPane.closePane()) {
|
if (!binding.slidingPane.closePane()) {
|
||||||
goBack()
|
goBack()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
sharedViewModel.layoutChangedEvent.observe(viewLifecycleOwner, {
|
)
|
||||||
|
sharedViewModel.layoutChangedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
sharedViewModel.canSlidingPaneBeClosed.value = binding.slidingPane.isSlideable
|
sharedViewModel.canSlidingPaneBeClosed.value = binding.slidingPane.isSlideable
|
||||||
if (binding.slidingPane.isSlideable) {
|
if (binding.slidingPane.isSlideable) {
|
||||||
|
@ -101,7 +106,8 @@ class MasterCallLogsFragment : MasterFragment<HistoryMasterFragmentBinding, Call
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
binding.slidingPane.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED
|
binding.slidingPane.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED
|
||||||
/*binding.slidingPane.addPanelSlideListener(object : SlidingPaneLayout.PanelSlideListener {
|
/*binding.slidingPane.addPanelSlideListener(object : SlidingPaneLayout.PanelSlideListener {
|
||||||
override fun onPanelSlide(panel: View, slideOffset: Float) { }
|
override fun onPanelSlide(panel: View, slideOffset: Float) { }
|
||||||
|
@ -156,16 +162,20 @@ class MasterCallLogsFragment : MasterFragment<HistoryMasterFragmentBinding, Call
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.showDeleteButton({
|
viewModel.showDeleteButton(
|
||||||
|
{
|
||||||
val deletedCallGroup = adapter.currentList[viewHolder.adapterPosition]
|
val deletedCallGroup = adapter.currentList[viewHolder.adapterPosition]
|
||||||
listViewModel.deleteCallLogGroup(deletedCallGroup)
|
listViewModel.deleteCallLogGroup(deletedCallGroup)
|
||||||
if (!binding.slidingPane.isSlideable &&
|
if (!binding.slidingPane.isSlideable &&
|
||||||
deletedCallGroup.lastCallLog.callId == sharedViewModel.selectedCallLogGroup.value?.lastCallLog?.callId) {
|
deletedCallGroup.lastCallLog.callId == sharedViewModel.selectedCallLogGroup.value?.lastCallLog?.callId
|
||||||
|
) {
|
||||||
Log.i("[History] Currently displayed history has been deleted, removing detail fragment")
|
Log.i("[History] Currently displayed history has been deleted, removing detail fragment")
|
||||||
clearDisplayedCallHistory()
|
clearDisplayedCallHistory()
|
||||||
}
|
}
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}, getString(R.string.dialog_delete))
|
},
|
||||||
|
getString(R.string.dialog_delete)
|
||||||
|
)
|
||||||
|
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
|
@ -180,41 +190,58 @@ class MasterCallLogsFragment : MasterFragment<HistoryMasterFragmentBinding, Call
|
||||||
val headerItemDecoration = RecyclerViewHeaderDecoration(requireContext(), adapter)
|
val headerItemDecoration = RecyclerViewHeaderDecoration(requireContext(), adapter)
|
||||||
binding.callLogsList.addItemDecoration(headerItemDecoration)
|
binding.callLogsList.addItemDecoration(headerItemDecoration)
|
||||||
|
|
||||||
listViewModel.callLogs.observe(viewLifecycleOwner, { callLogs ->
|
listViewModel.callLogs.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{ callLogs ->
|
||||||
if (listViewModel.missedCallLogsSelected.value == false) {
|
if (listViewModel.missedCallLogsSelected.value == false) {
|
||||||
adapter.submitList(callLogs)
|
adapter.submitList(callLogs)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
listViewModel.missedCallLogs.observe(viewLifecycleOwner, { callLogs ->
|
listViewModel.missedCallLogs.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{ callLogs ->
|
||||||
if (listViewModel.missedCallLogsSelected.value == true) {
|
if (listViewModel.missedCallLogsSelected.value == true) {
|
||||||
adapter.submitList(callLogs)
|
adapter.submitList(callLogs)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
listViewModel.missedCallLogsSelected.observe(viewLifecycleOwner, {
|
listViewModel.missedCallLogsSelected.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
if (it) {
|
if (it) {
|
||||||
adapter.submitList(listViewModel.missedCallLogs.value)
|
adapter.submitList(listViewModel.missedCallLogs.value)
|
||||||
} else {
|
} else {
|
||||||
adapter.submitList(listViewModel.callLogs.value)
|
adapter.submitList(listViewModel.callLogs.value)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
listViewModel.contactsUpdatedEvent.observe(viewLifecycleOwner, {
|
listViewModel.contactsUpdatedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
adapter.notifyDataSetChanged()
|
adapter.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
adapter.selectedCallLogEvent.observe(viewLifecycleOwner, {
|
adapter.selectedCallLogEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { callLog ->
|
it.consume { callLog ->
|
||||||
sharedViewModel.selectedCallLogGroup.value = callLog
|
sharedViewModel.selectedCallLogGroup.value = callLog
|
||||||
binding.slidingPane.openPane()
|
binding.slidingPane.openPane()
|
||||||
navigateToCallHistory()
|
navigateToCallHistory()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
adapter.startCallToEvent.observe(viewLifecycleOwner, {
|
adapter.startCallToEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { callLogGroup ->
|
it.consume { callLogGroup ->
|
||||||
val remoteAddress = callLogGroup.lastCallLog.remoteAddress
|
val remoteAddress = callLogGroup.lastCallLog.remoteAddress
|
||||||
if (coreContext.core.callsNb > 0) {
|
if (coreContext.core.callsNb > 0) {
|
||||||
|
@ -229,7 +256,8 @@ class MasterCallLogsFragment : MasterFragment<HistoryMasterFragmentBinding, Call
|
||||||
coreContext.startCall(remoteAddress, localAddress = localAddress)
|
coreContext.startCall(remoteAddress, localAddress = localAddress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
binding.setAllCallLogsToggleClickListener {
|
binding.setAllCallLogsToggleClickListener {
|
||||||
listViewModel.missedCallLogsSelected.value = false
|
listViewModel.missedCallLogsSelected.value = false
|
||||||
|
|
|
@ -109,7 +109,8 @@ class CallLogsListViewModel : ViewModel() {
|
||||||
if (previousCallLogGroup == null) {
|
if (previousCallLogGroup == null) {
|
||||||
previousCallLogGroup = GroupedCallLogData(callLog)
|
previousCallLogGroup = GroupedCallLogData(callLog)
|
||||||
} else if (previousCallLogGroup.lastCallLog.localAddress.weakEqual(callLog.localAddress) &&
|
} else if (previousCallLogGroup.lastCallLog.localAddress.weakEqual(callLog.localAddress) &&
|
||||||
previousCallLogGroup.lastCallLog.remoteAddress.weakEqual(callLog.remoteAddress)) {
|
previousCallLogGroup.lastCallLog.remoteAddress.weakEqual(callLog.remoteAddress)
|
||||||
|
) {
|
||||||
if (TimestampUtils.isSameDay(previousCallLogGroup.lastCallLog.startDate, callLog.startDate)) {
|
if (TimestampUtils.isSameDay(previousCallLogGroup.lastCallLog.startDate, callLog.startDate)) {
|
||||||
previousCallLogGroup.callLogs.add(callLog)
|
previousCallLogGroup.callLogs.add(callLog)
|
||||||
previousCallLogGroup.lastCallLog = callLog
|
previousCallLogGroup.lastCallLog = callLog
|
||||||
|
@ -126,7 +127,8 @@ class CallLogsListViewModel : ViewModel() {
|
||||||
if (previousMissedCallLogGroup == null) {
|
if (previousMissedCallLogGroup == null) {
|
||||||
previousMissedCallLogGroup = GroupedCallLogData(callLog)
|
previousMissedCallLogGroup = GroupedCallLogData(callLog)
|
||||||
} else if (previousMissedCallLogGroup.lastCallLog.localAddress.weakEqual(callLog.localAddress) &&
|
} else if (previousMissedCallLogGroup.lastCallLog.localAddress.weakEqual(callLog.localAddress) &&
|
||||||
previousMissedCallLogGroup.lastCallLog.remoteAddress.weakEqual(callLog.remoteAddress)) {
|
previousMissedCallLogGroup.lastCallLog.remoteAddress.weakEqual(callLog.remoteAddress)
|
||||||
|
) {
|
||||||
if (TimestampUtils.isSameDay(previousMissedCallLogGroup.lastCallLog.startDate, callLog.startDate)) {
|
if (TimestampUtils.isSameDay(previousMissedCallLogGroup.lastCallLog.startDate, callLog.startDate)) {
|
||||||
previousMissedCallLogGroup.callLogs.add(callLog)
|
previousMissedCallLogGroup.callLogs.add(callLog)
|
||||||
previousMissedCallLogGroup.lastCallLog = callLog
|
previousMissedCallLogGroup.lastCallLog = callLog
|
||||||
|
|
|
@ -68,9 +68,12 @@ class RecordingsFragment : MasterFragment<RecordingsFragmentBinding, RecordingsL
|
||||||
val headerItemDecoration = RecyclerViewHeaderDecoration(requireContext(), adapter)
|
val headerItemDecoration = RecyclerViewHeaderDecoration(requireContext(), adapter)
|
||||||
binding.recordingsList.addItemDecoration(headerItemDecoration)
|
binding.recordingsList.addItemDecoration(headerItemDecoration)
|
||||||
|
|
||||||
viewModel.recordingsList.observe(viewLifecycleOwner, { recordings ->
|
viewModel.recordingsList.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{ recordings ->
|
||||||
adapter.submitList(recordings)
|
adapter.submitList(recordings)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
binding.setBackClickListener { goBack() }
|
binding.setBackClickListener { goBack() }
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,8 @@ class AccountSettingsFragment : GenericFragment<SettingsAccountFragmentBinding>(
|
||||||
|
|
||||||
try {
|
try {
|
||||||
viewModel = ViewModelProvider(this, AccountSettingsViewModelFactory(identity)).get(
|
viewModel = ViewModelProvider(this, AccountSettingsViewModelFactory(identity)).get(
|
||||||
AccountSettingsViewModel::class.java)
|
AccountSettingsViewModel::class.java
|
||||||
|
)
|
||||||
} catch (nsee: NoSuchElementException) {
|
} catch (nsee: NoSuchElementException) {
|
||||||
Log.e("[Account Settings] Failed to find Account object, aborting!")
|
Log.e("[Account Settings] Failed to find Account object, aborting!")
|
||||||
goBack()
|
goBack()
|
||||||
|
@ -69,7 +70,9 @@ class AccountSettingsFragment : GenericFragment<SettingsAccountFragmentBinding>(
|
||||||
|
|
||||||
binding.setBackClickListener { goBack() }
|
binding.setBackClickListener { goBack() }
|
||||||
|
|
||||||
viewModel.linkPhoneNumberEvent.observe(viewLifecycleOwner, {
|
viewModel.linkPhoneNumberEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
val authInfo = viewModel.account.findAuthInfo()
|
val authInfo = viewModel.account.findAuthInfo()
|
||||||
if (authInfo == null) {
|
if (authInfo == null) {
|
||||||
|
@ -82,14 +85,18 @@ class AccountSettingsFragment : GenericFragment<SettingsAccountFragmentBinding>(
|
||||||
navigateToPhoneLinking(args)
|
navigateToPhoneLinking(args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.accountRemovedEvent.observe(viewLifecycleOwner, {
|
viewModel.accountRemovedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
sharedViewModel.accountRemoved.value = true
|
sharedViewModel.accountRemoved.value = true
|
||||||
goBack()
|
goBack()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun goBack() {
|
override fun goBack() {
|
||||||
|
|
|
@ -61,7 +61,9 @@ class AdvancedSettingsFragment : GenericFragment<SettingsAdvancedFragmentBinding
|
||||||
|
|
||||||
binding.setBackClickListener { goBack() }
|
binding.setBackClickListener { goBack() }
|
||||||
|
|
||||||
viewModel.uploadFinishedEvent.observe(viewLifecycleOwner, {
|
viewModel.uploadFinishedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { url ->
|
it.consume { url ->
|
||||||
val clipboard =
|
val clipboard =
|
||||||
requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
|
@ -73,23 +75,32 @@ class AdvancedSettingsFragment : GenericFragment<SettingsAdvancedFragmentBinding
|
||||||
|
|
||||||
AppUtils.shareUploadedLogsUrl(activity, url)
|
AppUtils.shareUploadedLogsUrl(activity, url)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.uploadErrorEvent.observe(viewLifecycleOwner, {
|
viewModel.uploadErrorEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
val activity = requireActivity() as MainActivity
|
val activity = requireActivity() as MainActivity
|
||||||
activity.showSnackBar(R.string.logs_upload_failure)
|
activity.showSnackBar(R.string.logs_upload_failure)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.resetCompleteEvent.observe(viewLifecycleOwner, {
|
viewModel.resetCompleteEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
val activity = requireActivity() as MainActivity
|
val activity = requireActivity() as MainActivity
|
||||||
activity.showSnackBar(R.string.logs_reset_complete)
|
activity.showSnackBar(R.string.logs_reset_complete)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.setNightModeEvent.observe(viewLifecycleOwner, {
|
viewModel.setNightModeEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { value ->
|
it.consume { value ->
|
||||||
AppCompatDelegate.setDefaultNightMode(
|
AppCompatDelegate.setDefaultNightMode(
|
||||||
when (value) {
|
when (value) {
|
||||||
|
@ -99,21 +110,30 @@ class AdvancedSettingsFragment : GenericFragment<SettingsAdvancedFragmentBinding
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.backgroundModeEnabled.value = !DeviceUtils.isAppUserRestricted(requireContext())
|
viewModel.backgroundModeEnabled.value = !DeviceUtils.isAppUserRestricted(requireContext())
|
||||||
|
|
||||||
viewModel.goToBatterySettingsEvent.observe(viewLifecycleOwner, { it.consume {
|
viewModel.goToBatterySettingsEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
|
it.consume {
|
||||||
try {
|
try {
|
||||||
val intent = Intent("android.settings.IGNORE_BATTERY_OPTIMIZATION_SETTINGS")
|
val intent = Intent("android.settings.IGNORE_BATTERY_OPTIMIZATION_SETTINGS")
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
} catch (anfe: ActivityNotFoundException) {
|
} catch (anfe: ActivityNotFoundException) {
|
||||||
Log.e("[Advanced Settings] ActivityNotFound exception: ", anfe)
|
Log.e("[Advanced Settings] ActivityNotFound exception: ", anfe)
|
||||||
}
|
}
|
||||||
} })
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.powerManagerSettingsVisibility.value = PowerManagerUtils.getDevicePowerManagerIntent(requireContext()) != null
|
viewModel.powerManagerSettingsVisibility.value = PowerManagerUtils.getDevicePowerManagerIntent(requireContext()) != null
|
||||||
viewModel.goToPowerManagerSettingsEvent.observe(viewLifecycleOwner, { it.consume {
|
viewModel.goToPowerManagerSettingsEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
|
it.consume {
|
||||||
val intent = PowerManagerUtils.getDevicePowerManagerIntent(requireActivity())
|
val intent = PowerManagerUtils.getDevicePowerManagerIntent(requireActivity())
|
||||||
if (intent != null) {
|
if (intent != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -122,16 +142,23 @@ class AdvancedSettingsFragment : GenericFragment<SettingsAdvancedFragmentBinding
|
||||||
Log.e("[Advanced Settings] Security exception: ", se)
|
Log.e("[Advanced Settings] Security exception: ", se)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} })
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.goToAndroidSettingsEvent.observe(viewLifecycleOwner, { it.consume {
|
viewModel.goToAndroidSettingsEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
|
it.consume {
|
||||||
val intent = Intent()
|
val intent = Intent()
|
||||||
intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
|
intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
|
||||||
intent.addCategory(Intent.CATEGORY_DEFAULT)
|
intent.addCategory(Intent.CATEGORY_DEFAULT)
|
||||||
intent.data = Uri.parse("package:${requireContext().packageName}")
|
intent.data = Uri.parse("package:${requireContext().packageName}")
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
|
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
|
||||||
ContextCompat.startActivity(requireContext(), intent, null)
|
ContextCompat.startActivity(requireContext(), intent, null)
|
||||||
} })
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun goBack() {
|
override fun goBack() {
|
||||||
|
|
|
@ -60,19 +60,25 @@ class AudioSettingsFragment : GenericFragment<SettingsAudioFragmentBinding>() {
|
||||||
|
|
||||||
binding.setBackClickListener { goBack() }
|
binding.setBackClickListener { goBack() }
|
||||||
|
|
||||||
viewModel.askAudioRecordPermissionForEchoCancellerCalibrationEvent.observe(viewLifecycleOwner, {
|
viewModel.askAudioRecordPermissionForEchoCancellerCalibrationEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
Log.i("[Audio Settings] Asking for RECORD_AUDIO permission for echo canceller calibration")
|
Log.i("[Audio Settings] Asking for RECORD_AUDIO permission for echo canceller calibration")
|
||||||
requestPermissions(arrayOf(android.Manifest.permission.RECORD_AUDIO), 1)
|
requestPermissions(arrayOf(android.Manifest.permission.RECORD_AUDIO), 1)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.askAudioRecordPermissionForEchoTesterEvent.observe(viewLifecycleOwner, {
|
viewModel.askAudioRecordPermissionForEchoTesterEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
Log.i("[Audio Settings] Asking for RECORD_AUDIO permission for echo tester")
|
Log.i("[Audio Settings] Asking for RECORD_AUDIO permission for echo tester")
|
||||||
requestPermissions(arrayOf(android.Manifest.permission.RECORD_AUDIO), 2)
|
requestPermissions(arrayOf(android.Manifest.permission.RECORD_AUDIO), 2)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
initAudioCodecsList()
|
initAudioCodecsList()
|
||||||
|
|
||||||
|
@ -107,11 +113,14 @@ class AudioSettingsFragment : GenericFragment<SettingsAudioFragmentBinding>() {
|
||||||
binding.setVariable(BR.title, payload.mimeType)
|
binding.setVariable(BR.title, payload.mimeType)
|
||||||
binding.setVariable(BR.subtitle, "${payload.clockRate} Hz")
|
binding.setVariable(BR.subtitle, "${payload.clockRate} Hz")
|
||||||
binding.setVariable(BR.checked, payload.enabled())
|
binding.setVariable(BR.checked, payload.enabled())
|
||||||
binding.setVariable(BR.listener, object : SettingListenerStub() {
|
binding.setVariable(
|
||||||
|
BR.listener,
|
||||||
|
object : SettingListenerStub() {
|
||||||
override fun onBoolValueChanged(newValue: Boolean) {
|
override fun onBoolValueChanged(newValue: Boolean) {
|
||||||
payload.enable(newValue)
|
payload.enable(newValue)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
binding.lifecycleOwner = this
|
binding.lifecycleOwner = this
|
||||||
list.add(binding)
|
list.add(binding)
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,16 +57,22 @@ class CallSettingsFragment : GenericFragment<SettingsCallFragmentBinding>() {
|
||||||
|
|
||||||
binding.setBackClickListener { goBack() }
|
binding.setBackClickListener { goBack() }
|
||||||
|
|
||||||
viewModel.systemWideOverlayEnabledEvent.observe(viewLifecycleOwner, {
|
viewModel.systemWideOverlayEnabledEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
if (!Compatibility.canDrawOverlay(requireContext())) {
|
if (!Compatibility.canDrawOverlay(requireContext())) {
|
||||||
val intent = Intent("android.settings.action.MANAGE_OVERLAY_PERMISSION", Uri.parse("package:${requireContext().packageName}"))
|
val intent = Intent("android.settings.action.MANAGE_OVERLAY_PERMISSION", Uri.parse("package:${requireContext().packageName}"))
|
||||||
startActivityForResult(intent, 0)
|
startActivityForResult(intent, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.goToAndroidNotificationSettingsEvent.observe(viewLifecycleOwner, { it.consume {
|
viewModel.goToAndroidNotificationSettingsEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
|
it.consume {
|
||||||
if (Build.VERSION.SDK_INT >= Version.API26_O_80) {
|
if (Build.VERSION.SDK_INT >= Version.API26_O_80) {
|
||||||
val i = Intent()
|
val i = Intent()
|
||||||
i.action = Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS
|
i.action = Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS
|
||||||
|
@ -81,7 +87,9 @@ class CallSettingsFragment : GenericFragment<SettingsCallFragmentBinding>() {
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
|
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
|
||||||
startActivity(i)
|
startActivity(i)
|
||||||
}
|
}
|
||||||
} })
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
|
|
|
@ -56,7 +56,9 @@ class ChatSettingsFragment : GenericFragment<SettingsChatFragmentBinding>() {
|
||||||
|
|
||||||
binding.setBackClickListener { goBack() }
|
binding.setBackClickListener { goBack() }
|
||||||
|
|
||||||
viewModel.launcherShortcutsEvent.observe(viewLifecycleOwner, {
|
viewModel.launcherShortcutsEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { newValue ->
|
it.consume { newValue ->
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
Compatibility.createShortcutsToChatRooms(requireContext())
|
Compatibility.createShortcutsToChatRooms(requireContext())
|
||||||
|
@ -64,9 +66,13 @@ class ChatSettingsFragment : GenericFragment<SettingsChatFragmentBinding>() {
|
||||||
Compatibility.removeShortcuts(requireContext())
|
Compatibility.removeShortcuts(requireContext())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.goToAndroidNotificationSettingsEvent.observe(viewLifecycleOwner, { it.consume {
|
viewModel.goToAndroidNotificationSettingsEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
|
it.consume {
|
||||||
if (Build.VERSION.SDK_INT >= Version.API26_O_80) {
|
if (Build.VERSION.SDK_INT >= Version.API26_O_80) {
|
||||||
val i = Intent()
|
val i = Intent()
|
||||||
i.action = Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS
|
i.action = Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS
|
||||||
|
@ -81,7 +87,9 @@ class ChatSettingsFragment : GenericFragment<SettingsChatFragmentBinding>() {
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
|
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
|
||||||
startActivity(i)
|
startActivity(i)
|
||||||
}
|
}
|
||||||
} })
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun goBack() {
|
override fun goBack() {
|
||||||
|
|
|
@ -57,7 +57,9 @@ class ContactsSettingsFragment : GenericFragment<SettingsContactsFragmentBinding
|
||||||
|
|
||||||
binding.setBackClickListener { goBack() }
|
binding.setBackClickListener { goBack() }
|
||||||
|
|
||||||
viewModel.launcherShortcutsEvent.observe(viewLifecycleOwner, {
|
viewModel.launcherShortcutsEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume { newValue ->
|
it.consume { newValue ->
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
Compatibility.createShortcutsToContacts(requireContext())
|
Compatibility.createShortcutsToContacts(requireContext())
|
||||||
|
@ -68,14 +70,18 @@ class ContactsSettingsFragment : GenericFragment<SettingsContactsFragmentBinding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.askWriteContactsPermissionForPresenceStorageEvent.observe(viewLifecycleOwner, {
|
viewModel.askWriteContactsPermissionForPresenceStorageEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
Log.i("[Contacts Settings] Asking for WRITE_CONTACTS permission to be able to store presence")
|
Log.i("[Contacts Settings] Asking for WRITE_CONTACTS permission to be able to store presence")
|
||||||
requestPermissions(arrayOf(android.Manifest.permission.WRITE_CONTACTS), 1)
|
requestPermissions(arrayOf(android.Manifest.permission.WRITE_CONTACTS), 1)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if (!PermissionHelper.required(requireContext()).hasReadContactsPermission()) {
|
if (!PermissionHelper.required(requireContext()).hasReadContactsPermission()) {
|
||||||
Log.i("[Contacts Settings] Asking for READ_CONTACTS permission")
|
Log.i("[Contacts Settings] Asking for READ_CONTACTS permission")
|
||||||
|
|
|
@ -57,14 +57,19 @@ class SettingsFragment : SecureFragment<SettingsFragmentBinding>() {
|
||||||
|
|
||||||
view.doOnPreDraw { sharedViewModel.canSlidingPaneBeClosed.value = binding.slidingPane.isSlideable }
|
view.doOnPreDraw { sharedViewModel.canSlidingPaneBeClosed.value = binding.slidingPane.isSlideable }
|
||||||
|
|
||||||
sharedViewModel.closeSlidingPaneEvent.observe(viewLifecycleOwner, {
|
sharedViewModel.closeSlidingPaneEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
if (!binding.slidingPane.closePane()) {
|
if (!binding.slidingPane.closePane()) {
|
||||||
goBack()
|
goBack()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
sharedViewModel.layoutChangedEvent.observe(viewLifecycleOwner, {
|
)
|
||||||
|
sharedViewModel.layoutChangedEvent.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
sharedViewModel.canSlidingPaneBeClosed.value = binding.slidingPane.isSlideable
|
sharedViewModel.canSlidingPaneBeClosed.value = binding.slidingPane.isSlideable
|
||||||
if (binding.slidingPane.isSlideable) {
|
if (binding.slidingPane.isSlideable) {
|
||||||
|
@ -75,7 +80,8 @@ class SettingsFragment : SecureFragment<SettingsFragmentBinding>() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
binding.slidingPane.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED
|
binding.slidingPane.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED
|
||||||
|
|
||||||
/* End of shared view model & sliding pane related */
|
/* End of shared view model & sliding pane related */
|
||||||
|
@ -85,10 +91,13 @@ class SettingsFragment : SecureFragment<SettingsFragmentBinding>() {
|
||||||
|
|
||||||
binding.setBackClickListener { goBack() }
|
binding.setBackClickListener { goBack() }
|
||||||
|
|
||||||
sharedViewModel.accountRemoved.observe(viewLifecycleOwner, {
|
sharedViewModel.accountRemoved.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
Log.i("[Settings] Account removed, update accounts list")
|
Log.i("[Settings] Account removed, update accounts list")
|
||||||
viewModel.updateAccountsList()
|
viewModel.updateAccountsList()
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
val identity = arguments?.getString("Identity")
|
val identity = arguments?.getString("Identity")
|
||||||
if (identity != null) {
|
if (identity != null) {
|
||||||
|
|
|
@ -93,7 +93,9 @@ class VideoSettingsFragment : GenericFragment<SettingsVideoFragmentBinding>() {
|
||||||
binding.setVariable(BR.text_subtitle, "")
|
binding.setVariable(BR.text_subtitle, "")
|
||||||
binding.setVariable(BR.defaultValue, payload.recvFmtp)
|
binding.setVariable(BR.defaultValue, payload.recvFmtp)
|
||||||
binding.setVariable(BR.checked, payload.enabled())
|
binding.setVariable(BR.checked, payload.enabled())
|
||||||
binding.setVariable(BR.listener, object : SettingListenerStub() {
|
binding.setVariable(
|
||||||
|
BR.listener,
|
||||||
|
object : SettingListenerStub() {
|
||||||
override fun onBoolValueChanged(newValue: Boolean) {
|
override fun onBoolValueChanged(newValue: Boolean) {
|
||||||
payload.enable(newValue)
|
payload.enable(newValue)
|
||||||
}
|
}
|
||||||
|
@ -101,7 +103,8 @@ class VideoSettingsFragment : GenericFragment<SettingsVideoFragmentBinding>() {
|
||||||
override fun onTextValueChanged(newValue: String) {
|
override fun onTextValueChanged(newValue: String) {
|
||||||
payload.recvFmtp = newValue
|
payload.recvFmtp = newValue
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
binding.lifecycleOwner = this
|
binding.lifecycleOwner = this
|
||||||
list.add(binding)
|
list.add(binding)
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,10 +67,13 @@ class SideMenuFragment : GenericFragment<SideMenuFragmentBinding>() {
|
||||||
ViewModelProvider(this).get(SharedMainViewModel::class.java)
|
ViewModelProvider(this).get(SharedMainViewModel::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
sharedViewModel.accountRemoved.observe(viewLifecycleOwner, {
|
sharedViewModel.accountRemoved.observe(
|
||||||
|
viewLifecycleOwner,
|
||||||
|
{
|
||||||
Log.i("[Side Menu] Account removed, update accounts list")
|
Log.i("[Side Menu] Account removed, update accounts list")
|
||||||
viewModel.updateAccountsList()
|
viewModel.updateAccountsList()
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.accountsSettingsListener = object : SettingListenerStub() {
|
viewModel.accountsSettingsListener = object : SettingListenerStub() {
|
||||||
override fun onAccountClicked(identity: String) {
|
override fun onAccountClicked(identity: String) {
|
||||||
|
|
|
@ -315,7 +315,8 @@ class ContactsManager(private val context: Context) {
|
||||||
val accounts = accountManager.getAccountsByType(context.getString(R.string.sync_account_type))
|
val accounts = accountManager.getAccountsByType(context.getString(R.string.sync_account_type))
|
||||||
if (accounts.isEmpty()) {
|
if (accounts.isEmpty()) {
|
||||||
val newAccount = Account(
|
val newAccount = Account(
|
||||||
context.getString(R.string.sync_account_name), context.getString(
|
context.getString(R.string.sync_account_name),
|
||||||
|
context.getString(
|
||||||
R.string.sync_account_type
|
R.string.sync_account_type
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -178,10 +178,13 @@ class CoreContext(val context: Context, coreConfig: Config) {
|
||||||
} else {
|
} else {
|
||||||
Log.i("[Context] Scheduling auto answering in $autoAnswerDelay milliseconds")
|
Log.i("[Context] Scheduling auto answering in $autoAnswerDelay milliseconds")
|
||||||
val mainThreadHandler = Handler(Looper.getMainLooper())
|
val mainThreadHandler = Handler(Looper.getMainLooper())
|
||||||
mainThreadHandler.postDelayed({
|
mainThreadHandler.postDelayed(
|
||||||
|
{
|
||||||
Log.w("[Context] Auto answering call")
|
Log.w("[Context] Auto answering call")
|
||||||
answerCall(call)
|
answerCall(call)
|
||||||
}, autoAnswerDelay.toLong())
|
},
|
||||||
|
autoAnswerDelay.toLong()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (state == Call.State.OutgoingInit) {
|
} else if (state == Call.State.OutgoingInit) {
|
||||||
|
@ -214,7 +217,8 @@ class CoreContext(val context: Context, coreConfig: Config) {
|
||||||
// Do not turn speaker on when video is enabled if headset or bluetooth is used
|
// Do not turn speaker on when video is enabled if headset or bluetooth is used
|
||||||
if (!AudioRouteUtils.isHeadsetAudioRouteAvailable() && !AudioRouteUtils.isBluetoothAudioRouteCurrentlyUsed(
|
if (!AudioRouteUtils.isHeadsetAudioRouteAvailable() && !AudioRouteUtils.isBluetoothAudioRouteCurrentlyUsed(
|
||||||
call
|
call
|
||||||
)) {
|
)
|
||||||
|
) {
|
||||||
Log.i("[Context] Video enabled and no wired headset not bluetooth in use, routing audio to speaker")
|
Log.i("[Context] Video enabled and no wired headset not bluetooth in use, routing audio to speaker")
|
||||||
AudioRouteUtils.routeAudioToSpeaker(call)
|
AudioRouteUtils.routeAudioToSpeaker(call)
|
||||||
}
|
}
|
||||||
|
@ -238,7 +242,8 @@ class CoreContext(val context: Context, coreConfig: Config) {
|
||||||
callErrorMessageResourceId.value = Event(message)
|
callErrorMessageResourceId.value = Event(message)
|
||||||
} else if (state == Call.State.End &&
|
} else if (state == Call.State.End &&
|
||||||
call.dir == Call.Dir.Outgoing &&
|
call.dir == Call.Dir.Outgoing &&
|
||||||
call.errorInfo.reason == Reason.Declined) {
|
call.errorInfo.reason == Reason.Declined
|
||||||
|
) {
|
||||||
Log.i("[Context] Call has been declined")
|
Log.i("[Context] Call has been declined")
|
||||||
val message = context.getString(R.string.call_error_declined)
|
val message = context.getString(R.string.call_error_declined)
|
||||||
callErrorMessageResourceId.value = Event(message)
|
callErrorMessageResourceId.value = Event(message)
|
||||||
|
@ -597,7 +602,8 @@ class CoreContext(val context: Context, coreConfig: Config) {
|
||||||
}
|
}
|
||||||
MotionEvent.ACTION_UP -> {
|
MotionEvent.ACTION_UP -> {
|
||||||
if (abs(overlayX - params.x) < CorePreferences.OVERLAY_CLICK_SENSITIVITY &&
|
if (abs(overlayX - params.x) < CorePreferences.OVERLAY_CLICK_SENSITIVITY &&
|
||||||
abs(overlayY - params.y) < CorePreferences.OVERLAY_CLICK_SENSITIVITY) {
|
abs(overlayY - params.y) < CorePreferences.OVERLAY_CLICK_SENSITIVITY
|
||||||
|
) {
|
||||||
view.performClick()
|
view.performClick()
|
||||||
}
|
}
|
||||||
overlayX = params.x.toFloat()
|
overlayX = params.x.toFloat()
|
||||||
|
|
|
@ -152,7 +152,8 @@ class NotificationsManager(private val context: Context) {
|
||||||
|
|
||||||
if (message.contents.find { content ->
|
if (message.contents.find { content ->
|
||||||
content.isFile or content.isFileTransfer or content.isText
|
content.isFile or content.isFileTransfer or content.isText
|
||||||
} == null) {
|
} == null
|
||||||
|
) {
|
||||||
Log.w("[Notifications Manager] Received message with neither text or attachment, do not notify")
|
Log.w("[Notifications Manager] Received message with neither text or attachment, do not notify")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -462,7 +463,8 @@ class NotificationsManager(private val context: Context) {
|
||||||
.createPendingIntent()
|
.createPendingIntent()
|
||||||
|
|
||||||
val builder = NotificationCompat.Builder(
|
val builder = NotificationCompat.Builder(
|
||||||
context, context.getString(R.string.notification_channel_missed_call_id))
|
context, context.getString(R.string.notification_channel_missed_call_id)
|
||||||
|
)
|
||||||
.setContentTitle(context.getString(R.string.missed_call_notification_title))
|
.setContentTitle(context.getString(R.string.missed_call_notification_title))
|
||||||
.setContentText(body)
|
.setContentText(body)
|
||||||
.setSmallIcon(R.drawable.topbar_missed_call_notification)
|
.setSmallIcon(R.drawable.topbar_missed_call_notification)
|
||||||
|
@ -546,7 +548,8 @@ class NotificationsManager(private val context: Context) {
|
||||||
val pendingIntent = PendingIntent.getActivity(context, 0, callNotificationIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
val pendingIntent = PendingIntent.getActivity(context, 0, callNotificationIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||||
|
|
||||||
val builder = NotificationCompat.Builder(
|
val builder = NotificationCompat.Builder(
|
||||||
context, channelToUse)
|
context, channelToUse
|
||||||
|
)
|
||||||
.setContentTitle(contact?.fullName ?: displayName)
|
.setContentTitle(contact?.fullName ?: displayName)
|
||||||
.setContentText(context.getString(stringResourceId))
|
.setContentText(context.getString(stringResourceId))
|
||||||
.setSmallIcon(iconResourceId)
|
.setSmallIcon(iconResourceId)
|
||||||
|
|
|
@ -106,7 +106,8 @@ class AudioRouteUtils {
|
||||||
fun isBluetoothAudioRouteAvailable(): Boolean {
|
fun isBluetoothAudioRouteAvailable(): Boolean {
|
||||||
for (audioDevice in coreContext.core.audioDevices) {
|
for (audioDevice in coreContext.core.audioDevices) {
|
||||||
if (audioDevice.type == AudioDevice.Type.Bluetooth &&
|
if (audioDevice.type == AudioDevice.Type.Bluetooth &&
|
||||||
audioDevice.hasCapability(AudioDevice.Capabilities.CapabilityPlay)) {
|
audioDevice.hasCapability(AudioDevice.Capabilities.CapabilityPlay)
|
||||||
|
) {
|
||||||
Log.i("[Audio Route Helper] Found bluetooth audio device [${audioDevice.deviceName}]")
|
Log.i("[Audio Route Helper] Found bluetooth audio device [${audioDevice.deviceName}]")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -117,7 +118,8 @@ class AudioRouteUtils {
|
||||||
fun isHeadsetAudioRouteAvailable(): Boolean {
|
fun isHeadsetAudioRouteAvailable(): Boolean {
|
||||||
for (audioDevice in coreContext.core.audioDevices) {
|
for (audioDevice in coreContext.core.audioDevices) {
|
||||||
if ((audioDevice.type == AudioDevice.Type.Headset || audioDevice.type == AudioDevice.Type.Headphones) &&
|
if ((audioDevice.type == AudioDevice.Type.Headset || audioDevice.type == AudioDevice.Type.Headphones) &&
|
||||||
audioDevice.hasCapability(AudioDevice.Capabilities.CapabilityPlay)) {
|
audioDevice.hasCapability(AudioDevice.Capabilities.CapabilityPlay)
|
||||||
|
) {
|
||||||
Log.i("[Audio Route Helper] Found headset/headphones audio device [${audioDevice.deviceName}]")
|
Log.i("[Audio Route Helper] Found headset/headphones audio device [${audioDevice.deviceName}]")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -417,7 +417,8 @@ class FileUtils {
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(
|
Log.e(
|
||||||
"[Chat Message] Couldn't get URI for file $file using file provider ${context.getString(
|
"[Chat Message] Couldn't get URI for file $file using file provider ${context.getString(
|
||||||
R.string.file_provider)}"
|
R.string.file_provider
|
||||||
|
)}"
|
||||||
)
|
)
|
||||||
Uri.parse(path)
|
Uri.parse(path)
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,10 +143,14 @@ class LinphoneUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isCallLogMissed(callLog: CallLog): Boolean {
|
fun isCallLogMissed(callLog: CallLog): Boolean {
|
||||||
return (callLog.dir == Call.Dir.Incoming &&
|
return (
|
||||||
(callLog.status == Call.Status.Missed ||
|
callLog.dir == Call.Dir.Incoming &&
|
||||||
|
(
|
||||||
|
callLog.status == Call.Status.Missed ||
|
||||||
callLog.status == Call.Status.Aborted ||
|
callLog.status == Call.Status.Aborted ||
|
||||||
callLog.status == Call.Status.EarlyAborted))
|
callLog.status == Call.Status.EarlyAborted
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getChatRoomId(localAddress: String, remoteAddress: String): String {
|
fun getChatRoomId(localAddress: String, remoteAddress: String): String {
|
||||||
|
|
|
@ -63,7 +63,8 @@ class VoiceRecordProgressBar : View {
|
||||||
context.theme.obtainStyledAttributes(
|
context.theme.obtainStyledAttributes(
|
||||||
attrs,
|
attrs,
|
||||||
R.styleable.VoiceRecordProgressBar,
|
R.styleable.VoiceRecordProgressBar,
|
||||||
0, 0).apply {
|
0, 0
|
||||||
|
).apply {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val drawable = getDrawable(R.styleable.VoiceRecordProgressBar_progressDrawable)
|
val drawable = getDrawable(R.styleable.VoiceRecordProgressBar_progressDrawable)
|
||||||
|
|
Loading…
Reference in a new issue