Moved lambdas arguments out of parenthesis
This commit is contained in:
parent
81884dd218
commit
a0ebeb1fea
47 changed files with 1238 additions and 1350 deletions
|
@ -79,66 +79,62 @@ class AccountLoginFragment : AbstractPhoneFragment<AssistantAccountLoginFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.goToSmsValidationEvent.observe(
|
viewModel.goToSmsValidationEvent.observe(
|
||||||
viewLifecycleOwner,
|
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(
|
viewModel.leaveAssistantEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
coreContext.contactsManager.updateLocalContacts()
|
coreContext.contactsManager.updateLocalContacts()
|
||||||
|
|
||||||
if (coreContext.core.isEchoCancellerCalibrationRequired) {
|
if (coreContext.core.isEchoCancellerCalibrationRequired) {
|
||||||
navigateToEchoCancellerCalibration()
|
navigateToEchoCancellerCalibration()
|
||||||
} else {
|
} else {
|
||||||
requireActivity().finish()
|
requireActivity().finish()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.invalidCredentialsEvent.observe(
|
viewModel.invalidCredentialsEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
val dialogViewModel =
|
val dialogViewModel =
|
||||||
DialogViewModel(getString(R.string.assistant_error_invalid_credentials))
|
DialogViewModel(getString(R.string.assistant_error_invalid_credentials))
|
||||||
val dialog: Dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
|
val dialog: Dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
|
||||||
|
|
||||||
dialogViewModel.showCancelButton {
|
dialogViewModel.showCancelButton {
|
||||||
viewModel.removeInvalidProxyConfig()
|
viewModel.removeInvalidProxyConfig()
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
|
||||||
|
|
||||||
dialogViewModel.showDeleteButton(
|
|
||||||
{
|
|
||||||
viewModel.continueEvenIfInvalidCredentials()
|
|
||||||
dialog.dismiss()
|
|
||||||
},
|
|
||||||
getString(R.string.assistant_continue_even_if_credentials_invalid)
|
|
||||||
)
|
|
||||||
|
|
||||||
dialog.show()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dialogViewModel.showDeleteButton(
|
||||||
|
{
|
||||||
|
viewModel.continueEvenIfInvalidCredentials()
|
||||||
|
dialog.dismiss()
|
||||||
|
},
|
||||||
|
getString(R.string.assistant_continue_even_if_credentials_invalid)
|
||||||
|
)
|
||||||
|
|
||||||
|
dialog.show()
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(
|
viewModel.onErrorEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { message ->
|
it.consume { message ->
|
||||||
(requireActivity() as AssistantActivity).showSnackBar(message)
|
(requireActivity() as AssistantActivity).showSnackBar(message)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60)) {
|
if (Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60)) {
|
||||||
checkPermissions()
|
checkPermissions()
|
||||||
|
|
|
@ -48,13 +48,12 @@ class EchoCancellerCalibrationFragment : GenericFragment<AssistantEchoCancellerC
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
viewModel.echoCalibrationTerminated.observe(
|
viewModel.echoCalibrationTerminated.observe(
|
||||||
viewLifecycleOwner,
|
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")
|
||||||
|
|
|
@ -50,21 +50,19 @@ class EmailAccountCreationFragment : GenericFragment<AssistantEmailAccountCreati
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
viewModel.goToEmailValidationEvent.observe(
|
viewModel.goToEmailValidationEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
navigateToEmailAccountValidation()
|
navigateToEmailAccountValidation()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(
|
viewModel.onErrorEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { message ->
|
it.consume { message ->
|
||||||
(requireActivity() as AssistantActivity).showSnackBar(message)
|
(requireActivity() as AssistantActivity).showSnackBar(message)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,27 +49,25 @@ class EmailAccountValidationFragment : GenericFragment<AssistantEmailAccountVali
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
viewModel.leaveAssistantEvent.observe(
|
viewModel.leaveAssistantEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
coreContext.contactsManager.updateLocalContacts()
|
coreContext.contactsManager.updateLocalContacts()
|
||||||
|
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
args.putBoolean("AllowSkip", true)
|
args.putBoolean("AllowSkip", true)
|
||||||
args.putString("Username", viewModel.accountCreator.username)
|
args.putString("Username", viewModel.accountCreator.username)
|
||||||
args.putString("Password", viewModel.accountCreator.password)
|
args.putString("Password", viewModel.accountCreator.password)
|
||||||
navigateToAccountLinking(args)
|
navigateToAccountLinking(args)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(
|
viewModel.onErrorEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { message ->
|
it.consume { message ->
|
||||||
(requireActivity() as AssistantActivity).showSnackBar(message)
|
(requireActivity() as AssistantActivity).showSnackBar(message)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,52 +54,50 @@ class GenericAccountLoginFragment : GenericFragment<AssistantGenericAccountLogin
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
viewModel.leaveAssistantEvent.observe(
|
viewModel.leaveAssistantEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
coreContext.contactsManager.updateLocalContacts()
|
coreContext.contactsManager.updateLocalContacts()
|
||||||
|
|
||||||
if (coreContext.core.isEchoCancellerCalibrationRequired) {
|
if (coreContext.core.isEchoCancellerCalibrationRequired) {
|
||||||
navigateToEchoCancellerCalibration()
|
navigateToEchoCancellerCalibration()
|
||||||
} else {
|
} else {
|
||||||
requireActivity().finish()
|
requireActivity().finish()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.invalidCredentialsEvent.observe(
|
viewModel.invalidCredentialsEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
val dialogViewModel = DialogViewModel(getString(R.string.assistant_error_invalid_credentials))
|
val dialogViewModel =
|
||||||
val dialog: Dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
|
DialogViewModel(getString(R.string.assistant_error_invalid_credentials))
|
||||||
|
val dialog: Dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
|
||||||
|
|
||||||
dialogViewModel.showCancelButton {
|
dialogViewModel.showCancelButton {
|
||||||
viewModel.removeInvalidProxyConfig()
|
viewModel.removeInvalidProxyConfig()
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
|
||||||
|
|
||||||
dialogViewModel.showDeleteButton(
|
|
||||||
{
|
|
||||||
viewModel.continueEvenIfInvalidCredentials()
|
|
||||||
dialog.dismiss()
|
|
||||||
},
|
|
||||||
getString(R.string.assistant_continue_even_if_credentials_invalid)
|
|
||||||
)
|
|
||||||
|
|
||||||
dialog.show()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dialogViewModel.showDeleteButton(
|
||||||
|
{
|
||||||
|
viewModel.continueEvenIfInvalidCredentials()
|
||||||
|
dialog.dismiss()
|
||||||
|
},
|
||||||
|
getString(R.string.assistant_continue_even_if_credentials_invalid)
|
||||||
|
)
|
||||||
|
|
||||||
|
dialog.show()
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(
|
viewModel.onErrorEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { message ->
|
it.consume { message ->
|
||||||
(requireActivity() as AssistantActivity).showSnackBar(message)
|
(requireActivity() as AssistantActivity).showSnackBar(message)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,25 +62,23 @@ class PhoneAccountCreationFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.goToSmsValidationEvent.observe(
|
viewModel.goToSmsValidationEvent.observe(
|
||||||
viewLifecycleOwner,
|
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(
|
viewModel.onErrorEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { message ->
|
it.consume { message ->
|
||||||
(requireActivity() as AssistantActivity).showSnackBar(message)
|
(requireActivity() as AssistantActivity).showSnackBar(message)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60)) {
|
if (Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60)) {
|
||||||
checkPermissions()
|
checkPermissions()
|
||||||
|
|
|
@ -73,38 +73,35 @@ class PhoneAccountLinkingFragment : AbstractPhoneFragment<AssistantPhoneAccountL
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.goToSmsValidationEvent.observe(
|
viewModel.goToSmsValidationEvent.observe(
|
||||||
viewLifecycleOwner,
|
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(
|
viewModel.leaveAssistantEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
if (LinphoneApplication.coreContext.core.isEchoCancellerCalibrationRequired) {
|
if (LinphoneApplication.coreContext.core.isEchoCancellerCalibrationRequired) {
|
||||||
navigateToEchoCancellerCalibration()
|
navigateToEchoCancellerCalibration()
|
||||||
} else {
|
} else {
|
||||||
requireActivity().finish()
|
requireActivity().finish()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(
|
viewModel.onErrorEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { message ->
|
it.consume { message ->
|
||||||
(requireActivity() as AssistantActivity).showSnackBar(message)
|
(requireActivity() as AssistantActivity).showSnackBar(message)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60)) {
|
if (Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60)) {
|
||||||
checkPermissions()
|
checkPermissions()
|
||||||
|
|
|
@ -59,37 +59,38 @@ class PhoneAccountValidationFragment : GenericFragment<AssistantPhoneAccountVali
|
||||||
viewModel.isLinking.value = arguments?.getBoolean("IsLinking", false)
|
viewModel.isLinking.value = arguments?.getBoolean("IsLinking", false)
|
||||||
|
|
||||||
viewModel.leaveAssistantEvent.observe(
|
viewModel.leaveAssistantEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
when {
|
when {
|
||||||
viewModel.isLogin.value == true || viewModel.isCreation.value == true -> {
|
viewModel.isLogin.value == true || viewModel.isCreation.value == true -> {
|
||||||
coreContext.contactsManager.updateLocalContacts()
|
coreContext.contactsManager.updateLocalContacts()
|
||||||
|
|
||||||
if (coreContext.core.isEchoCancellerCalibrationRequired) {
|
if (coreContext.core.isEchoCancellerCalibrationRequired) {
|
||||||
navigateToEchoCancellerCalibration()
|
navigateToEchoCancellerCalibration()
|
||||||
} else {
|
} else {
|
||||||
requireActivity().finish()
|
requireActivity().finish()
|
||||||
}
|
|
||||||
}
|
|
||||||
viewModel.isLinking.value == true -> {
|
|
||||||
val args = Bundle()
|
|
||||||
args.putString("Identity", "sip:${viewModel.accountCreator.username}@${viewModel.accountCreator.domain}")
|
|
||||||
navigateToAccountSettings(args)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
viewModel.isLinking.value == true -> {
|
||||||
|
val args = Bundle()
|
||||||
|
args.putString(
|
||||||
|
"Identity",
|
||||||
|
"sip:${viewModel.accountCreator.username}@${viewModel.accountCreator.domain}"
|
||||||
|
)
|
||||||
|
navigateToAccountSettings(args)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(
|
viewModel.onErrorEvent.observe(
|
||||||
viewLifecycleOwner,
|
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 {
|
||||||
|
|
|
@ -56,14 +56,13 @@ class QrCodeFragment : GenericFragment<AssistantQrCodeFragmentBinding>() {
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
viewModel.qrCodeFoundEvent.observe(
|
viewModel.qrCodeFoundEvent.observe(
|
||||||
viewLifecycleOwner,
|
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()) {
|
||||||
|
|
|
@ -55,22 +55,21 @@ class RemoteProvisioningFragment : GenericFragment<AssistantRemoteProvisioningFr
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.fetchSuccessfulEvent.observe(
|
viewModel.fetchSuccessfulEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { success ->
|
it.consume { success ->
|
||||||
if (success) {
|
if (success) {
|
||||||
if (coreContext.core.isEchoCancellerCalibrationRequired) {
|
if (coreContext.core.isEchoCancellerCalibrationRequired) {
|
||||||
navigateToEchoCancellerCalibration()
|
navigateToEchoCancellerCalibration()
|
||||||
} else {
|
|
||||||
requireActivity().finish()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
val activity = requireActivity() as AssistantActivity
|
requireActivity().finish()
|
||||||
activity.showSnackBar(R.string.assistant_remote_provisioning_failure)
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
val activity = requireActivity() as AssistantActivity
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,11 +73,10 @@ class WelcomeFragment : GenericFragment<AssistantWelcomeFragmentBinding>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.termsAndPrivacyAccepted.observe(
|
viewModel.termsAndPrivacyAccepted.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
if (it) corePreferences.readAndAgreeTermsAndPrivacy = true
|
if (it) corePreferences.readAndAgreeTermsAndPrivacy = true
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
setUpTermsAndPrivacyLinks()
|
setUpTermsAndPrivacyLinks()
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,40 +61,36 @@ class CallActivity : ProximitySensorActivity() {
|
||||||
sharedViewModel = ViewModelProvider(this)[SharedCallViewModel::class.java]
|
sharedViewModel = ViewModelProvider(this)[SharedCallViewModel::class.java]
|
||||||
|
|
||||||
sharedViewModel.toggleDrawerEvent.observe(
|
sharedViewModel.toggleDrawerEvent.observe(
|
||||||
this,
|
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)
|
||||||
} else {
|
} else {
|
||||||
binding.statsMenu.openDrawer(binding.sideMenuContent, true)
|
binding.statsMenu.openDrawer(binding.sideMenuContent, true)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
sharedViewModel.resetHiddenInterfaceTimerInVideoCallEvent.observe(
|
sharedViewModel.resetHiddenInterfaceTimerInVideoCallEvent.observe(
|
||||||
this,
|
this
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
viewModel.showMomentarily()
|
viewModel.showMomentarily()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.proximitySensorEnabled.observe(
|
viewModel.proximitySensorEnabled.observe(
|
||||||
this,
|
this
|
||||||
{
|
) {
|
||||||
enableProximitySensor(it)
|
enableProximitySensor(it)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
viewModel.videoEnabled.observe(
|
viewModel.videoEnabled.observe(
|
||||||
this,
|
this
|
||||||
{
|
) {
|
||||||
updateConstraintSetDependingOnFoldingState()
|
updateConstraintSetDependingOnFoldingState()
|
||||||
}
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLayoutChanges(foldingFeature: FoldingFeature?) {
|
override fun onLayoutChanges(foldingFeature: FoldingFeature?) {
|
||||||
|
|
|
@ -79,24 +79,22 @@ class IncomingCallActivity : GenericActivity() {
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
viewModel.callEndedEvent.observe(
|
viewModel.callEndedEvent.observe(
|
||||||
this,
|
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(
|
viewModel.earlyMediaVideoEnabled.observe(
|
||||||
this,
|
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
|
||||||
|
|
|
@ -80,64 +80,58 @@ class OutgoingCallActivity : ProximitySensorActivity() {
|
||||||
binding.controlsViewModel = controlsViewModel
|
binding.controlsViewModel = controlsViewModel
|
||||||
|
|
||||||
viewModel.callEndedEvent.observe(
|
viewModel.callEndedEvent.observe(
|
||||||
this,
|
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(
|
viewModel.callConnectedEvent.observe(
|
||||||
this,
|
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(
|
controlsViewModel.isSpeakerSelected.observe(
|
||||||
this,
|
this
|
||||||
{
|
) {
|
||||||
enableProximitySensor(!it)
|
enableProximitySensor(!it)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
controlsViewModel.askAudioRecordPermissionEvent.observe(
|
controlsViewModel.askAudioRecordPermissionEvent.observe(
|
||||||
this,
|
this
|
||||||
{
|
) {
|
||||||
it.consume { permission ->
|
it.consume { permission ->
|
||||||
requestPermissions(arrayOf(permission), 0)
|
requestPermissions(arrayOf(permission), 0)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
controlsViewModel.askCameraPermissionEvent.observe(
|
controlsViewModel.askCameraPermissionEvent.observe(
|
||||||
this,
|
this
|
||||||
{
|
) {
|
||||||
it.consume { permission ->
|
it.consume { permission ->
|
||||||
requestPermissions(arrayOf(permission), 0)
|
requestPermissions(arrayOf(permission), 0)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
controlsViewModel.toggleNumpadEvent.observe(
|
controlsViewModel.toggleNumpadEvent.observe(
|
||||||
this,
|
this
|
||||||
{
|
) {
|
||||||
it.consume { open ->
|
it.consume { open ->
|
||||||
if (this::numpadAnimator.isInitialized) {
|
if (this::numpadAnimator.isInitialized) {
|
||||||
if (open) {
|
if (open) {
|
||||||
numpadAnimator.start()
|
numpadAnimator.start()
|
||||||
} else {
|
} else {
|
||||||
numpadAnimator.reverse()
|
numpadAnimator.reverse()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60)) {
|
if (Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60)) {
|
||||||
checkPermissions()
|
checkPermissions()
|
||||||
|
|
|
@ -88,140 +88,129 @@ class ControlsFragment : GenericFragment<CallControlsFragmentBinding>() {
|
||||||
binding.conferenceViewModel = conferenceViewModel
|
binding.conferenceViewModel = conferenceViewModel
|
||||||
|
|
||||||
callsViewModel.currentCallViewModel.observe(
|
callsViewModel.currentCallViewModel.observe(
|
||||||
viewLifecycleOwner,
|
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(
|
callsViewModel.noMoreCallEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
requireActivity().finish()
|
requireActivity().finish()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
callsViewModel.askWriteExternalStoragePermissionEvent.observe(
|
callsViewModel.askWriteExternalStoragePermissionEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
if (!PermissionHelper.get().hasWriteExternalStoragePermission()) {
|
if (!PermissionHelper.get().hasWriteExternalStoragePermission()) {
|
||||||
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), 2)
|
requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 2)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
callsViewModel.callUpdateEvent.observe(
|
callsViewModel.callUpdateEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { call ->
|
it.consume { call ->
|
||||||
if (call.state == Call.State.StreamsRunning) {
|
if (call.state == Call.State.StreamsRunning) {
|
||||||
dialog?.dismiss()
|
dialog?.dismiss()
|
||||||
} else if (call.state == Call.State.UpdatedByRemote) {
|
} else if (call.state == Call.State.UpdatedByRemote) {
|
||||||
if (coreContext.core.isVideoCaptureEnabled || coreContext.core.isVideoDisplayEnabled) {
|
if (coreContext.core.isVideoCaptureEnabled || coreContext.core.isVideoDisplayEnabled) {
|
||||||
if (call.currentParams.isVideoEnabled != call.remoteParams?.isVideoEnabled) {
|
if (call.currentParams.isVideoEnabled != call.remoteParams?.isVideoEnabled) {
|
||||||
showCallVideoUpdateDialog(call)
|
showCallVideoUpdateDialog(call)
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w("[Controls Fragment] Video display & capture are disabled, don't show video dialog")
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Log.w("[Controls Fragment] Video display & capture are disabled, don't show video dialog")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
controlsViewModel.chatClickedEvent.observe(
|
controlsViewModel.chatClickedEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
val intent = Intent()
|
val intent = Intent()
|
||||||
intent.setClass(requireContext(), MainActivity::class.java)
|
intent.setClass(requireContext(), MainActivity::class.java)
|
||||||
intent.putExtra("Chat", true)
|
intent.putExtra("Chat", true)
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
controlsViewModel.addCallClickedEvent.observe(
|
controlsViewModel.addCallClickedEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
val intent = Intent()
|
val intent = Intent()
|
||||||
intent.setClass(requireContext(), MainActivity::class.java)
|
intent.setClass(requireContext(), MainActivity::class.java)
|
||||||
intent.putExtra("Dialer", true)
|
intent.putExtra("Dialer", true)
|
||||||
intent.putExtra("Transfer", false)
|
intent.putExtra("Transfer", false)
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
controlsViewModel.transferCallClickedEvent.observe(
|
controlsViewModel.transferCallClickedEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
val intent = Intent()
|
val intent = Intent()
|
||||||
intent.setClass(requireContext(), MainActivity::class.java)
|
intent.setClass(requireContext(), MainActivity::class.java)
|
||||||
intent.putExtra("Dialer", true)
|
intent.putExtra("Dialer", true)
|
||||||
intent.putExtra("Transfer", true)
|
intent.putExtra("Transfer", true)
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
controlsViewModel.askAudioRecordPermissionEvent.observe(
|
controlsViewModel.askAudioRecordPermissionEvent.observe(
|
||||||
viewLifecycleOwner,
|
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.askCameraPermissionEvent.observe(
|
controlsViewModel.askCameraPermissionEvent.observe(
|
||||||
viewLifecycleOwner,
|
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), 1)
|
requestPermissions(arrayOf(permission), 1)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
controlsViewModel.toggleNumpadEvent.observe(
|
controlsViewModel.toggleNumpadEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { open ->
|
it.consume { open ->
|
||||||
if (this::numpadAnimator.isInitialized) {
|
if (this::numpadAnimator.isInitialized) {
|
||||||
if (open) {
|
if (open) {
|
||||||
numpadAnimator.start()
|
numpadAnimator.start()
|
||||||
} else {
|
} else {
|
||||||
numpadAnimator.reverse()
|
numpadAnimator.reverse()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
controlsViewModel.somethingClickedEvent.observe(
|
controlsViewModel.somethingClickedEvent.observe(
|
||||||
viewLifecycleOwner,
|
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()
|
||||||
|
|
|
@ -64,15 +64,14 @@ class StatusFragment : GenericFragment<CallStatusFragmentBinding>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.showZrtpDialogEvent.observe(
|
viewModel.showZrtpDialogEvent.observe(
|
||||||
viewLifecycleOwner,
|
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?) {
|
||||||
|
|
|
@ -122,35 +122,36 @@ class ChatBubbleActivity : GenericActivity() {
|
||||||
adapter.disableContextMenu()
|
adapter.disableContextMenu()
|
||||||
|
|
||||||
adapter.openContentEvent.observe(
|
adapter.openContentEvent.observe(
|
||||||
this,
|
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(
|
||||||
} else {
|
this,
|
||||||
FileUtils.openFileInThirdPartyApp(this, content.filePath.orEmpty(), true)
|
R.string.chat_bubble_cant_open_enrypted_file,
|
||||||
}
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
} else {
|
||||||
|
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(
|
listViewModel.events.observe(
|
||||||
this,
|
this
|
||||||
{ events ->
|
) { events ->
|
||||||
adapter.submitList(events)
|
adapter.submitList(events)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
chatSendingViewModel.textToSend.observe(
|
chatSendingViewModel.textToSend.observe(
|
||||||
this,
|
this
|
||||||
{
|
) {
|
||||||
chatSendingViewModel.onTextToSendChanged(it)
|
chatSendingViewModel.onTextToSendChanged(it)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
binding.setOpenAppClickListener {
|
binding.setOpenAppClickListener {
|
||||||
coreContext.notificationsManager.currentlyDisplayedChatRoomAddress = null
|
coreContext.notificationsManager.currentlyDisplayedChatRoomAddress = null
|
||||||
|
|
|
@ -125,26 +125,24 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin
|
||||||
binding.callOverlayViewModel = callOverlayViewModel
|
binding.callOverlayViewModel = callOverlayViewModel
|
||||||
|
|
||||||
sharedViewModel.toggleDrawerEvent.observe(
|
sharedViewModel.toggleDrawerEvent.observe(
|
||||||
this,
|
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)
|
||||||
} else {
|
} else {
|
||||||
binding.sideMenu.openDrawer(binding.sideMenuContent, true)
|
binding.sideMenu.openDrawer(binding.sideMenuContent, true)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
coreContext.callErrorMessageResourceId.observe(
|
coreContext.callErrorMessageResourceId.observe(
|
||||||
this,
|
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) {
|
||||||
|
@ -251,7 +249,7 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin
|
||||||
tabsFragment.visibility = if (tabsFragmentVisible1 && tabsFragmentVisible2) View.VISIBLE else View.GONE
|
tabsFragment.visibility = if (tabsFragmentVisible1 && tabsFragmentVisible2) View.VISIBLE else View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
fun View.hideKeyboard() {
|
private fun View.hideKeyboard() {
|
||||||
val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
|
val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
imm.hideSoftInputFromWindow(windowToken, 0)
|
imm.hideSoftInputFromWindow(windowToken, 0)
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,11 +211,10 @@ class ChatMessagesListAdapter(
|
||||||
// This is for item selection through ListTopBarFragment
|
// This is for item selection through ListTopBarFragment
|
||||||
selectionListViewModel = selectionViewModel
|
selectionListViewModel = selectionViewModel
|
||||||
selectionViewModel.isEditionEnabled.observe(
|
selectionViewModel.isEditionEnabled.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
position = bindingAdapterPosition
|
position = bindingAdapterPosition
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
setClickListener {
|
setClickListener {
|
||||||
if (selectionViewModel.isEditionEnabled.value == true) {
|
if (selectionViewModel.isEditionEnabled.value == true) {
|
||||||
|
@ -416,11 +415,10 @@ class ChatMessagesListAdapter(
|
||||||
// This is for item selection through ListTopBarFragment
|
// This is for item selection through ListTopBarFragment
|
||||||
selectionListViewModel = selectionViewModel
|
selectionListViewModel = selectionViewModel
|
||||||
selectionViewModel.isEditionEnabled.observe(
|
selectionViewModel.isEditionEnabled.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
position = bindingAdapterPosition
|
position = bindingAdapterPosition
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
binding.setClickListener {
|
binding.setClickListener {
|
||||||
if (selectionViewModel.isEditionEnabled.value == true) {
|
if (selectionViewModel.isEditionEnabled.value == true) {
|
||||||
|
|
|
@ -73,11 +73,10 @@ class ChatRoomsListAdapter(
|
||||||
// This is for item selection through ListTopBarFragment
|
// This is for item selection through ListTopBarFragment
|
||||||
selectionListViewModel = selectionViewModel
|
selectionListViewModel = selectionViewModel
|
||||||
selectionViewModel.isEditionEnabled.observe(
|
selectionViewModel.isEditionEnabled.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
position = bindingAdapterPosition
|
position = bindingAdapterPosition
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
forwardPending = isForwardPending
|
forwardPending = isForwardPending
|
||||||
|
|
||||||
|
|
|
@ -93,62 +93,55 @@ class ChatRoomCreationFragment : SecureFragment<ChatRoomCreationFragmentBinding>
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.contactsList.observe(
|
viewModel.contactsList.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
adapter.submitList(it)
|
adapter.submitList(it)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
viewModel.isEncrypted.observe(
|
viewModel.isEncrypted.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
adapter.updateSecurity(it)
|
adapter.updateSecurity(it)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
viewModel.sipContactsSelected.observe(
|
viewModel.sipContactsSelected.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
viewModel.updateContactsList()
|
viewModel.updateContactsList()
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
viewModel.selectedAddresses.observe(
|
viewModel.selectedAddresses.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
adapter.updateSelectedAddresses(it)
|
adapter.updateSelectedAddresses(it)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
viewModel.chatRoomCreatedEvent.observe(
|
viewModel.chatRoomCreatedEvent.observe(
|
||||||
viewLifecycleOwner,
|
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(
|
viewModel.filter.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
viewModel.applyFilter()
|
viewModel.applyFilter()
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
adapter.selectedContact.observe(
|
adapter.selectedContact.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { searchResult ->
|
it.consume { searchResult ->
|
||||||
if (createGroup) {
|
if (createGroup) {
|
||||||
viewModel.toggleSelectionForSearchResult(searchResult)
|
viewModel.toggleSelectionForSearchResult(searchResult)
|
||||||
} else {
|
} else {
|
||||||
viewModel.createOneToOneChat(searchResult)
|
viewModel.createOneToOneChat(searchResult)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
addParticipantsFromSharedViewModel()
|
addParticipantsFromSharedViewModel()
|
||||||
|
|
||||||
|
@ -160,13 +153,12 @@ class ChatRoomCreationFragment : SecureFragment<ChatRoomCreationFragmentBinding>
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(
|
viewModel.onErrorEvent.observe(
|
||||||
viewLifecycleOwner,
|
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")
|
||||||
|
|
|
@ -294,193 +294,191 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
||||||
binding.chatMessagesList.addOnScrollListener(chatScrollListener)
|
binding.chatMessagesList.addOnScrollListener(chatScrollListener)
|
||||||
|
|
||||||
chatSendingViewModel.textToSend.observe(
|
chatSendingViewModel.textToSend.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
chatSendingViewModel.onTextToSendChanged(it)
|
chatSendingViewModel.onTextToSendChanged(it)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
chatSendingViewModel.requestRecordAudioPermissionEvent.observe(
|
chatSendingViewModel.requestRecordAudioPermissionEvent.observe(
|
||||||
viewLifecycleOwner,
|
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(
|
listViewModel.events.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{ events ->
|
) { events ->
|
||||||
adapter.setUnreadMessageCount(viewModel.chatRoom.unreadMessagesCount, viewModel.isUserScrollingUp.value == true)
|
adapter.setUnreadMessageCount(
|
||||||
adapter.submitList(events)
|
viewModel.chatRoom.unreadMessagesCount,
|
||||||
}
|
viewModel.isUserScrollingUp.value == true
|
||||||
)
|
)
|
||||||
|
adapter.submitList(events)
|
||||||
|
}
|
||||||
|
|
||||||
listViewModel.messageUpdatedEvent.observe(
|
listViewModel.messageUpdatedEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { position ->
|
it.consume { position ->
|
||||||
adapter.notifyItemChanged(position)
|
adapter.notifyItemChanged(position)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
listViewModel.requestWriteExternalStoragePermissionEvent.observe(
|
listViewModel.requestWriteExternalStoragePermissionEvent.observe(
|
||||||
viewLifecycleOwner,
|
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(
|
adapter.deleteMessageEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { chatMessage ->
|
it.consume { chatMessage ->
|
||||||
listViewModel.deleteMessage(chatMessage)
|
listViewModel.deleteMessage(chatMessage)
|
||||||
viewModel.updateLastMessageToDisplay()
|
viewModel.updateLastMessageToDisplay()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
adapter.resendMessageEvent.observe(
|
adapter.resendMessageEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { chatMessage ->
|
it.consume { chatMessage ->
|
||||||
listViewModel.resendMessage(chatMessage)
|
listViewModel.resendMessage(chatMessage)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
adapter.forwardMessageEvent.observe(
|
adapter.forwardMessageEvent.observe(
|
||||||
viewLifecycleOwner,
|
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
|
||||||
sharedViewModel.messageToForwardEvent.removeObservers(viewLifecycleOwner)
|
sharedViewModel.messageToForwardEvent.removeObservers(viewLifecycleOwner)
|
||||||
sharedViewModel.messageToForwardEvent.value = Event(chatMessage)
|
sharedViewModel.messageToForwardEvent.value = Event(chatMessage)
|
||||||
sharedViewModel.isPendingMessageForward.value = true
|
sharedViewModel.isPendingMessageForward.value = true
|
||||||
|
|
||||||
if (sharedViewModel.isSlidingPaneSlideable.value == true) {
|
if (sharedViewModel.isSlidingPaneSlideable.value == true) {
|
||||||
Log.i("[Chat Room] Forwarding message, going to chat rooms list")
|
Log.i("[Chat Room] Forwarding message, going to chat rooms list")
|
||||||
sharedViewModel.closeSlidingPaneEvent.value = Event(true)
|
sharedViewModel.closeSlidingPaneEvent.value = Event(true)
|
||||||
} else {
|
} else {
|
||||||
navigateToEmptyChatRoom()
|
navigateToEmptyChatRoom()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
adapter.replyMessageEvent.observe(
|
adapter.replyMessageEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { chatMessage ->
|
it.consume { chatMessage ->
|
||||||
chatSendingViewModel.pendingChatMessageToReplyTo.value?.destroy()
|
chatSendingViewModel.pendingChatMessageToReplyTo.value?.destroy()
|
||||||
chatSendingViewModel.pendingChatMessageToReplyTo.value = ChatMessageData(chatMessage)
|
chatSendingViewModel.pendingChatMessageToReplyTo.value =
|
||||||
chatSendingViewModel.isPendingAnswer.value = true
|
ChatMessageData(chatMessage)
|
||||||
}
|
chatSendingViewModel.isPendingAnswer.value = true
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
adapter.showImdnForMessageEvent.observe(
|
adapter.showImdnForMessageEvent.observe(
|
||||||
viewLifecycleOwner,
|
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(
|
adapter.addSipUriToContactEvent.observe(
|
||||||
viewLifecycleOwner,
|
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")
|
||||||
sharedViewModel.updateContactsAnimationsBasedOnDestination.value = Event(R.id.masterChatRoomsFragment)
|
sharedViewModel.updateContactsAnimationsBasedOnDestination.value =
|
||||||
navigateToContacts(sipUri)
|
Event(R.id.masterChatRoomsFragment)
|
||||||
}
|
navigateToContacts(sipUri)
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
adapter.openContentEvent.observe(
|
adapter.openContentEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { content ->
|
it.consume { content ->
|
||||||
val path = content.filePath.orEmpty()
|
val path = content.filePath.orEmpty()
|
||||||
|
|
||||||
if (!File(path).exists()) {
|
if (!File(path).exists()) {
|
||||||
(requireActivity() as MainActivity).showSnackBar(R.string.chat_room_file_not_found)
|
(requireActivity() as MainActivity).showSnackBar(R.string.chat_room_file_not_found)
|
||||||
} else {
|
} else {
|
||||||
Log.i("[Chat Message] Opening file: $path")
|
Log.i("[Chat Message] Opening file: $path")
|
||||||
sharedViewModel.contentToOpen.value = content
|
sharedViewModel.contentToOpen.value = content
|
||||||
|
|
||||||
if (corePreferences.useInAppFileViewerForNonEncryptedFiles || content.isFileEncrypted) {
|
if (corePreferences.useInAppFileViewerForNonEncryptedFiles || content.isFileEncrypted) {
|
||||||
val preventScreenshots =
|
val preventScreenshots =
|
||||||
viewModel.chatRoom.currentParams.isEncryptionEnabled
|
viewModel.chatRoom.currentParams.isEncryptionEnabled
|
||||||
when {
|
when {
|
||||||
FileUtils.isExtensionImage(path) -> navigateToImageFileViewer(
|
FileUtils.isExtensionImage(path) -> navigateToImageFileViewer(
|
||||||
preventScreenshots
|
preventScreenshots
|
||||||
)
|
)
|
||||||
FileUtils.isExtensionVideo(path) -> navigateToVideoFileViewer(
|
FileUtils.isExtensionVideo(path) -> navigateToVideoFileViewer(
|
||||||
preventScreenshots
|
preventScreenshots
|
||||||
)
|
)
|
||||||
FileUtils.isExtensionAudio(path) -> navigateToAudioFileViewer(
|
FileUtils.isExtensionAudio(path) -> navigateToAudioFileViewer(
|
||||||
preventScreenshots
|
preventScreenshots
|
||||||
)
|
)
|
||||||
FileUtils.isExtensionPdf(path) -> navigateToPdfFileViewer(
|
FileUtils.isExtensionPdf(path) -> navigateToPdfFileViewer(
|
||||||
preventScreenshots
|
preventScreenshots
|
||||||
)
|
)
|
||||||
FileUtils.isPlainTextFile(path) -> navigateToTextFileViewer(
|
FileUtils.isPlainTextFile(path) -> navigateToTextFileViewer(
|
||||||
preventScreenshots
|
preventScreenshots
|
||||||
)
|
)
|
||||||
else -> {
|
else -> {
|
||||||
if (content.isFileEncrypted) {
|
if (content.isFileEncrypted) {
|
||||||
Log.w("[Chat Message] File is encrypted and can't be opened in one of our viewers...")
|
Log.w("[Chat Message] File is encrypted and can't be opened in one of our viewers...")
|
||||||
showDialogForUserConsentBeforeExportingFileInThirdPartyApp(content)
|
showDialogForUserConsentBeforeExportingFileInThirdPartyApp(
|
||||||
} else if (!FileUtils.openFileInThirdPartyApp(requireActivity(), path)) {
|
content
|
||||||
showDialogToSuggestOpeningFileAsText()
|
)
|
||||||
}
|
} else if (!FileUtils.openFileInThirdPartyApp(
|
||||||
|
requireActivity(),
|
||||||
|
path
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
showDialogToSuggestOpeningFileAsText()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if (!FileUtils.openFileInThirdPartyApp(requireActivity(), path)) {
|
} else {
|
||||||
showDialogToSuggestOpeningFileAsText()
|
if (!FileUtils.openFileInThirdPartyApp(requireActivity(), path)) {
|
||||||
}
|
showDialogToSuggestOpeningFileAsText()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
adapter.scrollToChatMessageEvent.observe(
|
adapter.scrollToChatMessageEvent.observe(
|
||||||
viewLifecycleOwner,
|
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 ->
|
||||||
if (eventLog.eventLog.type == EventLog.Type.ConferenceChatMessage) {
|
if (eventLog.eventLog.type == EventLog.Type.ConferenceChatMessage) {
|
||||||
(eventLog.data as ChatMessageData).chatMessage.messageId == chatMessage.messageId
|
(eventLog.data as ChatMessageData).chatMessage.messageId == chatMessage.messageId
|
||||||
} else false
|
} else false
|
||||||
}
|
}
|
||||||
val index = events.indexOf(eventLog)
|
val index = events.indexOf(eventLog)
|
||||||
try {
|
try {
|
||||||
if (corePreferences.enableAnimations) {
|
if (corePreferences.enableAnimations) {
|
||||||
binding.chatMessagesList.smoothScrollToPosition(index)
|
binding.chatMessagesList.smoothScrollToPosition(index)
|
||||||
} else {
|
} else {
|
||||||
binding.chatMessagesList.scrollToPosition(index)
|
binding.chatMessagesList.scrollToPosition(index)
|
||||||
}
|
|
||||||
} catch (iae: IllegalArgumentException) {
|
|
||||||
Log.e("[Chat Room] Can't scroll to position $index")
|
|
||||||
}
|
}
|
||||||
|
} catch (iae: IllegalArgumentException) {
|
||||||
|
Log.e("[Chat Room] Can't scroll to position $index")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
binding.setBackClickListener {
|
binding.setBackClickListener {
|
||||||
goBack()
|
goBack()
|
||||||
|
@ -571,33 +569,31 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
||||||
}
|
}
|
||||||
|
|
||||||
sharedViewModel.richContentUri.observe(
|
sharedViewModel.richContentUri.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { uri ->
|
it.consume { uri ->
|
||||||
Log.i("[Chat] Found rich content URI: $uri")
|
Log.i("[Chat] Found rich content URI: $uri")
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
val path = FileUtils.getFilePath(requireContext(), uri)
|
val path = FileUtils.getFilePath(requireContext(), uri)
|
||||||
Log.i("[Chat] Rich content URI: $uri matching path is: $path")
|
Log.i("[Chat] Rich content URI: $uri matching path is: $path")
|
||||||
if (path != null) {
|
if (path != null) {
|
||||||
chatSendingViewModel.addAttachment(path)
|
chatSendingViewModel.addAttachment(path)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
sharedViewModel.messageToForwardEvent.observe(
|
sharedViewModel.messageToForwardEvent.observe(
|
||||||
viewLifecycleOwner,
|
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
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
binding.stubbedMessageToReplyTo.setOnInflateListener { _, inflated ->
|
binding.stubbedMessageToReplyTo.setOnInflateListener { _, inflated ->
|
||||||
Log.i("[Chat Room] Replying to message layout inflated")
|
Log.i("[Chat Room] Replying to message layout inflated")
|
||||||
|
|
|
@ -84,36 +84,32 @@ class GroupInfoFragment : SecureFragment<ChatRoomGroupInfoFragmentBinding>() {
|
||||||
binding.participants.addItemDecoration(AppUtils.getDividerDecoration(requireContext(), layoutManager))
|
binding.participants.addItemDecoration(AppUtils.getDividerDecoration(requireContext(), layoutManager))
|
||||||
|
|
||||||
viewModel.participants.observe(
|
viewModel.participants.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
adapter.submitList(it)
|
adapter.submitList(it)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
viewModel.isMeAdmin.observe(
|
viewModel.isMeAdmin.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{ isMeAdmin ->
|
) { isMeAdmin ->
|
||||||
adapter.showAdminControls(isMeAdmin && chatRoom != null)
|
adapter.showAdminControls(isMeAdmin && chatRoom != null)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
viewModel.meAdminChangedEvent.observe(
|
viewModel.meAdminChangedEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { isMeAdmin ->
|
it.consume { isMeAdmin ->
|
||||||
showMeAdminStateChanged(isMeAdmin)
|
showMeAdminStateChanged(isMeAdmin)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
adapter.participantRemovedEvent.observe(
|
adapter.participantRemovedEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { participant ->
|
it.consume { participant ->
|
||||||
viewModel.removeParticipant(participant)
|
viewModel.removeParticipant(participant)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
addParticipantsFromSharedViewModel()
|
addParticipantsFromSharedViewModel()
|
||||||
|
|
||||||
|
@ -122,22 +118,20 @@ class GroupInfoFragment : SecureFragment<ChatRoomGroupInfoFragmentBinding>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.createdChatRoomEvent.observe(
|
viewModel.createdChatRoomEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { chatRoom ->
|
it.consume { chatRoom ->
|
||||||
goToChatRoom(chatRoom, true)
|
goToChatRoom(chatRoom, true)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.updatedChatRoomEvent.observe(
|
viewModel.updatedChatRoomEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { chatRoom ->
|
it.consume { chatRoom ->
|
||||||
goToChatRoom(chatRoom, false)
|
goToChatRoom(chatRoom, false)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
binding.setNextClickListener {
|
binding.setNextClickListener {
|
||||||
if (viewModel.chatRoom != null) {
|
if (viewModel.chatRoom != null) {
|
||||||
|
@ -182,13 +176,12 @@ class GroupInfoFragment : SecureFragment<ChatRoomGroupInfoFragmentBinding>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(
|
viewModel.onErrorEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { messageResourceId ->
|
it.consume { messageResourceId ->
|
||||||
(activity as MainActivity).showSnackBar(messageResourceId)
|
(activity as MainActivity).showSnackBar(messageResourceId)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addParticipantsFromSharedViewModel() {
|
private fun addParticipantsFromSharedViewModel() {
|
||||||
|
|
|
@ -98,11 +98,10 @@ class ImdnFragment : SecureFragment<ChatRoomImdnFragmentBinding>() {
|
||||||
binding.participantsList.addItemDecoration(headerItemDecoration)
|
binding.participantsList.addItemDecoration(headerItemDecoration)
|
||||||
|
|
||||||
viewModel.participants.observe(
|
viewModel.participants.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
adapter.submitList(it)
|
adapter.submitList(it)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
binding.setBackClickListener {
|
binding.setBackClickListener {
|
||||||
goBack()
|
goBack()
|
||||||
|
|
|
@ -113,40 +113,38 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
|
||||||
|
|
||||||
// Chat room loading can take some time, so wait until it is ready before opening the pane
|
// Chat room loading can take some time, so wait until it is ready before opening the pane
|
||||||
sharedViewModel.chatRoomFragmentOpenedEvent.observe(
|
sharedViewModel.chatRoomFragmentOpenedEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
binding.slidingPane.openPane()
|
binding.slidingPane.openPane()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
sharedViewModel.closeSlidingPaneEvent.observe(
|
sharedViewModel.closeSlidingPaneEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
(requireActivity() as MainActivity).hideKeyboard()
|
(requireActivity() as MainActivity).hideKeyboard()
|
||||||
if (!binding.slidingPane.closePane()) {
|
if (!binding.slidingPane.closePane()) {
|
||||||
goBack()
|
goBack()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
sharedViewModel.layoutChangedEvent.observe(
|
sharedViewModel.layoutChangedEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
sharedViewModel.isSlidingPaneSlideable.value = binding.slidingPane.isSlideable
|
sharedViewModel.isSlidingPaneSlideable.value = binding.slidingPane.isSlideable
|
||||||
if (binding.slidingPane.isSlideable) {
|
if (binding.slidingPane.isSlideable) {
|
||||||
val navHostFragment = childFragmentManager.findFragmentById(R.id.chat_nav_container) as NavHostFragment
|
val navHostFragment =
|
||||||
if (navHostFragment.navController.currentDestination?.id == R.id.emptyChatFragment) {
|
childFragmentManager.findFragmentById(R.id.chat_nav_container) as NavHostFragment
|
||||||
Log.i("[Chat] Foldable device has been folded, closing side pane with empty fragment")
|
if (navHostFragment.navController.currentDestination?.id == R.id.emptyChatFragment) {
|
||||||
binding.slidingPane.closePane()
|
Log.i("[Chat] Foldable device has been folded, closing side pane with empty fragment")
|
||||||
}
|
binding.slidingPane.closePane()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
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 */
|
||||||
|
@ -216,50 +214,47 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
|
||||||
binding.chatList.addItemDecoration(AppUtils.getDividerDecoration(requireContext(), layoutManager))
|
binding.chatList.addItemDecoration(AppUtils.getDividerDecoration(requireContext(), layoutManager))
|
||||||
|
|
||||||
listViewModel.chatRooms.observe(
|
listViewModel.chatRooms.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{ chatRooms ->
|
) { chatRooms ->
|
||||||
adapter.submitList(chatRooms)
|
adapter.submitList(chatRooms)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
listViewModel.contactsUpdatedEvent.observe(
|
listViewModel.contactsUpdatedEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
adapter.notifyDataSetChanged()
|
adapter.notifyDataSetChanged()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
adapter.selectedChatRoomEvent.observe(
|
adapter.selectedChatRoomEvent.observe(
|
||||||
viewLifecycleOwner,
|
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!")
|
||||||
sharedViewModel.destructionPendingChatRoom = chatRoom
|
sharedViewModel.destructionPendingChatRoom = chatRoom
|
||||||
} else {
|
} else {
|
||||||
if (chatRoom.peerAddress.asStringUriOnly() == coreContext.notificationsManager.currentlyDisplayedChatRoomAddress) {
|
if (chatRoom.peerAddress.asStringUriOnly() == coreContext.notificationsManager.currentlyDisplayedChatRoomAddress) {
|
||||||
if (!binding.slidingPane.isOpen) {
|
if (!binding.slidingPane.isOpen) {
|
||||||
Log.w("[Chat] Chat room is displayed but sliding pane is closed...")
|
Log.w("[Chat] Chat room is displayed but sliding pane is closed...")
|
||||||
if (!binding.slidingPane.openPane()) {
|
if (!binding.slidingPane.openPane()) {
|
||||||
Log.e("[Chat] Tried to open pane to workaround already displayed chat room issue, failed!")
|
Log.e("[Chat] Tried to open pane to workaround already displayed chat room issue, failed!")
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w("[Chat] This chat room is already displayed!")
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sharedViewModel.selectedChatRoom.value = chatRoom
|
Log.w("[Chat] This chat room is already displayed!")
|
||||||
navigateToChatRoom(
|
|
||||||
AppUtils.createBundleWithSharedTextAndFiles(
|
|
||||||
sharedViewModel
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
sharedViewModel.selectedChatRoom.value = chatRoom
|
||||||
|
navigateToChatRoom(
|
||||||
|
AppUtils.createBundleWithSharedTextAndFiles(
|
||||||
|
sharedViewModel
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
binding.setEditClickListener {
|
binding.setEditClickListener {
|
||||||
listSelectionViewModel.isEditionEnabled.value = true
|
listSelectionViewModel.isEditionEnabled.value = true
|
||||||
|
@ -313,56 +308,52 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sharedViewModel.textToShare.observe(
|
sharedViewModel.textToShare.observe(
|
||||||
viewLifecycleOwner,
|
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
|
||||||
// activity.showSnackBar(R.string.chat_room_toast_choose_for_sharing)
|
// activity.showSnackBar(R.string.chat_room_toast_choose_for_sharing)
|
||||||
listViewModel.textSharingPending.value = true
|
listViewModel.textSharingPending.value = true
|
||||||
clearDisplayedChatRoom()
|
clearDisplayedChatRoom()
|
||||||
} else {
|
} else {
|
||||||
if (sharedViewModel.filesToShare.value.isNullOrEmpty()) {
|
if (sharedViewModel.filesToShare.value.isNullOrEmpty()) {
|
||||||
listViewModel.textSharingPending.value = false
|
listViewModel.textSharingPending.value = false
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
sharedViewModel.filesToShare.observe(
|
sharedViewModel.filesToShare.observe(
|
||||||
viewLifecycleOwner,
|
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
|
||||||
// activity.showSnackBar(R.string.chat_room_toast_choose_for_sharing)
|
// activity.showSnackBar(R.string.chat_room_toast_choose_for_sharing)
|
||||||
listViewModel.fileSharingPending.value = true
|
listViewModel.fileSharingPending.value = true
|
||||||
clearDisplayedChatRoom()
|
clearDisplayedChatRoom()
|
||||||
} else {
|
} else {
|
||||||
if (sharedViewModel.textToShare.value.isNullOrEmpty()) {
|
if (sharedViewModel.textToShare.value.isNullOrEmpty()) {
|
||||||
listViewModel.fileSharingPending.value = false
|
listViewModel.fileSharingPending.value = false
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
sharedViewModel.isPendingMessageForward.observe(
|
sharedViewModel.isPendingMessageForward.observe(
|
||||||
viewLifecycleOwner,
|
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(
|
listViewModel.onErrorEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { messageResourceId ->
|
it.consume { messageResourceId ->
|
||||||
(activity as MainActivity).showSnackBar(messageResourceId)
|
(activity as MainActivity).showSnackBar(messageResourceId)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,11 +71,10 @@ class ContactsListAdapter(
|
||||||
// This is for item selection through ListTopBarFragment
|
// This is for item selection through ListTopBarFragment
|
||||||
selectionListViewModel = selectionViewModel
|
selectionListViewModel = selectionViewModel
|
||||||
selectionViewModel.isEditionEnabled.observe(
|
selectionViewModel.isEditionEnabled.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
position = bindingAdapterPosition
|
position = bindingAdapterPosition
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
setClickListener {
|
setClickListener {
|
||||||
if (selectionViewModel.isEditionEnabled.value == true) {
|
if (selectionViewModel.isEditionEnabled.value == true) {
|
||||||
|
|
|
@ -83,47 +83,50 @@ class DetailContactFragment : GenericFragment<ContactDetailFragmentBinding>() {
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
viewModel.sendSmsToEvent.observe(
|
viewModel.sendSmsToEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { number ->
|
it.consume { number ->
|
||||||
sendSms(number)
|
sendSms(number)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.startCallToEvent.observe(
|
viewModel.startCallToEvent.observe(
|
||||||
viewLifecycleOwner,
|
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}")
|
||||||
sharedViewModel.updateContactsAnimationsBasedOnDestination.value = Event(R.id.dialerFragment)
|
sharedViewModel.updateContactsAnimationsBasedOnDestination.value =
|
||||||
sharedViewModel.updateDialerAnimationsBasedOnDestination.value = Event(R.id.masterContactsFragment)
|
Event(R.id.dialerFragment)
|
||||||
|
sharedViewModel.updateDialerAnimationsBasedOnDestination.value =
|
||||||
|
Event(R.id.masterContactsFragment)
|
||||||
|
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
args.putString("URI", address.asStringUriOnly())
|
args.putString("URI", address.asStringUriOnly())
|
||||||
args.putBoolean("Transfer", sharedViewModel.pendingCallTransfer)
|
args.putBoolean("Transfer", sharedViewModel.pendingCallTransfer)
|
||||||
args.putBoolean("SkipAutoCallStart", true) // If auto start call setting is enabled, ignore it
|
args.putBoolean(
|
||||||
navigateToDialer(args)
|
"SkipAutoCallStart",
|
||||||
} else {
|
true
|
||||||
coreContext.startCall(address)
|
) // If auto start call setting is enabled, ignore it
|
||||||
}
|
navigateToDialer(args)
|
||||||
|
} else {
|
||||||
|
coreContext.startCall(address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.chatRoomCreatedEvent.observe(
|
viewModel.chatRoomCreatedEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { chatRoom ->
|
it.consume { chatRoom ->
|
||||||
sharedViewModel.updateContactsAnimationsBasedOnDestination.value = Event(R.id.masterChatRoomsFragment)
|
sharedViewModel.updateContactsAnimationsBasedOnDestination.value =
|
||||||
val args = Bundle()
|
Event(R.id.masterChatRoomsFragment)
|
||||||
args.putString("LocalSipUri", chatRoom.localAddress.asStringUriOnly())
|
val args = Bundle()
|
||||||
args.putString("RemoteSipUri", chatRoom.peerAddress.asStringUriOnly())
|
args.putString("LocalSipUri", chatRoom.localAddress.asStringUriOnly())
|
||||||
navigateToChatRoom(args)
|
args.putString("RemoteSipUri", chatRoom.peerAddress.asStringUriOnly())
|
||||||
}
|
navigateToChatRoom(args)
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
binding.setBackClickListener {
|
binding.setBackClickListener {
|
||||||
goBack()
|
goBack()
|
||||||
|
@ -138,13 +141,12 @@ class DetailContactFragment : GenericFragment<ContactDetailFragmentBinding>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.onErrorEvent.observe(
|
viewModel.onErrorEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { messageResourceId ->
|
it.consume { messageResourceId ->
|
||||||
(activity as MainActivity).showSnackBar(messageResourceId)
|
(activity as MainActivity).showSnackBar(messageResourceId)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
view.doOnPreDraw {
|
view.doOnPreDraw {
|
||||||
// Notifies fragment is ready to be drawn
|
// Notifies fragment is ready to be drawn
|
||||||
|
|
|
@ -85,59 +85,58 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
|
||||||
|
|
||||||
useMaterialSharedAxisXForwardAnimation = false
|
useMaterialSharedAxisXForwardAnimation = false
|
||||||
sharedViewModel.updateContactsAnimationsBasedOnDestination.observe(
|
sharedViewModel.updateContactsAnimationsBasedOnDestination.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { id ->
|
it.consume { id ->
|
||||||
val forward = when (id) {
|
val forward = when (id) {
|
||||||
R.id.dialerFragment, R.id.masterChatRoomsFragment -> false
|
R.id.dialerFragment, R.id.masterChatRoomsFragment -> false
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
if (corePreferences.enableAnimations) {
|
if (corePreferences.enableAnimations) {
|
||||||
val portraitOrientation = resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE
|
val portraitOrientation =
|
||||||
val axis = if (portraitOrientation) MaterialSharedAxis.X else MaterialSharedAxis.Y
|
resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE
|
||||||
enterTransition = MaterialSharedAxis(axis, forward)
|
val axis =
|
||||||
reenterTransition = MaterialSharedAxis(axis, forward)
|
if (portraitOrientation) MaterialSharedAxis.X else MaterialSharedAxis.Y
|
||||||
returnTransition = MaterialSharedAxis(axis, !forward)
|
enterTransition = MaterialSharedAxis(axis, forward)
|
||||||
exitTransition = MaterialSharedAxis(axis, !forward)
|
reenterTransition = MaterialSharedAxis(axis, forward)
|
||||||
}
|
returnTransition = MaterialSharedAxis(axis, !forward)
|
||||||
|
exitTransition = MaterialSharedAxis(axis, !forward)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
sharedViewModel.contactFragmentOpenedEvent.observe(
|
sharedViewModel.contactFragmentOpenedEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
binding.slidingPane.openPane()
|
binding.slidingPane.openPane()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
sharedViewModel.closeSlidingPaneEvent.observe(
|
sharedViewModel.closeSlidingPaneEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
if (!binding.slidingPane.closePane()) {
|
if (!binding.slidingPane.closePane()) {
|
||||||
goBack()
|
goBack()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
sharedViewModel.layoutChangedEvent.observe(
|
sharedViewModel.layoutChangedEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
sharedViewModel.isSlidingPaneSlideable.value = binding.slidingPane.isSlideable
|
sharedViewModel.isSlidingPaneSlideable.value = binding.slidingPane.isSlideable
|
||||||
if (binding.slidingPane.isSlideable) {
|
if (binding.slidingPane.isSlideable) {
|
||||||
val navHostFragment = childFragmentManager.findFragmentById(R.id.contacts_nav_container) as NavHostFragment
|
val navHostFragment =
|
||||||
if (navHostFragment.navController.currentDestination?.id == R.id.emptyContactFragment) {
|
childFragmentManager.findFragmentById(R.id.contacts_nav_container) as NavHostFragment
|
||||||
Log.i("[Contacts] Foldable device has been folded, closing side pane with empty fragment")
|
if (navHostFragment.navController.currentDestination?.id == R.id.emptyContactFragment) {
|
||||||
binding.slidingPane.closePane()
|
Log.i("[Contacts] Foldable device has been folded, closing side pane with empty fragment")
|
||||||
}
|
binding.slidingPane.closePane()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
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 */
|
||||||
|
@ -208,38 +207,36 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
|
||||||
binding.contactsList.addItemDecoration(headerItemDecoration)
|
binding.contactsList.addItemDecoration(headerItemDecoration)
|
||||||
|
|
||||||
adapter.selectedContactEvent.observe(
|
adapter.selectedContactEvent.observe(
|
||||||
viewLifecycleOwner,
|
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
|
||||||
|
|
||||||
if (editOnClick) {
|
if (editOnClick) {
|
||||||
navigateToContactEditor(sipUriToAdd, binding.slidingPane)
|
navigateToContactEditor(sipUriToAdd, binding.slidingPane)
|
||||||
editOnClick = false
|
editOnClick = false
|
||||||
sipUriToAdd = null
|
sipUriToAdd = null
|
||||||
} else {
|
} else {
|
||||||
navigateToContact()
|
navigateToContact()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
listViewModel.contactsList.observe(
|
listViewModel.contactsList.observe(
|
||||||
viewLifecycleOwner,
|
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)
|
||||||
if (contact != null) {
|
if (contact != null) {
|
||||||
contactIdToDisplay = null
|
contactIdToDisplay = null
|
||||||
Log.i("[Contacts] Found matching contact $contact after callback")
|
Log.i("[Contacts] Found matching contact $contact after callback")
|
||||||
adapter.selectedContactEvent.value = Event(contact)
|
adapter.selectedContactEvent.value = Event(contact)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
adapter.submitList(it)
|
|
||||||
}
|
}
|
||||||
)
|
adapter.submitList(it)
|
||||||
|
}
|
||||||
|
|
||||||
binding.setAllContactsToggleClickListener {
|
binding.setAllContactsToggleClickListener {
|
||||||
listViewModel.sipContactsSelected.value = false
|
listViewModel.sipContactsSelected.value = false
|
||||||
|
@ -249,18 +246,16 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
|
||||||
}
|
}
|
||||||
|
|
||||||
listViewModel.sipContactsSelected.observe(
|
listViewModel.sipContactsSelected.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
listViewModel.updateContactsList()
|
listViewModel.updateContactsList()
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
listViewModel.filter.observe(
|
listViewModel.filter.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
listViewModel.updateContactsList()
|
listViewModel.updateContactsList()
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
binding.setNewContactClickListener {
|
binding.setNewContactClickListener {
|
||||||
// Remove any previously selected contact
|
// Remove any previously selected contact
|
||||||
|
|
|
@ -77,24 +77,25 @@ class DialerFragment : SecureFragment<DialerFragmentBinding>() {
|
||||||
|
|
||||||
useMaterialSharedAxisXForwardAnimation = false
|
useMaterialSharedAxisXForwardAnimation = false
|
||||||
sharedViewModel.updateDialerAnimationsBasedOnDestination.observe(
|
sharedViewModel.updateDialerAnimationsBasedOnDestination.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { id ->
|
it.consume { id ->
|
||||||
val forward = when (id) {
|
val forward = when (id) {
|
||||||
R.id.masterChatRoomsFragment -> false
|
R.id.masterChatRoomsFragment -> false
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
if (corePreferences.enableAnimations) {
|
if (corePreferences.enableAnimations) {
|
||||||
val portraitOrientation = resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE
|
val portraitOrientation =
|
||||||
val axis = if (portraitOrientation) MaterialSharedAxis.X else MaterialSharedAxis.Y
|
resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE
|
||||||
enterTransition = MaterialSharedAxis(axis, forward)
|
val axis =
|
||||||
reenterTransition = MaterialSharedAxis(axis, forward)
|
if (portraitOrientation) MaterialSharedAxis.X else MaterialSharedAxis.Y
|
||||||
returnTransition = MaterialSharedAxis(axis, !forward)
|
enterTransition = MaterialSharedAxis(axis, forward)
|
||||||
exitTransition = MaterialSharedAxis(axis, !forward)
|
reenterTransition = MaterialSharedAxis(axis, forward)
|
||||||
}
|
returnTransition = MaterialSharedAxis(axis, !forward)
|
||||||
|
exitTransition = MaterialSharedAxis(axis, !forward)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
binding.setNewContactClickListener {
|
binding.setNewContactClickListener {
|
||||||
sharedViewModel.updateDialerAnimationsBasedOnDestination.value = Event(R.id.masterContactsFragment)
|
sharedViewModel.updateDialerAnimationsBasedOnDestination.value = Event(R.id.masterContactsFragment)
|
||||||
|
@ -111,43 +112,40 @@ class DialerFragment : SecureFragment<DialerFragmentBinding>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.enteredUri.observe(
|
viewModel.enteredUri.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
if (it == corePreferences.debugPopupCode) {
|
if (it == corePreferences.debugPopupCode) {
|
||||||
displayDebugPopup()
|
displayDebugPopup()
|
||||||
viewModel.enteredUri.value = ""
|
viewModel.enteredUri.value = ""
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.uploadFinishedEvent.observe(
|
viewModel.uploadFinishedEvent.observe(
|
||||||
viewLifecycleOwner,
|
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) {
|
||||||
val clipboard =
|
val clipboard =
|
||||||
requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
val clip = ClipData.newPlainText("Logs url", url)
|
val clip = ClipData.newPlainText("Logs url", url)
|
||||||
clipboard.setPrimaryClip(clip)
|
clipboard.setPrimaryClip(clip)
|
||||||
|
|
||||||
val activity = requireActivity() as MainActivity
|
val activity = requireActivity() as MainActivity
|
||||||
activity.showSnackBar(R.string.logs_url_copied_to_clipboard)
|
activity.showSnackBar(R.string.logs_url_copied_to_clipboard)
|
||||||
|
|
||||||
AppUtils.shareUploadedLogsUrl(activity, url)
|
AppUtils.shareUploadedLogsUrl(activity, url)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.updateAvailableEvent.observe(
|
viewModel.updateAvailableEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { url ->
|
it.consume { url ->
|
||||||
displayNewVersionAvailableDialog(url)
|
displayNewVersionAvailableDialog(url)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
if (corePreferences.firstStart) {
|
if (corePreferences.firstStart) {
|
||||||
Log.w("[Dialer] First start detected, wait for assistant to be finished to check for update & request permissions")
|
Log.w("[Dialer] First start detected, wait for assistant to be finished to check for update & request permissions")
|
||||||
|
|
|
@ -139,7 +139,7 @@ class TopBarFragment : GenericFragment<FileViewerTopBarFragmentBinding>() {
|
||||||
Log.w("[File Viewer] Media store file path is empty, media store export failed?")
|
Log.w("[File Viewer] Media store file path is empty, media store export failed?")
|
||||||
|
|
||||||
val filePath = content.plainFilePath.orEmpty()
|
val filePath = content.plainFilePath.orEmpty()
|
||||||
plainFilePath = if (filePath.isEmpty()) content.filePath.orEmpty() else filePath
|
plainFilePath = filePath.ifEmpty { content.filePath.orEmpty() }
|
||||||
Log.i("[File Viewer] Plain file path is: $plainFilePath")
|
Log.i("[File Viewer] Plain file path is: $plainFilePath")
|
||||||
if (plainFilePath.isNotEmpty()) {
|
if (plainFilePath.isNotEmpty()) {
|
||||||
if (!FileUtils.openFileInThirdPartyApp(requireActivity(), plainFilePath)) {
|
if (!FileUtils.openFileInThirdPartyApp(requireActivity(), plainFilePath)) {
|
||||||
|
|
|
@ -56,56 +56,55 @@ abstract class MasterFragment<T : ViewDataBinding, U : SelectionListAdapter<*, *
|
||||||
listSelectionViewModel = ViewModelProvider(this)[ListTopBarViewModel::class.java]
|
listSelectionViewModel = ViewModelProvider(this)[ListTopBarViewModel::class.java]
|
||||||
|
|
||||||
listSelectionViewModel.isEditionEnabled.observe(
|
listSelectionViewModel.isEditionEnabled.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
if (!it) listSelectionViewModel.onUnSelectAll()
|
if (!it) listSelectionViewModel.onUnSelectAll()
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
listSelectionViewModel.selectAllEvent.observe(
|
listSelectionViewModel.selectAllEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
listSelectionViewModel.onSelectAll(getItemCount() - 1)
|
listSelectionViewModel.onSelectAll(getItemCount() - 1)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
listSelectionViewModel.unSelectAllEvent.observe(
|
listSelectionViewModel.unSelectAllEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
listSelectionViewModel.onUnSelectAll()
|
listSelectionViewModel.onUnSelectAll()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
listSelectionViewModel.deleteSelectionEvent.observe(
|
listSelectionViewModel.deleteSelectionEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
val confirmationDialog = AppUtils.getStringWithPlural(dialogConfirmationMessageBeforeRemoval, listSelectionViewModel.selectedItems.value.orEmpty().size)
|
val confirmationDialog = AppUtils.getStringWithPlural(
|
||||||
val viewModel = DialogViewModel(confirmationDialog)
|
dialogConfirmationMessageBeforeRemoval,
|
||||||
val dialog: Dialog = DialogUtils.getDialog(requireContext(), viewModel)
|
listSelectionViewModel.selectedItems.value.orEmpty().size
|
||||||
|
)
|
||||||
|
val viewModel = DialogViewModel(confirmationDialog)
|
||||||
|
val dialog: Dialog = DialogUtils.getDialog(requireContext(), viewModel)
|
||||||
|
|
||||||
viewModel.showCancelButton {
|
viewModel.showCancelButton {
|
||||||
|
dialog.dismiss()
|
||||||
|
listSelectionViewModel.isEditionEnabled.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.showDeleteButton(
|
||||||
|
{
|
||||||
|
delete()
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
listSelectionViewModel.isEditionEnabled.value = false
|
listSelectionViewModel.isEditionEnabled.value = false
|
||||||
}
|
},
|
||||||
|
getString(R.string.dialog_delete)
|
||||||
|
)
|
||||||
|
|
||||||
viewModel.showDeleteButton(
|
dialog.show()
|
||||||
{
|
|
||||||
delete()
|
|
||||||
dialog.dismiss()
|
|
||||||
listSelectionViewModel.isEditionEnabled.value = false
|
|
||||||
},
|
|
||||||
getString(R.string.dialog_delete)
|
|
||||||
)
|
|
||||||
|
|
||||||
dialog.show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun delete() {
|
private fun delete() {
|
||||||
|
|
|
@ -51,15 +51,14 @@ class StatusFragment : GenericFragment<StatusFragmentBinding>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
sharedViewModel.accountRemoved.observe(
|
sharedViewModel.accountRemoved.observe(
|
||||||
viewLifecycleOwner,
|
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)
|
||||||
|
|
|
@ -73,11 +73,10 @@ class CallLogsListAdapter(
|
||||||
// This is for item selection through ListTopBarFragment
|
// This is for item selection through ListTopBarFragment
|
||||||
selectionListViewModel = selectionViewModel
|
selectionListViewModel = selectionViewModel
|
||||||
selectionViewModel.isEditionEnabled.observe(
|
selectionViewModel.isEditionEnabled.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
position = bindingAdapterPosition
|
position = bindingAdapterPosition
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
setClickListener {
|
setClickListener {
|
||||||
if (selectionViewModel.isEditionEnabled.value == true) {
|
if (selectionViewModel.isEditionEnabled.value == true) {
|
||||||
|
|
|
@ -99,50 +99,48 @@ class DetailCallLogFragment : GenericFragment<HistoryDetailFragmentBinding>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.startCallEvent.observe(
|
viewModel.startCallEvent.observe(
|
||||||
viewLifecycleOwner,
|
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) {
|
||||||
Log.i("[History] Starting dialer with pre-filled URI ${address.asStringUriOnly()}, is transfer? ${sharedViewModel.pendingCallTransfer}")
|
Log.i("[History] Starting dialer with pre-filled URI ${address.asStringUriOnly()}, is transfer? ${sharedViewModel.pendingCallTransfer}")
|
||||||
sharedViewModel.updateDialerAnimationsBasedOnDestination.value = Event(R.id.masterCallLogsFragment)
|
sharedViewModel.updateDialerAnimationsBasedOnDestination.value =
|
||||||
|
Event(R.id.masterCallLogsFragment)
|
||||||
|
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
args.putString("URI", address.asStringUriOnly())
|
args.putString("URI", address.asStringUriOnly())
|
||||||
args.putBoolean("Transfer", sharedViewModel.pendingCallTransfer)
|
args.putBoolean("Transfer", sharedViewModel.pendingCallTransfer)
|
||||||
args.putBoolean(
|
args.putBoolean(
|
||||||
"SkipAutoCallStart",
|
"SkipAutoCallStart",
|
||||||
true
|
true
|
||||||
) // If auto start call setting is enabled, ignore it
|
) // If auto start call setting is enabled, ignore it
|
||||||
navigateToDialer(args)
|
navigateToDialer(args)
|
||||||
} else {
|
} else {
|
||||||
val localAddress = callLog.localAddress
|
val localAddress = callLog.localAddress
|
||||||
coreContext.startCall(address, localAddress = localAddress)
|
coreContext.startCall(address, localAddress = localAddress)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.chatRoomCreatedEvent.observe(
|
viewModel.chatRoomCreatedEvent.observe(
|
||||||
viewLifecycleOwner,
|
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(
|
viewModel.onErrorEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { messageResourceId ->
|
it.consume { messageResourceId ->
|
||||||
(activity as MainActivity).showSnackBar(messageResourceId)
|
(activity as MainActivity).showSnackBar(messageResourceId)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun goBack() {
|
override fun goBack() {
|
||||||
|
|
|
@ -101,30 +101,29 @@ class MasterCallLogsFragment : MasterFragment<HistoryMasterFragmentBinding, Call
|
||||||
view.doOnPreDraw { sharedViewModel.isSlidingPaneSlideable.value = binding.slidingPane.isSlideable }
|
view.doOnPreDraw { sharedViewModel.isSlidingPaneSlideable.value = binding.slidingPane.isSlideable }
|
||||||
|
|
||||||
sharedViewModel.closeSlidingPaneEvent.observe(
|
sharedViewModel.closeSlidingPaneEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
if (!binding.slidingPane.closePane()) {
|
if (!binding.slidingPane.closePane()) {
|
||||||
goBack()
|
goBack()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
sharedViewModel.layoutChangedEvent.observe(
|
sharedViewModel.layoutChangedEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
sharedViewModel.isSlidingPaneSlideable.value = binding.slidingPane.isSlideable
|
sharedViewModel.isSlidingPaneSlideable.value = binding.slidingPane.isSlideable
|
||||||
if (binding.slidingPane.isSlideable) {
|
if (binding.slidingPane.isSlideable) {
|
||||||
val navHostFragment = childFragmentManager.findFragmentById(R.id.history_nav_container) as NavHostFragment
|
val navHostFragment =
|
||||||
if (navHostFragment.navController.currentDestination?.id == R.id.emptyCallHistoryFragment) {
|
childFragmentManager.findFragmentById(R.id.history_nav_container) as NavHostFragment
|
||||||
Log.i("[History] Foldable device has been folded, closing side pane with empty fragment")
|
if (navHostFragment.navController.currentDestination?.id == R.id.emptyCallHistoryFragment) {
|
||||||
binding.slidingPane.closePane()
|
Log.i("[History] Foldable device has been folded, closing side pane with empty fragment")
|
||||||
}
|
binding.slidingPane.closePane()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
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 */
|
||||||
|
@ -193,73 +192,71 @@ class MasterCallLogsFragment : MasterFragment<HistoryMasterFragmentBinding, Call
|
||||||
binding.callLogsList.addItemDecoration(headerItemDecoration)
|
binding.callLogsList.addItemDecoration(headerItemDecoration)
|
||||||
|
|
||||||
listViewModel.callLogs.observe(
|
listViewModel.callLogs.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{ callLogs ->
|
) { callLogs ->
|
||||||
if (listViewModel.missedCallLogsSelected.value == false) {
|
if (listViewModel.missedCallLogsSelected.value == false) {
|
||||||
adapter.submitList(callLogs)
|
adapter.submitList(callLogs)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
listViewModel.missedCallLogs.observe(
|
listViewModel.missedCallLogs.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{ callLogs ->
|
) { callLogs ->
|
||||||
if (listViewModel.missedCallLogsSelected.value == true) {
|
if (listViewModel.missedCallLogsSelected.value == true) {
|
||||||
adapter.submitList(callLogs)
|
adapter.submitList(callLogs)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
listViewModel.missedCallLogsSelected.observe(
|
listViewModel.missedCallLogsSelected.observe(
|
||||||
viewLifecycleOwner,
|
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(
|
listViewModel.contactsUpdatedEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
adapter.notifyDataSetChanged()
|
adapter.notifyDataSetChanged()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
adapter.selectedCallLogEvent.observe(
|
adapter.selectedCallLogEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { callLog ->
|
it.consume { callLog ->
|
||||||
sharedViewModel.selectedCallLogGroup.value = callLog
|
sharedViewModel.selectedCallLogGroup.value = callLog
|
||||||
navigateToCallHistory(binding.slidingPane)
|
navigateToCallHistory(binding.slidingPane)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
adapter.startCallToEvent.observe(
|
adapter.startCallToEvent.observe(
|
||||||
viewLifecycleOwner,
|
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) {
|
||||||
Log.i("[History] Starting dialer with pre-filled URI ${remoteAddress.asStringUriOnly()}, is transfer? ${sharedViewModel.pendingCallTransfer}")
|
Log.i("[History] Starting dialer with pre-filled URI ${remoteAddress.asStringUriOnly()}, is transfer? ${sharedViewModel.pendingCallTransfer}")
|
||||||
sharedViewModel.updateDialerAnimationsBasedOnDestination.value = Event(R.id.masterCallLogsFragment)
|
sharedViewModel.updateDialerAnimationsBasedOnDestination.value =
|
||||||
val args = Bundle()
|
Event(R.id.masterCallLogsFragment)
|
||||||
args.putString("URI", remoteAddress.asStringUriOnly())
|
val args = Bundle()
|
||||||
args.putBoolean("Transfer", sharedViewModel.pendingCallTransfer)
|
args.putString("URI", remoteAddress.asStringUriOnly())
|
||||||
args.putBoolean("SkipAutoCallStart", true) // If auto start call setting is enabled, ignore it
|
args.putBoolean("Transfer", sharedViewModel.pendingCallTransfer)
|
||||||
navigateToDialer(args)
|
args.putBoolean(
|
||||||
} else {
|
"SkipAutoCallStart",
|
||||||
val localAddress = callLogGroup.lastCallLog.localAddress
|
true
|
||||||
coreContext.startCall(remoteAddress, localAddress = localAddress)
|
) // If auto start call setting is enabled, ignore it
|
||||||
}
|
navigateToDialer(args)
|
||||||
|
} else {
|
||||||
|
val localAddress = callLogGroup.lastCallLog.localAddress
|
||||||
|
coreContext.startCall(remoteAddress, localAddress = localAddress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
binding.setAllCallLogsToggleClickListener {
|
binding.setAllCallLogsToggleClickListener {
|
||||||
listViewModel.missedCallLogsSelected.value = false
|
listViewModel.missedCallLogsSelected.value = false
|
||||||
|
|
|
@ -22,7 +22,6 @@ package org.linphone.activities.main.history.viewmodels
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import java.util.*
|
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||||
import org.linphone.LinphoneApplication.Companion.corePreferences
|
import org.linphone.LinphoneApplication.Companion.corePreferences
|
||||||
|
|
|
@ -69,11 +69,10 @@ class RecordingsFragment : MasterFragment<RecordingsFragmentBinding, RecordingsL
|
||||||
binding.recordingsList.addItemDecoration(headerItemDecoration)
|
binding.recordingsList.addItemDecoration(headerItemDecoration)
|
||||||
|
|
||||||
viewModel.recordingsList.observe(
|
viewModel.recordingsList.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{ recordings ->
|
) { recordings ->
|
||||||
adapter.submitList(recordings)
|
adapter.submitList(recordings)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
binding.setBackClickListener { goBack() }
|
binding.setBackClickListener { goBack() }
|
||||||
|
|
||||||
|
|
|
@ -63,32 +63,30 @@ class AccountSettingsFragment : GenericSettingFragment<SettingsAccountFragmentBi
|
||||||
binding.setBackClickListener { goBack() }
|
binding.setBackClickListener { goBack() }
|
||||||
|
|
||||||
viewModel.linkPhoneNumberEvent.observe(
|
viewModel.linkPhoneNumberEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
val authInfo = viewModel.account.findAuthInfo()
|
val authInfo = viewModel.account.findAuthInfo()
|
||||||
if (authInfo == null) {
|
if (authInfo == null) {
|
||||||
Log.e("[Account Settings] Failed to find auth info for account ${viewModel.account}")
|
Log.e("[Account Settings] Failed to find auth info for account ${viewModel.account}")
|
||||||
} else {
|
} else {
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
args.putString("Username", authInfo.username)
|
args.putString("Username", authInfo.username)
|
||||||
args.putString("Password", authInfo.password)
|
args.putString("Password", authInfo.password)
|
||||||
args.putString("HA1", authInfo.ha1)
|
args.putString("HA1", authInfo.ha1)
|
||||||
navigateToPhoneLinking(args)
|
navigateToPhoneLinking(args)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.accountRemovedEvent.observe(
|
viewModel.accountRemovedEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
sharedViewModel.accountRemoved.value = true
|
sharedViewModel.accountRemoved.value = true
|
||||||
goBack()
|
goBack()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
view.doOnPreDraw {
|
view.doOnPreDraw {
|
||||||
// Notifies fragment is ready to be drawn
|
// Notifies fragment is ready to be drawn
|
||||||
|
|
|
@ -55,103 +55,96 @@ class AdvancedSettingsFragment : GenericSettingFragment<SettingsAdvancedFragment
|
||||||
binding.setBackClickListener { goBack() }
|
binding.setBackClickListener { goBack() }
|
||||||
|
|
||||||
viewModel.uploadFinishedEvent.observe(
|
viewModel.uploadFinishedEvent.observe(
|
||||||
viewLifecycleOwner,
|
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
|
||||||
val clip = ClipData.newPlainText("Logs url", url)
|
val clip = ClipData.newPlainText("Logs url", url)
|
||||||
clipboard.setPrimaryClip(clip)
|
clipboard.setPrimaryClip(clip)
|
||||||
|
|
||||||
val activity = requireActivity() as MainActivity
|
val activity = requireActivity() as MainActivity
|
||||||
activity.showSnackBar(R.string.logs_url_copied_to_clipboard)
|
activity.showSnackBar(R.string.logs_url_copied_to_clipboard)
|
||||||
|
|
||||||
AppUtils.shareUploadedLogsUrl(activity, url)
|
AppUtils.shareUploadedLogsUrl(activity, url)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.uploadErrorEvent.observe(
|
viewModel.uploadErrorEvent.observe(
|
||||||
viewLifecycleOwner,
|
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(
|
viewModel.resetCompleteEvent.observe(
|
||||||
viewLifecycleOwner,
|
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(
|
viewModel.setNightModeEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { value ->
|
it.consume { value ->
|
||||||
AppCompatDelegate.setDefaultNightMode(
|
AppCompatDelegate.setDefaultNightMode(
|
||||||
when (value) {
|
when (value) {
|
||||||
0 -> AppCompatDelegate.MODE_NIGHT_NO
|
0 -> AppCompatDelegate.MODE_NIGHT_NO
|
||||||
1 -> AppCompatDelegate.MODE_NIGHT_YES
|
1 -> AppCompatDelegate.MODE_NIGHT_YES
|
||||||
else -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
else -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.backgroundModeEnabled.value = !DeviceUtils.isAppUserRestricted(requireContext())
|
viewModel.backgroundModeEnabled.value = !DeviceUtils.isAppUserRestricted(requireContext())
|
||||||
|
|
||||||
viewModel.goToBatterySettingsEvent.observe(
|
viewModel.goToBatterySettingsEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
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(
|
viewModel.goToPowerManagerSettingsEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
val intent = PowerManagerUtils.getDevicePowerManagerIntent(requireActivity())
|
val intent = PowerManagerUtils.getDevicePowerManagerIntent(requireActivity())
|
||||||
if (intent != null) {
|
if (intent != null) {
|
||||||
try {
|
try {
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
} catch (se: SecurityException) {
|
} catch (se: SecurityException) {
|
||||||
Log.e("[Advanced Settings] Security exception: ", se)
|
Log.e("[Advanced Settings] Security exception: ", se)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.goToAndroidSettingsEvent.observe(
|
viewModel.goToAndroidSettingsEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
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() {
|
||||||
|
|
|
@ -54,24 +54,22 @@ class AudioSettingsFragment : GenericSettingFragment<SettingsAudioFragmentBindin
|
||||||
binding.setBackClickListener { goBack() }
|
binding.setBackClickListener { goBack() }
|
||||||
|
|
||||||
viewModel.askAudioRecordPermissionForEchoCancellerCalibrationEvent.observe(
|
viewModel.askAudioRecordPermissionForEchoCancellerCalibrationEvent.observe(
|
||||||
viewLifecycleOwner,
|
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(
|
viewModel.askAudioRecordPermissionForEchoTesterEvent.observe(
|
||||||
viewLifecycleOwner,
|
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()
|
||||||
|
|
||||||
|
|
|
@ -55,76 +55,75 @@ class CallSettingsFragment : GenericSettingFragment<SettingsCallFragmentBinding>
|
||||||
binding.setBackClickListener { goBack() }
|
binding.setBackClickListener { goBack() }
|
||||||
|
|
||||||
viewModel.systemWideOverlayEnabledEvent.observe(
|
viewModel.systemWideOverlayEnabledEvent.observe(
|
||||||
viewLifecycleOwner,
|
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(
|
||||||
startActivityForResult(intent, 0)
|
"android.settings.action.MANAGE_OVERLAY_PERMISSION",
|
||||||
}
|
Uri.parse("package:${requireContext().packageName}")
|
||||||
|
)
|
||||||
|
startActivityForResult(intent, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.goToAndroidNotificationSettingsEvent.observe(
|
viewModel.goToAndroidNotificationSettingsEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
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
|
||||||
i.putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName)
|
i.putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName)
|
||||||
i.putExtra(
|
i.putExtra(
|
||||||
Settings.EXTRA_CHANNEL_ID,
|
Settings.EXTRA_CHANNEL_ID,
|
||||||
getString(R.string.notification_channel_service_id)
|
getString(R.string.notification_channel_service_id)
|
||||||
)
|
)
|
||||||
i.addCategory(Intent.CATEGORY_DEFAULT)
|
i.addCategory(Intent.CATEGORY_DEFAULT)
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
|
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
|
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
|
||||||
startActivity(i)
|
startActivity(i)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.enableTelecomManagerEvent.observe(
|
viewModel.enableTelecomManagerEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
if (!Compatibility.hasTelecomManagerPermissions(requireContext())) {
|
if (!Compatibility.hasTelecomManagerPermissions(requireContext())) {
|
||||||
Compatibility.requestTelecomManagerPermissions(requireActivity(), 1)
|
Compatibility.requestTelecomManagerPermissions(requireActivity(), 1)
|
||||||
} else if (!TelecomHelper.exists()) {
|
} else if (!TelecomHelper.exists()) {
|
||||||
corePreferences.useTelecomManager = true
|
corePreferences.useTelecomManager = true
|
||||||
Log.w("[Telecom Helper] Doesn't exists yet, creating it")
|
Log.w("[Telecom Helper] Doesn't exists yet, creating it")
|
||||||
TelecomHelper.create(requireContext())
|
TelecomHelper.create(requireContext())
|
||||||
updateTelecomManagerAccount()
|
updateTelecomManagerAccount()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.goToAndroidNotificationSettingsEvent.observe(
|
viewModel.goToAndroidNotificationSettingsEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
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
|
||||||
i.putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName)
|
i.putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName)
|
||||||
i.putExtra(
|
i.putExtra(
|
||||||
Settings.EXTRA_CHANNEL_ID,
|
Settings.EXTRA_CHANNEL_ID,
|
||||||
getString(R.string.notification_channel_service_id)
|
getString(R.string.notification_channel_service_id)
|
||||||
)
|
)
|
||||||
i.addCategory(Intent.CATEGORY_DEFAULT)
|
i.addCategory(Intent.CATEGORY_DEFAULT)
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
|
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
|
||||||
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?) {
|
||||||
|
|
|
@ -50,39 +50,37 @@ class ChatSettingsFragment : GenericSettingFragment<SettingsChatFragmentBinding>
|
||||||
binding.setBackClickListener { goBack() }
|
binding.setBackClickListener { goBack() }
|
||||||
|
|
||||||
viewModel.launcherShortcutsEvent.observe(
|
viewModel.launcherShortcutsEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { newValue ->
|
it.consume { newValue ->
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
Compatibility.createShortcutsToChatRooms(requireContext())
|
Compatibility.createShortcutsToChatRooms(requireContext())
|
||||||
} else {
|
} else {
|
||||||
Compatibility.removeShortcuts(requireContext())
|
Compatibility.removeShortcuts(requireContext())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.goToAndroidNotificationSettingsEvent.observe(
|
viewModel.goToAndroidNotificationSettingsEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
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
|
||||||
i.putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName)
|
i.putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName)
|
||||||
i.putExtra(
|
i.putExtra(
|
||||||
Settings.EXTRA_CHANNEL_ID,
|
Settings.EXTRA_CHANNEL_ID,
|
||||||
getString(R.string.notification_channel_chat_id)
|
getString(R.string.notification_channel_chat_id)
|
||||||
)
|
)
|
||||||
i.addCategory(Intent.CATEGORY_DEFAULT)
|
i.addCategory(Intent.CATEGORY_DEFAULT)
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
|
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
|
||||||
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() {
|
||||||
|
|
|
@ -51,30 +51,28 @@ class ContactsSettingsFragment : GenericSettingFragment<SettingsContactsFragment
|
||||||
binding.setBackClickListener { goBack() }
|
binding.setBackClickListener { goBack() }
|
||||||
|
|
||||||
viewModel.launcherShortcutsEvent.observe(
|
viewModel.launcherShortcutsEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume { newValue ->
|
it.consume { newValue ->
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
Compatibility.createShortcutsToContacts(requireContext())
|
Compatibility.createShortcutsToContacts(requireContext())
|
||||||
} else {
|
} else {
|
||||||
Compatibility.removeShortcuts(requireContext())
|
Compatibility.removeShortcuts(requireContext())
|
||||||
if (corePreferences.chatRoomShortcuts) {
|
if (corePreferences.chatRoomShortcuts) {
|
||||||
Compatibility.createShortcutsToChatRooms(requireContext())
|
Compatibility.createShortcutsToChatRooms(requireContext())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.askWriteContactsPermissionForPresenceStorageEvent.observe(
|
viewModel.askWriteContactsPermissionForPresenceStorageEvent.observe(
|
||||||
viewLifecycleOwner,
|
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")
|
||||||
|
|
|
@ -69,39 +69,37 @@ class SettingsFragment : SecureFragment<SettingsFragmentBinding>() {
|
||||||
|
|
||||||
// Account settings loading can take some time, so wait until it is ready before opening the pane
|
// Account settings loading can take some time, so wait until it is ready before opening the pane
|
||||||
sharedViewModel.accountSettingsFragmentOpenedEvent.observe(
|
sharedViewModel.accountSettingsFragmentOpenedEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
binding.slidingPane.openPane()
|
binding.slidingPane.openPane()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
sharedViewModel.closeSlidingPaneEvent.observe(
|
sharedViewModel.closeSlidingPaneEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
if (!binding.slidingPane.closePane()) {
|
if (!binding.slidingPane.closePane()) {
|
||||||
goBack()
|
goBack()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
sharedViewModel.layoutChangedEvent.observe(
|
sharedViewModel.layoutChangedEvent.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
it.consume {
|
it.consume {
|
||||||
sharedViewModel.isSlidingPaneSlideable.value = binding.slidingPane.isSlideable
|
sharedViewModel.isSlidingPaneSlideable.value = binding.slidingPane.isSlideable
|
||||||
if (binding.slidingPane.isSlideable) {
|
if (binding.slidingPane.isSlideable) {
|
||||||
val navHostFragment = childFragmentManager.findFragmentById(R.id.settings_nav_container) as NavHostFragment
|
val navHostFragment =
|
||||||
if (navHostFragment.navController.currentDestination?.id == R.id.emptySettingsFragment) {
|
childFragmentManager.findFragmentById(R.id.settings_nav_container) as NavHostFragment
|
||||||
Log.i("[Settings] Foldable device has been folded, closing side pane with empty fragment")
|
if (navHostFragment.navController.currentDestination?.id == R.id.emptySettingsFragment) {
|
||||||
binding.slidingPane.closePane()
|
Log.i("[Settings] Foldable device has been folded, closing side pane with empty fragment")
|
||||||
}
|
binding.slidingPane.closePane()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
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 */
|
||||||
|
@ -112,12 +110,11 @@ class SettingsFragment : SecureFragment<SettingsFragmentBinding>() {
|
||||||
binding.setBackClickListener { goBack() }
|
binding.setBackClickListener { goBack() }
|
||||||
|
|
||||||
sharedViewModel.accountRemoved.observe(
|
sharedViewModel.accountRemoved.observe(
|
||||||
viewLifecycleOwner,
|
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) {
|
||||||
|
|
|
@ -33,7 +33,7 @@ class TelephonyListener(private val telephonyManager: TelephonyManager) : PhoneS
|
||||||
|
|
||||||
private fun runOnUiThreadExecutor(): Executor {
|
private fun runOnUiThreadExecutor(): Executor {
|
||||||
val handler = Handler(Looper.getMainLooper())
|
val handler = Handler(Looper.getMainLooper())
|
||||||
return Executor() {
|
return Executor {
|
||||||
handler.post(it)
|
handler.post(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
xmlns:bind="http://schemas.android.com/tools">
|
|
||||||
|
|
||||||
<data>
|
<data>
|
||||||
<import type="android.view.View"/>
|
<import type="android.view.View"/>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
xmlns:bind="http://schemas.android.com/tools">
|
|
||||||
|
|
||||||
<data>
|
<data>
|
||||||
<import type="android.view.View"/>
|
<import type="android.view.View"/>
|
||||||
|
|
Loading…
Reference in a new issue