123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- package com.reactnativenavigation.viewcontrollers.navigator;
-
- import android.app.Activity;
- import android.view.ViewGroup;
-
- import com.facebook.react.ReactInstanceManager;
- import com.reactnativenavigation.parse.Options;
- import com.reactnativenavigation.presentation.OverlayManager;
- import com.reactnativenavigation.presentation.Presenter;
- import com.reactnativenavigation.presentation.RootPresenter;
- import com.reactnativenavigation.react.events.EventEmitter;
- import com.reactnativenavigation.utils.CommandListener;
- import com.reactnativenavigation.utils.CommandListenerAdapter;
- import com.reactnativenavigation.utils.CompatUtils;
- import com.reactnativenavigation.utils.Functions.Func1;
- import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
- import com.reactnativenavigation.viewcontrollers.ParentController;
- import com.reactnativenavigation.viewcontrollers.ViewController;
- import com.reactnativenavigation.viewcontrollers.modal.ModalStack;
- import com.reactnativenavigation.viewcontrollers.stack.StackController;
-
- import java.util.Collection;
- import java.util.Collections;
- import java.util.List;
-
- import androidx.annotation.NonNull;
- import androidx.annotation.Nullable;
- import androidx.annotation.RestrictTo;
- import androidx.coordinatorlayout.widget.CoordinatorLayout;
-
- public class Navigator extends ParentController {
-
- private final ModalStack modalStack;
- private final OverlayManager overlayManager;
- private final RootPresenter rootPresenter;
- private ViewController root;
- private ViewController previousRoot;
- private final CoordinatorLayout rootLayout;
- private final CoordinatorLayout modalsLayout;
- private final CoordinatorLayout overlaysLayout;
- private ViewGroup contentLayout;
- private Options defaultOptions = new Options();
-
- @Override
- public void setDefaultOptions(Options defaultOptions) {
- super.setDefaultOptions(defaultOptions);
- this.defaultOptions = defaultOptions;
- modalStack.setDefaultOptions(defaultOptions);
- }
-
- public Options getDefaultOptions() {
- return defaultOptions;
- }
-
- CoordinatorLayout getRootLayout() {
- return rootLayout;
- }
-
- public void setEventEmitter(EventEmitter eventEmitter) {
- modalStack.setEventEmitter(eventEmitter);
- }
-
- public void setContentLayout(ViewGroup contentLayout) {
- this.contentLayout = contentLayout;
- contentLayout.addView(rootLayout);
- contentLayout.addView(modalsLayout);
- }
-
- public Navigator(final Activity activity, ChildControllersRegistry childRegistry, ModalStack modalStack, OverlayManager overlayManager, RootPresenter rootPresenter) {
- super(activity, childRegistry,"navigator" + CompatUtils.generateViewId(), new Presenter(activity, new Options()), new Options());
- this.modalStack = modalStack;
- this.overlayManager = overlayManager;
- this.rootPresenter = rootPresenter;
- rootLayout = new CoordinatorLayout(getActivity());
- modalsLayout = new CoordinatorLayout(getActivity());
- overlaysLayout = new CoordinatorLayout(getActivity());
- }
-
- public void bindViews() {
- modalStack.setModalsLayout(modalsLayout);
- modalStack.setRootLayout(rootLayout);
- rootPresenter.setRootContainer(rootLayout);
- }
-
- @NonNull
- @Override
- protected ViewGroup createView() {
- return rootLayout;
- }
-
- @NonNull
- @Override
- public Collection<ViewController> getChildControllers() {
- return root == null ? Collections.emptyList() : Collections.singletonList(root);
- }
-
- @Override
- public boolean handleBack(CommandListener listener) {
- if (modalStack.isEmpty() && root == null) return false;
- if (modalStack.isEmpty()) return root.handleBack(listener);
- return modalStack.handleBack(listener, root);
- }
-
- @Override
- protected ViewController getCurrentChild() {
- return root;
- }
-
- @Override
- public void destroy() {
- destroyViews();
- super.destroy();
- }
-
- public void destroyViews() {
- modalStack.destroy();
- overlayManager.destroy();
- destroyRoot();
- }
-
- private void destroyRoot() {
- if (root != null) root.destroy();
- root = null;
- }
-
- private void destroyPreviousRoot() {
- if (previousRoot != null) previousRoot.destroy();
- previousRoot = null;
- }
-
- @Override
- public void sendOnNavigationButtonPressed(String buttonId) {
-
- }
-
- public void setRoot(final ViewController viewController, CommandListener commandListener, ReactInstanceManager reactInstanceManager) {
- previousRoot = root;
- modalStack.destroy();
- final boolean removeSplashView = isRootNotCreated();
- if (isRootNotCreated()) getView();
- root = viewController;
- rootPresenter.setRoot(root, defaultOptions, new CommandListenerAdapter(commandListener) {
- @Override
- public void onSuccess(String childId) {
- if (removeSplashView) contentLayout.removeViewAt(0);
- super.onSuccess(childId);
- destroyPreviousRoot();
- }
- }, reactInstanceManager);
- }
-
- public void mergeOptions(final String componentId, Options options) {
- ViewController target = findController(componentId);
- if (target != null) {
- target.mergeOptions(options);
- }
- }
-
- public void push(final String id, final ViewController viewController, CommandListener listener) {
- applyOnStack(id, listener, stack -> stack.push(viewController, listener));
- }
-
- public void setStackRoot(String id, List<ViewController> children, CommandListener listener) {
- applyOnStack(id, listener, stack -> stack.setRoot(children, listener));
- }
-
- public void pop(String id, Options mergeOptions, CommandListener listener) {
- applyOnStack(id, listener, stack -> stack.pop(mergeOptions, listener));
- }
-
- public void popToRoot(final String id, Options mergeOptions, CommandListener listener) {
- applyOnStack(id, listener, stack -> stack.popToRoot(mergeOptions, listener));
- }
-
- public void popTo(final String id, Options mergeOptions, CommandListener listener) {
- ViewController target = findController(id);
- if (target != null) {
- target.performOnParentStack(stack -> ((StackController) stack).popTo(target, mergeOptions, listener));
- } else {
- listener.onError("Failed to execute stack command. Stack by " + id + " not found.");
- }
- }
-
- public void showModal(final ViewController viewController, CommandListener listener) {
- modalStack.showModal(viewController, root, listener);
- }
-
- public void dismissModal(final String componentId, CommandListener listener) {
- if (isRootNotCreated() && modalStack.size() == 1) {
- listener.onError("Can not dismiss modal if root is not set and only one modal is displayed.");
- return;
- }
- modalStack.dismissModal(componentId, root, listener);
- }
-
- public void dismissAllModals(Options mergeOptions, CommandListener listener) {
- modalStack.dismissAllModals(root, mergeOptions, listener);
- }
-
- public void showOverlay(ViewController overlay, CommandListener listener) {
- overlayManager.show(contentLayout, overlaysLayout, overlay, listener);
- }
-
- public void dismissOverlay(final String componentId, CommandListener listener) {
- overlayManager.dismiss(componentId, listener);
- }
-
- @Nullable
- @Override
- public ViewController findController(String id) {
- ViewController controllerById = super.findController(id);
- if (controllerById == null) {
- controllerById = modalStack.findControllerById(id);
- }
- if (controllerById == null) {
- controllerById = overlayManager.findControllerById(id);
- }
- return controllerById;
- }
-
- private void applyOnStack(String fromId, CommandListener listener, Func1<StackController> task) {
- ViewController from = findController(fromId);
- if (from != null) {
- if (from instanceof StackController) {
- task.run((StackController) from);
- } else {
- from.performOnParentStack(stack -> task.run((StackController) stack) );
- }
- } else {
- listener.onError("Failed to execute stack command. Stack " + fromId + " not found.");
- }
- }
-
- private boolean isRootNotCreated() {
- return view == null;
- }
-
- @RestrictTo(RestrictTo.Scope.TESTS)
- CoordinatorLayout getModalsLayout() {
- return modalsLayout;
- }
- }
|