Moves navController back into Compose

Adds a listener for newIntents
Fixes the App losing the back stack of screens
This commit is contained in:
Vitor Pamplona 2023-08-01 10:39:10 -04:00
parent bd7156082b
commit a50b0b7902
4 changed files with 75 additions and 59 deletions

View File

@ -17,16 +17,11 @@ import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.core.os.LocaleListCompat
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.vitorpamplona.amethyst.BuildConfig
import com.vitorpamplona.amethyst.LocalPreferences
import com.vitorpamplona.amethyst.ServiceManager
@ -44,7 +39,6 @@ import com.vitorpamplona.amethyst.ui.components.DefaultMutedSetting
import com.vitorpamplona.amethyst.ui.components.keepPlayingMutex
import com.vitorpamplona.amethyst.ui.navigation.Route
import com.vitorpamplona.amethyst.ui.navigation.debugState
import com.vitorpamplona.amethyst.ui.navigation.getRouteWithArguments
import com.vitorpamplona.amethyst.ui.note.Nip47
import com.vitorpamplona.amethyst.ui.screen.AccountScreen
import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel
@ -58,8 +52,6 @@ import java.net.URLEncoder
import java.nio.charset.StandardCharsets
class MainActivity : AppCompatActivity() {
lateinit var navController: NavHostController
@RequiresApi(Build.VERSION_CODES.R)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -75,7 +67,6 @@ class MainActivity : AppCompatActivity() {
}
setContent {
navController = rememberNavController()
val themeViewModel: ThemeViewModel = viewModel()
themeViewModel.onChange(LocalPreferences.getTheme())
@ -86,20 +77,9 @@ class MainActivity : AppCompatActivity() {
AccountStateViewModel(this@MainActivity)
}
AccountScreen(accountStateViewModel, themeViewModel, navController)
AccountScreen(accountStateViewModel, themeViewModel)
}
}
var actionableNextPage by remember { mutableStateOf(startingPage) }
actionableNextPage?.let {
LaunchedEffect(it) {
navController.navigate(it) {
popUpTo(Route.Home.route)
launchSingleTop = true
}
}
actionableNextPage = null
}
}
val networkRequest = NetworkRequest.Builder()
@ -161,36 +141,7 @@ class MainActivity : AppCompatActivity() {
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
if (this::navController.isInitialized) {
val uri = intent?.data?.toString()
val startingPage = uriToRoute(uri)
startingPage?.let { route ->
val currentRoute = getRouteWithArguments(navController)
if (!isSameRoute(currentRoute, route)) {
navController.navigate(route) {
popUpTo(Route.Home.route)
launchSingleTop = true
}
}
}
}
}
private fun isSameRoute(currentRoute: String?, newRoute: String): Boolean {
if (currentRoute == null) return false
if (currentRoute == newRoute) {
return true
}
if (newRoute.startsWith("Event/") && currentRoute.contains("/")) {
if (newRoute.split("/")[1] == currentRoute.split("/")[1]) {
return true
}
}
return false
println("AAA -OnNew Intent")
}
@OptIn(DelicateCoroutinesApi::class)

View File

@ -1,12 +1,22 @@
package com.vitorpamplona.amethyst.ui.navigation
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.core.util.Consumer
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import com.vitorpamplona.amethyst.ui.MainActivity
import com.vitorpamplona.amethyst.ui.note.UserReactionsViewModel
import com.vitorpamplona.amethyst.ui.screen.NostrChatroomListKnownFeedViewModel
import com.vitorpamplona.amethyst.ui.screen.NostrChatroomListNewFeedViewModel
@ -36,6 +46,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.SearchScreen
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SettingsScreen
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ThreadScreen
import com.vitorpamplona.amethyst.ui.screen.loggedIn.VideoScreen
import com.vitorpamplona.amethyst.ui.uriToRoute
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@ -54,6 +65,7 @@ fun AppNavigation(
navController: NavHostController,
accountViewModel: AccountViewModel,
startingPage: String? = null,
themeViewModel: ThemeViewModel
) {
val scope = rememberCoroutineScope()
@ -237,4 +249,58 @@ fun AppNavigation(
})
}
}
var actionableNextPage by remember { mutableStateOf(startingPage) }
actionableNextPage?.let {
LaunchedEffect(it) {
navController.navigate(it) {
popUpTo(Route.Home.route)
launchSingleTop = true
}
}
actionableNextPage = null
}
val activity = LocalContext.current.getActivity()
DisposableEffect(navController) {
val consumer = Consumer<Intent> { intent ->
val uri = intent?.data?.toString()
val newPage = uriToRoute(uri)
newPage?.let { route ->
val currentRoute = getRouteWithArguments(navController)
if (!isSameRoute(currentRoute, route)) {
navController.navigate(route) {
popUpTo(Route.Home.route)
launchSingleTop = true
}
}
}
}
activity.addOnNewIntentListener(consumer)
onDispose {
activity.removeOnNewIntentListener(consumer)
}
}
}
fun Context.getActivity(): MainActivity {
if (this is MainActivity) return this
return if (this is ContextWrapper) baseContext.getActivity() else getActivity()
}
private fun isSameRoute(currentRoute: String?, newRoute: String): Boolean {
if (currentRoute == null) return false
if (currentRoute == newRoute) {
return true
}
if (newRoute.startsWith("Event/") && currentRoute.contains("/")) {
if (newRoute.split("/")[1] == currentRoute.split("/")[1]) {
return true
}
}
return false
}

View File

@ -7,7 +7,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.MainScreen
import com.vitorpamplona.amethyst.ui.screen.loggedOff.LoginPage
@ -15,8 +14,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedOff.LoginPage
@Composable
fun AccountScreen(
accountStateViewModel: AccountStateViewModel,
themeViewModel: ThemeViewModel,
navController: NavHostController
themeViewModel: ThemeViewModel
) {
val accountState by accountStateViewModel.accountContent.collectAsState()
@ -32,7 +30,7 @@ fun AccountScreen(
factory = AccountViewModel.Factory(state.account)
)
MainScreen(accountViewModel, accountStateViewModel, themeViewModel, navController)
MainScreen(accountViewModel, accountStateViewModel, themeViewModel)
}
is AccountState.LoggedInViewOnly -> {
val accountViewModel: AccountViewModel = viewModel(
@ -40,7 +38,7 @@ fun AccountScreen(
factory = AccountViewModel.Factory(state.account)
)
MainScreen(accountViewModel, accountStateViewModel, themeViewModel, navController)
MainScreen(accountViewModel, accountStateViewModel, themeViewModel)
}
}
}

View File

@ -24,11 +24,12 @@ import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.vitorpamplona.amethyst.ui.buttons.ChannelFabColumn
import com.vitorpamplona.amethyst.ui.buttons.NewCommunityNoteButton
import com.vitorpamplona.amethyst.ui.buttons.NewImageButton
@ -60,8 +61,7 @@ import kotlinx.coroutines.launch
fun MainScreen(
accountViewModel: AccountViewModel,
accountStateViewModel: AccountStateViewModel,
themeViewModel: ThemeViewModel,
navController: NavHostController
themeViewModel: ThemeViewModel
) {
val scope = rememberCoroutineScope()
val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
@ -71,6 +71,7 @@ fun MainScreen(
skipHalfExpanded = true
)
val navController = rememberNavController()
val navState = navController.currentBackStackEntryAsState()
val nav = remember(navController) {