Skip to content

Commit

Permalink
Add screenPopped event (#5748)
Browse files Browse the repository at this point in the history
Called each time a screen is popped, either due to `Navigation.pop` or pop gesture.
closes #3941 

Navigation.events().registerScreenPoppedListener(({ componentId }) => {

});
  • Loading branch information
yogevbd authored and guyca committed Dec 18, 2019
1 parent d0c21e4 commit 71af559
Show file tree
Hide file tree
Showing 21 changed files with 256 additions and 138 deletions.
13 changes: 13 additions & 0 deletions docs/docs/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,19 @@ const modalDismissedListener = Navigation.events().registerModalDismissedListene
modalDismissedListener.remove();
```

## registerScreenPoppedListener
Invoked when screen is popped.

```js
// Subscribe
const screenPoppedListener = Navigation.events().registerScreenPoppedListener(({ componentId }) => {

});
...
// Unsubscribe
screenPoppedListener.remove();
```

| Parameter | Description |
|:--------------------:|:-----|
|**componentId** | Id of the modal|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ private ViewController createExternalComponent(LayoutNode node) {
}

private ViewController createStack(LayoutNode node) {
return new StackControllerBuilder(activity)
return new StackControllerBuilder(activity, eventEmitter)
.setChildren(createChildren(node.children))
.setChildRegistry(childRegistry)
.setTopBarController(new TopBarController())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class EventEmitter {
private static final String ComponentDidDisappear = "RNN.ComponentDidDisappear";
private static final String NavigationButtonPressed = "RNN.NavigationButtonPressed";
private static final String ModalDismissed = "RNN.ModalDismissed";
private static final String ScreenPopped = "RNN.ScreenPopped";
@Nullable
private ReactContext reactContext;

Expand Down Expand Up @@ -73,6 +74,12 @@ public void emitModalDismissed(String id, int modalsDismissed) {
emit(ModalDismissed, event);
}

public void emitScreenPoppedEvent(String componentId) {
WritableMap event = Arguments.createMap();
event.putString("componentId", componentId);
emit(ScreenPopped, event);
}

private void emit(String eventName) {
emit(eventName, Arguments.createMap());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.reactnativenavigation.presentation.Presenter;
import com.reactnativenavigation.presentation.StackPresenter;
import com.reactnativenavigation.react.Constants;
import com.reactnativenavigation.react.EventEmitter;
import com.reactnativenavigation.utils.CommandListener;
import com.reactnativenavigation.utils.CommandListenerAdapter;
import com.reactnativenavigation.utils.CompatUtils;
Expand Down Expand Up @@ -43,12 +44,14 @@ public class StackController extends ParentController<StackLayout> {

private IdStack<ViewController> stack = new IdStack<>();
private final NavigationAnimator animator;
private final EventEmitter eventEmitter;
private TopBarController topBarController;
private BackButtonHelper backButtonHelper;
private final StackPresenter presenter;

public StackController(Activity activity, List<ViewController> children, ChildControllersRegistry childRegistry, TopBarController topBarController, NavigationAnimator animator, String id, Options initialOptions, BackButtonHelper backButtonHelper, StackPresenter stackPresenter, Presenter presenter) {
public StackController(Activity activity, List<ViewController> children, ChildControllersRegistry childRegistry, EventEmitter eventEmitter, TopBarController topBarController, NavigationAnimator animator, String id, Options initialOptions, BackButtonHelper backButtonHelper, StackPresenter stackPresenter, Presenter presenter) {
super(activity, childRegistry, id, presenter, initialOptions);
this.eventEmitter = eventEmitter;
this.topBarController = topBarController;
this.animator = animator;
this.backButtonHelper = backButtonHelper;
Expand Down Expand Up @@ -277,6 +280,7 @@ public void pop(Options mergeOptions, CommandListener listener) {
private void finishPopping(ViewController disappearing, CommandListener listener) {
disappearing.destroy();
listener.onSuccess(disappearing.getId());
eventEmitter.emitScreenPoppedEvent(disappearing.getId());
}

public void popTo(ViewController viewController, Options mergeOptions, CommandListener listener) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.reactnativenavigation.parse.Options;
import com.reactnativenavigation.presentation.Presenter;
import com.reactnativenavigation.presentation.StackPresenter;
import com.reactnativenavigation.react.EventEmitter;
import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
import com.reactnativenavigation.viewcontrollers.ViewController;
import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
Expand All @@ -26,13 +27,20 @@ public class StackControllerBuilder {
private Presenter presenter;
private StackPresenter stackPresenter;
private List<ViewController> children = new ArrayList<>();
private EventEmitter eventEmitter;

public StackControllerBuilder(Activity activity) {
public StackControllerBuilder(Activity activity, EventEmitter eventEmitter) {
this.activity = activity;
this.eventEmitter = eventEmitter;
presenter = new Presenter(activity, new Options());
animator = new NavigationAnimator(activity, new ElementTransitionManager());
}

public StackControllerBuilder setEventEmitter(EventEmitter eventEmitter) {
this.eventEmitter = eventEmitter;
return this;
}

public StackControllerBuilder setChildren(ViewController... children) {
return setChildren(Arrays.asList(children));
}
Expand Down Expand Up @@ -86,6 +94,7 @@ public StackController build() {
return new StackController(activity,
children,
childRegistry,
eventEmitter,
topBarController,
animator,
id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.reactnativenavigation.parse.params.Bool;
import com.reactnativenavigation.presentation.RenderChecker;
import com.reactnativenavigation.presentation.StackPresenter;
import com.reactnativenavigation.react.EventEmitter;
import com.reactnativenavigation.utils.ImageLoader;
import com.reactnativenavigation.utils.UiUtils;
import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
Expand All @@ -33,7 +34,7 @@ protected TopBar createTopBar(Context context, StackLayout stackLayout) {
return topBar;
}
};
return new StackControllerBuilder(activity)
return new StackControllerBuilder(activity, Mockito.mock(EventEmitter.class))
.setId("stack")
.setChildRegistry(new ChildControllersRegistry())
.setTopBarController(topBarController)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,14 @@
import com.reactnativenavigation.TestUtils;
import com.reactnativenavigation.mocks.TestComponentLayout;
import com.reactnativenavigation.mocks.TestReactView;
import com.reactnativenavigation.mocks.TitleBarReactViewCreatorMock;
import com.reactnativenavigation.mocks.TopBarBackgroundViewCreatorMock;
import com.reactnativenavigation.mocks.TopBarButtonCreatorMock;
import com.reactnativenavigation.parse.Options;
import com.reactnativenavigation.parse.params.Bool;
import com.reactnativenavigation.parse.params.Colour;
import com.reactnativenavigation.parse.params.Text;
import com.reactnativenavigation.presentation.ComponentPresenter;
import com.reactnativenavigation.presentation.Presenter;
import com.reactnativenavigation.presentation.RenderChecker;
import com.reactnativenavigation.presentation.StackPresenter;
import com.reactnativenavigation.utils.CommandListenerAdapter;
import com.reactnativenavigation.utils.ImageLoader;
import com.reactnativenavigation.viewcontrollers.stack.StackController;
import com.reactnativenavigation.viewcontrollers.stack.StackControllerBuilder;
import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
import com.reactnativenavigation.views.StackLayout;
import com.reactnativenavigation.views.topbar.TopBar;
Expand Down Expand Up @@ -95,13 +88,7 @@ public void applyNavigationOptionsHandlesNoParentStack() {
@Test
public void initialOptionsAppliedOnAppear() {
uut.options.topBar.title.text = new Text("the title");
StackController stackController =
new StackControllerBuilder(activity)
.setTopBarController(new TopBarController())
.setId("stackId")
.setInitialOptions(new Options())
.setStackPresenter(new StackPresenter(activity, new TitleBarReactViewCreatorMock(), new TopBarBackgroundViewCreatorMock(), new TopBarButtonCreatorMock(), new ImageLoader(), new RenderChecker(), new Options()))
.build();
StackController stackController = TestUtils.newStackController(activity).build();
stackController.ensureViewIsCreated();
stackController.push(uut, new CommandListenerAdapter());
assertThat(stackController.getTopBar().getTitle()).isEmpty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
import com.reactnativenavigation.parse.params.Text;
import com.reactnativenavigation.presentation.RenderChecker;
import com.reactnativenavigation.presentation.StackPresenter;
import com.reactnativenavigation.react.EventEmitter;
import com.reactnativenavigation.utils.CommandListenerAdapter;
import com.reactnativenavigation.utils.ImageLoader;
import com.reactnativenavigation.utils.StatusBarUtils;
import com.reactnativenavigation.utils.TitleBarHelper;
import com.reactnativenavigation.utils.UiUtils;
Expand Down Expand Up @@ -66,6 +66,7 @@
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;

@LooperMode(LooperMode.Mode.PAUSED)
Expand All @@ -83,10 +84,12 @@ public class StackControllerTest extends BaseTest {
private TopBarController topBarController;
private StackPresenter presenter;
private BackButtonHelper backButtonHelper;
private EventEmitter eventEmitter;

@Override
public void beforeEach() {
super.beforeEach();
eventEmitter = Mockito.mock(EventEmitter.class);
backButtonHelper = spy(new BackButtonHelper());
activity = newActivity();
StatusBarUtils.saveStatusBarHeight(63);
Expand Down Expand Up @@ -383,12 +386,10 @@ public void onSuccess(String childId) {
@Test
public void pop_layoutHandlesChildWillDisappear() {
TopBarController topBarController = new TopBarController();
uut = new StackControllerBuilder(activity)
.setTopBarController(topBarController)
.setId("uut")
.setInitialOptions(new Options())
.setStackPresenter(new StackPresenter(activity, new TitleBarReactViewCreatorMock(), new TopBarBackgroundViewCreatorMock(), new TopBarButtonCreatorMock(), new ImageLoader(), new RenderChecker(), new Options()))
.build();
uut = TestUtils.newStackController(activity)
.setTopBarController(topBarController)
.setId("uut")
.build();
uut.ensureViewIsCreated();
uut.push(child1, new CommandListenerAdapter());
uut.push(child2, new CommandListenerAdapter() {
Expand All @@ -404,6 +405,30 @@ public void onSuccess(String childId) {
});
}

@Test
public void pop_popEventIsEmitted() {
disablePushAnimation(child1, child2);
disablePopAnimation(child2);
uut.push(child1, new CommandListenerAdapter());
uut.push(child2, new CommandListenerAdapter());

uut.pop(Options.EMPTY, new CommandListenerAdapter());
verify(eventEmitter).emitScreenPoppedEvent(child2.getId());
}

@Test
public void popToRoot_popEventIsEmitted() {
disablePushAnimation(child1, child2, child3);
disablePopAnimation(child2, child3);
uut.push(child1, new CommandListenerAdapter());
uut.push(child2, new CommandListenerAdapter());
uut.push(child3, new CommandListenerAdapter());

uut.pop(Options.EMPTY, new CommandListenerAdapter());
verify(eventEmitter).emitScreenPoppedEvent(child3.getId());
verifyNoMoreInteractions(eventEmitter);
}

@Test
public void stackOperations() {
assertThat(uut.peek()).isNull();
Expand Down Expand Up @@ -957,12 +982,9 @@ public void buttonPressInvokedOnCurrentStack() {

@Test
public void mergeChildOptions_updatesViewWithNewOptions() {
StackController uut = spy(new StackControllerBuilder(activity)
.setTopBarController(new TopBarController())
.setId("stack")
.setInitialOptions(new Options())
.setStackPresenter(new StackPresenter(activity, new TitleBarReactViewCreatorMock(), new TopBarBackgroundViewCreatorMock(), new TitleBarReactViewCreatorMock(), ImageLoaderMock.mock(), new RenderChecker(), Options.EMPTY))
.build());
StackController uut = spy(TestUtils.newStackController(activity)
.setId("stack")
.build());
Options optionsToMerge = new Options();
ViewController vc = mock(ViewController.class);
uut.mergeChildOptions(optionsToMerge, vc);
Expand All @@ -971,11 +993,8 @@ public void mergeChildOptions_updatesViewWithNewOptions() {

@Test
public void mergeChildOptions_updatesParentControllerWithNewOptions() {
StackController uut = new StackControllerBuilder(activity)
.setTopBarController(new TopBarController())
StackController uut = TestUtils.newStackController(activity)
.setId("stack")
.setInitialOptions(new Options())
.setStackPresenter(new StackPresenter(activity, new TitleBarReactViewCreatorMock(), new TopBarBackgroundViewCreatorMock(), new TitleBarReactViewCreatorMock(), ImageLoaderMock.mock(), new RenderChecker(), Options.EMPTY))
.build();
ParentController parentController = Mockito.mock(ParentController.class);
uut.setParentController(parentController);
Expand Down Expand Up @@ -1136,6 +1155,7 @@ private StackController createStack(List<ViewController> children) {
private StackControllerBuilder createStackBuilder(String id, List<ViewController> children) {
createTopBarController();
return TestUtils.newStackController(activity)
.setEventEmitter(eventEmitter)
.setChildren(children)
.setId(id)
.setTopBarController(topBarController)
Expand Down
4 changes: 1 addition & 3 deletions lib/ios/RNNCommandsHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,8 @@ - (void)pop:(NSString*)componentId commandId:(NSString*)commandId mergeOptions:(
UINavigationController *nvc = vc.navigationController;

if ([nvc topViewController] == vc) {
if (vc.resolveOptionsWithDefault.animations.pop) {
if (vc.resolveOptions.animations.pop.hasCustomAnimation) {
nvc.delegate = vc;
} else {
nvc.delegate = nil;
}
} else {
NSMutableArray * vcs = nvc.viewControllers.mutableCopy;
Expand Down
2 changes: 0 additions & 2 deletions lib/ios/RNNComponentViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ - (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo rootViewCreator:(

self.animator = [[RNNAnimator alloc] initWithTransitionOptions:self.resolveOptions.customTransition];

self.navigationController.delegate = self;

return self;
}

Expand Down
3 changes: 2 additions & 1 deletion lib/ios/RNNEventEmitter.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

#import <Foundation/Foundation.h>

#import <React/RCTEventEmitter.h>
Expand Down Expand Up @@ -26,5 +25,7 @@

- (void)sendModalsDismissedEvent:(NSString *)componentId numberOfModalsDismissed:(NSNumber *)modalsDismissed;

- (void)sendScreenPoppedEvent:(NSString *)componentId;


@end
Loading

0 comments on commit 71af559

Please sign in to comment.