diff --git a/Libraries/Alert/Alert.js b/Libraries/Alert/Alert.js index c47a1a796..ddc126516 100644 --- a/Libraries/Alert/Alert.js +++ b/Libraries/Alert/Alert.js @@ -51,9 +51,56 @@ class Alert { options?: Options, ): void { if (Platform.OS === 'ios') { - AlertIOS.alert(title, message, buttons); + Alert.prompt(title, message, buttons, 'default'); } else if (Platform.OS === 'android') { - AlertAndroid.alert(title, message, buttons, options); + let config = { + title: title || '', + message: message || '', + }; + + if (options) { + config = {...config, cancelable: options.cancelable}; + } + // At most three buttons (neutral, negative, positive). Ignore rest. + // The text 'OK' should be probably localized. iOS Alert does that in native. + const validButtons: Buttons = buttons + ? buttons.slice(0, 3) + : [{text: 'OK'}]; + const buttonPositive = validButtons.pop(); + const buttonNegative = validButtons.pop(); + const buttonNeutral = validButtons.pop(); + if (buttonNeutral) { + config = {...config, buttonNeutral: buttonNeutral.text || ''}; + } + if (buttonNegative) { + config = {...config, buttonNegative: buttonNegative.text || ''}; + } + if (buttonPositive) { + config = {...config, buttonPositive: buttonPositive.text || ''}; + } + NativeModules.DialogManagerAndroid.showAlert( + config, + errorMessage => console.warn(errorMessage), + (action, buttonKey) => { + if (action === NativeModules.DialogManagerAndroid.buttonClicked) { + if ( + buttonKey === NativeModules.DialogManagerAndroid.buttonNeutral + ) { + buttonNeutral.onPress && buttonNeutral.onPress(); + } else if ( + buttonKey === NativeModules.DialogManagerAndroid.buttonNegative + ) { + buttonNegative.onPress && buttonNegative.onPress(); + } else if ( + buttonKey === NativeModules.DialogManagerAndroid.buttonPositive + ) { + buttonPositive.onPress && buttonPositive.onPress(); + } + } else if (action === NativeModules.DialogManagerAndroid.dismissed) { + options && options.onDismiss && options.onDismiss(); + } + }, + ); } } @@ -66,157 +113,67 @@ class Alert { keyboardType?: string, ): void { if (Platform.OS === 'ios') { - AlertIOS.prompt( - title, - message, - callbackOrButtons, - type, - defaultValue, - keyboardType, - ); - } - } -} + if (typeof type === 'function') { + console.warn( + 'You passed a callback function as the "type" argument to Alert.prompt(). React Native is ' + + 'assuming you want to use the deprecated Alert.prompt(title, defaultValue, buttons, callback) ' + + 'signature. The current signature is Alert.prompt(title, message, callbackOrButtons, type, defaultValue, ' + + 'keyboardType) and the old syntax will be removed in a future version.', + ); -/** - * Wrapper around the iOS native module. - */ -class AlertIOS { - static alert( - title: ?string, - message?: ?string, - callbackOrButtons?: ?((() => void) | Buttons), - ): void { - this.prompt(title, message, callbackOrButtons, 'default'); - } + const callback = type; + RCTAlertManager.alertWithArgs( + { + title: title || '', + type: 'plain-text', + defaultValue: message, + }, + (id, value) => { + callback(value); + }, + ); + return; + } - static prompt( - title: ?string, - message?: ?string, - callbackOrButtons?: ?(((text: string) => void) | Buttons), - type?: ?AlertType = 'plain-text', - defaultValue?: string, - keyboardType?: string, - ): void { - if (typeof type === 'function') { - console.warn( - 'You passed a callback function as the "type" argument to Alert.prompt(). React Native is ' + - 'assuming you want to use the deprecated Alert.prompt(title, defaultValue, buttons, callback) ' + - 'signature. The current signature is Alert.prompt(title, message, callbackOrButtons, type, defaultValue, ' + - 'keyboardType) and the old syntax will be removed in a future version.', - ); + let callbacks = []; + const buttons = []; + let cancelButtonKey; + let destructiveButtonKey; + if (typeof callbackOrButtons === 'function') { + callbacks = [callbackOrButtons]; + } else if (Array.isArray(callbackOrButtons)) { + callbackOrButtons.forEach((btn, index) => { + callbacks[index] = btn.onPress; + if (btn.style === 'cancel') { + cancelButtonKey = String(index); + } else if (btn.style === 'destructive') { + destructiveButtonKey = String(index); + } + if (btn.text || index < (callbackOrButtons || []).length - 1) { + const btnDef = {}; + btnDef[index] = btn.text || ''; + buttons.push(btnDef); + } + }); + } - const callback = type; RCTAlertManager.alertWithArgs( { title: title || '', - type: 'plain-text', - defaultValue: message, + message: message || undefined, + buttons, + type: type || undefined, + defaultValue, + cancelButtonKey, + destructiveButtonKey, + keyboardType, }, (id, value) => { - callback(value); + const cb = callbacks[id]; + cb && cb(value); }, ); - return; } - - let callbacks = []; - const buttons = []; - let cancelButtonKey; - let destructiveButtonKey; - if (typeof callbackOrButtons === 'function') { - callbacks = [callbackOrButtons]; - } else if (Array.isArray(callbackOrButtons)) { - callbackOrButtons.forEach((btn, index) => { - callbacks[index] = btn.onPress; - if (btn.style === 'cancel') { - cancelButtonKey = String(index); - } else if (btn.style === 'destructive') { - destructiveButtonKey = String(index); - } - if (btn.text || index < (callbackOrButtons || []).length - 1) { - const btnDef = {}; - btnDef[index] = btn.text || ''; - buttons.push(btnDef); - } - }); - } - - RCTAlertManager.alertWithArgs( - { - title: title || '', - message: message || undefined, - buttons, - type: type || undefined, - defaultValue, - cancelButtonKey, - destructiveButtonKey, - keyboardType, - }, - (id, value) => { - const cb = callbacks[id]; - cb && cb(value); - }, - ); - } -} - -/** - * Wrapper around the Android native module. - */ -class AlertAndroid { - static alert( - title: ?string, - message?: ?string, - buttons?: Buttons, - options?: Options, - ): void { - let config = { - title: title || '', - message: message || '', - }; - - if (options) { - config = {...config, cancelable: options.cancelable}; - } - // At most three buttons (neutral, negative, positive). Ignore rest. - // The text 'OK' should be probably localized. iOS Alert does that in native. - const validButtons: Buttons = buttons - ? buttons.slice(0, 3) - : [{text: 'OK'}]; - const buttonPositive = validButtons.pop(); - const buttonNegative = validButtons.pop(); - const buttonNeutral = validButtons.pop(); - if (buttonNeutral) { - config = {...config, buttonNeutral: buttonNeutral.text || ''}; - } - if (buttonNegative) { - config = {...config, buttonNegative: buttonNegative.text || ''}; - } - if (buttonPositive) { - config = {...config, buttonPositive: buttonPositive.text || ''}; - } - NativeModules.DialogManagerAndroid.showAlert( - config, - errorMessage => console.warn(errorMessage), - (action, buttonKey) => { - if (action === NativeModules.DialogManagerAndroid.buttonClicked) { - if (buttonKey === NativeModules.DialogManagerAndroid.buttonNeutral) { - buttonNeutral.onPress && buttonNeutral.onPress(); - } else if ( - buttonKey === NativeModules.DialogManagerAndroid.buttonNegative - ) { - buttonNegative.onPress && buttonNegative.onPress(); - } else if ( - buttonKey === NativeModules.DialogManagerAndroid.buttonPositive - ) { - buttonPositive.onPress && buttonPositive.onPress(); - } - } else if (action === NativeModules.DialogManagerAndroid.dismissed) { - options && options.onDismiss && options.onDismiss(); - } - }, - ); } }