Skip to content
Closed
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
35 changes: 30 additions & 5 deletions Libraries/ActionSheetIOS/ActionSheetIOS.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
'use strict';

import RCTActionSheetManager from './NativeActionSheetManager';
import ReactNative from '../Renderer/shims/ReactNative';

const invariant = require('invariant');
const processColor = require('../StyleSheet/processColor');
Expand Down Expand Up @@ -41,11 +42,12 @@ const ActionSheetIOS = {
options: {|
+title?: ?string,
+message?: ?string,
+options: Array<string>,
+options: ?Array<string>,
+destructiveButtonIndex?: ?number | ?Array<number>,
+cancelButtonIndex?: ?number,
+anchor?: ?number,
+tintColor?: number | string,
+surface?: mixed,
|},
callback: (buttonIndex: number) => void,
) {
Expand All @@ -56,7 +58,13 @@ const ActionSheetIOS = {
invariant(typeof callback === 'function', 'Must provide a valid callback');
invariant(RCTActionSheetManager, "ActionSheetManager does't exist");

const {tintColor, destructiveButtonIndex, ...remainingOptions} = options;
const {
tintColor,
destructiveButtonIndex,
surface,
...remainingOptions
} = options;
const reactTag = ReactNative.findNodeHandle(surface) ?? -1;
let destructiveButtonIndices = null;

if (Array.isArray(destructiveButtonIndex)) {
Expand All @@ -68,6 +76,7 @@ const ActionSheetIOS = {
RCTActionSheetManager.showActionSheetWithOptions(
{
...remainingOptions,
reactTag,
tintColor: processColor(tintColor),
destructiveButtonIndices,
},
Expand Down Expand Up @@ -99,9 +108,17 @@ const ActionSheetIOS = {
* See http://facebook.github.io/react-native/docs/actionsheetios.html#showshareactionsheetwithoptions
*/
showShareActionSheetWithOptions(
options: Object,
options: {|
+message?: ?string,
+url?: ?string,
+subject?: ?string,
+anchor?: ?number,
+tintColor?: ?number | string,
+excludedActivityTypes?: ?Array<string>,
+surface?: mixed,
|},
failureCallback: Function,
successCallback: Function,
successCallback: (completed: boolean, activityType: ?string) => void,
) {
invariant(
typeof options === 'object' && options !== null,
Expand All @@ -116,8 +133,16 @@ const ActionSheetIOS = {
'Must provide a valid successCallback',
);
invariant(RCTActionSheetManager, "ActionSheetManager does't exist");

const {tintColor, surface, ...remainingOptions} = options;
const reactTag = ReactNative.findNodeHandle(surface) ?? -1;

RCTActionSheetManager.showShareActionSheetWithOptions(
{...options, tintColor: processColor(options.tintColor)},
{
...remainingOptions,
reactTag,
tintColor: processColor(options.tintColor),
},
failureCallback,
successCallback,
);
Expand Down
2 changes: 2 additions & 0 deletions Libraries/ActionSheetIOS/NativeActionSheetManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export interface Spec extends TurboModule {
+cancelButtonIndex?: ?number,
+anchor?: ?number,
+tintColor?: ?number,
+reactTag?: number,
|},
callback: (buttonIndex: number) => void,
) => void;
Expand All @@ -35,6 +36,7 @@ export interface Spec extends TurboModule {
+anchor?: ?number,
+tintColor?: ?number,
+excludedActivityTypes?: ?Array<string>,
+reactTag?: number,
|},
failureCallback: (error: {|
+domain: string,
Expand Down
22 changes: 16 additions & 6 deletions Libraries/Alert/Alert.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import NativeDialogManagerAndroid, {
type DialogOptions,
} from '../NativeModules/specs/NativeDialogManagerAndroid';
import RCTAlertManager from './RCTAlertManager';
import ReactNative from '../Renderer/shims/ReactNative';

export type AlertType =
| 'default'
Expand All @@ -30,11 +31,16 @@ export type Buttons = Array<{
}>;

type Options = {
cancelable?: ?boolean,
onDismiss?: ?() => void,
+cancelable?: ?boolean,
+onDismiss?: ?() => void,
+surface?: mixed,
...
};

type PromptOptions = {
surface?: mixed,
};

/**
* Launches an alert dialog with the specified title and message.
*
Expand All @@ -45,10 +51,12 @@ class Alert {
title: ?string,
message?: ?string,
buttons?: Buttons,
options?: Options,
options?: Options = {},
): void {
if (Platform.OS === 'ios') {
Alert.prompt(title, message, buttons, 'default');
Alert.prompt(title, message, buttons, 'default', undefined, undefined, {
surface: options.surface,
});
} else if (Platform.OS === 'android') {
if (!NativeDialogManagerAndroid) {
return;
Expand All @@ -61,7 +69,7 @@ class Alert {
cancelable: false,
};

if (options && options.cancelable) {
if (options.cancelable) {
config.cancelable = options.cancelable;
}
// At most three buttons (neutral, negative, positive). Ignore rest.
Expand Down Expand Up @@ -94,7 +102,7 @@ class Alert {
buttonPositive.onPress && buttonPositive.onPress();
}
} else if (action === constants.dismissed) {
options && options.onDismiss && options.onDismiss();
options.onDismiss && options.onDismiss();
}
};
const onError = errorMessage => console.warn(errorMessage);
Expand All @@ -109,6 +117,7 @@ class Alert {
type?: ?AlertType = 'plain-text',
defaultValue?: string,
keyboardType?: string,
options?: PromptOptions = {surface: undefined},
): void {
if (Platform.OS === 'ios') {
let callbacks = [];
Expand Down Expand Up @@ -143,6 +152,7 @@ class Alert {
cancelButtonKey,
destructiveButtonKey,
keyboardType,
reactTag: ReactNative.findNodeHandle(options.surface) ?? -1,
},
(id, value) => {
const cb = callbacks[id];
Expand Down
1 change: 1 addition & 0 deletions Libraries/Alert/NativeAlertManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type Args = {|
cancelButtonKey?: string,
destructiveButtonKey?: string,
keyboardType?: string,
reactTag?: number,
|};

export interface Spec extends TurboModule {
Expand Down
12 changes: 10 additions & 2 deletions Libraries/Components/StatusBar/NativeStatusBarManagerIOS.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,19 @@ export interface Spec extends TurboModule {
* - 'dark-content'
* - 'light-content'
*/
+setStyle: (statusBarStyle?: ?string, animated: boolean) => void;
+setStyle: (
statusBarStyle?: ?string,
animated: boolean,
reactTag?: number,
) => void;
/**
* - withAnimation can be: 'none' | 'fade' | 'slide'
*/
+setHidden: (hidden: boolean, withAnimation: string) => void;
+setHidden: (
hidden: boolean,
withAnimation: string,
reactTag?: number,
) => void;
}

export default (TurboModuleRegistry.getEnforcing<Spec>(
Expand Down
53 changes: 40 additions & 13 deletions Libraries/Components/StatusBar/StatusBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
'use strict';

const Platform = require('../../Utilities/Platform');
const RootTagContext = require('../../ReactNative/RootTagContext');
import ReactNative from '../../Renderer/shims/ReactNative';
const React = require('react');

const processColor = require('../../StyleSheet/processColor');
Expand Down Expand Up @@ -262,11 +264,19 @@ class StatusBar extends React.Component<Props> {
* @param animation Optional animation when
* changing the status bar hidden property.
*/
static setHidden(hidden: boolean, animation?: StatusBarAnimation) {
static setHidden(
hidden: boolean,
animation?: StatusBarAnimation,
surface?: mixed,
) {
animation = animation || 'none';
StatusBar._defaultProps.hidden.value = hidden;
if (Platform.OS === 'ios') {
NativeStatusBarManagerIOS.setHidden(hidden, animation);
NativeStatusBarManagerIOS.setHidden(
hidden,
animation,
ReactNative.findNodeHandle(surface) ?? -1,
);
} else if (Platform.OS === 'android') {
NativeStatusBarManagerAndroid.setHidden(hidden);
}
Expand All @@ -277,11 +287,19 @@ class StatusBar extends React.Component<Props> {
* @param style Status bar style to set
* @param animated Animate the style change.
*/
static setBarStyle(style: StatusBarStyle, animated?: boolean) {
static setBarStyle(
style: StatusBarStyle,
animated?: boolean,
surface?: mixed,
) {
animated = animated || false;
StatusBar._defaultProps.barStyle.value = style;
if (Platform.OS === 'ios') {
NativeStatusBarManagerIOS.setStyle(style, animated);
NativeStatusBarManagerIOS.setStyle(
style,
animated,
ReactNative.findNodeHandle(surface) ?? -1,
);
} else if (Platform.OS === 'android') {
NativeStatusBarManagerAndroid.setStyle(style);
}
Expand All @@ -290,6 +308,7 @@ class StatusBar extends React.Component<Props> {
/**
* Control the visibility of the network activity indicator
* @param visible Show the indicator.
* @platform ios
*/
static setNetworkActivityIndicatorVisible(visible: boolean) {
if (Platform.OS !== 'ios') {
Expand All @@ -306,6 +325,7 @@ class StatusBar extends React.Component<Props> {
* Set the background color for the status bar
* @param color Background color.
* @param animated Animate the style change.
* @platform android
*/
static setBackgroundColor(color: string, animated?: boolean) {
if (Platform.OS !== 'android') {
Expand All @@ -329,6 +349,7 @@ class StatusBar extends React.Component<Props> {
/**
* Control the translucency of the status bar
* @param translucent Set as translucent.
* @platform android
*/
static setTranslucent(translucent: boolean) {
if (Platform.OS !== 'android') {
Expand All @@ -345,10 +366,10 @@ class StatusBar extends React.Component<Props> {
*
* @param props Object containing the StatusBar props to use in the stack entry.
*/
static pushStackEntry(props: any): any {
static pushStackEntry(props: any, surface?: mixed): any {
const entry = createStackEntry(props);
StatusBar._propsStack.push(entry);
StatusBar._updatePropsStack();
StatusBar._updatePropsStack(surface);
return entry;
}

Expand All @@ -357,12 +378,12 @@ class StatusBar extends React.Component<Props> {
*
* @param entry Entry returned from `pushStackEntry`.
*/
static popStackEntry(entry: any) {
static popStackEntry(entry: any, surface?: mixed) {
const index = StatusBar._propsStack.indexOf(entry);
if (index !== -1) {
StatusBar._propsStack.splice(index, 1);
}
StatusBar._updatePropsStack();
StatusBar._updatePropsStack(surface);
}

/**
Expand All @@ -371,13 +392,13 @@ class StatusBar extends React.Component<Props> {
* @param entry Entry returned from `pushStackEntry` to replace.
* @param props Object containing the StatusBar props to use in the replacement stack entry.
*/
static replaceStackEntry(entry: any, props: any): any {
static replaceStackEntry(entry: any, props: any, surface?: mixed): any {
const newEntry = createStackEntry(props);
const index = StatusBar._propsStack.indexOf(entry);
if (index !== -1) {
StatusBar._propsStack[index] = newEntry;
}
StatusBar._updatePropsStack();
StatusBar._updatePropsStack(surface);
return newEntry;
}

Expand All @@ -389,33 +410,37 @@ class StatusBar extends React.Component<Props> {
showHideTransition: 'fade',
};

// $FlowFixMe (signature-verification-failure)
static contextType = RootTagContext;

_stackEntry = null;

componentDidMount() {
// Every time a StatusBar component is mounted, we push it's prop to a stack
// and always update the native status bar with the props from the top of then
// stack. This allows having multiple StatusBar components and the one that is
// added last or is deeper in the view hierarchy will have priority.
this._stackEntry = StatusBar.pushStackEntry(this.props);
this._stackEntry = StatusBar.pushStackEntry(this.props, this.context);
}

componentWillUnmount() {
// When a StatusBar is unmounted, remove itself from the stack and update
// the native bar with the next props.
StatusBar.popStackEntry(this._stackEntry);
StatusBar.popStackEntry(this._stackEntry, this.context);
}

componentDidUpdate() {
this._stackEntry = StatusBar.replaceStackEntry(
this._stackEntry,
this.props,
this.context,
);
}

/**
* Updates the native status bar with the props from the stack.
*/
static _updatePropsStack = () => {
static _updatePropsStack = (surface?: mixed) => {
// Send the update to the native module only once at the end of the frame.
clearImmediate(StatusBar._updateImmediate);
StatusBar._updateImmediate = setImmediate(() => {
Expand All @@ -434,6 +459,7 @@ class StatusBar extends React.Component<Props> {
NativeStatusBarManagerIOS.setStyle(
mergedProps.barStyle.value,
mergedProps.barStyle.animated || false,
ReactNative.findNodeHandle(surface) ?? -1,
);
}
if (!oldProps || oldProps.hidden.value !== mergedProps.hidden.value) {
Expand All @@ -442,6 +468,7 @@ class StatusBar extends React.Component<Props> {
mergedProps.hidden.animated
? mergedProps.hidden.transition
: 'none',
ReactNative.findNodeHandle(surface) ?? -1,
);
}

Expand Down
Loading