Skip to content

Commit 77aaa7c

Browse files
author
farfromrefuge
committed
fix(dialogs): allow AlertDialog to hide while resolving the show promise
1 parent fb6374e commit 77aaa7c

File tree

3 files changed

+38
-15
lines changed

3 files changed

+38
-15
lines changed

src/dialogs/dialogs-common.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,5 @@ export interface MDCAlertControlerOptions {
2525
export function isDialogOptions(arg) {
2626
return typeof arg === 'object';
2727
}
28+
29+
export const showingDialogs = [];

src/dialogs/dialogs.android.ts

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
} from '@nativescript/core';
2020
import { ad } from '@nativescript/core/utils';
2121
import { LoginOptions, MDCAlertControlerOptions, PromptOptions } from './dialogs';
22-
import { isDialogOptions } from './dialogs-common';
22+
import { isDialogOptions, showingDialogs } from './dialogs-common';
2323

2424
export { capitalizationType, inputType };
2525

@@ -152,6 +152,7 @@ function showDialog(dlg: androidx.appcompat.app.AlertDialog, options: DialogOpti
152152
}
153153
});
154154
}
155+
showingDialogs.push(dlg);
155156
dlg.show();
156157
return dlg;
157158
}
@@ -164,11 +165,14 @@ function prepareAndCreateAlertDialog(
164165
) {
165166
// onDismiss will always be called. Prevent calling callback multiple times
166167
let onDoneCalled = false;
167-
const onDone = function (result: boolean, dialog?: android.content.DialogInterface, toBeCalledBeforeCallback?) {
168+
const onDone = function (result: any, dialog?: android.content.DialogInterface, toBeCalledBeforeCallback?) {
168169
if (options && options.shouldResolveOnAction && !options.shouldResolveOnAction(validationArgs ? validationArgs(result) : result)) {
169170
return;
170171
}
171172
if (onDoneCalled) {
173+
if (toBeCalledBeforeCallback) {
174+
toBeCalledBeforeCallback();
175+
}
172176
return;
173177
}
174178
//ensure we hide any keyboard
@@ -177,7 +181,7 @@ function prepareAndCreateAlertDialog(
177181
Utils.android.dismissSoftInput(options.view.nativeView);
178182
} else {
179183
const activity = (Application.android.foregroundActivity || Application.android.startActivity) as globalAndroid.app.Activity;
180-
const context = ad.getApplicationContext();
184+
const context = Utils.android.getApplicationContext();
181185
const view = activity != null ? activity.getCurrentFocus() : null;
182186
if (view) {
183187
const imm = context.getSystemService(android.content.Context.INPUT_METHOD_SERVICE) as android.view.inputmethod.InputMethodManager;
@@ -197,7 +201,11 @@ function prepareAndCreateAlertDialog(
197201
}
198202
builder.setOnDismissListener(
199203
new DialogInterface.OnDismissListener({
200-
onDismiss() {
204+
onDismiss(dialog) {
205+
const index = showingDialogs.indexOf(dialog);
206+
if (index !== -1) {
207+
showingDialogs.splice(index, 1);
208+
}
201209
// ensure callback is called after destroying the custom view
202210
onDone(false, undefined, () => {
203211
if ((builder as any)._currentModalCustomView) {
@@ -213,17 +221,18 @@ function prepareAndCreateAlertDialog(
213221
})
214222
);
215223
const dlg = builder.create();
224+
dlg['onDone'] = onDone;
216225
if (!options) {
217226
return dlg;
218227
}
219228
if ((builder as any)._currentModalCustomView) {
220229
const view = (builder as any)._currentModalCustomView as View;
221230
const context = options.context || {};
222231
context.closeCallback = function (...originalArgs) {
223-
dlg.dismiss();
224-
if (callback) {
225-
callback.apply(this, originalArgs);
226-
}
232+
onDone(originalArgs);
233+
// if (callback) {
234+
// callback.apply(this, originalArgs);
235+
// }
227236
};
228237
view.bindingContext = fromObject(context);
229238
}
@@ -340,11 +349,15 @@ export class AlertDialog {
340349
showDialog(this.dialog, this.options);
341350
}
342351
}
343-
async hide() {
352+
async hide(result) {
344353
if (this.dialog) {
345354
return new Promise<void>((resolve) => {
346355
this.onCloseListeners.push(resolve);
347-
this.dialog.cancel();
356+
if (this.dialog['onDone']) {
357+
this.dialog['onDone'](result);
358+
} else {
359+
this.dialog.cancel();
360+
}
348361
this.dialog = null;
349362
});
350363
}

src/dialogs/dialogs.ios.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
inputType
2222
} from '@nativescript/core';
2323
import { LoginOptions, MDCAlertControlerOptions, PromptOptions } from './dialogs';
24-
import { isDialogOptions } from './dialogs-common';
24+
import { isDialogOptions, showingDialogs } from './dialogs-common';
2525

2626
export { capitalizationType, inputType };
2727

@@ -181,6 +181,10 @@ function createAlertController(options: DialogOptions & MDCAlertControlerOptions
181181
}
182182

183183
const clear = (alertController.clear = function clear() {
184+
const index = showingDialogs.indexOf(alertController);
185+
if (index !== -1) {
186+
showingDialogs.splice(index, 1);
187+
}
184188
alertController._resolveFunction = null;
185189
if (alertController.accessoryView instanceof UIViewAutoSizeUIViewAutoSize) {
186190
const view = alertController.accessoryView._view;
@@ -212,9 +216,9 @@ function createAlertController(options: DialogOptions & MDCAlertControlerOptions
212216
alertController._resolveFunction = resolve;
213217
const context = options.context || {};
214218
context.closeCallback = function (...originalArgs) {
215-
if (alertController._resolveFunction && resolve) {
219+
if (alertController._resolveFunction) {
220+
alertController._resolveFunction.apply(this, originalArgs);
216221
alertController._resolveFunction = null;
217-
resolve.apply(this, originalArgs);
218222
}
219223
alertController.dismissViewControllerAnimatedCompletion(true, () => {
220224
clear();
@@ -285,11 +289,15 @@ export class AlertDialog {
285289
}
286290
}
287291
hiding = false;
288-
async hide() {
292+
async hide(result) {
289293
if (this.presentingController && !this.hiding) {
290294
this.hiding = true;
291295
return new Promise<void>((resolve) => {
292296
this.presentingController.dismissViewControllerAnimatedCompletion(true, () => {
297+
if (this.alertController._resolveFunction) {
298+
this.alertController._resolveFunction(result);
299+
this.alertController._resolveFunction = null;
300+
}
293301
resolve?.();
294302
this.alertController.clear();
295303
this.presentingController = null;
@@ -569,7 +577,7 @@ function showUIAlertController(alertController: MDCAlertController, options: Dia
569577
while (viewController && viewController.presentedViewController) {
570578
viewController = viewController.presentedViewController;
571579
}
572-
580+
showingDialogs.push(alertController);
573581
if (viewController) {
574582
if (alertController.popoverPresentationController) {
575583
alertController.popoverPresentationController.sourceView = viewController.view;

0 commit comments

Comments
 (0)