@@ -31,7 +31,7 @@ import { VIEW_STATE_ATTACHED, VIEW_STATE_DESTROYED, VIEW_STATE_NEW, convertToVie
31
31
export class Nav implements NavOutlet {
32
32
private transInstr : TransitionInstruction [ ] = [ ] ;
33
33
private sbAni ?: Animation ;
34
- private animationEnabled = true ;
34
+ private gestureOrAnimationInProgress = false ;
35
35
private useRouter = false ;
36
36
private isTransitioning = false ;
37
37
private destroyed = false ;
@@ -869,7 +869,36 @@ export class Nav implements NavOutlet {
869
869
// or if it is a portal (modal, actionsheet, etc.)
870
870
const opts = ti . opts ! ;
871
871
872
- const progressCallback = opts . progressAnimation ? ( ani : Animation | undefined ) => ( this . sbAni = ani ) : undefined ;
872
+ const progressCallback = opts . progressAnimation
873
+ ? ( ani : Animation | undefined ) => {
874
+ /**
875
+ * Because this progress callback is called asynchronously
876
+ * it is possible for the gesture to start and end before
877
+ * the animation is ever set. In that scenario, we should
878
+ * immediately call progressEnd so that the transition promise
879
+ * resolves and the gesture does not get locked up.
880
+ */
881
+ if ( ani !== undefined && ! this . gestureOrAnimationInProgress ) {
882
+ this . gestureOrAnimationInProgress = true ;
883
+ ani . onFinish (
884
+ ( ) => {
885
+ this . gestureOrAnimationInProgress = false ;
886
+ } ,
887
+ { oneTimeCallback : true }
888
+ ) ;
889
+
890
+ /**
891
+ * Playing animation to beginning
892
+ * with a duration of 0 prevents
893
+ * any flickering when the animation
894
+ * is later cleaned up.
895
+ */
896
+ ani . progressEnd ( 0 , 0 , 0 ) ;
897
+ } else {
898
+ this . sbAni = ani ;
899
+ }
900
+ }
901
+ : undefined ;
873
902
const mode = getIonMode ( this ) ;
874
903
const enteringEl = enteringView . element ! ;
875
904
const leavingEl = leavingView && leavingView . element ! ;
@@ -1008,15 +1037,16 @@ export class Nav implements NavOutlet {
1008
1037
1009
1038
private canStart ( ) : boolean {
1010
1039
return (
1040
+ ! this . gestureOrAnimationInProgress &&
1011
1041
! ! this . swipeGesture &&
1012
1042
! this . isTransitioning &&
1013
1043
this . transInstr . length === 0 &&
1014
- this . animationEnabled &&
1015
1044
this . canGoBackSync ( )
1016
1045
) ;
1017
1046
}
1018
1047
1019
1048
private onStart ( ) {
1049
+ this . gestureOrAnimationInProgress = true ;
1020
1050
this . pop ( { direction : 'back' , progressAnimation : true } ) ;
1021
1051
}
1022
1052
@@ -1028,10 +1058,9 @@ export class Nav implements NavOutlet {
1028
1058
1029
1059
private onEnd ( shouldComplete : boolean , stepValue : number , dur : number ) {
1030
1060
if ( this . sbAni ) {
1031
- this . animationEnabled = false ;
1032
1061
this . sbAni . onFinish (
1033
1062
( ) => {
1034
- this . animationEnabled = true ;
1063
+ this . gestureOrAnimationInProgress = false ;
1035
1064
} ,
1036
1065
{ oneTimeCallback : true }
1037
1066
) ;
@@ -1055,6 +1084,8 @@ export class Nav implements NavOutlet {
1055
1084
}
1056
1085
1057
1086
this . sbAni . progressEnd ( shouldComplete ? 1 : 0 , newStepValue , dur ) ;
1087
+ } else {
1088
+ this . gestureOrAnimationInProgress = false ;
1058
1089
}
1059
1090
}
1060
1091
0 commit comments