Moved lambdas arguments out of parenthesis

This commit is contained in:
Sylvain Berfini 2022-01-28 16:49:00 +01:00
parent 81884dd218
commit a0ebeb1fea
47 changed files with 1238 additions and 1350 deletions

View file

@ -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()

View file

@ -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")

View file

@ -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)
}
} }
) }
} }
} }

View file

@ -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)
}
} }
) }
} }
} }

View file

@ -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)
}
} }
) }
} }
} }

View file

@ -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()

View file

@ -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()

View file

@ -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 {

View file

@ -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()) {

View file

@ -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
} }

View file

@ -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()
} }

View file

@ -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?) {

View file

@ -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

View file

@ -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()

View file

@ -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()

View file

@ -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?) {

View file

@ -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

View file

@ -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)
} }

View file

@ -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) {

View file

@ -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

View file

@ -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")

View file

@ -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")

View file

@ -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() {

View file

@ -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()

View file

@ -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)
}
} }
) }
} }
} }

View file

@ -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) {

View file

@ -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

View file

@ -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

View file

@ -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")

View file

@ -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)) {

View file

@ -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() {

View file

@ -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)

View file

@ -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) {

View file

@ -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() {

View file

@ -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

View file

@ -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

View file

@ -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() }

View file

@ -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

View file

@ -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() {

View file

@ -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()

View file

@ -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?) {

View file

@ -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() {

View file

@ -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")

View file

@ -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) {

View file

@ -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)
} }
} }

View file

@ -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"/>

View file

@ -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"/>