mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-21 03:28:47 +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 com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import io.reactivex.rxjava3.subjects.PublishSubject
|
import io.reactivex.rxjava3.subjects.PublishSubject
|
||||||
import io.reactivex.rxjava3.subjects.Subject
|
import io.reactivex.rxjava3.subjects.Subject
|
||||||
|
import org.signal.core.util.getParcelableExtraCompat
|
||||||
import org.signal.donations.InAppPaymentType
|
import org.signal.donations.InAppPaymentType
|
||||||
import org.thoughtcrime.securesms.MainActivity
|
import org.thoughtcrime.securesms.MainActivity
|
||||||
import org.thoughtcrime.securesms.R
|
import org.thoughtcrime.securesms.R
|
||||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsActivity
|
import org.thoughtcrime.securesms.components.settings.DSLSettingsActivity
|
||||||
import org.thoughtcrime.securesms.components.settings.app.chats.folders.CreateFoldersFragmentArgs
|
import org.thoughtcrime.securesms.components.settings.app.routes.AppSettingsRoute
|
||||||
import org.thoughtcrime.securesms.components.settings.app.notifications.profiles.EditNotificationProfileScheduleFragmentArgs
|
|
||||||
import org.thoughtcrime.securesms.components.settings.app.subscription.GooglePayComponent
|
import org.thoughtcrime.securesms.components.settings.app.subscription.GooglePayComponent
|
||||||
import org.thoughtcrime.securesms.components.settings.app.subscription.GooglePayRepository
|
import org.thoughtcrime.securesms.components.settings.app.subscription.GooglePayRepository
|
||||||
import org.thoughtcrime.securesms.help.HelpFragment
|
import org.thoughtcrime.securesms.help.HelpFragment
|
||||||
import org.thoughtcrime.securesms.keyvalue.SettingsValues
|
import org.thoughtcrime.securesms.keyvalue.SettingsValues
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||||
|
import org.thoughtcrime.securesms.profiles.manage.UsernameEditMode
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient
|
import org.thoughtcrime.securesms.recipients.Recipient
|
||||||
import org.thoughtcrime.securesms.service.KeyCachingService
|
import org.thoughtcrime.securesms.service.KeyCachingService
|
||||||
import org.thoughtcrime.securesms.util.CachedInflater
|
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.SignalE164Util
|
||||||
import org.thoughtcrime.securesms.util.navigation.safeNavigate
|
import org.thoughtcrime.securesms.util.navigation.safeNavigate
|
||||||
|
|
||||||
private const val START_LOCATION = "app.settings.start.location"
|
private const val START_ROUTE = "app.settings.args.START_ROUTE"
|
||||||
private const val START_ARGUMENTS = "app.settings.start.arguments"
|
|
||||||
private const val NOTIFICATION_CATEGORY = "android.intent.category.NOTIFICATION_PREFERENCES"
|
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 STATE_WAS_CONFIGURATION_UPDATED = "app.settings.state.configuration.updated"
|
||||||
private const val EXTRA_PERFORM_ACTION_ON_CREATE = "extra_perform_action_on_create"
|
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) {
|
val startingAction: NavDirections? = if (intent?.categories?.contains(NOTIFICATION_CATEGORY) == true) {
|
||||||
AppSettingsFragmentDirections.actionDirectToNotificationsSettingsFragment()
|
AppSettingsFragmentDirections.actionDirectToNotificationsSettingsFragment()
|
||||||
} else {
|
} else {
|
||||||
when (StartLocation.fromCode(intent?.getIntExtra(START_LOCATION, StartLocation.HOME.code))) {
|
val appSettingsRoute: AppSettingsRoute? = intent?.getParcelableExtraCompat(START_ROUTE, AppSettingsRoute::class.java)
|
||||||
StartLocation.HOME -> null
|
when (appSettingsRoute) {
|
||||||
StartLocation.BACKUPS -> AppSettingsFragmentDirections.actionDirectToBackupsPreferenceFragment()
|
AppSettingsRoute.Empty -> null
|
||||||
StartLocation.HELP -> AppSettingsFragmentDirections.actionDirectToHelpFragment()
|
AppSettingsRoute.BackupsRoute.Local -> AppSettingsFragmentDirections.actionDirectToBackupsPreferenceFragment()
|
||||||
.setStartCategoryIndex(intent.getIntExtra(HelpFragment.START_CATEGORY_INDEX, 0))
|
is AppSettingsRoute.HelpRoute.Settings -> AppSettingsFragmentDirections.actionDirectToHelpFragment()
|
||||||
|
.setStartCategoryIndex(appSettingsRoute.startCategoryIndex)
|
||||||
StartLocation.PROXY -> AppSettingsFragmentDirections.actionDirectToEditProxyFragment()
|
AppSettingsRoute.DataAndStorageRoute.Proxy -> AppSettingsFragmentDirections.actionDirectToEditProxyFragment()
|
||||||
StartLocation.NOTIFICATIONS -> AppSettingsFragmentDirections.actionDirectToNotificationsSettingsFragment()
|
AppSettingsRoute.NotificationsRoute.Notifications -> AppSettingsFragmentDirections.actionDirectToNotificationsSettingsFragment()
|
||||||
StartLocation.CHANGE_NUMBER -> AppSettingsFragmentDirections.actionDirectToChangeNumberFragment()
|
AppSettingsRoute.ChangeNumberRoute.Start -> AppSettingsFragmentDirections.actionDirectToChangeNumberFragment()
|
||||||
StartLocation.SUBSCRIPTIONS -> AppSettingsFragmentDirections.actionDirectToManageDonations().setDirectToCheckoutType(InAppPaymentType.RECURRING_DONATION)
|
is AppSettingsRoute.DonationsRoute.Donations -> AppSettingsFragmentDirections.actionDirectToManageDonations().setDirectToCheckoutType(appSettingsRoute.directToCheckoutType)
|
||||||
StartLocation.BOOST -> AppSettingsFragmentDirections.actionDirectToManageDonations().setDirectToCheckoutType(InAppPaymentType.ONE_TIME_DONATION)
|
AppSettingsRoute.NotificationsRoute.NotificationProfiles -> AppSettingsFragmentDirections.actionDirectToNotificationProfiles()
|
||||||
StartLocation.MANAGE_SUBSCRIPTIONS -> AppSettingsFragmentDirections.actionDirectToManageDonations()
|
is AppSettingsRoute.NotificationsRoute.EditProfile -> AppSettingsFragmentDirections.actionDirectToCreateNotificationProfiles()
|
||||||
StartLocation.NOTIFICATION_PROFILES -> AppSettingsFragmentDirections.actionDirectToNotificationProfiles()
|
is AppSettingsRoute.NotificationsRoute.ProfileDetails -> AppSettingsFragmentDirections.actionDirectToNotificationProfileDetails(
|
||||||
StartLocation.CREATE_NOTIFICATION_PROFILE -> AppSettingsFragmentDirections.actionDirectToCreateNotificationProfiles()
|
appSettingsRoute.profileId
|
||||||
StartLocation.NOTIFICATION_PROFILE_DETAILS -> AppSettingsFragmentDirections.actionDirectToNotificationProfileDetails(
|
|
||||||
EditNotificationProfileScheduleFragmentArgs.fromBundle(intent.getBundleExtra(START_ARGUMENTS)!!).profileId
|
|
||||||
)
|
)
|
||||||
|
|
||||||
StartLocation.PRIVACY -> AppSettingsFragmentDirections.actionDirectToPrivacy()
|
AppSettingsRoute.PrivacyRoute.Privacy -> AppSettingsFragmentDirections.actionDirectToPrivacy()
|
||||||
StartLocation.LINKED_DEVICES -> AppSettingsFragmentDirections.actionDirectToDevices()
|
AppSettingsRoute.LinkDeviceRoute.LinkDevice -> AppSettingsFragmentDirections.actionDirectToDevices()
|
||||||
StartLocation.USERNAME_LINK -> AppSettingsFragmentDirections.actionDirectToUsernameLinkSettings()
|
AppSettingsRoute.UsernameLinkRoute.UsernameLink -> AppSettingsFragmentDirections.actionDirectToUsernameLinkSettings()
|
||||||
StartLocation.RECOVER_USERNAME -> AppSettingsFragmentDirections.actionDirectToUsernameRecovery()
|
is AppSettingsRoute.AccountRoute.Username -> AppSettingsFragmentDirections.actionDirectToUsernameRecovery()
|
||||||
StartLocation.REMOTE_BACKUPS -> AppSettingsFragmentDirections.actionDirectToRemoteBackupsSettingsFragment()
|
is AppSettingsRoute.BackupsRoute.Remote -> AppSettingsFragmentDirections.actionDirectToRemoteBackupsSettingsFragment()
|
||||||
StartLocation.CHAT_FOLDERS -> AppSettingsFragmentDirections.actionDirectToChatFoldersFragment()
|
AppSettingsRoute.ChatFoldersRoute.ChatFolders -> AppSettingsFragmentDirections.actionDirectToChatFoldersFragment()
|
||||||
StartLocation.CREATE_CHAT_FOLDER -> AppSettingsFragmentDirections.actionDirectToCreateFoldersFragment(
|
is AppSettingsRoute.ChatFoldersRoute.CreateChatFolders -> AppSettingsFragmentDirections.actionDirectToCreateFoldersFragment(
|
||||||
CreateFoldersFragmentArgs.fromBundle(intent.getBundleExtra(START_ARGUMENTS)!!).folderId,
|
appSettingsRoute.folderId,
|
||||||
CreateFoldersFragmentArgs.fromBundle(intent.getBundleExtra(START_ARGUMENTS)!!).threadIds
|
appSettingsRoute.threadIds
|
||||||
)
|
)
|
||||||
|
|
||||||
StartLocation.BACKUPS_SETTINGS -> AppSettingsFragmentDirections.actionDirectToBackupsSettingsFragment()
|
AppSettingsRoute.BackupsRoute.Backups -> AppSettingsFragmentDirections.actionDirectToBackupsSettingsFragment()
|
||||||
StartLocation.INVITE -> AppSettingsFragmentDirections.actionDirectToInviteFragment()
|
AppSettingsRoute.Invite -> AppSettingsFragmentDirections.actionDirectToInviteFragment()
|
||||||
StartLocation.MANAGE_STORAGE -> AppSettingsFragmentDirections.actionDirectToStoragePreferenceFragment()
|
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) {
|
if (startingAction == null && savedInstanceState != null) {
|
||||||
wasConfigurationUpdated = savedInstanceState.getBoolean(STATE_WAS_CONFIGURATION_UPDATED)
|
wasConfigurationUpdated = savedInstanceState.getBoolean(STATE_WAS_CONFIGURATION_UPDATED)
|
||||||
@@ -148,123 +147,89 @@ class AppSettingsActivity : DSLSettingsActivity(), GooglePayComponent {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun home(context: Context, action: String? = null): Intent {
|
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)
|
.putExtra(EXTRA_PERFORM_ACTION_ON_CREATE, action)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun backups(context: Context): Intent = getIntentForStartLocation(context, StartLocation.BACKUPS)
|
fun backups(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.BackupsRoute.Local)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun help(context: Context, startCategoryIndex: Int = 0): Intent {
|
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)
|
.putExtra(HelpFragment.START_CATEGORY_INDEX, startCategoryIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun proxy(context: Context): Intent = getIntentForStartLocation(context, StartLocation.PROXY)
|
fun proxy(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.DataAndStorageRoute.Proxy)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun notifications(context: Context): Intent = getIntentForStartLocation(context, StartLocation.NOTIFICATIONS)
|
fun notifications(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.NotificationsRoute.Notifications)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun changeNumber(context: Context): Intent = getIntentForStartLocation(context, StartLocation.CHANGE_NUMBER)
|
fun changeNumber(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.ChangeNumberRoute.Start)
|
||||||
|
|
||||||
@JvmStatic
|
@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
|
@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
|
@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
|
@JvmStatic
|
||||||
fun notificationProfiles(context: Context): Intent = getIntentForStartLocation(context, StartLocation.NOTIFICATION_PROFILES)
|
fun notificationProfiles(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.NotificationsRoute.NotificationProfiles)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun createNotificationProfile(context: Context): Intent = getIntentForStartLocation(context, StartLocation.CREATE_NOTIFICATION_PROFILE)
|
fun createNotificationProfile(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.NotificationsRoute.EditProfile())
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun privacy(context: Context): Intent = getIntentForStartLocation(context, StartLocation.PRIVACY)
|
fun privacy(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.PrivacyRoute.Privacy)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun notificationProfileDetails(context: Context, profileId: Long): Intent {
|
fun notificationProfileDetails(context: Context, profileId: Long): Intent {
|
||||||
val arguments = EditNotificationProfileScheduleFragmentArgs.Builder(profileId, false)
|
return getIntentForStartLocation(context, AppSettingsRoute.NotificationsRoute.ProfileDetails(profileId = profileId))
|
||||||
.build()
|
|
||||||
.toBundle()
|
|
||||||
|
|
||||||
return getIntentForStartLocation(context, StartLocation.NOTIFICATION_PROFILE_DETAILS)
|
|
||||||
.putExtra(START_ARGUMENTS, arguments)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun linkedDevices(context: Context): Intent = getIntentForStartLocation(context, StartLocation.LINKED_DEVICES)
|
fun linkedDevices(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.LinkDeviceRoute.LinkDevice)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun usernameLinkSettings(context: Context): Intent = getIntentForStartLocation(context, StartLocation.USERNAME_LINK)
|
fun usernameLinkSettings(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.UsernameLinkRoute.UsernameLink)
|
||||||
|
|
||||||
@JvmStatic
|
@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
|
@JvmStatic
|
||||||
fun remoteBackups(context: Context): Intent = getIntentForStartLocation(context, StartLocation.REMOTE_BACKUPS)
|
fun remoteBackups(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.BackupsRoute.Remote())
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun chatFolders(context: Context): Intent = getIntentForStartLocation(context, StartLocation.CHAT_FOLDERS)
|
fun chatFolders(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.ChatFoldersRoute.ChatFolders)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun createChatFolder(context: Context, id: Long = -1, threadIds: LongArray?): Intent {
|
fun createChatFolder(context: Context, id: Long = -1, threadIds: LongArray?): Intent {
|
||||||
val arguments = CreateFoldersFragmentArgs.Builder(id, threadIds ?: longArrayOf())
|
return getIntentForStartLocation(
|
||||||
.build()
|
context,
|
||||||
.toBundle()
|
AppSettingsRoute.ChatFoldersRoute.CreateChatFolders(
|
||||||
|
folderId = id,
|
||||||
return getIntentForStartLocation(context, StartLocation.CREATE_CHAT_FOLDER).putExtra(START_ARGUMENTS, arguments)
|
threadIds = threadIds ?: longArrayOf()
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun backupsSettings(context: Context): Intent = getIntentForStartLocation(context, StartLocation.BACKUPS_SETTINGS)
|
fun backupsSettings(context: Context): Intent = getIntentForStartLocation(context, AppSettingsRoute.BackupsRoute.Backups)
|
||||||
|
|
||||||
@JvmStatic
|
@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)
|
return Intent(context, AppSettingsActivity::class.java)
|
||||||
.putExtra(ARG_NAV_GRAPH, R.navigation.app_settings_with_change_number)
|
.putExtra(ARG_NAV_GRAPH, R.navigation.app_settings_with_change_number)
|
||||||
.putExtra(START_LOCATION, startLocation.code)
|
.putExtra(START_ROUTE, startRoute)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.components.settings.app
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.annotation.IdRes
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
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.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.NavDirections
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.Flow
|
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.banner.ui.compose.Importance
|
||||||
import org.thoughtcrime.securesms.components.compose.TextWithBetaLabel
|
import org.thoughtcrime.securesms.components.compose.TextWithBetaLabel
|
||||||
import org.thoughtcrime.securesms.components.emoji.Emojifier
|
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.BadgeImageMedium
|
||||||
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaymentsRepository
|
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaymentsRepository
|
||||||
import org.thoughtcrime.securesms.components.settings.app.subscription.completed.InAppPaymentsBottomSheetDelegate
|
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 {
|
class AppSettingsFragment : ComposeFragment(), Callbacks {
|
||||||
|
|
||||||
private val viewModel: AppSettingsViewModel by viewModels()
|
private val viewModel: AppSettingsViewModel by viewModels()
|
||||||
|
private val appSettingsRouter by viewModels<AppSettingsRouter>()
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
viewLifecycleOwner.lifecycle.addObserver(InAppPaymentsBottomSheetDelegate(childFragmentManager, viewLifecycleOwner))
|
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
|
@Composable
|
||||||
@@ -118,12 +149,8 @@ class AppSettingsFragment : ComposeFragment(), Callbacks {
|
|||||||
requireActivity().finishAfterTransition()
|
requireActivity().finishAfterTransition()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun navigate(actionId: Int) {
|
override fun navigate(route: AppSettingsRoute) {
|
||||||
findNavController().safeNavigate(actionId)
|
appSettingsRouter.navigateTo(route)
|
||||||
}
|
|
||||||
|
|
||||||
override fun navigate(directions: NavDirections) {
|
|
||||||
findNavController().safeNavigate(directions)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
@@ -203,7 +230,7 @@ private fun AppSettingsContent(
|
|||||||
BackupsWarningRow(
|
BackupsWarningRow(
|
||||||
text = stringResource(R.string.AppSettingsFragment__renew_your_signal_backups_subscription),
|
text = stringResource(R.string.AppSettingsFragment__renew_your_signal_backups_subscription),
|
||||||
onClick = {
|
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),
|
text = stringResource(R.string.AppSettingsFragment__couldnt_complete_backup),
|
||||||
onClick = {
|
onClick = {
|
||||||
BackupRepository.markBackupFailedIndicatorClicked()
|
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),
|
text = stringResource(R.string.AppSettingsFragment__couldnt_redeem_your_backups_subscription),
|
||||||
onClick = {
|
onClick = {
|
||||||
BackupRepository.markBackupAlreadyRedeemedIndicatorClicked()
|
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),
|
icon = ImageVector.vectorResource(R.drawable.symbol_error_circle_fill_24),
|
||||||
iconTint = MaterialTheme.colorScheme.error,
|
iconTint = MaterialTheme.colorScheme.error,
|
||||||
onClick = {
|
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),
|
text = stringResource(R.string.AccountSettingsFragment__account),
|
||||||
icon = painterResource(R.drawable.symbol_person_circle_24),
|
icon = painterResource(R.drawable.symbol_person_circle_24),
|
||||||
onClick = {
|
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),
|
text = stringResource(R.string.preferences__linked_devices),
|
||||||
icon = painterResource(R.drawable.symbol_devices_24),
|
icon = painterResource(R.drawable.symbol_devices_24),
|
||||||
onClick = {
|
onClick = {
|
||||||
callbacks.navigate(R.id.action_appSettingsFragment_to_linkDeviceFragment)
|
callbacks.navigate(AppSettingsRoute.LinkDeviceRoute.LinkDevice)
|
||||||
},
|
},
|
||||||
enabled = isRegisteredAndUpToDate
|
enabled = isRegisteredAndUpToDate
|
||||||
)
|
)
|
||||||
@@ -312,7 +339,7 @@ private fun AppSettingsContent(
|
|||||||
},
|
},
|
||||||
onClick = {
|
onClick = {
|
||||||
if (state.allowUserToGoToDonationManagementScreen) {
|
if (state.allowUserToGoToDonationManagementScreen) {
|
||||||
callbacks.navigate(R.id.action_appSettingsFragment_to_manageDonationsFragment)
|
callbacks.navigate(AppSettingsRoute.DonationsRoute.Donations())
|
||||||
} else {
|
} else {
|
||||||
CommunicationActions.openBrowserLink(context, donateUrl)
|
CommunicationActions.openBrowserLink(context, donateUrl)
|
||||||
}
|
}
|
||||||
@@ -332,7 +359,7 @@ private fun AppSettingsContent(
|
|||||||
text = stringResource(R.string.preferences__appearance),
|
text = stringResource(R.string.preferences__appearance),
|
||||||
icon = painterResource(R.drawable.symbol_appearance_24),
|
icon = painterResource(R.drawable.symbol_appearance_24),
|
||||||
onClick = {
|
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),
|
text = stringResource(R.string.preferences_chats__chats),
|
||||||
icon = painterResource(R.drawable.symbol_chat_24),
|
icon = painterResource(R.drawable.symbol_chat_24),
|
||||||
onClick = {
|
onClick = {
|
||||||
callbacks.navigate(R.id.action_appSettingsFragment_to_chatsSettingsFragment)
|
callbacks.navigate(AppSettingsRoute.ChatsRoute.Chats)
|
||||||
},
|
},
|
||||||
enabled = state.legacyLocalBackupsEnabled || isRegisteredAndUpToDate
|
enabled = state.legacyLocalBackupsEnabled || isRegisteredAndUpToDate
|
||||||
)
|
)
|
||||||
@@ -353,7 +380,7 @@ private fun AppSettingsContent(
|
|||||||
text = stringResource(R.string.preferences__stories),
|
text = stringResource(R.string.preferences__stories),
|
||||||
icon = painterResource(R.drawable.symbol_stories_24),
|
icon = painterResource(R.drawable.symbol_stories_24),
|
||||||
onClick = {
|
onClick = {
|
||||||
callbacks.navigate(AppSettingsFragmentDirections.actionAppSettingsFragmentToStoryPrivacySettings(R.string.preferences__stories))
|
callbacks.navigate(AppSettingsRoute.StoriesRoute.Privacy(titleId = R.string.preferences__stories))
|
||||||
},
|
},
|
||||||
enabled = isRegisteredAndUpToDate
|
enabled = isRegisteredAndUpToDate
|
||||||
)
|
)
|
||||||
@@ -364,7 +391,7 @@ private fun AppSettingsContent(
|
|||||||
text = stringResource(R.string.preferences__notifications),
|
text = stringResource(R.string.preferences__notifications),
|
||||||
icon = painterResource(R.drawable.symbol_bell_24),
|
icon = painterResource(R.drawable.symbol_bell_24),
|
||||||
onClick = {
|
onClick = {
|
||||||
callbacks.navigate(R.id.action_appSettingsFragment_to_notificationsSettingsFragment)
|
callbacks.navigate(AppSettingsRoute.NotificationsRoute.Notifications)
|
||||||
},
|
},
|
||||||
enabled = isRegisteredAndUpToDate
|
enabled = isRegisteredAndUpToDate
|
||||||
)
|
)
|
||||||
@@ -375,7 +402,7 @@ private fun AppSettingsContent(
|
|||||||
text = stringResource(R.string.preferences__privacy),
|
text = stringResource(R.string.preferences__privacy),
|
||||||
icon = painterResource(R.drawable.symbol_lock_24),
|
icon = painterResource(R.drawable.symbol_lock_24),
|
||||||
onClick = {
|
onClick = {
|
||||||
callbacks.navigate(R.id.action_appSettingsFragment_to_privacySettingsFragment)
|
callbacks.navigate(AppSettingsRoute.PrivacyRoute.Privacy)
|
||||||
},
|
},
|
||||||
enabled = isRegisteredAndUpToDate
|
enabled = isRegisteredAndUpToDate
|
||||||
)
|
)
|
||||||
@@ -398,7 +425,7 @@ private fun AppSettingsContent(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
onClick = {
|
onClick = {
|
||||||
callbacks.navigate(R.id.action_appSettingsFragment_to_backupsSettingsFragment)
|
callbacks.navigate(AppSettingsRoute.BackupsRoute.Backups)
|
||||||
},
|
},
|
||||||
onLongClick = {
|
onLongClick = {
|
||||||
callbacks.copyRemoteBackupsSubscriberIdToClipboard()
|
callbacks.copyRemoteBackupsSubscriberIdToClipboard()
|
||||||
@@ -413,7 +440,7 @@ private fun AppSettingsContent(
|
|||||||
text = stringResource(R.string.preferences__data_and_storage),
|
text = stringResource(R.string.preferences__data_and_storage),
|
||||||
icon = painterResource(R.drawable.symbol_data_24),
|
icon = painterResource(R.drawable.symbol_data_24),
|
||||||
onClick = {
|
onClick = {
|
||||||
callbacks.navigate(R.id.action_appSettingsFragment_to_dataAndStorageSettingsFragment)
|
callbacks.navigate(AppSettingsRoute.DataAndStorageRoute.DataAndStorage)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -424,7 +451,7 @@ private fun AppSettingsContent(
|
|||||||
text = "App updates",
|
text = "App updates",
|
||||||
icon = painterResource(R.drawable.symbol_calendar_24),
|
icon = painterResource(R.drawable.symbol_calendar_24),
|
||||||
onClick = {
|
onClick = {
|
||||||
callbacks.navigate(R.id.action_appSettingsFragment_to_appUpdatesSettingsFragment)
|
callbacks.navigate(AppSettingsRoute.AppUpdates)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -467,7 +494,7 @@ private fun AppSettingsContent(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
onClick = {
|
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),
|
text = stringResource(R.string.preferences__help),
|
||||||
icon = painterResource(R.drawable.symbol_help_24),
|
icon = painterResource(R.drawable.symbol_help_24),
|
||||||
onClick = {
|
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),
|
text = stringResource(R.string.AppSettingsFragment__invite_your_friends),
|
||||||
icon = painterResource(R.drawable.symbol_invite_24),
|
icon = painterResource(R.drawable.symbol_invite_24),
|
||||||
onClick = {
|
onClick = {
|
||||||
callbacks.navigate(R.id.action_appSettingsFragment_to_inviteFragment)
|
callbacks.navigate(AppSettingsRoute.Invite)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -506,7 +533,7 @@ private fun AppSettingsContent(
|
|||||||
Rows.TextRow(
|
Rows.TextRow(
|
||||||
text = stringResource(R.string.preferences__internal_preferences),
|
text = stringResource(R.string.preferences__internal_preferences),
|
||||||
onClick = {
|
onClick = {
|
||||||
callbacks.navigate(R.id.action_appSettingsFragment_to_internalSettingsFragment)
|
callbacks.navigate(AppSettingsRoute.InternalRoute.Internal)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -558,7 +585,7 @@ private fun BioRow(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clickable(
|
.clickable(
|
||||||
onClick = {
|
onClick = {
|
||||||
callbacks.navigate(R.id.action_appSettingsFragment_to_manageProfileActivity)
|
callbacks.navigate(AppSettingsRoute.AccountRoute.ManageProfile)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.horizontalGutters()
|
.horizontalGutters()
|
||||||
@@ -632,7 +659,7 @@ private fun BioRow(
|
|||||||
if (hasUsername) {
|
if (hasUsername) {
|
||||||
IconButtons.IconButton(
|
IconButtons.IconButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
callbacks.navigate(R.id.action_appSettingsFragment_to_usernameLinkSettingsFragment)
|
callbacks.navigate(AppSettingsRoute.UsernameLinkRoute.UsernameLink)
|
||||||
},
|
},
|
||||||
size = 36.dp,
|
size = 36.dp,
|
||||||
colors = IconButtons.iconButtonColors(
|
colors = IconButtons.iconButtonColors(
|
||||||
@@ -711,8 +738,7 @@ private fun BioRowPreview() {
|
|||||||
|
|
||||||
private interface Callbacks {
|
private interface Callbacks {
|
||||||
fun onNavigationClick(): Unit = error("Not implemented.")
|
fun onNavigationClick(): Unit = error("Not implemented.")
|
||||||
fun navigate(@IdRes actionId: Int): Unit = error("Not implemented")
|
fun navigate(route: AppSettingsRoute): Unit = error("Not implemented")
|
||||||
fun navigate(directions: NavDirections): Unit = error("Not implemented")
|
|
||||||
fun copyDonorBadgeSubscriberIdToClipboard(): Unit = error("Not implemented")
|
fun copyDonorBadgeSubscriberIdToClipboard(): Unit = error("Not implemented")
|
||||||
fun copyRemoteBackupsSubscriberIdToClipboard(): 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