mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-20 19:18:37 +00:00
Start conversion from Fragment Nav Framework to utilizing a centralized AppSettingsRouter.
This commit is contained in:
committed by
Greyson Parrelli
parent
909ea6b925
commit
23b5a3dcb0
@@ -7,17 +7,18 @@ import androidx.navigation.NavDirections
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import io.reactivex.rxjava3.subjects.PublishSubject
|
||||
import io.reactivex.rxjava3.subjects.Subject
|
||||
import org.signal.core.util.getParcelableExtraCompat
|
||||
import org.signal.donations.InAppPaymentType
|
||||
import org.thoughtcrime.securesms.MainActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsActivity
|
||||
import org.thoughtcrime.securesms.components.settings.app.chats.folders.CreateFoldersFragmentArgs
|
||||
import org.thoughtcrime.securesms.components.settings.app.notifications.profiles.EditNotificationProfileScheduleFragmentArgs
|
||||
import org.thoughtcrime.securesms.components.settings.app.routes.AppSettingsRoute
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.GooglePayComponent
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.GooglePayRepository
|
||||
import org.thoughtcrime.securesms.help.HelpFragment
|
||||
import org.thoughtcrime.securesms.keyvalue.SettingsValues
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.profiles.manage.UsernameEditMode
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.service.KeyCachingService
|
||||
import org.thoughtcrime.securesms.util.CachedInflater
|
||||
@@ -25,8 +26,7 @@ import org.thoughtcrime.securesms.util.DynamicTheme
|
||||
import org.thoughtcrime.securesms.util.SignalE164Util
|
||||
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"
|
||||
private const val START_ROUTE = "app.settings.args.START_ROUTE"
|
||||
private const val NOTIFICATION_CATEGORY = "android.intent.category.NOTIFICATION_PREFERENCES"
|
||||
private const val STATE_WAS_CONFIGURATION_UPDATED = "app.settings.state.configuration.updated"
|
||||
private const val EXTRA_PERFORM_ACTION_ON_CREATE = "extra_perform_action_on_create"
|
||||
@@ -48,42 +48,41 @@ class AppSettingsActivity : DSLSettingsActivity(), GooglePayComponent {
|
||||
val startingAction: NavDirections? = if (intent?.categories?.contains(NOTIFICATION_CATEGORY) == true) {
|
||||
AppSettingsFragmentDirections.actionDirectToNotificationsSettingsFragment()
|
||||
} else {
|
||||
when (StartLocation.fromCode(intent?.getIntExtra(START_LOCATION, StartLocation.HOME.code))) {
|
||||
StartLocation.HOME -> null
|
||||
StartLocation.BACKUPS -> AppSettingsFragmentDirections.actionDirectToBackupsPreferenceFragment()
|
||||
StartLocation.HELP -> AppSettingsFragmentDirections.actionDirectToHelpFragment()
|
||||
.setStartCategoryIndex(intent.getIntExtra(HelpFragment.START_CATEGORY_INDEX, 0))
|
||||
|
||||
StartLocation.PROXY -> AppSettingsFragmentDirections.actionDirectToEditProxyFragment()
|
||||
StartLocation.NOTIFICATIONS -> AppSettingsFragmentDirections.actionDirectToNotificationsSettingsFragment()
|
||||
StartLocation.CHANGE_NUMBER -> AppSettingsFragmentDirections.actionDirectToChangeNumberFragment()
|
||||
StartLocation.SUBSCRIPTIONS -> AppSettingsFragmentDirections.actionDirectToManageDonations().setDirectToCheckoutType(InAppPaymentType.RECURRING_DONATION)
|
||||
StartLocation.BOOST -> AppSettingsFragmentDirections.actionDirectToManageDonations().setDirectToCheckoutType(InAppPaymentType.ONE_TIME_DONATION)
|
||||
StartLocation.MANAGE_SUBSCRIPTIONS -> AppSettingsFragmentDirections.actionDirectToManageDonations()
|
||||
StartLocation.NOTIFICATION_PROFILES -> AppSettingsFragmentDirections.actionDirectToNotificationProfiles()
|
||||
StartLocation.CREATE_NOTIFICATION_PROFILE -> AppSettingsFragmentDirections.actionDirectToCreateNotificationProfiles()
|
||||
StartLocation.NOTIFICATION_PROFILE_DETAILS -> AppSettingsFragmentDirections.actionDirectToNotificationProfileDetails(
|
||||
EditNotificationProfileScheduleFragmentArgs.fromBundle(intent.getBundleExtra(START_ARGUMENTS)!!).profileId
|
||||
val appSettingsRoute: AppSettingsRoute? = intent?.getParcelableExtraCompat(START_ROUTE, AppSettingsRoute::class.java)
|
||||
when (appSettingsRoute) {
|
||||
AppSettingsRoute.Empty -> null
|
||||
AppSettingsRoute.BackupsRoute.Local -> AppSettingsFragmentDirections.actionDirectToBackupsPreferenceFragment()
|
||||
is AppSettingsRoute.HelpRoute.Settings -> AppSettingsFragmentDirections.actionDirectToHelpFragment()
|
||||
.setStartCategoryIndex(appSettingsRoute.startCategoryIndex)
|
||||
AppSettingsRoute.DataAndStorageRoute.Proxy -> AppSettingsFragmentDirections.actionDirectToEditProxyFragment()
|
||||
AppSettingsRoute.NotificationsRoute.Notifications -> AppSettingsFragmentDirections.actionDirectToNotificationsSettingsFragment()
|
||||
AppSettingsRoute.ChangeNumberRoute.Start -> AppSettingsFragmentDirections.actionDirectToChangeNumberFragment()
|
||||
is AppSettingsRoute.DonationsRoute.Donations -> AppSettingsFragmentDirections.actionDirectToManageDonations().setDirectToCheckoutType(appSettingsRoute.directToCheckoutType)
|
||||
AppSettingsRoute.NotificationsRoute.NotificationProfiles -> AppSettingsFragmentDirections.actionDirectToNotificationProfiles()
|
||||
is AppSettingsRoute.NotificationsRoute.EditProfile -> AppSettingsFragmentDirections.actionDirectToCreateNotificationProfiles()
|
||||
is AppSettingsRoute.NotificationsRoute.ProfileDetails -> AppSettingsFragmentDirections.actionDirectToNotificationProfileDetails(
|
||||
appSettingsRoute.profileId
|
||||
)
|
||||
|
||||
StartLocation.PRIVACY -> AppSettingsFragmentDirections.actionDirectToPrivacy()
|
||||
StartLocation.LINKED_DEVICES -> AppSettingsFragmentDirections.actionDirectToDevices()
|
||||
StartLocation.USERNAME_LINK -> AppSettingsFragmentDirections.actionDirectToUsernameLinkSettings()
|
||||
StartLocation.RECOVER_USERNAME -> AppSettingsFragmentDirections.actionDirectToUsernameRecovery()
|
||||
StartLocation.REMOTE_BACKUPS -> AppSettingsFragmentDirections.actionDirectToRemoteBackupsSettingsFragment()
|
||||
StartLocation.CHAT_FOLDERS -> AppSettingsFragmentDirections.actionDirectToChatFoldersFragment()
|
||||
StartLocation.CREATE_CHAT_FOLDER -> AppSettingsFragmentDirections.actionDirectToCreateFoldersFragment(
|
||||
CreateFoldersFragmentArgs.fromBundle(intent.getBundleExtra(START_ARGUMENTS)!!).folderId,
|
||||
CreateFoldersFragmentArgs.fromBundle(intent.getBundleExtra(START_ARGUMENTS)!!).threadIds
|
||||
AppSettingsRoute.PrivacyRoute.Privacy -> AppSettingsFragmentDirections.actionDirectToPrivacy()
|
||||
AppSettingsRoute.LinkDeviceRoute.LinkDevice -> AppSettingsFragmentDirections.actionDirectToDevices()
|
||||
AppSettingsRoute.UsernameLinkRoute.UsernameLink -> AppSettingsFragmentDirections.actionDirectToUsernameLinkSettings()
|
||||
is AppSettingsRoute.AccountRoute.Username -> AppSettingsFragmentDirections.actionDirectToUsernameRecovery()
|
||||
is AppSettingsRoute.BackupsRoute.Remote -> AppSettingsFragmentDirections.actionDirectToRemoteBackupsSettingsFragment()
|
||||
AppSettingsRoute.ChatFoldersRoute.ChatFolders -> AppSettingsFragmentDirections.actionDirectToChatFoldersFragment()
|
||||
is AppSettingsRoute.ChatFoldersRoute.CreateChatFolders -> AppSettingsFragmentDirections.actionDirectToCreateFoldersFragment(
|
||||
appSettingsRoute.folderId,
|
||||
appSettingsRoute.threadIds
|
||||
)
|
||||
|
||||
StartLocation.BACKUPS_SETTINGS -> AppSettingsFragmentDirections.actionDirectToBackupsSettingsFragment()
|
||||
StartLocation.INVITE -> AppSettingsFragmentDirections.actionDirectToInviteFragment()
|
||||
StartLocation.MANAGE_STORAGE -> AppSettingsFragmentDirections.actionDirectToStoragePreferenceFragment()
|
||||
AppSettingsRoute.BackupsRoute.Backups -> AppSettingsFragmentDirections.actionDirectToBackupsSettingsFragment()
|
||||
AppSettingsRoute.Invite -> AppSettingsFragmentDirections.actionDirectToInviteFragment()
|
||||
AppSettingsRoute.DataAndStorageRoute.DataAndStorage -> AppSettingsFragmentDirections.actionDirectToStoragePreferenceFragment()
|
||||
else -> error("Unsupported start location: ${appSettingsRoute?.javaClass?.name}")
|
||||
}
|
||||
}
|
||||
|
||||
intent = intent.putExtra(START_LOCATION, StartLocation.HOME)
|
||||
intent = intent.putExtra(START_ROUTE, AppSettingsRoute.Empty)
|
||||
|
||||
if (startingAction == null && savedInstanceState != null) {
|
||||
wasConfigurationUpdated = savedInstanceState.getBoolean(STATE_WAS_CONFIGURATION_UPDATED)
|
||||
@@ -148,123 +147,89 @@ class AppSettingsActivity : DSLSettingsActivity(), GooglePayComponent {
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun home(context: Context, action: String? = null): Intent {
|
||||
return getIntentForStartLocation(context, StartLocation.HOME)
|
||||
return getIntentForStartLocation(context, AppSettingsRoute.Empty)
|
||||
.putExtra(EXTRA_PERFORM_ACTION_ON_CREATE, action)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun backups(context: Context): Intent = getIntentForStartLocation(context, StartLocation.BACKUPS)
|
||||
fun backups(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.BackupsRoute.Local)
|
||||
|
||||
@JvmStatic
|
||||
fun help(context: Context, startCategoryIndex: Int = 0): Intent {
|
||||
return getIntentForStartLocation(context, StartLocation.HELP)
|
||||
return getIntentForStartLocation(context, AppSettingsRoute.HelpRoute.Settings(startCategoryIndex = startCategoryIndex))
|
||||
.putExtra(HelpFragment.START_CATEGORY_INDEX, startCategoryIndex)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun proxy(context: Context): Intent = getIntentForStartLocation(context, StartLocation.PROXY)
|
||||
fun proxy(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.DataAndStorageRoute.Proxy)
|
||||
|
||||
@JvmStatic
|
||||
fun notifications(context: Context): Intent = getIntentForStartLocation(context, StartLocation.NOTIFICATIONS)
|
||||
fun notifications(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.NotificationsRoute.Notifications)
|
||||
|
||||
@JvmStatic
|
||||
fun changeNumber(context: Context): Intent = getIntentForStartLocation(context, StartLocation.CHANGE_NUMBER)
|
||||
fun changeNumber(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.ChangeNumberRoute.Start)
|
||||
|
||||
@JvmStatic
|
||||
fun subscriptions(context: Context): Intent = getIntentForStartLocation(context, StartLocation.SUBSCRIPTIONS)
|
||||
fun subscriptions(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.DonationsRoute.Donations(directToCheckoutType = InAppPaymentType.RECURRING_DONATION))
|
||||
|
||||
@JvmStatic
|
||||
fun boost(context: Context): Intent = getIntentForStartLocation(context, StartLocation.BOOST)
|
||||
fun boost(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.DonationsRoute.Donations(directToCheckoutType = InAppPaymentType.ONE_TIME_DONATION))
|
||||
|
||||
@JvmStatic
|
||||
fun manageSubscriptions(context: Context): Intent = getIntentForStartLocation(context, StartLocation.MANAGE_SUBSCRIPTIONS)
|
||||
fun manageSubscriptions(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.DonationsRoute.Donations())
|
||||
|
||||
fun manageStorage(context: Context): Intent = getIntentForStartLocation(context, StartLocation.MANAGE_STORAGE)
|
||||
fun manageStorage(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.DataAndStorageRoute.DataAndStorage)
|
||||
|
||||
@JvmStatic
|
||||
fun notificationProfiles(context: Context): Intent = getIntentForStartLocation(context, StartLocation.NOTIFICATION_PROFILES)
|
||||
fun notificationProfiles(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.NotificationsRoute.NotificationProfiles)
|
||||
|
||||
@JvmStatic
|
||||
fun createNotificationProfile(context: Context): Intent = getIntentForStartLocation(context, StartLocation.CREATE_NOTIFICATION_PROFILE)
|
||||
fun createNotificationProfile(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.NotificationsRoute.EditProfile())
|
||||
|
||||
@JvmStatic
|
||||
fun privacy(context: Context): Intent = getIntentForStartLocation(context, StartLocation.PRIVACY)
|
||||
fun privacy(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.PrivacyRoute.Privacy)
|
||||
|
||||
@JvmStatic
|
||||
fun notificationProfileDetails(context: Context, profileId: Long): Intent {
|
||||
val arguments = EditNotificationProfileScheduleFragmentArgs.Builder(profileId, false)
|
||||
.build()
|
||||
.toBundle()
|
||||
|
||||
return getIntentForStartLocation(context, StartLocation.NOTIFICATION_PROFILE_DETAILS)
|
||||
.putExtra(START_ARGUMENTS, arguments)
|
||||
return getIntentForStartLocation(context, AppSettingsRoute.NotificationsRoute.ProfileDetails(profileId = profileId))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun linkedDevices(context: Context): Intent = getIntentForStartLocation(context, StartLocation.LINKED_DEVICES)
|
||||
fun linkedDevices(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.LinkDeviceRoute.LinkDevice)
|
||||
|
||||
@JvmStatic
|
||||
fun usernameLinkSettings(context: Context): Intent = getIntentForStartLocation(context, StartLocation.USERNAME_LINK)
|
||||
fun usernameLinkSettings(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.UsernameLinkRoute.UsernameLink)
|
||||
|
||||
@JvmStatic
|
||||
fun usernameRecovery(context: Context): Intent = getIntentForStartLocation(context, StartLocation.RECOVER_USERNAME)
|
||||
fun usernameRecovery(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.AccountRoute.Username(mode = UsernameEditMode.RECOVERY))
|
||||
|
||||
@JvmStatic
|
||||
fun remoteBackups(context: Context): Intent = getIntentForStartLocation(context, StartLocation.REMOTE_BACKUPS)
|
||||
fun remoteBackups(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.BackupsRoute.Remote())
|
||||
|
||||
@JvmStatic
|
||||
fun chatFolders(context: Context): Intent = getIntentForStartLocation(context, StartLocation.CHAT_FOLDERS)
|
||||
fun chatFolders(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.ChatFoldersRoute.ChatFolders)
|
||||
|
||||
@JvmStatic
|
||||
fun createChatFolder(context: Context, id: Long = -1, threadIds: LongArray?): Intent {
|
||||
val arguments = CreateFoldersFragmentArgs.Builder(id, threadIds ?: longArrayOf())
|
||||
.build()
|
||||
.toBundle()
|
||||
|
||||
return getIntentForStartLocation(context, StartLocation.CREATE_CHAT_FOLDER).putExtra(START_ARGUMENTS, arguments)
|
||||
return getIntentForStartLocation(
|
||||
context,
|
||||
AppSettingsRoute.ChatFoldersRoute.CreateChatFolders(
|
||||
folderId = id,
|
||||
threadIds = threadIds ?: longArrayOf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun backupsSettings(context: Context): Intent = getIntentForStartLocation(context, StartLocation.BACKUPS_SETTINGS)
|
||||
fun backupsSettings(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.BackupsRoute.Backups)
|
||||
|
||||
@JvmStatic
|
||||
fun invite(context: Context): Intent = getIntentForStartLocation(context, StartLocation.INVITE)
|
||||
fun invite(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.Invite)
|
||||
|
||||
private fun getIntentForStartLocation(context: Context, startLocation: StartLocation): Intent {
|
||||
private fun getIntentForStartLocation(context: Context, startRoute: AppSettingsRoute): Intent {
|
||||
return Intent(context, AppSettingsActivity::class.java)
|
||||
.putExtra(ARG_NAV_GRAPH, R.navigation.app_settings_with_change_number)
|
||||
.putExtra(START_LOCATION, startLocation.code)
|
||||
}
|
||||
}
|
||||
|
||||
private enum class StartLocation(val code: Int) {
|
||||
HOME(0),
|
||||
BACKUPS(1),
|
||||
HELP(2),
|
||||
PROXY(3),
|
||||
NOTIFICATIONS(4),
|
||||
CHANGE_NUMBER(5),
|
||||
SUBSCRIPTIONS(6),
|
||||
BOOST(7),
|
||||
MANAGE_SUBSCRIPTIONS(8),
|
||||
NOTIFICATION_PROFILES(9),
|
||||
CREATE_NOTIFICATION_PROFILE(10),
|
||||
NOTIFICATION_PROFILE_DETAILS(11),
|
||||
PRIVACY(12),
|
||||
LINKED_DEVICES(13),
|
||||
USERNAME_LINK(14),
|
||||
RECOVER_USERNAME(15),
|
||||
REMOTE_BACKUPS(16),
|
||||
CHAT_FOLDERS(17),
|
||||
CREATE_CHAT_FOLDER(18),
|
||||
BACKUPS_SETTINGS(19),
|
||||
INVITE(20),
|
||||
MANAGE_STORAGE(21);
|
||||
|
||||
companion object {
|
||||
fun fromCode(code: Int?): StartLocation {
|
||||
return entries.find { code == it.code } ?: HOME
|
||||
}
|
||||
.putExtra(START_ROUTE, startRoute)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.components.settings.app
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
@@ -39,8 +38,9 @@ import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.NavDirections
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@@ -67,6 +67,8 @@ import org.thoughtcrime.securesms.banner.ui.compose.DefaultBanner
|
||||
import org.thoughtcrime.securesms.banner.ui.compose.Importance
|
||||
import org.thoughtcrime.securesms.components.compose.TextWithBetaLabel
|
||||
import org.thoughtcrime.securesms.components.emoji.Emojifier
|
||||
import org.thoughtcrime.securesms.components.settings.app.routes.AppSettingsRoute
|
||||
import org.thoughtcrime.securesms.components.settings.app.routes.AppSettingsRouter
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.BadgeImageMedium
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaymentsRepository
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.completed.InAppPaymentsBottomSheetDelegate
|
||||
@@ -83,9 +85,38 @@ import org.thoughtcrime.securesms.util.navigation.safeNavigate
|
||||
class AppSettingsFragment : ComposeFragment(), Callbacks {
|
||||
|
||||
private val viewModel: AppSettingsViewModel by viewModels()
|
||||
private val appSettingsRouter by viewModels<AppSettingsRouter>()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
viewLifecycleOwner.lifecycle.addObserver(InAppPaymentsBottomSheetDelegate(childFragmentManager, viewLifecycleOwner))
|
||||
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||
appSettingsRouter.currentRoute.collect { route ->
|
||||
when (route) {
|
||||
is AppSettingsRoute.BackupsRoute.Remote -> findNavController().safeNavigate(R.id.action_appSettingsFragment_to_remoteBackupsSettingsFragment)
|
||||
is AppSettingsRoute.AccountRoute.Account -> findNavController().safeNavigate(R.id.action_appSettingsFragment_to_accountSettingsFragment)
|
||||
is AppSettingsRoute.LinkDeviceRoute.LinkDevice -> findNavController().safeNavigate(R.id.action_appSettingsFragment_to_linkDeviceFragment)
|
||||
is AppSettingsRoute.DonationsRoute.Donations -> findNavController().safeNavigate(R.id.action_appSettingsFragment_to_manageDonationsFragment)
|
||||
is AppSettingsRoute.AppearanceRoute.Appearance -> findNavController().safeNavigate(R.id.action_appSettingsFragment_to_appearanceSettingsFragment)
|
||||
is AppSettingsRoute.ChatsRoute.Chats -> findNavController().safeNavigate(R.id.action_appSettingsFragment_to_chatsSettingsFragment)
|
||||
is AppSettingsRoute.StoriesRoute.Privacy -> findNavController().safeNavigate(AppSettingsFragmentDirections.actionAppSettingsFragmentToStoryPrivacySettings(route.titleId))
|
||||
is AppSettingsRoute.NotificationsRoute.Notifications -> findNavController().safeNavigate(R.id.action_appSettingsFragment_to_notificationsSettingsFragment)
|
||||
is AppSettingsRoute.PrivacyRoute.Privacy -> findNavController().safeNavigate(R.id.action_appSettingsFragment_to_privacySettingsFragment)
|
||||
is AppSettingsRoute.BackupsRoute.Backups -> findNavController().safeNavigate(R.id.action_appSettingsFragment_to_backupsSettingsFragment)
|
||||
is AppSettingsRoute.DataAndStorageRoute.DataAndStorage -> findNavController().safeNavigate(R.id.action_appSettingsFragment_to_dataAndStorageSettingsFragment)
|
||||
is AppSettingsRoute.AppUpdates -> findNavController().safeNavigate(R.id.action_appSettingsFragment_to_appUpdatesSettingsFragment)
|
||||
is AppSettingsRoute.Payments -> findNavController().safeNavigate(R.id.action_appSettingsFragment_to_paymentsActivity)
|
||||
is AppSettingsRoute.HelpRoute.Settings -> findNavController().safeNavigate(R.id.action_appSettingsFragment_to_helpSettingsFragment)
|
||||
is AppSettingsRoute.Invite -> findNavController().safeNavigate(R.id.action_appSettingsFragment_to_inviteFragment)
|
||||
is AppSettingsRoute.InternalRoute.Internal -> findNavController().safeNavigate(R.id.action_appSettingsFragment_to_internalSettingsFragment)
|
||||
is AppSettingsRoute.AccountRoute.ManageProfile -> findNavController().safeNavigate(R.id.action_appSettingsFragment_to_manageProfileActivity)
|
||||
is AppSettingsRoute.UsernameLinkRoute.UsernameLink -> findNavController().safeNavigate(R.id.action_appSettingsFragment_to_usernameLinkSettingsFragment)
|
||||
else -> error("Unsupported route: ${route.javaClass.name}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -118,12 +149,8 @@ class AppSettingsFragment : ComposeFragment(), Callbacks {
|
||||
requireActivity().finishAfterTransition()
|
||||
}
|
||||
|
||||
override fun navigate(actionId: Int) {
|
||||
findNavController().safeNavigate(actionId)
|
||||
}
|
||||
|
||||
override fun navigate(directions: NavDirections) {
|
||||
findNavController().safeNavigate(directions)
|
||||
override fun navigate(route: AppSettingsRoute) {
|
||||
appSettingsRouter.navigateTo(route)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
@@ -203,7 +230,7 @@ private fun AppSettingsContent(
|
||||
BackupsWarningRow(
|
||||
text = stringResource(R.string.AppSettingsFragment__renew_your_signal_backups_subscription),
|
||||
onClick = {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_remoteBackupsSettingsFragment)
|
||||
callbacks.navigate(AppSettingsRoute.BackupsRoute.Remote())
|
||||
}
|
||||
)
|
||||
|
||||
@@ -219,7 +246,7 @@ private fun AppSettingsContent(
|
||||
text = stringResource(R.string.AppSettingsFragment__couldnt_complete_backup),
|
||||
onClick = {
|
||||
BackupRepository.markBackupFailedIndicatorClicked()
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_remoteBackupsSettingsFragment)
|
||||
callbacks.navigate(AppSettingsRoute.BackupsRoute.Remote())
|
||||
}
|
||||
)
|
||||
|
||||
@@ -235,7 +262,7 @@ private fun AppSettingsContent(
|
||||
text = stringResource(R.string.AppSettingsFragment__couldnt_redeem_your_backups_subscription),
|
||||
onClick = {
|
||||
BackupRepository.markBackupAlreadyRedeemedIndicatorClicked()
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_remoteBackupsSettingsFragment)
|
||||
callbacks.navigate(AppSettingsRoute.BackupsRoute.Remote())
|
||||
}
|
||||
)
|
||||
|
||||
@@ -252,7 +279,7 @@ private fun AppSettingsContent(
|
||||
icon = ImageVector.vectorResource(R.drawable.symbol_error_circle_fill_24),
|
||||
iconTint = MaterialTheme.colorScheme.error,
|
||||
onClick = {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_remoteBackupsSettingsFragment)
|
||||
callbacks.navigate(AppSettingsRoute.BackupsRoute.Remote())
|
||||
}
|
||||
)
|
||||
|
||||
@@ -268,7 +295,7 @@ private fun AppSettingsContent(
|
||||
text = stringResource(R.string.AccountSettingsFragment__account),
|
||||
icon = painterResource(R.drawable.symbol_person_circle_24),
|
||||
onClick = {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_accountSettingsFragment)
|
||||
callbacks.navigate(AppSettingsRoute.AccountRoute.Account)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -278,7 +305,7 @@ private fun AppSettingsContent(
|
||||
text = stringResource(R.string.preferences__linked_devices),
|
||||
icon = painterResource(R.drawable.symbol_devices_24),
|
||||
onClick = {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_linkDeviceFragment)
|
||||
callbacks.navigate(AppSettingsRoute.LinkDeviceRoute.LinkDevice)
|
||||
},
|
||||
enabled = isRegisteredAndUpToDate
|
||||
)
|
||||
@@ -312,7 +339,7 @@ private fun AppSettingsContent(
|
||||
},
|
||||
onClick = {
|
||||
if (state.allowUserToGoToDonationManagementScreen) {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_manageDonationsFragment)
|
||||
callbacks.navigate(AppSettingsRoute.DonationsRoute.Donations())
|
||||
} else {
|
||||
CommunicationActions.openBrowserLink(context, donateUrl)
|
||||
}
|
||||
@@ -332,7 +359,7 @@ private fun AppSettingsContent(
|
||||
text = stringResource(R.string.preferences__appearance),
|
||||
icon = painterResource(R.drawable.symbol_appearance_24),
|
||||
onClick = {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_appearanceSettingsFragment)
|
||||
callbacks.navigate(AppSettingsRoute.AppearanceRoute.Appearance)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -342,7 +369,7 @@ private fun AppSettingsContent(
|
||||
text = stringResource(R.string.preferences_chats__chats),
|
||||
icon = painterResource(R.drawable.symbol_chat_24),
|
||||
onClick = {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_chatsSettingsFragment)
|
||||
callbacks.navigate(AppSettingsRoute.ChatsRoute.Chats)
|
||||
},
|
||||
enabled = state.legacyLocalBackupsEnabled || isRegisteredAndUpToDate
|
||||
)
|
||||
@@ -353,7 +380,7 @@ private fun AppSettingsContent(
|
||||
text = stringResource(R.string.preferences__stories),
|
||||
icon = painterResource(R.drawable.symbol_stories_24),
|
||||
onClick = {
|
||||
callbacks.navigate(AppSettingsFragmentDirections.actionAppSettingsFragmentToStoryPrivacySettings(R.string.preferences__stories))
|
||||
callbacks.navigate(AppSettingsRoute.StoriesRoute.Privacy(titleId = R.string.preferences__stories))
|
||||
},
|
||||
enabled = isRegisteredAndUpToDate
|
||||
)
|
||||
@@ -364,7 +391,7 @@ private fun AppSettingsContent(
|
||||
text = stringResource(R.string.preferences__notifications),
|
||||
icon = painterResource(R.drawable.symbol_bell_24),
|
||||
onClick = {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_notificationsSettingsFragment)
|
||||
callbacks.navigate(AppSettingsRoute.NotificationsRoute.Notifications)
|
||||
},
|
||||
enabled = isRegisteredAndUpToDate
|
||||
)
|
||||
@@ -375,7 +402,7 @@ private fun AppSettingsContent(
|
||||
text = stringResource(R.string.preferences__privacy),
|
||||
icon = painterResource(R.drawable.symbol_lock_24),
|
||||
onClick = {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_privacySettingsFragment)
|
||||
callbacks.navigate(AppSettingsRoute.PrivacyRoute.Privacy)
|
||||
},
|
||||
enabled = isRegisteredAndUpToDate
|
||||
)
|
||||
@@ -398,7 +425,7 @@ private fun AppSettingsContent(
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_backupsSettingsFragment)
|
||||
callbacks.navigate(AppSettingsRoute.BackupsRoute.Backups)
|
||||
},
|
||||
onLongClick = {
|
||||
callbacks.copyRemoteBackupsSubscriberIdToClipboard()
|
||||
@@ -413,7 +440,7 @@ private fun AppSettingsContent(
|
||||
text = stringResource(R.string.preferences__data_and_storage),
|
||||
icon = painterResource(R.drawable.symbol_data_24),
|
||||
onClick = {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_dataAndStorageSettingsFragment)
|
||||
callbacks.navigate(AppSettingsRoute.DataAndStorageRoute.DataAndStorage)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -424,7 +451,7 @@ private fun AppSettingsContent(
|
||||
text = "App updates",
|
||||
icon = painterResource(R.drawable.symbol_calendar_24),
|
||||
onClick = {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_appUpdatesSettingsFragment)
|
||||
callbacks.navigate(AppSettingsRoute.AppUpdates)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -467,7 +494,7 @@ private fun AppSettingsContent(
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_paymentsActivity)
|
||||
callbacks.navigate(AppSettingsRoute.Payments)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -482,7 +509,7 @@ private fun AppSettingsContent(
|
||||
text = stringResource(R.string.preferences__help),
|
||||
icon = painterResource(R.drawable.symbol_help_24),
|
||||
onClick = {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_helpSettingsFragment)
|
||||
callbacks.navigate(AppSettingsRoute.HelpRoute.Settings())
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -492,7 +519,7 @@ private fun AppSettingsContent(
|
||||
text = stringResource(R.string.AppSettingsFragment__invite_your_friends),
|
||||
icon = painterResource(R.drawable.symbol_invite_24),
|
||||
onClick = {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_inviteFragment)
|
||||
callbacks.navigate(AppSettingsRoute.Invite)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -506,7 +533,7 @@ private fun AppSettingsContent(
|
||||
Rows.TextRow(
|
||||
text = stringResource(R.string.preferences__internal_preferences),
|
||||
onClick = {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_internalSettingsFragment)
|
||||
callbacks.navigate(AppSettingsRoute.InternalRoute.Internal)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -558,7 +585,7 @@ private fun BioRow(
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
onClick = {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_manageProfileActivity)
|
||||
callbacks.navigate(AppSettingsRoute.AccountRoute.ManageProfile)
|
||||
}
|
||||
)
|
||||
.horizontalGutters()
|
||||
@@ -632,7 +659,7 @@ private fun BioRow(
|
||||
if (hasUsername) {
|
||||
IconButtons.IconButton(
|
||||
onClick = {
|
||||
callbacks.navigate(R.id.action_appSettingsFragment_to_usernameLinkSettingsFragment)
|
||||
callbacks.navigate(AppSettingsRoute.UsernameLinkRoute.UsernameLink)
|
||||
},
|
||||
size = 36.dp,
|
||||
colors = IconButtons.iconButtonColors(
|
||||
@@ -711,8 +738,7 @@ private fun BioRowPreview() {
|
||||
|
||||
private interface Callbacks {
|
||||
fun onNavigationClick(): Unit = error("Not implemented.")
|
||||
fun navigate(@IdRes actionId: Int): Unit = error("Not implemented")
|
||||
fun navigate(directions: NavDirections): Unit = error("Not implemented")
|
||||
fun navigate(route: AppSettingsRoute): Unit = error("Not implemented")
|
||||
fun copyDonorBadgeSubscriberIdToClipboard(): Unit = error("Not implemented")
|
||||
fun copyRemoteBackupsSubscriberIdToClipboard(): Unit = error("Not implemented")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright 2025 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.components.settings.app.routes
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.annotation.StringRes
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.signal.donations.InAppPaymentType
|
||||
import org.thoughtcrime.securesms.database.model.DistributionListId
|
||||
import org.thoughtcrime.securesms.groups.ParcelableGroupId
|
||||
import org.thoughtcrime.securesms.profiles.manage.UsernameEditMode
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
|
||||
/**
|
||||
* Describes a route that the AppSettings screen can open. Every route listed here is displayed in
|
||||
* the PRIMARY (detail) pane of the AppSettingsScreen.
|
||||
*/
|
||||
@Parcelize
|
||||
sealed interface AppSettingsRoute : Parcelable {
|
||||
/**
|
||||
* Empty state, displayed when there is no current route. In this case, the "top" of our
|
||||
* scaffold navigator should be the SECONDARY (list) pane.
|
||||
*/
|
||||
data object Empty : AppSettingsRoute
|
||||
|
||||
@Parcelize
|
||||
sealed interface AccountRoute : AppSettingsRoute {
|
||||
data object Account : AccountRoute
|
||||
data object ManageProfile : AccountRoute
|
||||
data object AdvancedPinSettings : AccountRoute
|
||||
data object DeleteAccount : AccountRoute
|
||||
data object ExportAccountData : AccountRoute
|
||||
data object OldDeviceTransfer : AccountRoute
|
||||
data class Username(val mode: UsernameEditMode = UsernameEditMode.NORMAL) : AccountRoute
|
||||
}
|
||||
|
||||
data object Payments : AppSettingsRoute
|
||||
data object Invite : AppSettingsRoute
|
||||
data object AppUpdates : AppSettingsRoute
|
||||
|
||||
@Parcelize
|
||||
sealed interface StoriesRoute : AppSettingsRoute {
|
||||
data class Privacy(@StringRes val titleId: Int) : StoriesRoute
|
||||
data object MyStory : StoriesRoute
|
||||
data class PrivateStory(val distributionListId: DistributionListId) : StoriesRoute
|
||||
data class GroupStory(val groupId: ParcelableGroupId) : StoriesRoute
|
||||
data object OnlyShareWith : StoriesRoute
|
||||
data object AllExcept : StoriesRoute
|
||||
data object SignalConnections : StoriesRoute
|
||||
data class EditName(val distributionListId: DistributionListId, val name: String) : StoriesRoute
|
||||
data class AddViewers(val distributionListId: DistributionListId) : StoriesRoute
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
sealed interface UsernameLinkRoute : AppSettingsRoute {
|
||||
data object UsernameLink : UsernameLinkRoute
|
||||
data object QRColorPicker : UsernameLinkRoute
|
||||
data object Share : UsernameLinkRoute
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
sealed interface BackupsRoute : AppSettingsRoute {
|
||||
data object Backups : BackupsRoute
|
||||
data object Local : BackupsRoute
|
||||
data class Remote(val backupLaterSelected: Boolean = false) : BackupsRoute
|
||||
data object DisplayKey : BackupsRoute
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
sealed interface NotificationsRoute : AppSettingsRoute {
|
||||
data object Notifications : NotificationsRoute
|
||||
data object NotificationProfiles : NotificationsRoute
|
||||
data class EditProfile(val profileId: Long = -1L) : NotificationsRoute
|
||||
data class ProfileDetails(val profileId: Long) : NotificationsRoute
|
||||
data class AddAllowedMembers(val profileId: Long) : NotificationsRoute
|
||||
|
||||
data class SelectRecipients(val profileId: Long, val currentSelection: Array<RecipientId>? = null) : NotificationsRoute {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as SelectRecipients
|
||||
|
||||
if (profileId != other.profileId) return false
|
||||
if (!currentSelection.contentEquals(other.currentSelection)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = profileId.hashCode()
|
||||
result = 31 * result + (currentSelection?.contentHashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
data class EditSchedule(val profileId: Long, val createMode: Boolean) : NotificationsRoute
|
||||
data class Created(val profileId: Long) : NotificationsRoute
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
sealed interface DonationsRoute : AppSettingsRoute {
|
||||
data class Donations(
|
||||
val directToCheckoutType: InAppPaymentType = InAppPaymentType.UNKNOWN
|
||||
) : DonationsRoute
|
||||
|
||||
data object Badges : DonationsRoute
|
||||
data object Receipts : DonationsRoute
|
||||
data class Receipt(val id: Long) : DonationsRoute
|
||||
data object LearnMore : DonationsRoute
|
||||
data object Featured : DonationsRoute
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
sealed interface InternalRoute : AppSettingsRoute {
|
||||
data object Internal : InternalRoute
|
||||
data object DonorErrorConfiguration : InternalRoute
|
||||
data object StoryDialogs : InternalRoute
|
||||
data object Search : InternalRoute
|
||||
data object SvrPlayground : InternalRoute
|
||||
data object ChatSpringboard : InternalRoute
|
||||
data object OneTimeDonationConfiguration : InternalRoute
|
||||
data object TerminalDonationConfiguration : InternalRoute
|
||||
data object BackupPlayground : InternalRoute
|
||||
data object StorageServicePlayground : InternalRoute
|
||||
data object SqlitePlayground : InternalRoute
|
||||
data object ConversationTestFragment : InternalRoute
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
sealed interface PrivacyRoute : AppSettingsRoute {
|
||||
data object Privacy : PrivacyRoute
|
||||
data object BlockedUsers : PrivacyRoute
|
||||
data object Advanced : PrivacyRoute
|
||||
data object ExpiringMessages : PrivacyRoute
|
||||
data object PhoneNumberPrivacy : PrivacyRoute
|
||||
data object ScreenLock : PrivacyRoute
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
sealed interface DataAndStorageRoute : AppSettingsRoute {
|
||||
data object DataAndStorage : DataAndStorageRoute
|
||||
data object Storage : DataAndStorageRoute
|
||||
data object Proxy : DataAndStorageRoute
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
sealed interface HelpRoute : AppSettingsRoute {
|
||||
data class Settings(
|
||||
val startCategoryIndex: Int = 0
|
||||
) : HelpRoute
|
||||
|
||||
data object Help : HelpRoute
|
||||
data object DebugLog : HelpRoute
|
||||
data object Licenses : HelpRoute
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
sealed interface AppearanceRoute : AppSettingsRoute {
|
||||
data object Appearance : AppearanceRoute
|
||||
data object Wallpaper : AppearanceRoute
|
||||
data object AppIconSelection : AppearanceRoute
|
||||
data object AppIconTutorial : AppearanceRoute
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
sealed interface ChatsRoute : AppSettingsRoute {
|
||||
data object Chats : ChatsRoute
|
||||
data object Reactions : ChatsRoute
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
sealed interface ChatFoldersRoute : AppSettingsRoute {
|
||||
data object ChatFolders : ChatFoldersRoute
|
||||
|
||||
data class CreateChatFolders(
|
||||
val folderId: Long,
|
||||
val threadIds: LongArray
|
||||
) : ChatFoldersRoute {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as CreateChatFolders
|
||||
|
||||
if (folderId != other.folderId) return false
|
||||
if (!threadIds.contentEquals(other.threadIds)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = folderId.hashCode()
|
||||
result = 31 * result + threadIds.contentHashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
data object Education : ChatFoldersRoute
|
||||
data object ChooseChats : ChatFoldersRoute
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
sealed interface LinkDeviceRoute : AppSettingsRoute {
|
||||
data object LinkDevice : LinkDeviceRoute
|
||||
data object Finished : LinkDeviceRoute
|
||||
data object LearnMore : LinkDeviceRoute
|
||||
data object Education : LinkDeviceRoute
|
||||
data object EditName : LinkDeviceRoute
|
||||
data object Add : LinkDeviceRoute
|
||||
data object Intro : LinkDeviceRoute
|
||||
data object Sync : LinkDeviceRoute
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
sealed interface ChangeNumberRoute : AppSettingsRoute {
|
||||
data object Start : ChangeNumberRoute
|
||||
data object EnterPhoneNumber : ChangeNumberRoute
|
||||
data object Confirm : ChangeNumberRoute
|
||||
data object CountryPicker : ChangeNumberRoute
|
||||
data object Verify : ChangeNumberRoute
|
||||
data object Captcha : ChangeNumberRoute
|
||||
data object EnterCode : ChangeNumberRoute
|
||||
data object RegistrationLock : ChangeNumberRoute
|
||||
data object AccountLocked : ChangeNumberRoute
|
||||
data object PinDiffers : ChangeNumberRoute
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2025 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.components.settings.app.routes
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* Router which manages what screen we are displaying in app settings. Underneath, this is a ViewModel
|
||||
* that is tied to the top-level parent, so that all screens throughout the app settings can access it.
|
||||
*
|
||||
* This gives a single point to navigate to a new page, but assumes that the actual backstack of routes
|
||||
* will be handled elsewhere. This just emits routing requests.
|
||||
*/
|
||||
class AppSettingsRouter() : ViewModel() {
|
||||
|
||||
val currentRoute = MutableSharedFlow<AppSettingsRoute>()
|
||||
|
||||
fun navigateTo(route: AppSettingsRoute) {
|
||||
viewModelScope.launch {
|
||||
currentRoute.emit(route)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user