Skip to content

Commit

Permalink
fix(modal): prevent double dismiss via gesture and backdrop tap on ca…
Browse files Browse the repository at this point in the history
…rd-style modal (#20203)

* fix double dismiss via backdrop tap

* add back deleted line

* fix whitespace
  • Loading branch information
liamdebeasi committed Jan 14, 2020
1 parent dc66ce4 commit 5b0400d
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
8 changes: 5 additions & 3 deletions core/src/components/modal/gestures/swipe-to-close.ts
Expand Up @@ -70,13 +70,15 @@ export const createSwipeToCloseGesture = (

animation
.onFinish(() => {
if (shouldComplete) {
onDismiss();
} else {
if (!shouldComplete) {
gesture.enable(true);
}
})
.progressEnd((shouldComplete) ? 1 : 0, newStepValue, duration);

if (shouldComplete) {
onDismiss();
}
};

const gesture = createGesture({
Expand Down
24 changes: 23 additions & 1 deletion core/src/components/modal/modal.tsx
Expand Up @@ -30,6 +30,8 @@ export class Modal implements ComponentInterface, OverlayInterface {
// Reference to the user's provided modal content
private usersElement?: HTMLElement;

// Whether or not modal is being dismissed via gesture
private gestureAnimationDismissing = false;
presented = false;
animation?: Animation;
mode = getIonMode(this);
Expand Down Expand Up @@ -152,7 +154,23 @@ export class Modal implements ComponentInterface, OverlayInterface {
this.gesture = createSwipeToCloseGesture(
this.el,
ani,
() => this.dismiss(undefined, 'gesture')
() => {
/**
* While the gesture animation is finishing
* it is possible for a user to tap the backdrop.
* This would result in the dismiss animation
* being played again. Typically this is avoided
* by setting `presented = false` on the overlay
* component; however, we cannot do that here as
* that would prevent the element from being
* removed from the DOM.
*/
this.gestureAnimationDismissing = true;
this.animation!.onFinish(async () => {
await this.dismiss(undefined, 'gesture');
this.gestureAnimationDismissing = false;
});
},
);
this.gesture.enable(true);
}
Expand All @@ -166,6 +184,10 @@ export class Modal implements ComponentInterface, OverlayInterface {
*/
@Method()
async dismiss(data?: any, role?: string): Promise<boolean> {
if (this.gestureAnimationDismissing && role !== 'gesture') {
return false;
}

const iosAni = (this.animation === undefined || (role === BACKDROP || role === undefined)) ? iosLeaveAnimation : undefined;
const enteringAnimation = activeAnimations.get(this) || [];
const dismissed = await dismiss(this, data, role, 'modalLeave', iosAni, mdLeaveAnimation, this.presentingElement);
Expand Down

0 comments on commit 5b0400d

Please sign in to comment.