-
-
Notifications
You must be signed in to change notification settings - Fork 139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dispose Screens only when transition ends #436
Conversation
) { | ||
// This can be costly because is checking every single item in the list | ||
// we should re evaluate how validation works, maybe validating screen keys or === | ||
val previousItems = rememberPrevious(navigator.items) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should collect all navigator items changes.
Case:
We have navigator with transitions, it's stack: A -> B -> C
.
User presses "back" 2 times quickly, so the stack now: A
.
IMPORTANT NOTE: the transition was not completed during the entire stack change.
After all these actions, screens B, C should be disposed. But as i understand from your solution, only screen B will be disposed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So because of this case i collect all navigator item changes: https://github.com/adrielcafe/voyager/pull/427/files#diff-b8d3186fe9802c02964e8e565ad0ae0195d79ae7e74854c8b3c256ba68e572daR70
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So my idea is simple:
Collect all screens created during transitions (because during slow transition crazy user can navigate to and from different screens). After completion of transition compare collected screens with idled stack. Then dispose screens that are no longer in the navigation stack
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeh, I have being testing exactly that previously and I was able to reproduce it! I will try your suggestion.
@shpasha I have bring your solution instead of This way we can let as experimental and rethink if a Channel with Local Composition is a better solution in the future, for now, I think let this responsibility to the actual Transition component is safer and makes more sense and also, does not do any changes on Navigator Core |
onDispose { | ||
val newScreenKeys = navigator.items.map { it.key } | ||
screenCandidatesToDispose.value += currentScreens.filter { it.key !in newScreenKeys } | ||
.map { ScreenData(it.key, it) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, i don't understand why I wrote this line 😄
I think we can get rid of ScreenData without any problems. Just save Screen only
@@ -104,8 +167,34 @@ public fun ScreenTransition( | |||
}, | |||
modifier = modifier | |||
) { screen -> | |||
if (this.transition.targetState == this.transition.currentState) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest changing the condition a little:
if (this.transition.targetState == this.transition.currentState && disposeScreenAfterTransitionEnd) {
...
}
and get rid of disposeScreenAfterTransitionEnd
check in LaunchedEffect
|
||
val currentScreens = navigator.items | ||
|
||
DisposableEffect(currentScreens) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggest to wrap 142-148 lines in if condition if (disposeScreenAfterTransitionEnd) { ... }
@DevSrSouza thanks! |
ISSUE SOLVED: #106
To use this new behavior you have to disable
disposeBehavior.disposeSteps
and use theScreenTransition.disposeScreenAfterTransitionEnd = true