Skip to content
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

Fix a crash during the first build of NavigationSheet with a path that contains multiple routes such as /a/b/c #113

Merged
merged 4 commits into from
May 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions package/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 0.5.2 May 5, 2024

- Fix a crash during the first build of `NavigationSheet` with a path that contains multiple routes such as `/a/b/c` (#109)

## 0.5.1 May 4, 2024

- Re-export `NavigationSheetRoute` that is unintentionally omitted in v0.5.0 (#110)
Expand Down
47 changes: 26 additions & 21 deletions package/lib/src/internal/transition_observer.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:flutter/widgets.dart';

@optionalTypeArgs
class TransitionObserver extends NavigatorObserver {
final Set<TransitionAwareStateMixin> _listeners = {};

Expand Down Expand Up @@ -58,34 +57,40 @@ mixin TransitionAwareWidgetMixin on StatefulWidget {

mixin TransitionAwareStateMixin<T extends TransitionAwareWidgetMixin>
on State<T> {
Transition? _currentTransition;
Transition? _lastReportedTransition;
Transition? get currentTransition => _lastReportedTransition;

void _setCurrentTransition(Transition? transition) {
if (_currentTransition != transition) {
_currentTransition = transition;
didChangeTransitionState(_currentTransition);
void _notify(Transition? transition) {
if (_lastReportedTransition != transition) {
_lastReportedTransition = transition;
didChangeTransitionState(transition);
}
}

void didChangeTransitionState(Transition? transition);

void didPush(ModalRoute<dynamic> route, ModalRoute<dynamic>? previousRoute) {
final currentState = _currentTransition;
final currentState = currentTransition;

if (previousRoute == null) {
_setCurrentTransition(NoTransition(currentRoute: route));
if (previousRoute == null || route.animation!.isCompleted) {
// There is only one roue in the history stack, or multiple routes
// are pushed at the same time without transition animation.
_notify(NoTransition(currentRoute: route));
} else if (route.isCurrent && currentState is NoTransition) {
_setCurrentTransition(ForwardTransition(
// A new route is pushed on top of the stack with transition animation.
// Then, notify the listener of the beginning of the transition.
_notify(ForwardTransition(
originRoute: currentState.currentRoute,
destinationRoute: route,
animation: route.animation!,
));

// Notify the listener again when the transition is completed.
void transitionStatusListener(AnimationStatus status) {
if (status == AnimationStatus.completed && !route.offstage) {
route.animation!.removeStatusListener(transitionStatusListener);
if (_currentTransition is ForwardTransition) {
_setCurrentTransition(NoTransition(currentRoute: route));
if (currentTransition is ForwardTransition) {
_notify(NoTransition(currentRoute: route));
}
}
}
Expand All @@ -96,16 +101,16 @@ mixin TransitionAwareStateMixin<T extends TransitionAwareWidgetMixin>

void didPop(ModalRoute<dynamic> route, ModalRoute<dynamic>? previousRoute) {
if (previousRoute == null) {
_setCurrentTransition(null);
_notify(null);
} else {
_setCurrentTransition(BackwardTransition(
_notify(BackwardTransition(
originRoute: route,
destinationRoute: previousRoute,
animation: route.animation!.drive(Tween(begin: 1, end: 0)),
));
route.completed.whenComplete(() {
if (_currentTransition is BackwardTransition) {
_setCurrentTransition(NoTransition(currentRoute: previousRoute));
if (currentTransition is BackwardTransition) {
_notify(NoTransition(currentRoute: previousRoute));
}
});
}
Expand All @@ -115,16 +120,16 @@ mixin TransitionAwareStateMixin<T extends TransitionAwareWidgetMixin>
ModalRoute<dynamic> route,
ModalRoute<dynamic>? previousRoute,
) {
_setCurrentTransition(UserGestureTransition(
_notify(UserGestureTransition(
currentRoute: route,
previousRoute: previousRoute!,
animation: route.animation!.drive(Tween(begin: 1, end: 0)),
));
}

void didStopUserGesture() {
if (_currentTransition case final UserGestureTransition state) {
_setCurrentTransition(NoTransition(
if (currentTransition case final UserGestureTransition state) {
_notify(NoTransition(
currentRoute: state.currentRoute,
));
}
Expand All @@ -142,14 +147,14 @@ mixin TransitionAwareStateMixin<T extends TransitionAwareWidgetMixin>
if (widget.transitionObserver != oldWidget.transitionObserver) {
oldWidget.transitionObserver.unmount(this);
widget.transitionObserver.mount(this);
_setCurrentTransition(null);
_notify(null);
}
}

@override
void dispose() {
widget.transitionObserver.unmount(this);
_setCurrentTransition(null);
_notify(null);
super.dispose();
}
}
Expand Down
4 changes: 1 addition & 3 deletions package/lib/src/navigation/navigation_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ class NavigationSheet extends StatefulWidget with TransitionAwareWidgetMixin {
class _NavigationSheetState extends State<NavigationSheet>
with TransitionAwareStateMixin, SheetExtentDelegate {
final GlobalKey<SheetExtentScopeState> _scopeKey = GlobalKey();
Transition? _currentTransition;

@override
void didChangeTransitionState(Transition? transition) {
Expand Down Expand Up @@ -87,12 +86,11 @@ class _NavigationSheetState extends State<NavigationSheet>
};

_scopeKey.currentState?.extent.beginActivity(sheetActivity);
_currentTransition = transition;
}

@override
SheetActivity createIdleActivity() {
return switch (_currentTransition) {
return switch (currentTransition) {
NoTransition(:final NavigationSheetRoute<dynamic> currentRoute) =>
_ProxySheetActivity(entry: currentRoute),
_ => IdleSheetActivity(),
Expand Down
2 changes: 1 addition & 1 deletion package/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: smooth_sheets
description: Sheet widgets with smooth motion and great flexibility. Also supports nested navigation in both imperative and declarative ways.
version: 0.5.1
version: 0.5.2
repository: https://github.com/fujidaiti/smooth_sheets

environment:
Expand Down
Loading