Skip to content
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
21 changes: 21 additions & 0 deletions e2e/Overlay.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,24 @@ describe('Overlay', () => {
await expect(elementById(TestIDs.TOP_BAR_ELEMENT)).toBeVisible();
});
});

describe('Overlay Dismiss all', () => {
beforeEach(async () => {
await device.launchApp({ newInstance: true });
await elementById(TestIDs.NAVIGATION_TAB).tap();
await elementById(TestIDs.OVERLAY_BTN).tap();
});

it('dismissAllOverlays should dismiss all opened overlays', async() => {
await elementById(TestIDs.SHOW_FULLSCREEN_OVERLAY_BTN).tap();
await elementById(TestIDs.SHOW_OVERLAY_BTN).tap();
await elementById(TestIDs.DISMISS_ALL_OVERLAYS_BUTTON).tap();
await expect(elementById(TestIDs.OVERLAY_DISMISSED_COUNT)).toHaveText('2');
});

it('dismissAllOverlays should be able to dismiss only one overlay', async() => {
await elementById(TestIDs.SHOW_OVERLAY_BTN).tap();
await elementById(TestIDs.DISMISS_ALL_OVERLAYS_BUTTON).tap();
await expect(elementById(TestIDs.OVERLAY_DISMISSED_COUNT)).toHaveText('1');
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@ public void dismissOverlay(String commandId, String componentId, Promise promise
handle(() -> navigator().dismissOverlay(componentId, new NativeCommandListener("dismissOverlay", commandId, promise, eventEmitter, now)));
}

@ReactMethod
public void dismissAllOverlays(String commandId, Promise promise) {
handle(() -> navigator().dismissAllOverlays(new NativeCommandListener("dismissAllOverlays", commandId, promise, eventEmitter, now)));
}

private Navigator navigator() {
return activity().getNavigator();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ public void dismissOverlay(final String componentId, CommandListener listener) {
overlayManager.dismiss(overlaysLayout, componentId, listener);
}

public void dismissAllOverlays(CommandListener listener) {
overlayManager.dismissAll(overlaysLayout, listener);
}

@Nullable
@Override
public ViewController findController(String id) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ public void dismiss(ViewGroup overlaysContainer, String componentId, CommandList
}
}

public void dismissAll(ViewGroup overlaysContainer, CommandListener listener) {
destroy(overlaysContainer);
listener.onSuccess("");
}

public void destroy(ViewGroup overlaysContainer) {
forEach(overlayRegistry.values(), overlay -> destroyOverlay(overlaysContainer, overlay));
}
Expand Down
10 changes: 10 additions & 0 deletions lib/ios/RNNBridgeModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,16 @@ - (instancetype)initWithCommandsHandler:(RNNCommandsHandler *)commandsHandler {
});
}

RCT_EXPORT_METHOD(dismissAllOverlays
: (NSString *)commandId componentId
: (RCTPromiseResolveBlock)resolve rejecter
: (RCTPromiseRejectBlock)reject) {
RCTExecuteOnMainQueue(^{
[self->_commandsHandler dismissAllOverlays:commandId];
resolve(nil);
});
}

RCT_EXPORT_METHOD(getLaunchArgs
: (NSString *)commandId
: (RCTPromiseResolveBlock)resolve rejecter
Expand Down
2 changes: 2 additions & 0 deletions lib/ios/RNNCommandsHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,6 @@
completion:(RNNTransitionCompletionBlock)completion
rejection:(RNNTransitionRejectionBlock)reject;

- (void)dismissAllOverlays:(NSString *)commandId;

@end
9 changes: 9 additions & 0 deletions lib/ios/RNNCommandsHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
static NSString *const dismissAllModals = @"dismissAllModals";
static NSString *const showOverlay = @"showOverlay";
static NSString *const dismissOverlay = @"dismissOverlay";
static NSString *const dismissAllOverlays = @"dismissAllOverlays";
static NSString *const mergeOptions = @"mergeOptions";
static NSString *const setDefaultOptions = @"setDefaultOptions";

Expand Down Expand Up @@ -467,6 +468,14 @@ - (void)dismissOverlay:(NSString *)componentId
}
}

- (void)dismissAllOverlays:(NSString *)commandId {
[self assertReady];
RNNAssertMainQueue();

[_overlayManager dismissAllOverlays];
[self->_eventEmitter sendOnNavigationCommandCompletion:dismissAllOverlays commandId:commandId];
}

#pragma mark - private

- (void)assertReady {
Expand Down
7 changes: 7 additions & 0 deletions lib/src/Navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,13 @@ export class NavigationRoot {
return this.commands.dismissOverlay(componentId);
}

/**
* dismiss all overlays
*/
public dismissAllOverlays(): Promise<string> {
return this.commands.dismissAllOverlays();
}

/**
* Resolves arguments passed on launch
*/
Expand Down
5 changes: 5 additions & 0 deletions lib/src/adapters/NativeCommandsSender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ interface NativeCommandsModule {
dismissAllModals(commandId: string, options?: object): Promise<any>;
showOverlay(commandId: string, layout: object): Promise<any>;
dismissOverlay(commandId: string, componentId: string): Promise<any>;
dismissAllOverlays(commandId: string): Promise<any>;
getLaunchArgs(commandId: string): Promise<any>;
}

Expand Down Expand Up @@ -75,6 +76,10 @@ export class NativeCommandsSender {
return this.nativeCommandsModule.dismissOverlay(commandId, componentId);
}

dismissAllOverlays(commandId: string) {
return this.nativeCommandsModule.dismissAllOverlays(commandId);
}

getLaunchArgs(commandId: string) {
return this.nativeCommandsModule.getLaunchArgs(commandId);
}
Expand Down
2 changes: 2 additions & 0 deletions lib/src/commands/Commands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@ describe('Commands', () => {
setStackRoot: ['id', [{}]],
showOverlay: [{}],
dismissOverlay: ['id'],
dismissAllOverlays: [{}],
getLaunchArgs: ['id'],
};
const paramsForMethodName: Record<string, object> = {
Expand All @@ -541,6 +542,7 @@ describe('Commands', () => {
},
showOverlay: { commandId: 'showOverlay+UNIQUE_ID', layout: null },
dismissOverlay: { commandId: 'dismissOverlay+UNIQUE_ID', componentId: 'id' },
dismissAllOverlays: { commandId: 'dismissAllOverlays+UNIQUE_ID' },
getLaunchArgs: { commandId: 'getLaunchArgs+UNIQUE_ID' },
};
forEach(getAllMethodsOfUut(), (m) => {
Expand Down
7 changes: 7 additions & 0 deletions lib/src/commands/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,13 @@ export class Commands {
return result;
}

public dismissAllOverlays() {
const commandId = this.uniqueIdProvider.generate(CommandName.DismissAllOverlays);
const result = this.nativeCommandsSender.dismissAllOverlays(commandId);
this.commandsObserver.notify(CommandName.DismissAllOverlays, { commandId });
return result;
}

public getLaunchArgs() {
const commandId = this.uniqueIdProvider.generate(CommandName.GetLaunchArgs);
const result = this.nativeCommandsSender.getLaunchArgs(commandId);
Expand Down
1 change: 1 addition & 0 deletions lib/src/interfaces/CommandName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export enum CommandName {
SetStackRoot = 'setStackRoot',
ShowOverlay = 'showOverlay',
DismissOverlay = 'dismissOverlay',
DismissAllOverlays = 'dismissAllOverlays',
GetLaunchArgs = 'getLaunchArgs',
}
31 changes: 28 additions & 3 deletions playground/src/screens/OverlayAlert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,40 @@ import { component } from '../commons/Layouts';
import Screens from './Screens';
import testIDs from '../testIDs';

const { OVERLAY_ALERT_HEADER, DISMISS_BTN, SET_INTERCEPT_TOUCH } = testIDs;
const {
OVERLAY_ALERT_HEADER,
DISMISS_BTN,
SET_INTERCEPT_TOUCH,
DISMISS_ALL_OVERLAYS_BUTTON,
} = testIDs;

export default class OverlayAlert extends React.PureComponent<NavigationComponentProps> {
interface Props extends NavigationComponentProps {
incrementDismissedOverlays: any;
}

export default class OverlayAlert extends React.PureComponent<Props> {
constructor(props: Props) {
super(props);
Navigation.events().registerCommandCompletedListener((event) => {
if (event.commandName === 'dismissAllOverlays') {
if (this.props.incrementDismissedOverlays) {
this.props.incrementDismissedOverlays();
}
}
});
}
render() {
return (
<View style={styles.root}>
<Text style={styles.title} testID={OVERLAY_ALERT_HEADER}>
Test view
</Text>
<Button title="Dismiss" testID={DISMISS_BTN} onPress={this.dismiss} />
<Button
title="Dismiss All Overlays"
testID={DISMISS_ALL_OVERLAYS_BUTTON}
onPress={this.dismissAllOverlays}
/>
<Button title="Set Root" onPress={this.setRoot} />
<Button
title="Set Intercept touch"
Expand All @@ -25,6 +49,7 @@ export default class OverlayAlert extends React.PureComponent<NavigationComponen
);
}

dismissAllOverlays = () => Navigation.dismissAllOverlays();
dismiss = () => Navigation.dismissOverlay(this.props.componentId);
setRoot = () => Navigation.setRoot({ root: component(Screens.Pushed) });

Expand All @@ -46,7 +71,7 @@ const styles = StyleSheet.create<Style>({
position: 'absolute',
backgroundColor: 'green',
alignItems: 'center',
height: 160,
height: 200,
bottom: 0,
left: 0,
right: 0,
Expand Down
64 changes: 59 additions & 5 deletions playground/src/screens/OverlayScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,25 @@ import { component } from '../commons/Layouts';
import Navigation from '../services/Navigation';
import Screens from './Screens';
import testIDs from '../testIDs';
import { Text } from 'react-native';

const {
SHOW_OVERLAY_BTN,
SHOW_TOUCH_THROUGH_OVERLAY_BTN,
ALERT_BUTTON,
SET_ROOT_BTN,
TOAST_BTN,
SHOW_FULLSCREEN_OVERLAY_BTN,
OVERLAY_DISMISSED_COUNT,
} = testIDs;

export default class OverlayScreen extends React.Component<NavigationComponentProps> {
interface State {
overlayDismissedCount?: number;
}
interface Props extends NavigationComponentProps {
incrementDismissedOverlays: any;
}
export default class OverlayScreen extends React.Component<Props, State> {
static options() {
return {
topBar: {
Expand All @@ -26,16 +35,44 @@ export default class OverlayScreen extends React.Component<NavigationComponentPr
};
}

state = {
overlayDismissedCount: 0,
};

constructor(props: Props) {
super(props);
Navigation.events().registerCommandCompletedListener((event) => {
if (event.commandName === 'dismissAllOverlays') {
if (this.props.incrementDismissedOverlays) {
this.props.incrementDismissedOverlays();
}
}
});
this.incrementDismissedOverlays = this.incrementDismissedOverlays.bind(this);
}

incrementDismissedOverlays() {
this.setState({
overlayDismissedCount: this.state.overlayDismissedCount + 1,
});
}

render() {
return (
<Root componentId={this.props.componentId}>
<Text testID={OVERLAY_DISMISSED_COUNT}>{this.state?.overlayDismissedCount || ''}</Text>
<Button label="Toast" testID={TOAST_BTN} onPress={this.toast} />
<Button label="Alert" testID={ALERT_BUTTON} onPress={() => alert('Alert displayed')} />
<Button
label="Show overlay"
testID={SHOW_OVERLAY_BTN}
onPress={() => this.showOverlay(true)}
/>
<Button
label="Show fullscreen overlay"
testID={SHOW_FULLSCREEN_OVERLAY_BTN}
onPress={() => this.showFullScreenOverlay()}
/>
<Button
label="Show touch through overlay"
testID={SHOW_TOUCH_THROUGH_OVERLAY_BTN}
Expand All @@ -50,10 +87,27 @@ export default class OverlayScreen extends React.Component<NavigationComponentPr
toast = () => Navigation.showOverlay(Screens.Toast);

showOverlay = (interceptTouchOutside: boolean) =>
Navigation.showOverlay(Screens.OverlayAlert, {
layout: { componentBackgroundColor: 'transparent' },
overlay: { interceptTouchOutside },
});
Navigation.showOverlay(
Screens.OverlayAlert,
{
layout: { componentBackgroundColor: 'transparent' },
overlay: { interceptTouchOutside },
},
{
incrementDismissedOverlays:
this.props.incrementDismissedOverlays || this.incrementDismissedOverlays,
}
);

showFullScreenOverlay = () =>
Navigation.showOverlay(
Screens.Overlay,
{},
{
incrementDismissedOverlays:
this.props.incrementDismissedOverlays || this.incrementDismissedOverlays,
}
);

setRoot = () => Navigation.setRoot({ root: component(Screens.Pushed) });

Expand Down
7 changes: 5 additions & 2 deletions playground/src/services/Navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ const dismissModal = (selfOrCompId: SelfOrCompId, mergeOptions?: Options) =>

const dismissAllModals = () => Navigation.dismissAllModals();

const showOverlay = (name: CompIdOrLayout, options?: Options) =>
Navigation.showOverlay(component(name, options));
const showOverlay = (name: CompIdOrLayout, options?: Options, passProps?: any) =>
Navigation.showOverlay(component(name, options, passProps));

const dismissOverlay = (compId: string) => Navigation.dismissOverlay(compId);

const dismissAllOverlays = () => Navigation.dismissAllOverlays();

const popToRoot = (self: ComponentIdProp) => Navigation.popToRoot(self.props.componentId);

const mergeOptions = (selfOrCompId: SelfOrCompId, options: Options) =>
Expand Down Expand Up @@ -76,6 +78,7 @@ const CustomNavigation = {
dismissAllModals,
showOverlay,
dismissOverlay,
dismissAllOverlays,
events: Navigation.events.bind(Navigation),
popTo: Navigation.popTo.bind(Navigation),
setDefaultOptions: Navigation.setDefaultOptions.bind(Navigation),
Expand Down
4 changes: 4 additions & 0 deletions playground/src/testIDs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const testIDs = {
BUTTONS_TAB: 'BUTTONS_TAB',
SIDE_MENU_INSIDE_BOTTOM_TABS_BTN: 'SIDE_MENU_INSIDE_BOTTOM_TABS',
OVERLAY_BTN: 'OVERLAY_BTN',
DISMISS_ALL_OVERLAYS_BUTTON: 'DISMISS_ALL_OVERLAYS_BUTTON',
SIDE_MENU_BTN: 'SIDE_MENU_BTN',
MODAL_COMMANDS_BTN: 'MODAL_COMMANDS_BTN',
STACK_COMMANDS_BTN: 'STACK_COMMANDS_BTN',
Expand All @@ -24,6 +25,9 @@ const testIDs = {
ALERT_BUTTON: 'ALERT_BUTTON',
OVERLAY_ALERT_HEADER: 'OVERLAY_ALERT_HEADER',
SHOW_OVERLAY_BTN: 'SHOW_OVERLAY_BTN',
SHOW_FULLSCREEN_OVERLAY_BTN: 'SHOW_FULLSCREEN_OVERLAY_BTN',
OVERLAY_SCREEN: 'OVERLAY_SCREEN',
OVERLAY_DISMISSED_COUNT: 'OVERLAY_DISMISSED_COUNT',
SHOW_TOUCH_THROUGH_OVERLAY_BTN: 'SHOW_TOUCH_THROUGH_OVERLAY_BTN',
DISMISS_BTN: 'DISMISS_BTN',
STACK_SCREEN_HEADER: 'STACK_SCREEN_HEADER',
Expand Down
7 changes: 7 additions & 0 deletions website/docs/api/api-overlay.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,10 @@ Dismisses an overlay matching the given overlay componentId.
```js
Navigation.dismissOverlay(this.props.componentId);
```

## `dismissAllOverlays()`
Dismisses all overlays.

```js
Navigation.dismissAllOverlays();
```