Coder Social home page Coder Social logo

compose-router's People

Contributors

ahulyk avatar amatsegor avatar arturm-hexagon avatar cgudea avatar dancing-koala avatar friendoye avatar luca992 avatar madhavajay avatar molikto avatar pranavmaganti avatar shikasd avatar zsoltk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

compose-router's Issues

Support for Dynamic Features?

With deeplink I think it's support between Dynamice Feature navigation, cmiiw or does it requires any setup/configuration differences than using Deeplink?

Crash with Jetpack Compose Alpha07

Version of Jetpack Compose: alpha07
Version of Compose router: 0.21.0

The following runtime error is thrown

 java.lang.NoSuchFieldError: No field Companion of type Landroidx/compose/runtime/SlotTable$Companion; in class Landroidx/compose/runtime/SlotTable; or its superclasses (declaration of 'androidx.compose.runtime.SlotTable' appears in /data/data/com.metamythlabs.theseries/code_cache/.overlay/base.apk/classes.dex)
        at com.github.zsoltk.compose.router.RouterKt.Router(Router.kt:105)
        at com.metamythlabs.theseries.screens.MainRouter$Companion.Content(MainRouter.kt:28)

Usage of router (excerpt)

 companion object {
        @Composable
        fun Content(defaultRouting: Routing = Routing.Home) {
            Router("Main", defaultRouting) { backStack ->

                Providers(
                    AppNavigatorAmbient provides TheSeenNavigator(backStack)
                ) {
                    when (val routing = backStack.last()) {
                        is Routing.Home -> HomeRouter.Content()
                        is Routing.MoviesDetail -> MovieRouter.Content(movieId = routing.movieId)
                        is Routing.SeriesDetail -> SeriesRouter.Content(seriesId = routing.seriesId)
                        is Routing.UniverseDetail -> UniverseRouter.Content(universeId = routing.universeId)
                    }
                }
            }
        }
    }
}

Sadly I couldn't solve it quickly, hence I wanna report it.

Crash with 0.11.1

Version 0.11.1 crashes withbackPressHandler is not initialized at a certain route depth. Downgrading to 0.9.0 fixes the issue. I'm having trouble reproducing this properly.

Implicit id for Router

Right now Router needs an explicit unique id for back stack store/retrieval from parent. It would be nice to make this implicitly without having to ask client code to define id.

Multiplatform support

Would be nice to also support kotlin multiplatform - i.e. kotlin native targets, js and non-android jvm.

ViewModels not cleared when navigation out

The ViewModels provided in the composition by hilt, are never destroyed when a new root destination is selected.
With compose navigation this is different because models are cleared as soon as the destination gets cleared from the back stack.

Unable to import when built with com.android.tools.build:gradle > 4.1.0-alpha05

I mentioned this bug in #21. Probably needs to be reported to Google. It still does not work with 4.1.0-alpha09.

For some reason with com.android.tools.build:gradle versions 4.1.0-alpha06 - 4.1.0-alpha08 the META-INF folder isn't added to the classes.jar in the .aar outputs

Screenshot from 2020-05-11 16-30-42

Screenshot from 2020-05-11 16-26-20

My branch built with com.android.tools.build:gradle:4.1.0-alpha05 includes the META-INF folder and I can successfully build my project
Screenshot from 2020-05-11 16-27-40

How do I save the state in a previous view?

Assuming you have two destinations, A and B. A displays a long list. You click on an item in the list to navigate to B. Once in B you click on the back button. The A view is entirely recreated. The list is at the top again. I am unsure if this is by design or not.

sealed class Routing {
  object A: Routing()
  data class B(val slug: String) : Routing()
}
@Composable
fun AppStore(routing: Routing = Routing.A) {
  Router(routing) { backStack ->
    val onItemClicked: (String) = { slug ->
      backStack.push(Routing.B(slug))
    }
    when (val value = backStack.last()) {
      is Routing.A-> AController(onItemClicked)
      is Routing.B-> BController(value.slug)
    }
  }
}

I've already added a rememberLazyListState but this seems to be recreated entirely as well

I am using version 0.24.2

Top of Stack

Hi,

I'd find it really useful to know what the top item in the backstack is - I'm using bottom navigation and knowing the top item on the backstack would help in deciding which item at the bottom should be highlighted (even when a few destinations deep in that stack).

Is there a reason this shouldn't be exposed?

[Proposal] Expose read access for BackStack#elements

I wonder if there is any way to retrieve all elements from BackStack?
It can be useful in the following cases:

  1. We want to render all screens from BackStack on top of each other, so after navigating back we will not re-render some screens.
  2. Integration with compose-backstack (library for rendering animated transitions between backstacks of screens) would be much simpler, because nowadays it requires list of screens as one of args to its Composable. There are some workarounds, such as using Kotlin Reflection or using state/remember for maintaining backstack yourself, but it would be great to have read access directly to BackStack#elements.

@zsoltk WDYT?

How to handle TopAppBar navigation back event?

Initial setup of BackPressHandler in the MainActivity works well with navigation but how to handle Appbar navback button click event?
Now I've forked and created RootBackPressHandler Ambient which is set once in root Router and then I'm accessing it from anywhere

Navigation screens seem to be duplicated

I'm trying out your library (0.5.0) and it's great. But I ran into an issue. I will post code here to reproduce it. I might be using the library wrong though.

class MainActivity : AppCompatActivity() {
    private val backPressHandler = BackPressHandler()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MaterialTheme {
                Providers(AmbientBackPressHandler provides backPressHandler) {
                    MyRouter(startRoute = SplashRoute)
                }
            }
        }
    }

    override fun onBackPressed() {
        if (!backPressHandler.handle()) {
            super.onBackPressed()
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.saveAmbient()
    }
}

sealed class MyRoute {
    object SplashRoute : MyRoute()
    object HomeRoute : MyRoute()
    object DetailsRoute : MyRoute()
}

@Composable
fun MyRouter(startRoute: MyRoute) {
    Router(contextId = "app", defaultRouting = startRoute) { backStack ->
        when (backStack.last()) {
            SplashRoute -> SplashRouteScreen(onInitialized = { backStack.newRoot(HomeRoute) })
            HomeRoute -> HomeRouteScreen(onShowDetails = { backStack.push(DetailsRoute) })
            DetailsRoute -> DetailsRouteScreen()
        }
    }
}

@Composable
fun SplashRouteScreen(onInitialized: () -> Unit) {
    onActive {
        onInitialized()
    }
}

@Composable
fun HomeRouteScreen(onShowDetails: () -> Unit) {
    onActive {
        Log.d("HomeRouteScreen", "onActive ${System.currentTimeMillis()}")

        onDispose {
            Log.d("HomeRouteScreen", "onDispose ${System.currentTimeMillis()}")
        }
    }

    Center {
        Button(onClick = onShowDetails) {
            Text(text = "Show details")
        }
    }
}

@Composable
fun DetailsRouteScreen() {
    Center {
        Text("Details")
    }
}

So if you open the app and you navigate through screens everything is fine. Logs in HomeRouteScreen work as intended. But if you leave the app with back button (don't kill the app), then:

  1. Open app again
  2. Tap "Show details"
  3. Press back

Logs will look like this:

D/HomeRouteScreen: onActive 1582533598703
D/HomeRouteScreen: onDispose 1582533600692
D/HomeRouteScreen: onDispose 1582533600697
D/HomeRouteScreen: onActive 1582533602550
D/HomeRouteScreen: onActive 1582533602551

If you leave the app again, and repeat those steps:

HomeRouteScreen: onActive 1582533684493
HomeRouteScreen: onDispose 1582533699006
HomeRouteScreen: onDispose 1582533699009
HomeRouteScreen: onDispose 1582533699011
HomeRouteScreen: onActive 1582533699988
HomeRouteScreen: onActive 1582533699989
HomeRouteScreen: onActive 1582533699989

Seems like every time you close the app with back button then reopen, something gets duplicated.

Off by one error in replace

My understanding of the replace function on BackStack is that it should swap the item at the top of the stack, so if the routing is a,b,c and replace(d) is called it should become a,b,d.

However, the replace function uses .subList(0, elements.lastIndex - 1) which removes 2 elements (the second argument being exclusive).

This should probably either change to use size or remove the -1 (the latter makes more sense to me).

This is, of course, all invalid if I've misunderstood what replace is supposed to do.

Make example apps independent of library version

Goal
To not block updating the library itself by breaking example apps UI whenever a new compose version is available.

How
Make the example apps grab the built artifact from jitpack instead of compiling from inside the project.

It's understood that this implies that example apps can and will become outdated UI-wise. Their point is to demonstrate Router usage though, and that remains very much the same across Compose versions.

The benefit of being able to update library itself very quickly is worth this trade-off.

Back stack is not in order

  1. Open nested sample app
  2. Tap L4.R1.NEXT and L4.R2.NEXT buttons alternatively a few times
  3. Start pressing back

What should happen: Back stack should be popped alternatively between L4.R1 and L4.R2
What happens: First L4.R1 gets fully popped, then L4.R2

I created another repository with navigation library where I solved this by having a "Global stack" that handles back stacks from each Router.

[Question] Integration with ViewModelStore?

I'm wondering if it's possible to adapt compose-router to be able to scope AndroidX ViewModel to a Backstack element?

For example, as long as the route is still in the backstack then the ViewModel is kept alive, and once the route is popped ViewModel's onCleared() gets called.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.