How to deal with logic in `MenuBar`? if for exampl...
# compose-desktop
p
How to deal with logic in
MenuBar
? if for example, I wanna display a "about" or a "help" dialog in my desktop app, that logic should be executed from a
viewmodel
... but
MenuBar
is always visible and shared by the entire application, visible on every screen, and each one of the screens of my app has their own
viewmodel
, which is exclusive of the screen, without having references to the
MenuBar
... does that mean that I need two
viewmodels
coexisting at the same moment? one for the window of the app, managing the menubar events and other for the current visible screen? this seems to be very confussing.
c
IMHO thats rather an “app state” than a view model pattern. have a look at the “Now in android” application. there is a “global” app state thats passed through the app. that will also help with your previous problem wit the navigation. https://github.com/android/nowinandroid/blob/d15c739812f25401b21614fe0f7e18534d285[…]n/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt
p
it seems to be very interesting! I'm trying to implement it, but for that, I had to access content in commonMain that is placed in desktopMain, for example, my AppState. It ask to me to add a circular dependency to desktopMain. It warns that it's a circular dependency. Is that a good practice?
c
in the app state you should only have the “root” navigation that can be triggered from the platform specific screens. i.e. menu bar on desktop or bottom tab navigation in android. the screens internal navigation should stay in a nested nav graph in the screen itself.
p
I edited my text
because I tryed without moving the navigation routes enum, but I have the same issue because I need to reference the AppState
I'm passing the AppState instance (which contains the navhost) to my commonMain screens, they need it to trigger navigation
c
no, they should not need it to trigger navigation. the navigation in your screens should have their own nav controllers.
in the app state you should only have the “root” navigation that can be triggered from the platform specific screens. i.e. menu bar on desktop or bottom tab navigation in android. the screens internal navigation should stay in a nested nav graph in the screen itself.
is still valid. app state has a root nav contoller. your screens have their own controller
p
but in the nowinandroid app they are sharing the navcontroller
they are triggering the navitation using the app state
with some functions for navigating using the navcontroller saved there
c
yes, they are not multiplatform 😉 it was just a hint how you can solve it - mot a copy-paste. adjust to your app.
also if you have code in common and platform specific and you want to share logic - expect/actual is the part you might be missing. https://kotlinlang.org/docs/multiplatform-expect-actual.html
p
well, finally I managed to share the navcontroller, I simply moved the AppState class to commonMain, so no circular dependences anymore. But I can't make it work... when executing the app I got a runtime exception on the commonMain navigation part, when adding the first composable to navigation, with no literal results on google:
Could not find Navigator with class "class androidx.navigation.compose.ComposeNavigator". You must call NavController.addNavigator() for each navigation type.
also, can't understand why you prefeer to have two sepparated navcontrollers, one for menu bar and other for the commonMain screens. Both must have the same current screen and both have the same routes
c
I don’t prefer it. It depends on the architecture of the app and for what you have told so far it seems like a good solution. And no, they don’t have the same routes - one is for the main navigation and the others are for the detail navigation of each screens deeper navigation. But I guess you will find a solution that fits your needs.
p
oh, now I understand you, you thought the navigation on the screens was internal deeper navigation for displaying details, but not, in this case, the screens can move between them with the same routes as the menu bar