Skip to content

fix: modal beforeClosed and afterClosed consistency between platforms #87

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

Merged
merged 1 commit into from
Sep 13, 2022
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
11 changes: 8 additions & 3 deletions packages/angular/src/lib/cdk/dialog/dialog-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,14 @@ export class NativeDialogRef<T, R = any> {
.subscribe(() => {
clearTimeout(this._closeFallbackTimeout);
this._finishDialogClose();
this._afterClosed.next(this._result);
this._afterClosed.complete();
});

_nativeModalRef.onDismiss.subscribe(() => {
this._beforeClosed.next(this._result);
this._beforeClosed.complete();
this._afterClosed.next(this._result);
this._afterClosed.complete();

this.componentInstance = null!;
_nativeModalRef.dispose();
});
Expand Down Expand Up @@ -98,7 +99,11 @@ export class NativeDialogRef<T, R = any> {
// amount of time plus 100ms. We don't need to run this outside the NgZone, because for the
// vast majority of cases the timeout will have been cleared before it has the chance to fire.
this._closeFallbackTimeout = setTimeout(
() => this._finishDialogClose(),
() => {
this._finishDialogClose();
this._afterClosed.next(this._result);
this._afterClosed.complete();
},
//event.totalTime + 100);
100
);
Expand Down
18 changes: 11 additions & 7 deletions packages/angular/src/lib/cdk/dialog/native-modal-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export class NativeModalRef {
modalViewRef: NgViewRef<any>;

private _closeCallback: () => void;
private _isDismissed = false;

constructor(private _config: NativeDialogConfig, private _injector: Injector, @Optional() private location?: NSLocationStrategy) {
let parentView = this._config.viewContainerRef?.element.nativeElement || Application.getRootView();
Expand All @@ -38,10 +39,12 @@ export class NativeModalRef {
}
this.parentView = parentView;

this._closeCallback = once(() => {
this._closeCallback = once(async () => {
this.stateChanged.next({ state: 'closing' });
this.modalViewRef.firstNativeLikeView?.closeModal();
this.location?._closeModalNavigation();
if (!this._isDismissed) {
this.modalViewRef.firstNativeLikeView?.closeModal();
}
await this.location?._closeModalNavigation();
// this.detachedLoaderRef?.destroy();
if (this.modalViewRef?.firstNativeLikeView.isLoaded) {
fromEvent(this.modalViewRef.firstNativeLikeView, 'unloaded')
Expand Down Expand Up @@ -81,8 +84,8 @@ export class NativeModalRef {
this.parentView.showModal(this.modalViewRef.firstNativeLikeView, {
context: null,
...userOptions,
closeCallback: () => {
this.location?._closeModalNavigation();
closeCallback: async () => {
await this.location?._closeModalNavigation();
this.onDismiss.next();
this.onDismiss.complete();
},
Expand Down Expand Up @@ -113,8 +116,9 @@ export class NativeModalRef {
this.parentView.showModal(this.modalViewRef.firstNativeLikeView, {
context: null,
...userOptions,
closeCallback: () => {
this.location?._closeModalNavigation();
closeCallback: async () => {
this._isDismissed = true;
this._closeCallback(); // close callback can only be called once, so we call it here to setup the exit events
this.onDismiss.next();
this.onDismiss.complete();
},
Expand Down
4 changes: 2 additions & 2 deletions packages/angular/src/lib/legacy/directives/dialogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,15 @@ export class ModalDialogService {
let detachedLoaderRef: ComponentRef<DetachedLoader>;
let portalOutlet: NativeScriptDomPortalOutlet;

const closeCallback = once((...args) => {
const closeCallback = once(async (...args) => {
options.doneCallback.apply(undefined, args);
if (componentViewRef) {
componentViewRef.firstNativeLikeView.closeModal();
const params = this.openedModalParams.pop();
if (this._closed$) {
this._closed$.next(params);
}
this.location._closeModalNavigation();
await this.location._closeModalNavigation();
if (detachedLoaderRef || portalOutlet) {
this.zone.run(() => {
portalOutlet?.dispose();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@ export class NSLocationStrategy extends LocationStrategy {
this.currentOutlet = outlet;
this.currentOutlet.showingModal = false;
this.callPopState(this.currentOutlet.peekState(), false);
// this is needed because angular does a setTimeout on onPopState, so if we don't do this we might end up with inconsistent state
return new Promise((resolve) => setTimeout(resolve, 0));
}
}

Expand Down