Skip to content

Commit

Permalink
Fix a crash during the first build of NavigationSheet with a path tha…
Browse files Browse the repository at this point in the history
…t contains multiple routes such as /a/b/c (#113)

Fixes #109.
  • Loading branch information
fujidaiti authored May 5, 2024
1 parent 0ebfc20 commit 42003d7
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 25 deletions.
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

0 comments on commit 42003d7

Please sign in to comment.