mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-01-12 22:50:10 +08:00
Properly gate platform specific code in Alert
Summary: In the past, Alert and AlertIOS were separate modules and both were shipped on Android even though only Alert can be used there. We unified the two modules but it meant that the code for both was still shipped on both platforms. This diff changes it so that platform specific code is gated in a `Platform.OS` block, which means that the unnecessary code per platform is being stripped out. I'm not looking to win a beauty contest with the code in this module - we have barely touched it in years and I don't think we will touch it anytime soon, so I just merged the sub-classes (which only had static methods anyway) directly into the main class. I'm aware I could make two separate files with platform extensions but that ends up being more code here and it seems straightforward enough to me. Reviewed By: TheSavior Differential Revision: D14057404 fbshipit-source-id: 1ae1d227a39d76de9779b3db62960cca46e9b75c
This commit is contained in:
committed by
Facebook Github Bot
parent
c974b5e966
commit
c6d8f6048a
@@ -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();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user