diff --git a/app/src/main/java/org/thoughtcrime/securesms/avatar/picker/AvatarPickerFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/avatar/picker/AvatarPickerFragment.kt index 316046fa4..7e0851790 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/avatar/picker/AvatarPickerFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/avatar/picker/AvatarPickerFragment.kt @@ -30,6 +30,7 @@ import org.thoughtcrime.securesms.mediasend.Media import org.thoughtcrime.securesms.permissions.Permissions import org.thoughtcrime.securesms.util.MappingAdapter import org.thoughtcrime.securesms.util.ViewUtil +import org.thoughtcrime.securesms.util.navigation.safeNavigate import org.thoughtcrime.securesms.util.visible /** @@ -198,18 +199,18 @@ class AvatarPickerFragment : Fragment(R.layout.avatar_picker_fragment) { private fun openPhotoEditor(photo: Avatar.Photo) { Navigation.findNavController(requireView()) - .navigate(AvatarPickerFragmentDirections.actionAvatarPickerFragmentToAvatarPhotoEditorFragment(AvatarBundler.bundlePhoto(photo))) + .safeNavigate(AvatarPickerFragmentDirections.actionAvatarPickerFragmentToAvatarPhotoEditorFragment(AvatarBundler.bundlePhoto(photo))) } private fun openVectorEditor(vector: Avatar.Vector) { Navigation.findNavController(requireView()) - .navigate(AvatarPickerFragmentDirections.actionAvatarPickerFragmentToVectorAvatarCreationFragment(AvatarBundler.bundleVector(vector))) + .safeNavigate(AvatarPickerFragmentDirections.actionAvatarPickerFragmentToVectorAvatarCreationFragment(AvatarBundler.bundleVector(vector))) } private fun openTextEditor(text: Avatar.Text?) { val bundle = if (text != null) AvatarBundler.bundleText(text) else null Navigation.findNavController(requireView()) - .navigate(AvatarPickerFragmentDirections.actionAvatarPickerFragmentToTextAvatarCreationFragment(bundle)) + .safeNavigate(AvatarPickerFragmentDirections.actionAvatarPickerFragmentToTextAvatarCreationFragment(bundle)) } @Suppress("DEPRECATION") diff --git a/app/src/main/java/org/thoughtcrime/securesms/badges/self/overview/BadgesOverviewFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/badges/self/overview/BadgesOverviewFragment.kt index a26ddbc61..13f436616 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/badges/self/overview/BadgesOverviewFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/badges/self/overview/BadgesOverviewFragment.kt @@ -18,6 +18,7 @@ import org.thoughtcrime.securesms.components.settings.configure import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.util.LifecycleDisposable +import org.thoughtcrime.securesms.util.navigation.safeNavigate /** * Fragment to allow user to manage options related to the badges they've unlocked. @@ -37,7 +38,7 @@ class BadgesOverviewFragment : DSLSettingsFragment( override fun bindAdapter(adapter: DSLSettingsAdapter) { Badge.register(adapter) { badge, _, isFaded -> if (badge.isExpired() || isFaded) { - findNavController().navigate(BadgesOverviewFragmentDirections.actionBadgeManageFragmentToExpiredBadgeDialog(badge)) + findNavController().safeNavigate(BadgesOverviewFragmentDirections.actionBadgeManageFragmentToExpiredBadgeDialog(badge)) } else { ViewBadgeBottomSheetDialogFragment.show(parentFragmentManager, Recipient.self().id, badge) } @@ -83,7 +84,7 @@ class BadgesOverviewFragment : DSLSettingsFragment( summary = state.featuredBadge?.name?.let { DSLSettingsText.from(it) }, isEnabled = state.stage == BadgesOverviewState.Stage.READY && state.hasUnexpiredBadges && state.hasInternet, onClick = { - findNavController().navigate(BadgesOverviewFragmentDirections.actionBadgeManageFragmentToFeaturedBadgeFragment()) + findNavController().safeNavigate(BadgesOverviewFragmentDirections.actionBadgeManageFragmentToFeaturedBadgeFragment()) } ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsActivity.kt index ba355879d..81d8da17f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsActivity.kt @@ -18,6 +18,7 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.service.KeyCachingService import org.thoughtcrime.securesms.util.CachedInflater import org.thoughtcrime.securesms.util.DynamicTheme +import org.thoughtcrime.securesms.util.navigation.safeNavigate private const val START_LOCATION = "app.settings.start.location" private const val START_ARGUMENTS = "app.settings.start.arguments" @@ -65,7 +66,7 @@ class AppSettingsActivity : DSLSettingsActivity(), DonationPaymentComponent { } startingAction?.let { - navController.navigate(it) + navController.safeNavigate(it) } SignalStore.settings().onConfigurationSettingChanged.observe(this) { key -> diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsFragment.kt index 80b65f743..bc2cdd51b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsFragment.kt @@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.components.settings.app import android.view.View import android.widget.TextView import androidx.fragment.app.viewModels -import androidx.navigation.Navigation import androidx.navigation.fragment.findNavController import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.badges.BadgeImageView @@ -25,6 +24,7 @@ import org.thoughtcrime.securesms.util.FeatureFlags import org.thoughtcrime.securesms.util.MappingAdapter import org.thoughtcrime.securesms.util.MappingViewHolder import org.thoughtcrime.securesms.util.PlayServicesUtil +import org.thoughtcrime.securesms.util.navigation.safeNavigate class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__menu_settings) { @@ -54,7 +54,7 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men customPref( BioPreference(state.self) { - Navigation.findNavController(requireView()).navigate(R.id.action_appSettingsFragment_to_manageProfileActivity) + findNavController().safeNavigate(R.id.action_appSettingsFragment_to_manageProfileActivity) } ) @@ -62,7 +62,7 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men title = DSLSettingsText.from(R.string.AccountSettingsFragment__account), icon = DSLSettingsIcon.from(R.drawable.ic_profile_circle_24), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_appSettingsFragment_to_accountSettingsFragment) + findNavController().safeNavigate(R.id.action_appSettingsFragment_to_accountSettingsFragment) } ) @@ -70,7 +70,7 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men title = DSLSettingsText.from(R.string.preferences__linked_devices), icon = DSLSettingsIcon.from(R.drawable.ic_linked_devices_24), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_appSettingsFragment_to_deviceActivity) + findNavController().safeNavigate(R.id.action_appSettingsFragment_to_deviceActivity) } ) @@ -79,7 +79,7 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men PaymentsPreference( unreadCount = state.unreadPaymentsCount ) { - Navigation.findNavController(requireView()).navigate(R.id.action_appSettingsFragment_to_paymentsActivity) + findNavController().safeNavigate(R.id.action_appSettingsFragment_to_paymentsActivity) } ) } @@ -90,7 +90,7 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men title = DSLSettingsText.from(R.string.preferences__appearance), icon = DSLSettingsIcon.from(R.drawable.ic_appearance_24), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_appSettingsFragment_to_appearanceSettingsFragment) + findNavController().safeNavigate(R.id.action_appSettingsFragment_to_appearanceSettingsFragment) } ) @@ -98,7 +98,7 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men title = DSLSettingsText.from(R.string.preferences_chats__chats), icon = DSLSettingsIcon.from(R.drawable.ic_message_tinted_bitmap_24), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_appSettingsFragment_to_chatsSettingsFragment) + findNavController().safeNavigate(R.id.action_appSettingsFragment_to_chatsSettingsFragment) } ) @@ -106,7 +106,7 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men title = DSLSettingsText.from(R.string.preferences__notifications), icon = DSLSettingsIcon.from(R.drawable.ic_bell_24), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_appSettingsFragment_to_notificationsSettingsFragment) + findNavController().safeNavigate(R.id.action_appSettingsFragment_to_notificationsSettingsFragment) } ) @@ -114,7 +114,7 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men title = DSLSettingsText.from(R.string.preferences__privacy), icon = DSLSettingsIcon.from(R.drawable.ic_lock_24), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_appSettingsFragment_to_privacySettingsFragment) + findNavController().safeNavigate(R.id.action_appSettingsFragment_to_privacySettingsFragment) } ) @@ -122,7 +122,7 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men title = DSLSettingsText.from(R.string.preferences__data_and_storage), icon = DSLSettingsIcon.from(R.drawable.ic_archive_24dp), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_appSettingsFragment_to_dataAndStorageSettingsFragment) + findNavController().safeNavigate(R.id.action_appSettingsFragment_to_dataAndStorageSettingsFragment) } ) @@ -132,7 +132,7 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men title = DSLSettingsText.from(R.string.preferences__help), icon = DSLSettingsIcon.from(R.drawable.ic_help_24), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_appSettingsFragment_to_helpSettingsFragment) + findNavController().safeNavigate(R.id.action_appSettingsFragment_to_helpSettingsFragment) } ) @@ -140,7 +140,7 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men title = DSLSettingsText.from(R.string.AppSettingsFragment__invite_your_friends), icon = DSLSettingsIcon.from(R.drawable.ic_invite_24), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_appSettingsFragment_to_inviteActivity) + findNavController().safeNavigate(R.id.action_appSettingsFragment_to_inviteActivity) } ) @@ -158,9 +158,9 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men isActive = state.hasActiveSubscription, onClick = { isActive -> if (isActive) { - findNavController().navigate(AppSettingsFragmentDirections.actionAppSettingsFragmentToManageDonationsFragment()) + findNavController().safeNavigate(AppSettingsFragmentDirections.actionAppSettingsFragmentToManageDonationsFragment()) } else { - findNavController().navigate(AppSettingsFragmentDirections.actionAppSettingsFragmentToSubscribeFragment()) + findNavController().safeNavigate(AppSettingsFragmentDirections.actionAppSettingsFragmentToSubscribeFragment()) } } ) @@ -169,7 +169,7 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men title = DSLSettingsText.from(R.string.preferences__signal_boost), icon = DSLSettingsIcon.from(R.drawable.ic_boost_24), onClick = { - findNavController().navigate(AppSettingsFragmentDirections.actionAppSettingsFragmentToBoostsFragment()) + findNavController().safeNavigate(AppSettingsFragmentDirections.actionAppSettingsFragmentToBoostsFragment()) } ) } else { @@ -186,7 +186,7 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men clickPref( title = DSLSettingsText.from(R.string.preferences__internal_preferences), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_appSettingsFragment_to_internalSettingsFragment) + findNavController().safeNavigate(R.id.action_appSettingsFragment_to_internalSettingsFragment) } ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsFragment.kt index bb280cd37..8be7bdb2b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsFragment.kt @@ -34,6 +34,7 @@ import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.util.FeatureFlags import org.thoughtcrime.securesms.util.ServiceUtil import org.thoughtcrime.securesms.util.ThemeUtil +import org.thoughtcrime.securesms.util.navigation.safeNavigate class AccountSettingsFragment : DSLSettingsFragment(R.string.AccountSettingsFragment__account) { @@ -98,7 +99,7 @@ class AccountSettingsFragment : DSLSettingsFragment(R.string.AccountSettingsFrag clickPref( title = DSLSettingsText.from(R.string.preferences__advanced_pin_settings), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_accountSettingsFragment_to_advancedPinSettingsActivity) + Navigation.findNavController(requireView()).safeNavigate(R.id.action_accountSettingsFragment_to_advancedPinSettingsActivity) } ) @@ -110,7 +111,7 @@ class AccountSettingsFragment : DSLSettingsFragment(R.string.AccountSettingsFrag clickPref( title = DSLSettingsText.from(R.string.AccountSettingsFragment__change_phone_number), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_accountSettingsFragment_to_changePhoneNumberFragment) + Navigation.findNavController(requireView()).safeNavigate(R.id.action_accountSettingsFragment_to_changePhoneNumberFragment) } ) } @@ -119,14 +120,14 @@ class AccountSettingsFragment : DSLSettingsFragment(R.string.AccountSettingsFrag title = DSLSettingsText.from(R.string.preferences_chats__transfer_account), summary = DSLSettingsText.from(R.string.preferences_chats__transfer_account_to_a_new_android_device), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_accountSettingsFragment_to_oldDeviceTransferActivity) + Navigation.findNavController(requireView()).safeNavigate(R.id.action_accountSettingsFragment_to_oldDeviceTransferActivity) } ) clickPref( title = DSLSettingsText.from(R.string.preferences__delete_account, ContextCompat.getColor(requireContext(), R.color.signal_alert_primary)), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_accountSettingsFragment_to_deleteAccountFragment) + Navigation.findNavController(requireView()).safeNavigate(R.id.action_accountSettingsFragment_to_deleteAccountFragment) } ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/appearance/AppearanceSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/appearance/AppearanceSettingsFragment.kt index addbb3121..06a21ec3f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/appearance/AppearanceSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/appearance/AppearanceSettingsFragment.kt @@ -8,6 +8,7 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsAdapter import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment import org.thoughtcrime.securesms.components.settings.DSLSettingsText import org.thoughtcrime.securesms.components.settings.configure +import org.thoughtcrime.securesms.util.navigation.safeNavigate class AppearanceSettingsFragment : DSLSettingsFragment(R.string.preferences__appearance) { @@ -44,7 +45,7 @@ class AppearanceSettingsFragment : DSLSettingsFragment(R.string.preferences__app clickPref( title = DSLSettingsText.from(R.string.preferences__chat_color_and_wallpaper), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_appearanceSettings_to_wallpaperActivity) + Navigation.findNavController(requireView()).safeNavigate(R.id.action_appearanceSettings_to_wallpaperActivity) } ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberConfirmFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberConfirmFragment.kt index 3b5fb79d2..563e25937 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberConfirmFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberConfirmFragment.kt @@ -7,6 +7,7 @@ import androidx.appcompat.widget.Toolbar import androidx.navigation.fragment.findNavController import org.thoughtcrime.securesms.LoggingFragment import org.thoughtcrime.securesms.R +import org.thoughtcrime.securesms.util.navigation.safeNavigate class ChangeNumberConfirmFragment : LoggingFragment(R.layout.fragment_change_number_confirm) { private lateinit var viewModel: ChangeNumberViewModel @@ -28,6 +29,6 @@ class ChangeNumberConfirmFragment : LoggingFragment(R.layout.fragment_change_num editNumber.setOnClickListener { findNavController().navigateUp() } val changeNumber: View = view.findViewById(R.id.change_number_confirm_change_number) - changeNumber.setOnClickListener { findNavController().navigate(R.id.action_changePhoneNumberConfirmFragment_to_changePhoneNumberVerifyFragment) } + changeNumber.setOnClickListener { findNavController().safeNavigate(R.id.action_changePhoneNumberConfirmFragment_to_changePhoneNumberVerifyFragment) } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberEnterPhoneNumberFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberEnterPhoneNumberFragment.kt index 239abdd99..1c644412a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberEnterPhoneNumberFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberEnterPhoneNumberFragment.kt @@ -18,6 +18,7 @@ import org.thoughtcrime.securesms.registration.fragments.CountryPickerFragment import org.thoughtcrime.securesms.registration.fragments.CountryPickerFragmentArgs import org.thoughtcrime.securesms.registration.util.RegistrationNumberInputController import org.thoughtcrime.securesms.util.Dialogs +import org.thoughtcrime.securesms.util.navigation.safeNavigate private const val OLD_NUMBER_COUNTRY_SELECT = "old_number_country" private const val NEW_NUMBER_COUNTRY_SELECT = "new_number_country" @@ -73,7 +74,7 @@ class ChangeNumberEnterPhoneNumberFragment : LoggingFragment(R.layout.fragment_c override fun onPickCountry(view: View) { val arguments: CountryPickerFragmentArgs = CountryPickerFragmentArgs.Builder().setResultKey(OLD_NUMBER_COUNTRY_SELECT).build() - findNavController().navigate(R.id.action_enterPhoneNumberChangeFragment_to_countryPickerFragment, arguments.toBundle()) + findNavController().safeNavigate(R.id.action_enterPhoneNumberChangeFragment_to_countryPickerFragment, arguments.toBundle()) } override fun setNationalNumber(number: String) { @@ -110,7 +111,7 @@ class ChangeNumberEnterPhoneNumberFragment : LoggingFragment(R.layout.fragment_c override fun onPickCountry(view: View) { val arguments: CountryPickerFragmentArgs = CountryPickerFragmentArgs.Builder().setResultKey(NEW_NUMBER_COUNTRY_SELECT).build() - findNavController().navigate(R.id.action_enterPhoneNumberChangeFragment_to_countryPickerFragment, arguments.toBundle()) + findNavController().safeNavigate(R.id.action_enterPhoneNumberChangeFragment_to_countryPickerFragment, arguments.toBundle()) } override fun setNationalNumber(number: String) { @@ -157,7 +158,7 @@ class ChangeNumberEnterPhoneNumberFragment : LoggingFragment(R.layout.fragment_c } when (viewModel.canContinue()) { - ContinueStatus.CAN_CONTINUE -> findNavController().navigate(R.id.action_enterPhoneNumberChangeFragment_to_changePhoneNumberConfirmFragment) + ContinueStatus.CAN_CONTINUE -> findNavController().safeNavigate(R.id.action_enterPhoneNumberChangeFragment_to_changePhoneNumberConfirmFragment) ContinueStatus.INVALID_NUMBER -> { Dialogs.showAlertDialog( context, getString(R.string.RegistrationActivity_invalid_number), String.format(getString(R.string.RegistrationActivity_the_number_you_specified_s_is_invalid), viewModel.number.e164Number) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberEnterSmsCodeFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberEnterSmsCodeFragment.kt index bd2bcccc7..621cf9622 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberEnterSmsCodeFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberEnterSmsCodeFragment.kt @@ -11,6 +11,7 @@ import org.thoughtcrime.securesms.components.settings.app.changenumber.ChangeNum import org.thoughtcrime.securesms.components.settings.app.changenumber.ChangeNumberUtil.getViewModel import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.registration.fragments.BaseEnterSmsCodeFragment +import org.thoughtcrime.securesms.util.navigation.safeNavigate class ChangeNumberEnterSmsCodeFragment : BaseEnterSmsCodeFragment(R.layout.fragment_change_number_enter_code) { @@ -50,14 +51,14 @@ class ChangeNumberEnterSmsCodeFragment : BaseEnterSmsCodeFragment(R.id.change_phone_number_continue).setOnClickListener { - findNavController().navigate(R.id.action_changePhoneNumberFragment_to_enterPhoneNumberChangeFragment) + findNavController().safeNavigate(R.id.action_changePhoneNumberFragment_to_enterPhoneNumberChangeFragment) } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRegistrationLockFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRegistrationLockFragment.kt index a98e90226..c47de765c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRegistrationLockFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRegistrationLockFragment.kt @@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.registration.viewmodel.BaseRegistrationViewMod import org.thoughtcrime.securesms.util.CircularProgressButtonUtil.cancelSpinning import org.thoughtcrime.securesms.util.CommunicationActions import org.thoughtcrime.securesms.util.SupportEmailUtil +import org.thoughtcrime.securesms.util.navigation.safeNavigate class ChangeNumberRegistrationLockFragment : BaseRegistrationLockFragment(R.layout.fragment_change_number_registration_lock) { @@ -38,7 +39,7 @@ class ChangeNumberRegistrationLockFragment : BaseRegistrationLockFragment(R.layo } override fun navigateToAccountLocked() { - findNavController().navigate(ChangeNumberRegistrationLockFragmentDirections.actionChangeNumberRegistrationLockToChangeNumberAccountLocked()) + findNavController().safeNavigate(ChangeNumberRegistrationLockFragmentDirections.actionChangeNumberRegistrationLockToChangeNumberAccountLocked()) } override fun handleSuccessfulPinEntry(pin: String) { @@ -47,7 +48,7 @@ class ChangeNumberRegistrationLockFragment : BaseRegistrationLockFragment(R.layo cancelSpinning(pinButton) if (pinsDiffer) { - findNavController().navigate(ChangeNumberRegistrationLockFragmentDirections.actionChangeNumberRegistrationLockToChangeNumberPinDiffers()) + findNavController().safeNavigate(ChangeNumberRegistrationLockFragmentDirections.actionChangeNumberRegistrationLockToChangeNumberPinDiffers()) } else { changeNumberSuccess() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberUtil.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberUtil.kt index b06a7b389..c39781df8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberUtil.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberUtil.kt @@ -9,6 +9,7 @@ import androidx.navigation.fragment.findNavController import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.registration.fragments.CaptchaFragment import org.thoughtcrime.securesms.registration.viewmodel.BaseRegistrationViewModel +import org.thoughtcrime.securesms.util.navigation.safeNavigate /** * Helpers for various aspects of the change number flow. @@ -35,7 +36,7 @@ object ChangeNumberUtil { } fun Fragment.changeNumberSuccess() { - findNavController().navigate(R.id.action_pop_app_settings_change_number) + findNavController().safeNavigate(R.id.action_pop_app_settings_change_number) Toast.makeText(requireContext(), R.string.ChangeNumber__your_phone_number_has_been_changed, Toast.LENGTH_SHORT).show() } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberVerifyFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberVerifyFragment.kt index ed22e3580..c9951f21b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberVerifyFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberVerifyFragment.kt @@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.components.settings.app.changenumber.ChangeNum import org.thoughtcrime.securesms.components.settings.app.changenumber.ChangeNumberUtil.getViewModel import org.thoughtcrime.securesms.registration.VerifyAccountRepository import org.thoughtcrime.securesms.util.LifecycleDisposable +import org.thoughtcrime.securesms.util.navigation.safeNavigate private val TAG: String = Log.tag(ChangeNumberVerifyFragment::class.java) @@ -52,13 +53,13 @@ class ChangeNumberVerifyFragment : LoggingFragment(R.layout.fragment_change_phon .observeOn(AndroidSchedulers.mainThread()) .subscribe { processor -> if (processor.hasResult()) { - findNavController().navigate(R.id.action_changePhoneNumberVerifyFragment_to_changeNumberEnterCodeFragment) + findNavController().safeNavigate(R.id.action_changePhoneNumberVerifyFragment_to_changeNumberEnterCodeFragment) } else if (processor.localRateLimit()) { Log.i(TAG, "Unable to request sms code due to local rate limit") - findNavController().navigate(R.id.action_changePhoneNumberVerifyFragment_to_changeNumberEnterCodeFragment) + findNavController().safeNavigate(R.id.action_changePhoneNumberVerifyFragment_to_changeNumberEnterCodeFragment) } else if (processor.captchaRequired()) { Log.i(TAG, "Unable to request sms code due to captcha required") - findNavController().navigate(R.id.action_changePhoneNumberVerifyFragment_to_captchaFragment, getCaptchaArguments()) + findNavController().safeNavigate(R.id.action_changePhoneNumberVerifyFragment_to_captchaFragment, getCaptchaArguments()) requestingCaptcha = true } else if (processor.rateLimit()) { Log.i(TAG, "Unable to request sms code due to rate limit") diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsFragment.kt index 75062e85c..9ba820e45 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsFragment.kt @@ -8,6 +8,7 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsAdapter import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment import org.thoughtcrime.securesms.components.settings.DSLSettingsText import org.thoughtcrime.securesms.components.settings.configure +import org.thoughtcrime.securesms.util.navigation.safeNavigate class ChatsSettingsFragment : DSLSettingsFragment(R.string.preferences_chats__chats) { @@ -29,7 +30,7 @@ class ChatsSettingsFragment : DSLSettingsFragment(R.string.preferences_chats__ch clickPref( title = DSLSettingsText.from(R.string.preferences__sms_mms), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_chatsSettingsFragment_to_smsSettingsFragment) + Navigation.findNavController(requireView()).safeNavigate(R.id.action_chatsSettingsFragment_to_smsSettingsFragment) } ) @@ -79,7 +80,7 @@ class ChatsSettingsFragment : DSLSettingsFragment(R.string.preferences_chats__ch title = DSLSettingsText.from(R.string.preferences_chats__chat_backups), summary = DSLSettingsText.from(if (state.chatBackupsEnabled) R.string.arrays__enabled else R.string.arrays__disabled), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_chatsSettingsFragment_to_backupsPreferenceFragment) + Navigation.findNavController(requireView()).safeNavigate(R.id.action_chatsSettingsFragment_to_backupsPreferenceFragment) } ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/sms/SmsSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/sms/SmsSettingsFragment.kt index 2e80caa73..c4a342756 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/sms/SmsSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/sms/SmsSettingsFragment.kt @@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.components.settings.configure import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.util.SmsUtil import org.thoughtcrime.securesms.util.Util +import org.thoughtcrime.securesms.util.navigation.safeNavigate private const val SMS_REQUEST_CODE: Short = 1234 @@ -76,7 +77,7 @@ class SmsSettingsFragment : DSLSettingsFragment(R.string.preferences__sms_mms) { clickPref( title = DSLSettingsText.from(R.string.preferences__advanced_mms_access_point_names), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_smsSettingsFragment_to_mmsPreferencesFragment) + Navigation.findNavController(requireView()).safeNavigate(R.id.action_smsSettingsFragment_to_mmsPreferencesFragment) } ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/data/DataAndStorageSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/data/DataAndStorageSettingsFragment.kt index 041ec7c78..961c7e121 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/data/DataAndStorageSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/data/DataAndStorageSettingsFragment.kt @@ -11,6 +11,7 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsText import org.thoughtcrime.securesms.components.settings.configure import org.thoughtcrime.securesms.mms.SentMediaQuality import org.thoughtcrime.securesms.util.Util +import org.thoughtcrime.securesms.util.navigation.safeNavigate import org.thoughtcrime.securesms.webrtc.CallBandwidthMode import kotlin.math.abs @@ -47,7 +48,7 @@ class DataAndStorageSettingsFragment : DSLSettingsFragment(R.string.preferences_ title = DSLSettingsText.from(R.string.preferences_data_and_storage__manage_storage), summary = DSLSettingsText.from(Util.getPrettyFileSize(state.totalStorageUse)), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_dataAndStorageSettingsFragment_to_storagePreferenceFragment) + Navigation.findNavController(requireView()).safeNavigate(R.id.action_dataAndStorageSettingsFragment_to_storagePreferenceFragment) } ) @@ -125,7 +126,7 @@ class DataAndStorageSettingsFragment : DSLSettingsFragment(R.string.preferences_ title = DSLSettingsText.from(R.string.preferences_use_proxy), summary = DSLSettingsText.from(if (state.isProxyEnabled) R.string.preferences_on else R.string.preferences_off), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_dataAndStorageSettingsFragment_to_editProxyFragment) + Navigation.findNavController(requireView()).safeNavigate(R.id.action_dataAndStorageSettingsFragment_to_editProxyFragment) } ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/help/HelpSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/help/HelpSettingsFragment.kt index 4df197aa9..54f0b4837 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/help/HelpSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/help/HelpSettingsFragment.kt @@ -8,6 +8,7 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsAdapter import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment import org.thoughtcrime.securesms.components.settings.DSLSettingsText import org.thoughtcrime.securesms.components.settings.configure +import org.thoughtcrime.securesms.util.navigation.safeNavigate class HelpSettingsFragment : DSLSettingsFragment(R.string.preferences__help) { @@ -25,7 +26,7 @@ class HelpSettingsFragment : DSLSettingsFragment(R.string.preferences__help) { clickPref( title = DSLSettingsText.from(R.string.HelpSettingsFragment__contact_us), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_helpSettingsFragment_to_helpFragment) + Navigation.findNavController(requireView()).safeNavigate(R.id.action_helpSettingsFragment_to_helpFragment) } ) @@ -39,7 +40,7 @@ class HelpSettingsFragment : DSLSettingsFragment(R.string.preferences__help) { clickPref( title = DSLSettingsText.from(R.string.HelpSettingsFragment__debug_log), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_helpSettingsFragment_to_submitDebugLogActivity) + Navigation.findNavController(requireView()).safeNavigate(R.id.action_helpSettingsFragment_to_submitDebugLogActivity) } ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsFragment.kt index acd9315cf..67b656a0c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsFragment.kt @@ -32,6 +32,7 @@ import org.thoughtcrime.securesms.notifications.NotificationChannels import org.thoughtcrime.securesms.util.MappingAdapter import org.thoughtcrime.securesms.util.RingtoneUtil import org.thoughtcrime.securesms.util.ViewUtil +import org.thoughtcrime.securesms.util.navigation.safeNavigate private const val MESSAGE_SOUND_SELECT: Int = 1 private const val CALL_RINGTONE_SELECT: Int = 2 @@ -225,7 +226,7 @@ class NotificationsSettingsFragment : DSLSettingsFragment(R.string.preferences__ title = DSLSettingsText.from(R.string.NotificationsSettingsFragment__profiles), summary = DSLSettingsText.from(R.string.NotificationsSettingsFragment__create_a_profile_to_receive_notifications_only_from_people_and_groups_you_choose), onClick = { - findNavController().navigate(R.id.action_notificationsSettingsFragment_to_notificationProfilesFragment) + findNavController().safeNavigate(R.id.action_notificationsSettingsFragment_to_notificationProfilesFragment) } ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/AddAllowedMembersFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/AddAllowedMembersFragment.kt index 235ac4cdf..e0eeff598 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/AddAllowedMembersFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/AddAllowedMembersFragment.kt @@ -21,6 +21,7 @@ import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.util.LifecycleDisposable +import org.thoughtcrime.securesms.util.navigation.safeNavigate /** * Show and allow addition of recipients to a profile during the create flow. @@ -38,7 +39,7 @@ class AddAllowedMembersFragment : DSLSettingsFragment(layoutId = R.layout.fragme view.findViewById(R.id.add_allowed_members_profile_next).apply { setOnClickListener { - findNavController().navigate(AddAllowedMembersFragmentDirections.actionAddAllowedMembersFragmentToEditNotificationProfileScheduleFragment(profileId, true)) + findNavController().safeNavigate(AddAllowedMembersFragmentDirections.actionAddAllowedMembersFragmentToEditNotificationProfileScheduleFragment(profileId, true)) } } } @@ -62,7 +63,7 @@ class AddAllowedMembersFragment : DSLSettingsFragment(layoutId = R.layout.fragme customPref( NotificationProfileAddMembers.Model( onClick = { id, currentSelection -> - findNavController().navigate( + findNavController().safeNavigate( AddAllowedMembersFragmentDirections.actionAddAllowedMembersFragmentToSelectRecipientsFragment(id) .setCurrentSelection(currentSelection.toTypedArray()) ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/EditNotificationProfileFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/EditNotificationProfileFragment.kt index a45b5a4a7..5f1c72b3f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/EditNotificationProfileFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/EditNotificationProfileFragment.kt @@ -29,6 +29,7 @@ import org.thoughtcrime.securesms.util.BottomSheetUtil import org.thoughtcrime.securesms.util.CircularProgressButtonUtil import org.thoughtcrime.securesms.util.LifecycleDisposable import org.thoughtcrime.securesms.util.ViewUtil +import org.thoughtcrime.securesms.util.navigation.safeNavigate import org.thoughtcrime.securesms.util.text.AfterTextChanged /** @@ -104,7 +105,7 @@ class EditNotificationProfileFragment : DSLSettingsFragment(layoutId = R.layout. is SaveNotificationProfileResult.Success -> { ViewUtil.hideKeyboard(requireContext(), nameView) if (saveResult.createMode) { - findNavController().navigate(EditNotificationProfileFragmentDirections.actionEditNotificationProfileFragmentToAddAllowedMembersFragment(saveResult.profile.id)) + findNavController().safeNavigate(EditNotificationProfileFragmentDirections.actionEditNotificationProfileFragmentToAddAllowedMembersFragment(saveResult.profile.id)) } else { findNavController().navigateUp() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/EditNotificationProfileScheduleFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/EditNotificationProfileScheduleFragment.kt index 153536597..848c6a358 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/EditNotificationProfileScheduleFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/EditNotificationProfileScheduleFragment.kt @@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.components.settings.app.notifications.profiles import org.thoughtcrime.securesms.util.LifecycleDisposable import org.thoughtcrime.securesms.util.ViewUtil import org.thoughtcrime.securesms.util.formatHours +import org.thoughtcrime.securesms.util.navigation.safeNavigate import org.thoughtcrime.securesms.util.orderOfDaysInWeek import org.thoughtcrime.securesms.util.visible import java.time.DayOfWeek @@ -82,7 +83,7 @@ class EditNotificationProfileScheduleFragment : LoggingFragment(R.layout.fragmen when (result) { SaveScheduleResult.Success -> { if (createMode) { - findNavController().navigate(EditNotificationProfileScheduleFragmentDirections.actionEditNotificationProfileScheduleFragmentToNotificationProfileCreatedFragment(profileId)) + findNavController().safeNavigate(EditNotificationProfileScheduleFragmentDirections.actionEditNotificationProfileScheduleFragmentToNotificationProfileCreatedFragment(profileId)) } else { findNavController().navigateUp() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfileCreatedFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfileCreatedFragment.kt index 8c9127050..76d5299e6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfileCreatedFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfileCreatedFragment.kt @@ -10,6 +10,7 @@ import io.reactivex.rxjava3.kotlin.subscribeBy import org.thoughtcrime.securesms.LoggingFragment import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.util.LifecycleDisposable +import org.thoughtcrime.securesms.util.navigation.safeNavigate /** * Shown at the end of the profile create flow. @@ -28,7 +29,7 @@ class NotificationProfileCreatedFragment : LoggingFragment(R.layout.fragment_not val bottomText: TextView = view.findViewById(R.id.notification_profile_created_bottom_text) view.findViewById(R.id.notification_profile_created_done).setOnClickListener { - findNavController().navigate(NotificationProfileCreatedFragmentDirections.actionNotificationProfileCreatedFragmentToNotificationProfileDetailsFragment(profileId)) + findNavController().safeNavigate(NotificationProfileCreatedFragmentDirections.actionNotificationProfileCreatedFragmentToNotificationProfileDetailsFragment(profileId)) } lifecycleDisposable.bindTo(viewLifecycleOwner.lifecycle) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfileDetailsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfileDetailsFragment.kt index a46cddd4d..2118af9ad 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfileDetailsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfileDetailsFragment.kt @@ -33,6 +33,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.util.LifecycleDisposable import org.thoughtcrime.securesms.util.SpanUtil import org.thoughtcrime.securesms.util.formatHours +import org.thoughtcrime.securesms.util.navigation.safeNavigate import org.thoughtcrime.securesms.util.orderOfDaysInWeek import java.time.DayOfWeek import java.time.format.TextStyle @@ -77,7 +78,7 @@ class NotificationProfileDetailsFragment : DSLSettingsFragment() { toolbar?.title = state.profile.name toolbar?.setOnMenuItemClickListener { item -> if (item.itemId == R.id.action_edit) { - findNavController().navigate(NotificationProfileDetailsFragmentDirections.actionNotificationProfileDetailsFragmentToEditNotificationProfileFragment().setProfileId(state.profile.id)) + findNavController().safeNavigate(NotificationProfileDetailsFragmentDirections.actionNotificationProfileDetailsFragmentToEditNotificationProfileFragment().setProfileId(state.profile.id)) true } else { false @@ -117,7 +118,7 @@ class NotificationProfileDetailsFragment : DSLSettingsFragment() { customPref( NotificationProfileAddMembers.Model( onClick = { id, currentSelection -> - findNavController().navigate( + findNavController().safeNavigate( NotificationProfileDetailsFragmentDirections.actionNotificationProfileDetailsFragmentToSelectRecipientsFragment(id) .setCurrentSelection(currentSelection.toTypedArray()) ) @@ -174,7 +175,7 @@ class NotificationProfileDetailsFragment : DSLSettingsFragment() { summary = DSLSettingsText.from(if (profile.schedule.enabled) R.string.NotificationProfileDetails__on else R.string.NotificationProfileDetails__off), icon = DSLSettingsIcon.from(R.drawable.ic_recent_20, NO_TINT), onClick = { - findNavController().navigate(NotificationProfileDetailsFragmentDirections.actionNotificationProfileDetailsFragmentToEditNotificationProfileScheduleFragment(profile.id, false)) + findNavController().safeNavigate(NotificationProfileDetailsFragmentDirections.actionNotificationProfileDetailsFragmentToEditNotificationProfileScheduleFragment(profile.id, false)) } ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfilesFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfilesFragment.kt index d1e2db961..91eca4ea4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfilesFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfilesFragment.kt @@ -22,6 +22,7 @@ import org.thoughtcrime.securesms.megaphone.Megaphones import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile import org.thoughtcrime.securesms.notifications.profiles.NotificationProfiles import org.thoughtcrime.securesms.util.LifecycleDisposable +import org.thoughtcrime.securesms.util.navigation.safeNavigate /** * Primary entry point for Notification Profiles. When user has no profiles, shows empty state, otherwise shows @@ -75,7 +76,7 @@ class NotificationProfilesFragment : DSLSettingsFragment() { if (profiles.isEmpty()) { customPref( NoNotificationProfiles.Model( - onClick = { findNavController().navigate(R.id.action_notificationProfilesFragment_to_editNotificationProfileFragment) } + onClick = { findNavController().safeNavigate(R.id.action_notificationProfilesFragment_to_editNotificationProfileFragment) } ) ) } else { @@ -85,7 +86,7 @@ class NotificationProfilesFragment : DSLSettingsFragment() { LargeIconClickPreference.Model( title = DSLSettingsText.from(R.string.NotificationProfilesFragment__new_profile), icon = DSLSettingsIcon.from(R.drawable.add_to_a_group, NO_TINT), - onClick = { findNavController().navigate(R.id.action_notificationProfilesFragment_to_editNotificationProfileFragment) } + onClick = { findNavController().safeNavigate(R.id.action_notificationProfilesFragment_to_editNotificationProfileFragment) } ) ) @@ -98,7 +99,7 @@ class NotificationProfilesFragment : DSLSettingsFragment() { icon = if (profile.emoji.isNotEmpty()) EmojiUtil.convertToDrawable(requireContext(), profile.emoji)?.let { DSLSettingsIcon.from(it) } else DSLSettingsIcon.from(R.drawable.ic_moon_24, NO_TINT), color = profile.color, onClick = { - findNavController().navigate(NotificationProfilesFragmentDirections.actionNotificationProfilesFragmentToNotificationProfileDetailsFragment(profile.id)) + findNavController().safeNavigate(NotificationProfilesFragmentDirections.actionNotificationProfilesFragmentToNotificationProfileDetailsFragment(profile.id)) } ) ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsFragment.kt index 3e4a6991b..743151d6d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsFragment.kt @@ -43,6 +43,7 @@ import org.thoughtcrime.securesms.util.MappingAdapter import org.thoughtcrime.securesms.util.ServiceUtil import org.thoughtcrime.securesms.util.SpanUtil import org.thoughtcrime.securesms.util.TextSecurePreferences +import org.thoughtcrime.securesms.util.navigation.safeNavigate import java.lang.Integer.max import java.util.Locale import java.util.concurrent.TimeUnit @@ -88,7 +89,7 @@ class PrivacySettingsFragment : DSLSettingsFragment(R.string.preferences__privac summary = DSLSettingsText.from(getString(R.string.PrivacySettingsFragment__d_contacts, state.blockedCount)), onClick = { Navigation.findNavController(requireView()) - .navigate(R.id.action_privacySettingsFragment_to_blockedUsersActivity) + .safeNavigate(R.id.action_privacySettingsFragment_to_blockedUsersActivity) } ) @@ -147,7 +148,7 @@ class PrivacySettingsFragment : DSLSettingsFragment(R.string.preferences__privac title = DSLSettingsText.from(R.string.PrivacySettingsFragment__default_timer_for_new_changes), summary = DSLSettingsText.from(R.string.PrivacySettingsFragment__set_a_default_disappearing_message_timer_for_all_new_chats_started_by_you), onClick = { - NavHostFragment.findNavController(this@PrivacySettingsFragment).navigate(R.id.action_privacySettingsFragment_to_disappearingMessagesTimerSelectFragment) + NavHostFragment.findNavController(this@PrivacySettingsFragment).safeNavigate(R.id.action_privacySettingsFragment_to_disappearingMessagesTimerSelectFragment) } ) ) @@ -293,7 +294,7 @@ class PrivacySettingsFragment : DSLSettingsFragment(R.string.preferences__privac title = DSLSettingsText.from(R.string.preferences__advanced), summary = DSLSettingsText.from(R.string.PrivacySettingsFragment__signal_message_and_calls), onClick = { - Navigation.findNavController(requireView()).navigate(R.id.action_privacySettingsFragment_to_advancedPrivacySettingsFragment) + Navigation.findNavController(requireView()).safeNavigate(R.id.action_privacySettingsFragment_to_advancedPrivacySettingsFragment) } ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/expire/ExpireTimerSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/expire/ExpireTimerSettingsFragment.kt index aa4973a68..f9ae41e6b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/expire/ExpireTimerSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/expire/ExpireTimerSettingsFragment.kt @@ -21,6 +21,7 @@ import org.thoughtcrime.securesms.util.ExpirationUtil import org.thoughtcrime.securesms.util.ViewUtil import org.thoughtcrime.securesms.util.livedata.ProcessState import org.thoughtcrime.securesms.util.livedata.distinctUntilChanged +import org.thoughtcrime.securesms.util.navigation.safeNavigate /** * Depending on the arguments, can be used to set the universal expire timer, set expire timer @@ -115,7 +116,7 @@ class ExpireTimerSettingsFragment : DSLSettingsFragment( title = DSLSettingsText.from(R.string.ExpireTimerSettingsFragment__custom_time), summary = if (hasCustomValue) DSLSettingsText.from(ExpirationUtil.getExpirationDisplayValue(requireContext(), state.currentTimer)) else null, isChecked = hasCustomValue, - onClick = { NavHostFragment.findNavController(this@ExpireTimerSettingsFragment).navigate(R.id.action_expireTimerSettingsFragment_to_customExpireTimerSelectDialog) } + onClick = { NavHostFragment.findNavController(this@ExpireTimerSettingsFragment).safeNavigate(R.id.action_expireTimerSettingsFragment_to_customExpireTimerSelectDialog) } ) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/boost/BoostFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/boost/BoostFragment.kt index 512f1765b..cab4dad3f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/boost/BoostFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/boost/BoostFragment.kt @@ -36,6 +36,7 @@ import org.thoughtcrime.securesms.util.CommunicationActions import org.thoughtcrime.securesms.util.LifecycleDisposable import org.thoughtcrime.securesms.util.Projection import org.thoughtcrime.securesms.util.SpanUtil +import org.thoughtcrime.securesms.util.navigation.safeNavigate /** * UX to allow users to donate ephemerally. @@ -167,7 +168,7 @@ class BoostFragment : DSLSettingsBottomSheetFragment( selectedCurrency = state.currencySelection, isEnabled = state.stage == BoostState.Stage.READY, onClick = { - findNavController().navigate(BoostFragmentDirections.actionBoostFragmentToSetDonationCurrencyFragment(true, viewModel.getSupportedCurrencyCodes().toTypedArray())) + findNavController().safeNavigate(BoostFragmentDirections.actionBoostFragmentToSetDonationCurrencyFragment(true, viewModel.getSupportedCurrencyCodes().toTypedArray())) } ) ) @@ -232,7 +233,7 @@ class BoostFragment : DSLSettingsBottomSheetFragment( } private fun onPaymentConfirmed(boostBadge: Badge) { - findNavController().navigate( + findNavController().safeNavigate( BoostFragmentDirections.actionBoostFragmentToBoostThanksForYourSupportBottomSheetDialog(boostBadge).setIsBoost(true), NavOptions.Builder().setPopUpTo(R.id.boostFragment, true).build() ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/manage/ManageDonationsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/manage/ManageDonationsFragment.kt index 541bd336c..b00b46f2e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/manage/ManageDonationsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/manage/ManageDonationsFragment.kt @@ -20,6 +20,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.help.HelpFragment import org.thoughtcrime.securesms.subscription.Subscription import org.thoughtcrime.securesms.util.LifecycleDisposable +import org.thoughtcrime.securesms.util.navigation.safeNavigate import java.util.Currency import java.util.concurrent.TimeUnit @@ -101,7 +102,7 @@ class ManageDonationsFragment : DSLSettingsFragment() { price = FiatMoney(activeAmount, activeCurrency), subscription = subscription, onAddBoostClick = { - findNavController().navigate(ManageDonationsFragmentDirections.actionManageDonationsFragmentToBoosts()) + findNavController().safeNavigate(ManageDonationsFragmentDirections.actionManageDonationsFragmentToBoosts()) }, renewalTimestamp = TimeUnit.SECONDS.toMillis(activeSubscription.endOfCurrentPeriod), redemptionState = state.getRedemptionState(), @@ -129,7 +130,7 @@ class ManageDonationsFragment : DSLSettingsFragment() { icon = DSLSettingsIcon.from(R.drawable.ic_person_white_24dp), isEnabled = state.getRedemptionState() != ManageDonationsState.SubscriptionRedemptionState.IN_PROGRESS, onClick = { - findNavController().navigate(ManageDonationsFragmentDirections.actionManageDonationsFragmentToSubscribeFragment()) + findNavController().safeNavigate(ManageDonationsFragmentDirections.actionManageDonationsFragmentToSubscribeFragment()) } ) @@ -137,7 +138,7 @@ class ManageDonationsFragment : DSLSettingsFragment() { title = DSLSettingsText.from(R.string.ManageDonationsFragment__badges), icon = DSLSettingsIcon.from(R.drawable.ic_badge_24), onClick = { - findNavController().navigate(ManageDonationsFragmentDirections.actionManageDonationsFragmentToManageBadges()) + findNavController().safeNavigate(ManageDonationsFragmentDirections.actionManageDonationsFragmentToManageBadges()) } ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/subscribe/SubscribeFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/subscribe/SubscribeFragment.kt index 8de281f7e..c0ad587e1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/subscribe/SubscribeFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/subscribe/SubscribeFragment.kt @@ -36,6 +36,7 @@ import org.thoughtcrime.securesms.payments.FiatMoneyUtil import org.thoughtcrime.securesms.subscription.Subscription import org.thoughtcrime.securesms.util.LifecycleDisposable import org.thoughtcrime.securesms.util.SpanUtil +import org.thoughtcrime.securesms.util.navigation.safeNavigate import java.util.Calendar import java.util.Currency import java.util.concurrent.TimeUnit @@ -54,7 +55,7 @@ class SubscribeFragment : DSLSettingsFragment( .append(" ") .append( SpanUtil.readMore(requireContext(), ContextCompat.getColor(requireContext(), R.color.signal_button_secondary_text)) { - findNavController().navigate(SubscribeFragmentDirections.actionSubscribeFragmentToSubscribeLearnMoreBottomSheetDialog()) + findNavController().safeNavigate(SubscribeFragmentDirections.actionSubscribeFragmentToSubscribeLearnMoreBottomSheetDialog()) } ) } @@ -147,7 +148,7 @@ class SubscribeFragment : DSLSettingsFragment( onClick = { val selectableCurrencies = viewModel.getSelectableCurrencyCodes() if (selectableCurrencies != null) { - findNavController().navigate(SubscribeFragmentDirections.actionSubscribeFragmentToSetDonationCurrencyFragment(false, selectableCurrencies.toTypedArray())) + findNavController().safeNavigate(SubscribeFragmentDirections.actionSubscribeFragmentToSetDonationCurrencyFragment(false, selectableCurrencies.toTypedArray())) } } ) @@ -270,7 +271,7 @@ class SubscribeFragment : DSLSettingsFragment( } private fun onPaymentConfirmed(badge: Badge) { - findNavController().navigate( + findNavController().safeNavigate( SubscribeFragmentDirections.actionSubscribeFragmentToSubscribeThanksForYourSupportBottomSheetDialog(badge).setIsBoost(false), ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt index daade299e..a4120bf0d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt @@ -80,6 +80,7 @@ import org.thoughtcrime.securesms.util.ExpirationUtil import org.thoughtcrime.securesms.util.FeatureFlags import org.thoughtcrime.securesms.util.ThemeUtil import org.thoughtcrime.securesms.util.ViewUtil +import org.thoughtcrime.securesms.util.navigation.safeNavigate import org.thoughtcrime.securesms.util.views.SimpleProgressDialog import org.thoughtcrime.securesms.verify.VerifyIdentityActivity import org.thoughtcrime.securesms.wallpaper.ChatWallpaperActivity @@ -330,7 +331,7 @@ class ConversationSettingsFragment : DSLSettingsFragment( recipient = state.recipient, onInternalDetailsClicked = { val action = ConversationSettingsFragmentDirections.actionConversationSettingsFragmentToInternalDetailsSettingsFragment(state.recipient.id) - navController.navigate(action) + navController.safeNavigate(action) } ) ) @@ -403,7 +404,7 @@ class ConversationSettingsFragment : DSLSettingsFragment( .setRecipientId(state.recipient.id) .setForResultMode(false) - navController.navigate(action) + navController.safeNavigate(action) } ) @@ -422,7 +423,7 @@ class ConversationSettingsFragment : DSLSettingsFragment( onClick = { val action = ConversationSettingsFragmentDirections.actionConversationSettingsFragmentToSoundsAndNotificationsSettingsFragment(state.recipient.id) - navController.navigate(action) + navController.safeNavigate(action) } ) } @@ -614,7 +615,7 @@ class ConversationSettingsFragment : DSLSettingsFragment( summary = DSLSettingsText.from(if (groupState.groupLinkEnabled) R.string.preferences_on else R.string.preferences_off), icon = DSLSettingsIcon.from(R.drawable.ic_link_16), onClick = { - navController.navigate(ConversationSettingsFragmentDirections.actionConversationSettingsFragmentToShareableGroupLinkFragment(groupState.groupId.requireV2().toString())) + navController.safeNavigate(ConversationSettingsFragmentDirections.actionConversationSettingsFragmentToShareableGroupLinkFragment(groupState.groupId.requireV2().toString())) } ) @@ -632,7 +633,7 @@ class ConversationSettingsFragment : DSLSettingsFragment( icon = DSLSettingsIcon.from(R.drawable.ic_lock_24), onClick = { val action = ConversationSettingsFragmentDirections.actionConversationSettingsFragmentToPermissionsSettingsFragment(ParcelableGroupId.from(groupState.groupId)) - navController.navigate(action) + navController.safeNavigate(action) } ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/SoundsAndNotificationsSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/SoundsAndNotificationsSettingsFragment.kt index 334de4c4b..5ad9e9ea4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/SoundsAndNotificationsSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/SoundsAndNotificationsSettingsFragment.kt @@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.components.settings.configure import org.thoughtcrime.securesms.components.settings.conversation.preferences.Utils.formatMutedUntil import org.thoughtcrime.securesms.database.RecipientDatabase import org.thoughtcrime.securesms.recipients.Recipient +import org.thoughtcrime.securesms.util.navigation.safeNavigate class SoundsAndNotificationsSettingsFragment : DSLSettingsFragment( titleId = R.string.ConversationSettingsFragment__sounds_and_notifications @@ -116,7 +117,7 @@ class SoundsAndNotificationsSettingsFragment : DSLSettingsFragment( summary = DSLSettingsText.from(customSoundSummary), onClick = { val action = SoundsAndNotificationsSettingsFragmentDirections.actionSoundsAndNotificationsSettingsFragmentToCustomNotificationsSettingsFragment(state.recipientId) - Navigation.findNavController(requireView()).navigate(action) + Navigation.findNavController(requireView()).safeNavigate(action) } ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ui/ChatColorSelectionFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ui/ChatColorSelectionFragment.kt index ecc0f9f14..5e55f5ca9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ui/ChatColorSelectionFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ui/ChatColorSelectionFragment.kt @@ -9,6 +9,7 @@ import androidx.recyclerview.widget.RecyclerView import com.google.android.material.dialog.MaterialAlertDialogBuilder import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.conversation.colors.ChatColors +import org.thoughtcrime.securesms.util.navigation.safeNavigate class ChatColorSelectionFragment : Fragment(R.layout.chat_color_selection_fragment) { @@ -102,7 +103,7 @@ class ChatColorSelectionFragment : Fragment(R.layout.chat_color_selection_fragme .actionChatColorSelectionFragmentToCustomChatColorCreatorFragment(args.recipientId, startPage) .setChatColorId(chatColors.id.longValue) - Navigation.findNavController(view).navigate(directions) + Navigation.findNavController(view).safeNavigate(directions) } override fun onDuplicate(chatColors: ChatColors) { @@ -115,7 +116,7 @@ class ChatColorSelectionFragment : Fragment(R.layout.chat_color_selection_fragme override fun onAdd() { val directions = ChatColorSelectionFragmentDirections.actionChatColorSelectionFragmentToCustomChatColorCreatorFragment(args.recipientId, 0) - Navigation.findNavController(view).navigate(directions) + Navigation.findNavController(view).safeNavigate(directions) } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferCompleteFragment.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferCompleteFragment.java index 674c72c88..013cd9346 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferCompleteFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferCompleteFragment.java @@ -10,6 +10,7 @@ import androidx.navigation.fragment.NavHostFragment; import org.thoughtcrime.securesms.LoggingFragment; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; /** * Shown after the new device successfully completes receiving a backup from the old device. @@ -22,8 +23,8 @@ public final class NewDeviceTransferCompleteFragment extends LoggingFragment { @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { view.findViewById(R.id.new_device_transfer_complete_fragment_continue_registration) - .setOnClickListener(v -> NavHostFragment.findNavController(this) - .navigate(R.id.action_newDeviceTransferComplete_to_enterPhoneNumberFragment)); + .setOnClickListener(v -> SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), + R.id.action_newDeviceTransferComplete_to_enterPhoneNumberFragment)); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferFragment.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferFragment.java index 3332b2124..9baf718d6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferFragment.java @@ -13,6 +13,7 @@ import org.greenrobot.eventbus.ThreadMode; import org.signal.devicetransfer.DeviceToDeviceTransferService; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.devicetransfer.DeviceTransferFragment; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; /** * Shows transfer progress on the new device. Most logic is in {@link DeviceTransferFragment} @@ -36,19 +37,18 @@ public final class NewDeviceTransferFragment extends DeviceTransferFragment { @Override protected void navigateToRestartTransfer() { - NavHostFragment.findNavController(this).navigate(R.id.action_newDeviceTransfer_to_newDeviceTransferInstructions); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), R.id.action_newDeviceTransfer_to_newDeviceTransferInstructions); } @Override protected void navigateAwayFromTransfer() { EventBus.getDefault().unregister(serverTaskListener); - NavHostFragment.findNavController(this) - .navigate(R.id.action_restart_to_welcomeFragment); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), R.id.action_restart_to_welcomeFragment); } @Override protected void navigateToTransferComplete() { - NavHostFragment.findNavController(this).navigate(R.id.action_newDeviceTransfer_to_newDeviceTransferComplete); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), R.id.action_newDeviceTransfer_to_newDeviceTransferComplete); } private class ServerTaskListener { diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferInstructionsFragment.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferInstructionsFragment.java index 6fc34bcc4..c4c509859 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferInstructionsFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferInstructionsFragment.java @@ -11,6 +11,7 @@ import org.greenrobot.eventbus.EventBus; import org.signal.devicetransfer.TransferStatus; import org.thoughtcrime.securesms.LoggingFragment; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; /** * Shows instructions for new device to being transfer. @@ -23,7 +24,7 @@ public final class NewDeviceTransferInstructionsFragment extends LoggingFragment @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { view.findViewById(R.id.new_device_transfer_instructions_fragment_continue) - .setOnClickListener(v -> Navigation.findNavController(v).navigate(R.id.action_device_transfer_setup)); + .setOnClickListener(v -> SafeNavigation.safeNavigate(Navigation.findNavController(v), R.id.action_device_transfer_setup)); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferSetupFragment.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferSetupFragment.java index 1296f13e0..af8e4f278 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferSetupFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferSetupFragment.java @@ -10,10 +10,11 @@ import org.signal.devicetransfer.DeviceToDeviceTransferService; import org.signal.devicetransfer.DeviceToDeviceTransferService.TransferNotificationData; import org.thoughtcrime.securesms.MainActivity; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.devicetransfer.SetupStep; import org.thoughtcrime.securesms.devicetransfer.DeviceTransferSetupFragment; +import org.thoughtcrime.securesms.devicetransfer.SetupStep; import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.notifications.NotificationIds; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; /** * Most responsibility is in {@link DeviceTransferSetupFragment} and delegates here @@ -25,13 +26,12 @@ public final class NewDeviceTransferSetupFragment extends DeviceTransferSetupFra @Override protected void navigateAwayFromTransfer() { - NavHostFragment.findNavController(this) - .navigate(R.id.action_deviceTransferSetup_to_transferOrRestore); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), R.id.action_deviceTransferSetup_to_transferOrRestore); } @Override protected void navigateToTransferConnected() { - NavHostFragment.findNavController(this).navigate(R.id.action_new_device_transfer); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), R.id.action_new_device_transfer); } @Override @@ -77,8 +77,7 @@ public final class NewDeviceTransferSetupFragment extends DeviceTransferSetupFra @Override protected void navigateWhenWifiDirectUnavailable() { - NavHostFragment.findNavController(this) - .navigate(R.id.action_deviceTransferSetup_to_transferOrRestore); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), R.id.action_deviceTransferSetup_to_transferOrRestore); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/TransferOrRestoreFragment.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/TransferOrRestoreFragment.java index 12951e7ac..209149ef3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/TransferOrRestoreFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/TransferOrRestoreFragment.java @@ -12,6 +12,7 @@ import androidx.navigation.Navigation; import org.thoughtcrime.securesms.LoggingFragment; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.util.SpanUtil; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; /** * Simple jumping off menu to starts a device-to-device transfer or restore a backup. @@ -25,11 +26,11 @@ public final class TransferOrRestoreFragment extends LoggingFragment { @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { view.findViewById(R.id.transfer_or_restore_fragment_transfer) - .setOnClickListener(v -> Navigation.findNavController(v).navigate(R.id.action_new_device_transfer_instructions)); + .setOnClickListener(v -> SafeNavigation.safeNavigate(Navigation.findNavController(v), R.id.action_new_device_transfer_instructions)); View restoreBackup = view.findViewById(R.id.transfer_or_restore_fragment_restore); if (Build.VERSION.SDK_INT >= 21) { - restoreBackup.setOnClickListener(v -> Navigation.findNavController(v).navigate(R.id.action_choose_backup)); + restoreBackup.setOnClickListener(v -> SafeNavigation.safeNavigate(Navigation.findNavController(v), R.id.action_choose_backup)); } else { restoreBackup.setVisibility(View.GONE); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferFragment.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferFragment.java index ba32523d2..e51a5a6a6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferFragment.java @@ -14,9 +14,9 @@ import org.signal.devicetransfer.DeviceToDeviceTransferService; import org.signal.devicetransfer.TransferStatus; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.devicetransfer.DeviceTransferFragment; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import java.text.NumberFormat; -import java.util.Locale; /** * Shows transfer progress on the old device. Most logic is in {@link DeviceTransferFragment} @@ -40,7 +40,7 @@ public final class OldDeviceTransferFragment extends DeviceTransferFragment { @Override protected void navigateToRestartTransfer() { - NavHostFragment.findNavController(this).navigate(R.id.action_directly_to_oldDeviceTransferInstructions); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), R.id.action_directly_to_oldDeviceTransferInstructions); } @Override @@ -51,7 +51,7 @@ public final class OldDeviceTransferFragment extends DeviceTransferFragment { @Override protected void navigateToTransferComplete() { - NavHostFragment.findNavController(this).navigate(R.id.action_oldDeviceTransfer_to_oldDeviceTransferComplete); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), R.id.action_oldDeviceTransfer_to_oldDeviceTransferComplete); } private class ClientTaskListener { @@ -70,7 +70,7 @@ public final class OldDeviceTransferFragment extends DeviceTransferFragment { ignoreTransferStatusEvents(); EventBus.getDefault().removeStickyEvent(TransferStatus.class); DeviceToDeviceTransferService.stop(requireContext()); - NavHostFragment.findNavController(OldDeviceTransferFragment.this).navigate(R.id.action_oldDeviceTransfer_to_oldDeviceTransferComplete); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(OldDeviceTransferFragment.this), R.id.action_oldDeviceTransfer_to_oldDeviceTransferComplete); } else { if (event.getEstimatedMessageCount() == 0) { status.setText(getString(R.string.DeviceTransfer__d_messages_so_far, event.getMessageCount())); diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferInstructionsFragment.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferInstructionsFragment.java index 449796880..bb4ec5b8a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferInstructionsFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferInstructionsFragment.java @@ -14,6 +14,7 @@ import org.signal.devicetransfer.DeviceToDeviceTransferService; import org.signal.devicetransfer.TransferStatus; import org.thoughtcrime.securesms.LoggingFragment; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; /** * Provides instructions for the old device on how to start a device-to-device transfer. @@ -34,16 +35,15 @@ public final class OldDeviceTransferInstructionsFragment extends LoggingFragment }); view.findViewById(R.id.old_device_transfer_instructions_fragment_continue) - .setOnClickListener(v -> Navigation.findNavController(v) - .navigate(R.id.action_oldDeviceTransferInstructions_to_oldDeviceTransferSetup)); + .setOnClickListener(v -> SafeNavigation.safeNavigate(Navigation.findNavController(v), R.id.action_oldDeviceTransferInstructions_to_oldDeviceTransferSetup)); } @Override public void onResume() { super.onResume(); if (EventBus.getDefault().getStickyEvent(TransferStatus.class) != null) { - NavHostFragment.findNavController(this) - .navigate(R.id.action_oldDeviceTransferInstructions_to_oldDeviceTransferSetup); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), + R.id.action_oldDeviceTransferInstructions_to_oldDeviceTransferSetup); } else { DeviceToDeviceTransferService.stop(requireContext()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferSetupFragment.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferSetupFragment.java index 63eaecdb3..3ae26f624 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferSetupFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferSetupFragment.java @@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.devicetransfer.SetupStep; import org.thoughtcrime.securesms.jobs.LocalBackupJob; import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.notifications.NotificationIds; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; /** * Most responsibility is in {@link DeviceTransferSetupFragment} and delegates here @@ -41,7 +42,7 @@ public final class OldDeviceTransferSetupFragment extends DeviceTransferSetupFra @Override protected void navigateToTransferConnected() { - NavHostFragment.findNavController(this).navigate(R.id.action_oldDeviceTransferSetup_to_oldDeviceTransfer); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), R.id.action_oldDeviceTransferSetup_to_oldDeviceTransfer); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsFragment.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsFragment.java index d37ba0b45..6373947f2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsFragment.java @@ -49,6 +49,7 @@ import org.thoughtcrime.securesms.util.BitmapUtil; import org.thoughtcrime.securesms.util.ExpirationUtil; import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.ViewUtil; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import org.thoughtcrime.securesms.util.text.AfterTextChanged; import org.thoughtcrime.securesms.util.views.LearnMoreTextView; @@ -275,7 +276,7 @@ public class AddGroupDetailsFragment extends LoggingFragment { private void showAvatarPicker() { Media media = viewModel.getAvatarMedia(); - Navigation.findNavController(requireView()).navigate(AddGroupDetailsFragmentDirections.actionAddGroupDetailsFragmentToAvatarPicker(null, media).setIsNewGroup(true)); + SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), AddGroupDetailsFragmentDirections.actionAddGroupDetailsFragmentToAvatarPicker(null, media).setIsNewGroup(true)); } public interface Callback { diff --git a/app/src/main/java/org/thoughtcrime/securesms/lock/v2/CreateKbsPinFragment.java b/app/src/main/java/org/thoughtcrime/securesms/lock/v2/CreateKbsPinFragment.java index c6b2b1d0f..477947977 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/lock/v2/CreateKbsPinFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/lock/v2/CreateKbsPinFragment.java @@ -14,6 +14,7 @@ import androidx.navigation.Navigation; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.util.SpanUtil; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; public class CreateKbsPinFragment extends BaseKbsPinFragment { @@ -75,7 +76,7 @@ public class CreateKbsPinFragment extends BaseKbsPinFragment 0) { - hostFragment.navController.navigate( + hostFragment.navController.safeNavigate( startDestination, Bundle().apply { putBoolean("first", true) diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionNavigator.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionNavigator.kt index 36668c903..6a1d665e1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionNavigator.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionNavigator.kt @@ -7,6 +7,7 @@ import androidx.fragment.app.Fragment import androidx.navigation.Navigation import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.permissions.Permissions +import org.thoughtcrime.securesms.util.navigation.safeNavigate class MediaSelectionNavigator( private val toCamera: Int = -1, @@ -19,13 +20,13 @@ class MediaSelectionNavigator( fun goToCamera(view: View) { if (toCamera == -1) return - Navigation.findNavController(view).navigate(toCamera) + Navigation.findNavController(view).safeNavigate(toCamera) } fun goToGallery(view: View) { if (toGallery == -1) return - Navigation.findNavController(view).navigate(toGallery) + Navigation.findNavController(view).safeNavigate(toGallery) } companion object { diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/backup/PaymentsRecoveryPasteFragment.java b/app/src/main/java/org/thoughtcrime/securesms/payments/backup/PaymentsRecoveryPasteFragment.java index 39fd8e9a8..b466d4306 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/backup/PaymentsRecoveryPasteFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/backup/PaymentsRecoveryPasteFragment.java @@ -12,6 +12,7 @@ import androidx.fragment.app.Fragment; import androidx.navigation.Navigation; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import org.thoughtcrime.securesms.util.text.AfterTextChanged; import org.whispersystems.signalservice.api.payments.PaymentsConstants; @@ -47,7 +48,7 @@ public class PaymentsRecoveryPasteFragment extends Fragment { return; } - Navigation.findNavController(v).navigate(PaymentsRecoveryPasteFragmentDirections.actionPaymentsRecoveryEntryToPaymentsRecoveryPhrase(false).setWords(words)); + SafeNavigation.safeNavigate(Navigation.findNavController(v), PaymentsRecoveryPasteFragmentDirections.actionPaymentsRecoveryEntryToPaymentsRecoveryPhrase(false).setWords(words)); }); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/backup/PaymentsRecoveryStartFragment.java b/app/src/main/java/org/thoughtcrime/securesms/payments/backup/PaymentsRecoveryStartFragment.java index 2793c1039..4d1e71ec7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/backup/PaymentsRecoveryStartFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/backup/PaymentsRecoveryStartFragment.java @@ -12,6 +12,7 @@ import androidx.fragment.app.Fragment; import androidx.navigation.Navigation; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import org.thoughtcrime.securesms.util.views.LearnMoreTextView; import org.whispersystems.signalservice.api.payments.PaymentsConstants; @@ -37,15 +38,15 @@ public class PaymentsRecoveryStartFragment extends Fragment { title.setText(R.string.PaymentsRecoveryStartFragment__enter_recovery_phrase); message.setText(getString(R.string.PaymentsRecoveryStartFragment__your_recovery_phrase_is_a, PaymentsConstants.MNEMONIC_LENGTH)); message.setLink(getString(R.string.PaymentsRecoveryStartFragment__learn_more__restore)); - startButton.setOnClickListener(v -> Navigation.findNavController(requireView()).navigate(PaymentsRecoveryStartFragmentDirections.actionPaymentsRecoveryStartToPaymentsRecoveryEntry())); + startButton.setOnClickListener(v -> SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), PaymentsRecoveryStartFragmentDirections.actionPaymentsRecoveryStartToPaymentsRecoveryEntry())); startButton.setText(R.string.PaymentsRecoveryStartFragment__enter_manually); pasteButton.setVisibility(View.VISIBLE); - pasteButton.setOnClickListener(v -> Navigation.findNavController(v).navigate(PaymentsRecoveryStartFragmentDirections.actionPaymentsRecoveryStartToPaymentsRecoveryPaste())); + pasteButton.setOnClickListener(v -> SafeNavigation.safeNavigate(Navigation.findNavController(v), PaymentsRecoveryStartFragmentDirections.actionPaymentsRecoveryStartToPaymentsRecoveryPaste())); } else { title.setText(R.string.PaymentsRecoveryStartFragment__view_recovery_phrase); message.setText(getString(R.string.PaymentsRecoveryStartFragment__your_balance_will_automatically_restore, PaymentsConstants.MNEMONIC_LENGTH)); message.setLink(getString(R.string.PaymentsRecoveryStartFragment__learn_more__view)); - startButton.setOnClickListener(v -> Navigation.findNavController(requireView()).navigate(PaymentsRecoveryStartFragmentDirections.actionPaymentsRecoveryStartToPaymentsRecoveryPhrase(args.getFinishOnConfirm()))); + startButton.setOnClickListener(v -> SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), PaymentsRecoveryStartFragmentDirections.actionPaymentsRecoveryStartToPaymentsRecoveryPhrase(args.getFinishOnConfirm()))); startButton.setText(R.string.PaymentsRecoveryStartFragment__start); pasteButton.setVisibility(View.GONE); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/backup/entry/PaymentsRecoveryEntryFragment.java b/app/src/main/java/org/thoughtcrime/securesms/payments/backup/entry/PaymentsRecoveryEntryFragment.java index f89f54f78..6e4953a23 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/backup/entry/PaymentsRecoveryEntryFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/backup/entry/PaymentsRecoveryEntryFragment.java @@ -19,6 +19,7 @@ import com.google.android.material.textfield.TextInputLayout; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.payments.Mnemonic; import org.thoughtcrime.securesms.util.Util; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import org.thoughtcrime.securesms.util.text.AfterTextChanged; public class PaymentsRecoveryEntryFragment extends Fragment { @@ -54,8 +55,8 @@ public class PaymentsRecoveryEntryFragment extends Fragment { viewModel.getEvents().observe(getViewLifecycleOwner(), event -> { if (event == PaymentsRecoveryEntryViewModel.Events.GO_TO_CONFIRM) { - Navigation.findNavController(view).navigate(PaymentsRecoveryEntryFragmentDirections.actionPaymentsRecoveryEntryToPaymentsRecoveryPhrase(false) - .setWords(viewModel.getWords())); + SafeNavigation.safeNavigate(Navigation.findNavController(view), PaymentsRecoveryEntryFragmentDirections.actionPaymentsRecoveryEntryToPaymentsRecoveryPhrase(false) + .setWords(viewModel.getWords())); } }); diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/backup/phrase/PaymentsRecoveryPhraseFragment.java b/app/src/main/java/org/thoughtcrime/securesms/payments/backup/phrase/PaymentsRecoveryPhraseFragment.java index 08b0eafe6..7f22de226 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/backup/phrase/PaymentsRecoveryPhraseFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/backup/phrase/PaymentsRecoveryPhraseFragment.java @@ -27,6 +27,7 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.payments.Mnemonic; import org.thoughtcrime.securesms.util.ServiceUtil; import org.thoughtcrime.securesms.util.Util; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import java.util.Arrays; import java.util.Comparator; @@ -125,7 +126,7 @@ public class PaymentsRecoveryPhraseFragment extends Fragment { @NonNull PaymentsRecoveryPhraseFragmentArgs args) { message.setText(getString(R.string.PaymentsRecoveryPhraseFragment__write_down_the_following_d_words, words.size())); - next.setOnClickListener(v -> Navigation.findNavController(v).navigate(PaymentsRecoveryPhraseFragmentDirections.actionPaymentsRecoveryPhraseToPaymentsRecoveryPhraseConfirm(args.getFinishOnConfirm()))); + next.setOnClickListener(v -> SafeNavigation.safeNavigate(Navigation.findNavController(v), PaymentsRecoveryPhraseFragmentDirections.actionPaymentsRecoveryPhraseToPaymentsRecoveryPhraseConfirm(args.getFinishOnConfirm()))); edit.setVisibility(View.GONE); copy.setVisibility(View.VISIBLE); copy.setOnClickListener(v -> confirmCopy(words)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/confirm/ConfirmPaymentFragment.java b/app/src/main/java/org/thoughtcrime/securesms/payments/confirm/ConfirmPaymentFragment.java index ea96ac47c..2fc7b9e6c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/confirm/ConfirmPaymentFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/confirm/ConfirmPaymentFragment.java @@ -35,6 +35,7 @@ import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.BottomSheetUtil; import org.thoughtcrime.securesms.util.MappingModelList; import org.thoughtcrime.securesms.util.StringUtil; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import org.whispersystems.signalservice.api.payments.FormatterOptions; import java.util.concurrent.TimeUnit; @@ -49,7 +50,7 @@ public class ConfirmPaymentFragment extends BottomSheetDialogFragment { requireActivity().setResult(Activity.RESULT_OK); requireActivity().finish(); } else { - NavHostFragment.findNavController(this).navigate(R.id.action_directly_to_paymentsHome); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), R.id.action_directly_to_paymentsHome); } }; diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/create/CreatePaymentFragment.java b/app/src/main/java/org/thoughtcrime/securesms/payments/create/CreatePaymentFragment.java index 1913fc962..918ec4390 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/create/CreatePaymentFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/create/CreatePaymentFragment.java @@ -29,6 +29,7 @@ import org.thoughtcrime.securesms.payments.preferences.RecipientHasNotEnabledPay import org.thoughtcrime.securesms.util.CommunicationActions; import org.thoughtcrime.securesms.util.SpanUtil; import org.thoughtcrime.securesms.util.ViewUtil; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import org.whispersystems.signalservice.api.payments.FormatterOptions; import org.whispersystems.signalservice.api.payments.Money; @@ -113,13 +114,13 @@ public class CreatePaymentFragment extends LoggingFragment { initializeInfoIcon(); - note.setOnClickListener(v -> Navigation.findNavController(v).navigate(R.id.action_createPaymentFragment_to_editPaymentNoteFragment)); - addNote.setOnClickListener(v -> Navigation.findNavController(v).navigate(R.id.action_createPaymentFragment_to_editPaymentNoteFragment)); + note.setOnClickListener(v -> SafeNavigation.safeNavigate(Navigation.findNavController(v), R.id.action_createPaymentFragment_to_editPaymentNoteFragment)); + addNote.setOnClickListener(v -> SafeNavigation.safeNavigate(Navigation.findNavController(v), R.id.action_createPaymentFragment_to_editPaymentNoteFragment)); pay.setOnClickListener(v -> { NavDirections directions = CreatePaymentFragmentDirections.actionCreatePaymentFragmentToConfirmPaymentFragment(viewModel.getCreatePaymentDetails()) .setFinishOnConfirm(arguments.getFinishOnConfirm()); - Navigation.findNavController(v).navigate(directions); + SafeNavigation.safeNavigate(Navigation.findNavController(v), directions); }); toggle.setOnClickListener(v -> viewModel.toggleMoneyInputTarget()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/deactivate/DeactivateWalletFragment.java b/app/src/main/java/org/thoughtcrime/securesms/payments/deactivate/DeactivateWalletFragment.java index 78b761fd3..31a560fac 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/deactivate/DeactivateWalletFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/deactivate/DeactivateWalletFragment.java @@ -18,6 +18,7 @@ import androidx.navigation.Navigation; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.payments.MoneyView; import org.thoughtcrime.securesms.util.SpanUtil; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import org.thoughtcrime.securesms.util.views.LearnMoreTextView; public class DeactivateWalletFragment extends Fragment { @@ -49,7 +50,7 @@ public class DeactivateWalletFragment extends Fragment { } }); - transferRemainingBalance.setOnClickListener(v -> Navigation.findNavController(requireView()).navigate(R.id.action_deactivateWallet_to_paymentsTransfer)); + transferRemainingBalance.setOnClickListener(v -> SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), R.id.action_deactivateWallet_to_paymentsTransfer)); toolbar.setNavigationOnClickListener(v -> Navigation.findNavController(requireView()).popBackStack()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentRecipientSelectionFragment.java b/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentRecipientSelectionFragment.java index 21b2bf9dd..877659271 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentRecipientSelectionFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentRecipientSelectionFragment.java @@ -23,6 +23,7 @@ import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.ViewUtil; import org.thoughtcrime.securesms.util.concurrent.SimpleTask; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import org.whispersystems.libsignal.util.guava.Optional; import java.util.function.Consumer; @@ -106,7 +107,7 @@ public class PaymentRecipientSelectionFragment extends LoggingFragment implement private void createPayment(@NonNull RecipientId recipientId) { hideKeyboard(); - Navigation.findNavController(requireView()).navigate(PaymentRecipientSelectionFragmentDirections.actionPaymentRecipientSelectionToCreatePayment(new PayeeParcelable(recipientId))); + SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), PaymentRecipientSelectionFragmentDirections.actionPaymentRecipientSelectionToCreatePayment(new PayeeParcelable(recipientId))); } private void showWarningDialog(@NonNull RecipientId recipientId) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsActivity.java b/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsActivity.java index e092d3855..759245d8d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsActivity.java @@ -12,6 +12,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobs.PaymentLedgerUpdateJob; import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme; import org.thoughtcrime.securesms.util.DynamicTheme; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; public class PaymentsActivity extends PassphraseRequiredActivity { @@ -31,7 +32,7 @@ public class PaymentsActivity extends PassphraseRequiredActivity { int startingAction = getIntent().getIntExtra(EXTRA_PAYMENTS_STARTING_ACTION, R.id.paymentsHome); if (startingAction != R.id.paymentsHome) { - controller.navigate(startingAction, getIntent().getBundleExtra(EXTRA_STARTING_ARGUMENTS)); + SafeNavigation.safeNavigate(controller, startingAction, getIntent().getBundleExtra(EXTRA_STARTING_ARGUMENTS)); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsHomeFragment.java b/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsHomeFragment.java index bf5343920..c9533c52f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsHomeFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsHomeFragment.java @@ -1,7 +1,6 @@ package org.thoughtcrime.securesms.payments.preferences; import android.app.AlertDialog; -import android.content.Intent; import android.graphics.Color; import android.os.Bundle; import android.view.MenuItem; @@ -37,6 +36,7 @@ import org.thoughtcrime.securesms.payments.MoneyView; import org.thoughtcrime.securesms.payments.preferences.model.PaymentItem; import org.thoughtcrime.securesms.util.CommunicationActions; import org.thoughtcrime.securesms.util.SpanUtil; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; public class PaymentsHomeFragment extends LoggingFragment { @@ -71,14 +71,14 @@ public class PaymentsHomeFragment extends LoggingFragment { addMoney.setOnClickListener(v -> { if (SignalStore.paymentsValues().getPaymentsAvailability().isSendAllowed()) { - Navigation.findNavController(v).navigate(PaymentsHomeFragmentDirections.actionPaymentsHomeToPaymentsAddMoney()); + SafeNavigation.safeNavigate(Navigation.findNavController(v), PaymentsHomeFragmentDirections.actionPaymentsHomeToPaymentsAddMoney()); } else { showPaymentsDisabledDialog(); } }); sendMoney.setOnClickListener(v -> { if (SignalStore.paymentsValues().getPaymentsAvailability().isSendAllowed()) { - Navigation.findNavController(v).navigate(PaymentsHomeFragmentDirections.actionPaymentsHomeToPaymentRecipientSelectionFragment()); + SafeNavigation.safeNavigate(Navigation.findNavController(v), PaymentsHomeFragmentDirections.actionPaymentsHomeToPaymentRecipientSelectionFragment()); } else { showPaymentsDisabledDialog(); } @@ -169,7 +169,7 @@ public class PaymentsHomeFragment extends LoggingFragment { case DEACTIVATE_WITH_BALANCE: builder.setPositiveButton(getString(R.string.PaymentsHomeFragment__continue), (dialog, which) -> { dialog.dismiss(); - NavHostFragment.findNavController(this).navigate(R.id.deactivateWallet); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), R.id.deactivateWallet); }); break; case ACTIVATED: @@ -211,16 +211,16 @@ public class PaymentsHomeFragment extends LoggingFragment { private boolean onMenuItemSelected(@NonNull MenuItem item) { if (item.getItemId() == R.id.payments_home_fragment_menu_transfer_to_exchange) { - NavHostFragment.findNavController(this).navigate(R.id.action_paymentsHome_to_paymentsTransfer); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), R.id.action_paymentsHome_to_paymentsTransfer); return true; } else if (item.getItemId() == R.id.payments_home_fragment_menu_set_currency) { - NavHostFragment.findNavController(this).navigate(R.id.action_paymentsHome_to_setCurrency); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), R.id.action_paymentsHome_to_setCurrency); return true; } else if (item.getItemId() == R.id.payments_home_fragment_menu_deactivate_wallet) { viewModel.deactivatePayments(); return true; } else if (item.getItemId() == R.id.payments_home_fragment_menu_view_recovery_phrase) { - NavHostFragment.findNavController(this).navigate(R.id.action_paymentsHome_to_paymentsBackup); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), R.id.action_paymentsHome_to_paymentsBackup); return true; } else if (item.getItemId() == R.id.payments_home_fragment_menu_help) { startActivity(AppSettingsActivity.help(requireContext(), HelpFragment.PAYMENT_INDEX)); @@ -255,20 +255,20 @@ public class PaymentsHomeFragment extends LoggingFragment { @Override public void onRestorePaymentsAccount() { - NavHostFragment.findNavController(PaymentsHomeFragment.this) - .navigate(PaymentsHomeFragmentDirections.actionPaymentsHomeToPaymentsBackup().setIsRestore(true)); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(PaymentsHomeFragment.this), + PaymentsHomeFragmentDirections.actionPaymentsHomeToPaymentsBackup().setIsRestore(true)); } @Override public void onSeeAll(@NonNull PaymentType paymentType) { - NavHostFragment.findNavController(PaymentsHomeFragment.this) - .navigate(PaymentsHomeFragmentDirections.actionPaymentsHomeToPaymentsAllActivity(paymentType)); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(PaymentsHomeFragment.this), + PaymentsHomeFragmentDirections.actionPaymentsHomeToPaymentsAllActivity(paymentType)); } @Override public void onPaymentItem(@NonNull PaymentItem model) { - NavHostFragment.findNavController(PaymentsHomeFragment.this) - .navigate(PaymentPreferencesDirections.actionDirectlyToPaymentDetails(model.getPaymentDetailsParcelable())); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(PaymentsHomeFragment.this), + PaymentPreferencesDirections.actionDirectlyToPaymentDetails(model.getPaymentDetailsParcelable())); } @Override @@ -283,7 +283,7 @@ public class PaymentsHomeFragment extends LoggingFragment { @Override public void onViewRecoveryPhrase() { - NavHostFragment.findNavController(PaymentsHomeFragment.this).navigate(R.id.action_paymentsHome_to_paymentsBackup); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(PaymentsHomeFragment.this), R.id.action_paymentsHome_to_paymentsBackup); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsPagerItemFragment.java b/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsPagerItemFragment.java index ea35d33ed..0a176e3c7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsPagerItemFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsPagerItemFragment.java @@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.LoggingFragment; import org.thoughtcrime.securesms.PaymentPreferencesDirections; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.payments.preferences.model.PaymentItem; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; public class PaymentsPagerItemFragment extends LoggingFragment { @@ -62,8 +63,8 @@ public class PaymentsPagerItemFragment extends LoggingFragment { private class Callbacks implements PaymentsHomeAdapter.Callbacks { @Override public void onPaymentItem(@NonNull PaymentItem model) { - NavHostFragment.findNavController(PaymentsPagerItemFragment.this) - .navigate(PaymentPreferencesDirections.actionDirectlyToPaymentDetails(model.getPaymentDetailsParcelable())); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(PaymentsPagerItemFragment.this), + PaymentPreferencesDirections.actionDirectlyToPaymentDetails(model.getPaymentDetailsParcelable())); } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/transfer/PaymentsTransferFragment.java b/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/transfer/PaymentsTransferFragment.java index e3d01b431..4a32d26fa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/transfer/PaymentsTransferFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/transfer/PaymentsTransferFragment.java @@ -22,6 +22,7 @@ import org.thoughtcrime.securesms.payments.MobileCoinPublicAddress; import org.thoughtcrime.securesms.payments.preferences.model.PayeeParcelable; import org.thoughtcrime.securesms.permissions.Permissions; import org.thoughtcrime.securesms.util.ViewUtil; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; public final class PaymentsTransferFragment extends LoggingFragment { @@ -77,7 +78,7 @@ public final class PaymentsTransferFragment extends LoggingFragment { NavDirections action = PaymentsTransferFragmentDirections.actionPaymentsTransferToCreatePayment(new PayeeParcelable(publicAddress)) .setFinishOnConfirm(PaymentsTransferFragmentArgs.fromBundle(requireArguments()).getFinishOnConfirm()); - Navigation.findNavController(requireView()).navigate(action); + SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), action); return true; } catch (MobileCoinPublicAddress.AddressException e) { Log.w(TAG, "Address is not valid", e); @@ -96,7 +97,7 @@ public final class PaymentsTransferFragment extends LoggingFragment { .ifNecessary() .withRationaleDialog(getString(R.string.PaymentsTransferFragment__to_scan_a_qr_code_signal_needs), R.drawable.ic_camera_24) .onAnyPermanentlyDenied(this::onCameraPermissionPermanentlyDenied) - .onAllGranted(() -> Navigation.findNavController(requireView()).navigate(R.id.action_paymentsTransfer_to_paymentsScanQr)) + .onAllGranted(() -> SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), R.id.action_paymentsTransfer_to_paymentsScanQr)) .onAnyDenied(() -> Toast.makeText(requireContext(), R.string.PaymentsTransferFragment__to_scan_a_qr_code_signal_needs_access_to_the_camera, Toast.LENGTH_LONG).show()) .execute(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/transfer/PaymentsTransferQrScanFragment.java b/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/transfer/PaymentsTransferQrScanFragment.java index 5c2a20f0a..ef47233b5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/transfer/PaymentsTransferQrScanFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/transfer/PaymentsTransferQrScanFragment.java @@ -18,6 +18,7 @@ import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.components.camera.CameraView; import org.thoughtcrime.securesms.payments.MobileCoinPublicAddress; import org.thoughtcrime.securesms.qr.ScanningThread; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; public final class PaymentsTransferQrScanFragment extends LoggingFragment { @@ -56,7 +57,7 @@ public final class PaymentsTransferQrScanFragment extends LoggingFragment { scanningThread.setScanListener(data -> ThreadUtil.runOnMain(() -> { try { viewModel.postQrData(MobileCoinPublicAddress.fromQr(data).getPaymentAddressBase58()); - Navigation.findNavController(requireView()).navigate(R.id.action_paymentsScanQr_pop); + SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), R.id.action_paymentsScanQr_pop); } catch (MobileCoinPublicAddress.AddressException e) { Log.e(TAG, "Not a valid address"); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/pin/PinRestoreEntryFragment.java b/app/src/main/java/org/thoughtcrime/securesms/pin/PinRestoreEntryFragment.java index 71ce2f625..eba184790 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/pin/PinRestoreEntryFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/pin/PinRestoreEntryFragment.java @@ -41,6 +41,7 @@ import org.thoughtcrime.securesms.util.CommunicationActions; import org.thoughtcrime.securesms.util.ServiceUtil; import org.thoughtcrime.securesms.util.SupportEmailUtil; import org.thoughtcrime.securesms.util.ViewUtil; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; public class PinRestoreEntryFragment extends LoggingFragment { private static final String TAG = Log.tag(PinRestoreActivity.class); @@ -226,7 +227,7 @@ public class PinRestoreEntryFragment extends LoggingFragment { } private void onAccountLocked() { - Navigation.findNavController(requireView()).navigate(PinRestoreEntryFragmentDirections.actionAccountLocked()); + SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), PinRestoreEntryFragmentDirections.actionAccountLocked()); } private void handleSuccess() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditProfileFragment.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditProfileFragment.java index 1f781f158..3bba294e6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditProfileFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditProfileFragment.java @@ -45,6 +45,7 @@ import org.thoughtcrime.securesms.providers.BlobProvider; import org.thoughtcrime.securesms.util.CommunicationActions; import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.concurrent.SimpleTask; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import org.thoughtcrime.securesms.util.text.AfterTextChanged; import org.thoughtcrime.securesms.util.views.LearnMoreTextView; @@ -290,9 +291,9 @@ public class EditProfileFragment extends LoggingFragment { private void startAvatarSelection() { if (viewModel.isGroup()) { Parcelable groupId = ParcelableGroupId.from(viewModel.getGroupId()); - Navigation.findNavController(requireView()).navigate(EditProfileFragmentDirections.actionCreateProfileFragmentToAvatarPicker((ParcelableGroupId) groupId, viewModel.getAvatarMedia())); + SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), EditProfileFragmentDirections.actionCreateProfileFragmentToAvatarPicker((ParcelableGroupId) groupId, viewModel.getAvatarMedia())); } else { - Navigation.findNavController(requireView()).navigate(EditProfileFragmentDirections.actionCreateProfileFragmentToAvatarPicker(null, null)); + SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), EditProfileFragmentDirections.actionCreateProfileFragmentToAvatarPicker(null, null)); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/ManageProfileActivity.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/ManageProfileActivity.java index 78fdaaecc..33df03f3b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/ManageProfileActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/ManageProfileActivity.java @@ -17,6 +17,7 @@ import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.reactions.any.ReactWithAnyEmojiBottomSheetDialogFragment; import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme; import org.thoughtcrime.securesms.util.DynamicTheme; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; /** * Activity that manages the local user's profile, as accessed via the settings. @@ -63,13 +64,13 @@ public class ManageProfileActivity extends PassphraseRequiredActivity implements navController.setGraph(graph, extras != null ? extras : new Bundle()); if (extras != null && extras.getBoolean(START_AT_USERNAME, false)) { - NavDirections action = ManageProfileFragmentDirections.actionManageUsername(); - navController.navigate(action); + NavDirections action = ManageProfileFragmentDirections.actionManageUsername(); + SafeNavigation.safeNavigate(navController, action); } if (extras != null && extras.getBoolean(START_AT_AVATAR, false)) { NavDirections action = ManageProfileFragmentDirections.actionManageProfileFragmentToAvatarPicker(null, null); - navController.navigate(action); + SafeNavigation.safeNavigate(navController, action); } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/ManageProfileFragment.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/ManageProfileFragment.java index 63fd3c81d..5eaa53777 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/ManageProfileFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/ManageProfileFragment.java @@ -39,6 +39,7 @@ import org.thoughtcrime.securesms.profiles.manage.ManageProfileViewModel.AvatarS import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.NameUtil; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import org.thoughtcrime.securesms.util.views.SimpleProgressDialog; import org.whispersystems.libsignal.util.guava.Optional; @@ -94,15 +95,15 @@ public class ManageProfileFragment extends LoggingFragment { editAvatar.setOnClickListener(v -> onEditAvatarClicked()); this.profileNameContainer.setOnClickListener(v -> { - Navigation.findNavController(v).navigate(ManageProfileFragmentDirections.actionManageProfileName()); + SafeNavigation.safeNavigate(Navigation.findNavController(v), ManageProfileFragmentDirections.actionManageProfileName()); }); this.usernameContainer.setOnClickListener(v -> { - Navigation.findNavController(v).navigate(ManageProfileFragmentDirections.actionManageUsername()); + SafeNavigation.safeNavigate(Navigation.findNavController(v), ManageProfileFragmentDirections.actionManageUsername()); }); this.aboutContainer.setOnClickListener(v -> { - Navigation.findNavController(v).navigate(ManageProfileFragmentDirections.actionManageAbout()); + SafeNavigation.safeNavigate(Navigation.findNavController(v), ManageProfileFragmentDirections.actionManageAbout()); }); getParentFragmentManager().setFragmentResultListener(AvatarPickerFragment.REQUEST_KEY_SELECT_AVATAR, getViewLifecycleOwner(), (key, bundle) -> { @@ -125,7 +126,7 @@ public class ManageProfileFragment extends LoggingFragment { if (Recipient.self().getBadges().isEmpty()) { BecomeASustainerFragment.show(getParentFragmentManager()); } else { - Navigation.findNavController(v).navigate(ManageProfileFragmentDirections.actionManageProfileFragmentToBadgeManageFragment()); + SafeNavigation.safeNavigate(Navigation.findNavController(v), ManageProfileFragmentDirections.actionManageProfileFragmentToBadgeManageFragment()); } }); } else { @@ -256,6 +257,6 @@ public class ManageProfileFragment extends LoggingFragment { } private void onEditAvatarClicked() { - Navigation.findNavController(requireView()).navigate(ManageProfileFragmentDirections.actionManageProfileFragmentToAvatarPicker(null, null)); + SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), ManageProfileFragmentDirections.actionManageProfileFragmentToAvatarPicker(null, null)); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/ChooseBackupFragment.java b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/ChooseBackupFragment.java index 8a97a9077..f076ed11a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/ChooseBackupFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/ChooseBackupFragment.java @@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.database.documents.Document; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.util.BackupUtil; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; public class ChooseBackupFragment extends LoggingFragment { @@ -57,7 +58,7 @@ public class ChooseBackupFragment extends LoggingFragment { restore.setUri(data.getData()); - Navigation.findNavController(requireView()).navigate(restore); + SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), restore); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/EnterPhoneNumberFragment.java b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/EnterPhoneNumberFragment.java index 5011239ca..d3393845b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/EnterPhoneNumberFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/EnterPhoneNumberFragment.java @@ -1,10 +1,5 @@ package org.thoughtcrime.securesms.registration.fragments; -import static org.thoughtcrime.securesms.registration.fragments.RegistrationViewDelegate.setDebugLogSubmitMultiTapView; -import static org.thoughtcrime.securesms.registration.fragments.RegistrationViewDelegate.showConfirmNumberDialogIfTranslated; -import static org.thoughtcrime.securesms.util.CircularProgressButtonUtil.cancelSpinning; -import static org.thoughtcrime.securesms.util.CircularProgressButtonUtil.setSpinning; - import android.content.Context; import android.os.Bundle; import android.text.TextUtils; @@ -43,7 +38,6 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.LoggingFragment; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.components.LabeledEditText; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.registration.VerifyAccountRepository.Mode; import org.thoughtcrime.securesms.registration.util.RegistrationNumberInputController; @@ -54,12 +48,17 @@ import org.thoughtcrime.securesms.util.Dialogs; import org.thoughtcrime.securesms.util.LifecycleDisposable; import org.thoughtcrime.securesms.util.PlayServicesUtil; import org.thoughtcrime.securesms.util.SupportEmailUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.ViewUtil; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.disposables.Disposable; +import static org.thoughtcrime.securesms.registration.fragments.RegistrationViewDelegate.setDebugLogSubmitMultiTapView; +import static org.thoughtcrime.securesms.registration.fragments.RegistrationViewDelegate.showConfirmNumberDialogIfTranslated; +import static org.thoughtcrime.securesms.util.CircularProgressButtonUtil.cancelSpinning; +import static org.thoughtcrime.securesms.util.CircularProgressButtonUtil.setSpinning; + public final class EnterPhoneNumberFragment extends LoggingFragment implements RegistrationNumberInputController.Callbacks { private static final String TAG = Log.tag(EnterPhoneNumberFragment.class); @@ -136,7 +135,7 @@ public final class EnterPhoneNumberFragment extends LoggingFragment implements R @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { if (item.getItemId() == R.id.phone_menu_use_proxy) { - Navigation.findNavController(requireView()).navigate(EnterPhoneNumberFragmentDirections.actionEditProxy()); + SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), EnterPhoneNumberFragmentDirections.actionEditProxy()); return true; } else { return false; @@ -226,13 +225,13 @@ public final class EnterPhoneNumberFragment extends LoggingFragment implements R .observeOn(AndroidSchedulers.mainThread()) .subscribe(processor -> { if (processor.hasResult()) { - navController.navigate(EnterPhoneNumberFragmentDirections.actionEnterVerificationCode()); + SafeNavigation.safeNavigate(navController, EnterPhoneNumberFragmentDirections.actionEnterVerificationCode()); } else if (processor.localRateLimit()) { Log.i(TAG, "Unable to request sms code due to local rate limit"); - navController.navigate(EnterPhoneNumberFragmentDirections.actionEnterVerificationCode()); + SafeNavigation.safeNavigate(navController, EnterPhoneNumberFragmentDirections.actionEnterVerificationCode()); } else if (processor.captchaRequired()) { Log.i(TAG, "Unable to request sms code due to captcha required"); - navController.navigate(EnterPhoneNumberFragmentDirections.actionRequestCaptcha()); + SafeNavigation.safeNavigate(navController, EnterPhoneNumberFragmentDirections.actionRequestCaptcha()); } else if (processor.rateLimit()) { Log.i(TAG, "Unable to request sms code due to rate limit"); Toast.makeText(register.getContext(), R.string.RegistrationActivity_rate_limited_to_service, Toast.LENGTH_LONG).show(); @@ -273,7 +272,7 @@ public final class EnterPhoneNumberFragment extends LoggingFragment implements R @Override public void onPickCountry(@NonNull View view) { - Navigation.findNavController(view).navigate(R.id.action_pickCountry); + SafeNavigation.safeNavigate(Navigation.findNavController(view), R.id.action_pickCountry); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/EnterSmsCodeFragment.java b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/EnterSmsCodeFragment.java index 100d30589..0f109362e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/EnterSmsCodeFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/EnterSmsCodeFragment.java @@ -10,6 +10,7 @@ import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.registration.viewmodel.RegistrationViewModel; import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.concurrent.SimpleTask; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import java.io.IOException; @@ -37,22 +38,22 @@ public final class EnterSmsCodeFragment extends BaseEnterSmsCodeFragment displaySuccess(() -> Navigation.findNavController(requireView()).navigate(EnterSmsCodeFragmentDirections.actionSuccessfulRegistration()))); + }, none -> displaySuccess(() -> SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), EnterSmsCodeFragmentDirections.actionSuccessfulRegistration()))); } @Override protected void navigateToRegistrationLock(long timeRemaining) { - Navigation.findNavController(requireView()) - .navigate(EnterSmsCodeFragmentDirections.actionRequireKbsLockPin(timeRemaining)); + SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), + EnterSmsCodeFragmentDirections.actionRequireKbsLockPin(timeRemaining)); } @Override protected void navigateToCaptcha() { - NavHostFragment.findNavController(this).navigate(EnterSmsCodeFragmentDirections.actionRequestCaptcha()); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), EnterSmsCodeFragmentDirections.actionRequestCaptcha()); } @Override protected void navigateToKbsAccountLocked() { - Navigation.findNavController(requireView()).navigate(RegistrationLockFragmentDirections.actionAccountLocked()); + SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), RegistrationLockFragmentDirections.actionAccountLocked()); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RegistrationLockFragment.java b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RegistrationLockFragment.java index e2eca0b51..976b251ce 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RegistrationLockFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RegistrationLockFragment.java @@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.Stopwatch; import org.thoughtcrime.securesms.util.SupportEmailUtil; import org.thoughtcrime.securesms.util.concurrent.SimpleTask; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import java.io.IOException; import java.util.concurrent.TimeUnit; @@ -38,7 +39,7 @@ public final class RegistrationLockFragment extends BaseRegistrationLockFragment @Override protected void navigateToAccountLocked() { - Navigation.findNavController(requireView()).navigate(RegistrationLockFragmentDirections.actionAccountLocked()); + SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), RegistrationLockFragmentDirections.actionAccountLocked()); } @Override @@ -68,7 +69,7 @@ public final class RegistrationLockFragment extends BaseRegistrationLockFragment return null; }, none -> { cancelSpinning(pinButton); - Navigation.findNavController(requireView()).navigate(RegistrationLockFragmentDirections.actionSuccessfulRegistration()); + SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), RegistrationLockFragmentDirections.actionSuccessfulRegistration()); }); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RestoreBackupFragment.java b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RestoreBackupFragment.java index 9b4ff6e6d..e65488fff 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RestoreBackupFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RestoreBackupFragment.java @@ -55,6 +55,7 @@ import org.thoughtcrime.securesms.util.BackupUtil; import org.thoughtcrime.securesms.util.DateUtils; import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.util.concurrent.SimpleTask; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import java.io.IOException; import java.util.Locale; @@ -97,16 +98,16 @@ public final class RestoreBackupFragment extends LoggingFragment { skipRestoreButton.setOnClickListener((v) -> { Log.i(TAG, "User skipped backup restore."); - Navigation.findNavController(view) - .navigate(RestoreBackupFragmentDirections.actionSkip()); + SafeNavigation.safeNavigate(Navigation.findNavController(view), + RestoreBackupFragmentDirections.actionSkip()); }); viewModel = new ViewModelProvider(requireActivity()).get(RegistrationViewModel.class); if (viewModel.isReregister()) { Log.i(TAG, "Skipping backup restore during re-register."); - Navigation.findNavController(view) - .navigate(RestoreBackupFragmentDirections.actionSkipNoReturn()); + SafeNavigation.safeNavigate(Navigation.findNavController(view), + RestoreBackupFragmentDirections.actionSkipNoReturn()); return; } @@ -117,8 +118,8 @@ public final class RestoreBackupFragment extends LoggingFragment { if (SignalStore.settings().isBackupEnabled()) { Log.i(TAG, "Backups enabled, so a backup must have been previously restored."); - Navigation.findNavController(view) - .navigate(RestoreBackupFragmentDirections.actionSkipNoReturn()); + SafeNavigation.safeNavigate(Navigation.findNavController(view), + RestoreBackupFragmentDirections.actionSkipNoReturn()); return; } @@ -134,8 +135,8 @@ public final class RestoreBackupFragment extends LoggingFragment { initializeBackupDetection(view); } else { Log.i(TAG, "Skipping backup detection. We don't have the permission."); - Navigation.findNavController(view) - .navigate(RestoreBackupFragmentDirections.actionSkipNoReturn()); + SafeNavigation.safeNavigate(Navigation.findNavController(view), + RestoreBackupFragmentDirections.actionSkipNoReturn()); } } @@ -152,8 +153,8 @@ public final class RestoreBackupFragment extends LoggingFragment { enableBackups(requireContext()); - Navigation.findNavController(requireView()) - .navigate(RestoreBackupFragmentDirections.actionBackupRestored()); + SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), + RestoreBackupFragmentDirections.actionBackupRestored()); } } @@ -175,8 +176,8 @@ public final class RestoreBackupFragment extends LoggingFragment { if (backup == null) { Log.i(TAG, "Skipping backup detection. No backup found, or permission revoked since."); - Navigation.findNavController(view) - .navigate(RestoreBackupFragmentDirections.actionNoBackupFound()); + SafeNavigation.safeNavigate(Navigation.findNavController(view), + RestoreBackupFragmentDirections.actionNoBackupFound()); } else { restoreBackupSize.setText(getString(R.string.RegistrationActivity_backup_size_s, Util.getPrettyFileSize(backup.getSize()))); restoreBackupTime.setText(getString(R.string.RegistrationActivity_backup_timestamp_s, DateUtils.getExtendedRelativeTimeSpanString(requireContext(), Locale.getDefault(), backup.getTimestamp()))); @@ -348,8 +349,8 @@ public final class RestoreBackupFragment extends LoggingFragment { if (BackupUtil.isUserSelectionRequired(requireContext()) && !BackupUtil.canUserAccessBackupDirectory(requireContext())) { displayConfirmationDialog(requireContext()); } else { - Navigation.findNavController(requireView()) - .navigate(RestoreBackupFragmentDirections.actionBackupRestored()); + SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), + RestoreBackupFragmentDirections.actionBackupRestored()); } } @@ -379,8 +380,8 @@ public final class RestoreBackupFragment extends LoggingFragment { BackupPassphrase.set(context, null); dialog.dismiss(); - Navigation.findNavController(requireView()) - .navigate(RestoreBackupFragmentDirections.actionBackupRestored()); + SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), + RestoreBackupFragmentDirections.actionBackupRestored()); }) .setCancelable(false) .show(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/WelcomeFragment.java b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/WelcomeFragment.java index 0d7174e9d..4c5a119e5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/WelcomeFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/WelcomeFragment.java @@ -1,9 +1,5 @@ package org.thoughtcrime.securesms.registration.fragments; -import static org.thoughtcrime.securesms.registration.fragments.RegistrationViewDelegate.setDebugLogSubmitMultiTapView; -import static org.thoughtcrime.securesms.util.CircularProgressButtonUtil.cancelSpinning; -import static org.thoughtcrime.securesms.util.CircularProgressButtonUtil.setSpinning; - import android.Manifest; import android.annotation.SuppressLint; import android.content.Context; @@ -43,8 +39,13 @@ import org.thoughtcrime.securesms.util.BackupUtil; import org.thoughtcrime.securesms.util.CommunicationActions; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import org.whispersystems.libsignal.util.guava.Optional; +import static org.thoughtcrime.securesms.registration.fragments.RegistrationViewDelegate.setDebugLogSubmitMultiTapView; +import static org.thoughtcrime.securesms.util.CircularProgressButtonUtil.cancelSpinning; +import static org.thoughtcrime.securesms.util.CircularProgressButtonUtil.setSpinning; + public final class WelcomeFragment extends LoggingFragment { private static final String TAG = Log.tag(WelcomeFragment.class); @@ -101,8 +102,8 @@ public final class WelcomeFragment extends LoggingFragment { Log.i(TAG, "Skipping restore because this is a reregistration."); viewModel.setWelcomeSkippedOnRestore(); - Navigation.findNavController(view) - .navigate(WelcomeFragmentDirections.actionSkipRestore()); + SafeNavigation.safeNavigate(Navigation.findNavController(view), + WelcomeFragmentDirections.actionSkipRestore()); } else { setDebugLogSubmitMultiTapView(view.findViewById(R.id.image)); @@ -133,7 +134,7 @@ public final class WelcomeFragment extends LoggingFragment { super.onResume(); if (EventBus.getDefault().getStickyEvent(TransferStatus.class) != null) { Log.i(TAG, "Found existing transferStatus, redirect to transfer flow"); - NavHostFragment.findNavController(this).navigate(R.id.action_welcomeFragment_to_deviceTransferSetup); + SafeNavigation.safeNavigate(NavHostFragment.findNavController(this), R.id.action_welcomeFragment_to_deviceTransferSetup); } else { DeviceToDeviceTransferService.stop(requireContext()); } @@ -179,11 +180,11 @@ public final class WelcomeFragment extends LoggingFragment { if (backup == null) { Log.i(TAG, "Skipping backup. No backup found, or no permission to look."); - Navigation.findNavController(view) - .navigate(WelcomeFragmentDirections.actionSkipRestore()); + SafeNavigation.safeNavigate(Navigation.findNavController(view), + WelcomeFragmentDirections.actionSkipRestore()); } else { - Navigation.findNavController(view) - .navigate(WelcomeFragmentDirections.actionRestore()); + SafeNavigation.safeNavigate(Navigation.findNavController(view), + WelcomeFragmentDirections.actionRestore()); } }); } @@ -193,8 +194,8 @@ public final class WelcomeFragment extends LoggingFragment { initializeNumber(); - Navigation.findNavController(view) - .navigate(WelcomeFragmentDirections.actionTransferOrRestore()); + SafeNavigation.safeNavigate(Navigation.findNavController(view), + WelcomeFragmentDirections.actionTransferOrRestore()); } @SuppressLint("MissingPermission") diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/navigation/SafeNavigation.kt b/app/src/main/java/org/thoughtcrime/securesms/util/navigation/SafeNavigation.kt new file mode 100644 index 000000000..658456224 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/util/navigation/SafeNavigation.kt @@ -0,0 +1,70 @@ +@file:JvmName("SafeNavigation") + +package org.thoughtcrime.securesms.util.navigation + +import android.content.res.Resources +import android.os.Bundle +import androidx.annotation.IdRes +import androidx.navigation.NavController +import androidx.navigation.NavDirections +import androidx.navigation.NavOptions +import org.signal.core.util.logging.Log +import org.thoughtcrime.securesms.dependencies.ApplicationDependencies + +private const val TAG = "SafeNavigation" + +/** + * Check [currentDestination] has an action with [resId] before attempting to navigate. + */ +fun NavController.safeNavigate(@IdRes resId: Int) { + if (currentDestination?.getAction(resId) != null) { + navigate(resId) + } else { + Log.w(TAG, "Unable to find action ${getDisplayName(resId)} for $currentDestination") + } +} + +/** + * Check [currentDestination] has an action with [resId] before attempting to navigate. + */ +fun NavController.safeNavigate(@IdRes resId: Int, arguments: Bundle?) { + if (currentDestination?.getAction(resId) != null) { + navigate(resId, arguments) + } else { + Log.w(TAG, "Unable to find action ${getDisplayName(resId)} for $currentDestination") + } +} + +/** + * Check [currentDestination] has an action for [directions] before attempting to navigate. + */ +fun NavController.safeNavigate(directions: NavDirections) { + if (currentDestination?.getAction(directions.actionId) != null) { + navigate(directions) + } else { + Log.w(TAG, "Unable to find ${getDisplayName(directions.actionId)} for $currentDestination") + } +} + +/** + * Check [currentDestination] has an action for [directions] before attempting to navigate. + */ +fun NavController.safeNavigate(directions: NavDirections, navOptions: NavOptions?) { + if (currentDestination?.getAction(directions.actionId) != null) { + navigate(directions, navOptions) + } else { + Log.w(TAG, "Unable to find ${getDisplayName(directions.actionId)} for $currentDestination") + } +} + +private fun getDisplayName(id: Int): String? { + return if (id <= 0x00FFFFFF) { + id.toString() + } else { + try { + ApplicationDependencies.getApplication().resources.getResourceName(id) + } catch (e: Resources.NotFoundException) { + id.toString() + } + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/wallpaper/ChatWallpaperFragment.java b/app/src/main/java/org/thoughtcrime/securesms/wallpaper/ChatWallpaperFragment.java index 9aa3de891..16dfedef3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/wallpaper/ChatWallpaperFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/wallpaper/ChatWallpaperFragment.java @@ -31,6 +31,7 @@ import org.thoughtcrime.securesms.util.DisplayMetricsUtil; import org.thoughtcrime.securesms.util.Projection; import org.thoughtcrime.securesms.util.ThemeUtil; import org.thoughtcrime.securesms.util.ViewUtil; +import org.thoughtcrime.securesms.util.navigation.SafeNavigation; import java.util.Collections; @@ -101,10 +102,10 @@ public class ChatWallpaperFragment extends Fragment { }); chatWallpaperPreview.setOnClickListener(unused -> setWallpaper.performClick()); - setWallpaper.setOnClickListener(unused -> Navigation.findNavController(view) - .navigate(R.id.action_chatWallpaperFragment_to_chatWallpaperSelectionFragment)); - setChatColor.setOnClickListener(unused -> Navigation.findNavController(view) - .navigate(ChatWallpaperFragmentDirections.actionChatWallpaperFragmentToChatColorSelectionFragment(viewModel.getRecipientId()))); + setWallpaper.setOnClickListener(unused -> SafeNavigation.safeNavigate(Navigation.findNavController(view), + R.id.action_chatWallpaperFragment_to_chatWallpaperSelectionFragment)); + setChatColor.setOnClickListener(unused -> SafeNavigation.safeNavigate(Navigation.findNavController(view), + ChatWallpaperFragmentDirections.actionChatWallpaperFragmentToChatColorSelectionFragment(viewModel.getRecipientId()))); if (viewModel.isGlobal()) { resetAllWallpaper.setOnClickListener(unused -> {