Skip to content

Commit

Permalink
Fixed navigationPrefix handling for child screens
Browse files Browse the repository at this point in the history
  • Loading branch information
gius committed Jan 28, 2022
1 parent b78f7d8 commit e774efd
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { testLifecycle } from "../navigator.testHelpers";

describe("ActiveChildConductor", () => {
testLifecycle((screen, eventHub) => {
const conductor = new ActiveChildConductor(screen, eventHub);
const conductor = new ActiveChildConductor(screen, undefined, eventHub);
conductor.findNavigationChild = () => Promise.resolve({ newChild: undefined });
return conductor;
});
Expand Down Expand Up @@ -161,4 +161,6 @@ describe("ActiveChildConductor", () => {
expect(childNavigator.deactivate).toBeCalledWith(true);
});
});

// TODO test proper child finding with navigationPrefix used
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ import { testLifecycle } from "./navigator.testHelpers";
class TestNavigator extends LifecycleScreenNavigatorBase<any, any> {}

describe("LifecycleScreenNavigatorBase", () => {
testLifecycle((screen, eventHub) => new TestNavigator(screen, eventHub));
testLifecycle((screen, eventHub) => new TestNavigator(screen, undefined, eventHub));
});
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,16 @@ export default class ActiveChildConductor<
const currentChildNavigator = getNavigator<LifecycleScreenNavigator>(currentChild);
await currentChildNavigator?.deactivate?.(!!childResult.closePrevious);

if (isChildFoundResult(childResult) && childResult.attachToParent !== false) {
this.connectChild(childResult.newChild);
}

runInAction(() => (this.activeChildValue = childResult.newChild));
}

if (isChildFoundResult(childResult)) {
if (childResult.attachToParent !== false) {
this.connectChild(childResult.newChild);
}

const newChildNavigator = getNavigator<LifecycleScreenNavigator>(childResult.newChild);
await newChildNavigator?.navigate(childResult.pathForChild ?? path.slice(1));
await newChildNavigator?.navigate(childResult.pathForChild ?? path.slice(this.getNavigationStateLength()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export default class AllChildrenActiveConductor<
> extends LifecycleScreenNavigatorBase<TScreen, TNavigationParams> {
readonly children: TChild[];

constructor(screen?: TScreen, eventHub?: ScreenLifecycleEventHub<TScreen>) {
super(screen, eventHub);
constructor(screen?: TScreen, navigationPrefix?: string, eventHub?: ScreenLifecycleEventHub<TScreen>) {
super(screen, navigationPrefix, eventHub);

const children = observable.array<TChild>([], { deep: false });
children.intercept(this.handleChildrenChanged);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,17 @@ export default class OneOfListActiveConductor<
/** When set to `true`, navigating directly to the conductor (with no child path specified) activates the previously set `activeChild`. */
preserveActiveChild = false;

constructor(screen?: TScreen, eventHub?: ScreenLifecycleEventHub<TScreen>) {
super(screen, eventHub);
constructor(screen?: TScreen, navigationPrefix?: string, eventHub?: ScreenLifecycleEventHub<TScreen>) {
super(screen, navigationPrefix, eventHub);

const children = observable.array<TChild>([], { deep: false });
children.intercept(this.handleChildrenChanged);
this.children = children;
}

canChangeActiveChild = async (context: NavigationContext<TScreen>, currentChild: TChild | undefined) => {
const newNavigationName = context.path[1]?.name;
const pathElementsToSkip = this.getNavigationStateLength();
const newNavigationName = context.path[pathElementsToSkip]?.name;
const activeChildNavigator = getNavigator<LifecycleScreenNavigator>(this.activeChild);

if (!activeChildNavigator || activeChildNavigator.navigationName === newNavigationName) {
Expand All @@ -37,7 +38,8 @@ export default class OneOfListActiveConductor<
};

findNavigationChild = (context: NavigationContext<TScreen>, currentChild: TChild | undefined) => {
const searchedNavigationName = context.path[1]?.name;
const pathElementsToSkip = this.getNavigationStateLength();
const searchedNavigationName = context.path[pathElementsToSkip]?.name;
const newChild = this.findChild(searchedNavigationName);
return { newChild, closePrevious: false } as FindChildResult<TChild>;
};
Expand Down
11 changes: 9 additions & 2 deletions packages/screens/src/navigation/lifecycleScreenNavigatorBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,14 @@ export default abstract class LifecycleScreenNavigatorBase<

parent: ScreenNavigator | undefined = undefined;

constructor(screen?: TScreen, eventHub?: ScreenLifecycleEventHub<TScreen>) {
constructor(screen?: TScreen, navigationPrefix?: string, eventHub?: ScreenLifecycleEventHub<TScreen>) {
this.screenValue = screen;
this.eventHub = eventHub ?? screen?.events;

if (navigationPrefix) {
this.getNavigationState = () => [{ name: navigationPrefix }, this.createDefaultNavigationState()];
this.getNavigationStateLength = () => 2;
}
}

canNavigate(path: PathElement[]) {
Expand All @@ -50,8 +55,10 @@ export default abstract class LifecycleScreenNavigatorBase<

getNavigationParams?: () => TNavigationParams | undefined;
getNavigationState: () => PathElement[] = () => [this.createDefaultNavigationState()];
// Current NavigationState can contain multiple elements (not just one). In that case, we need to skip all of them.
getNavigationStateLength: () => number = () => 1;

createDefaultNavigationState() {
protected createDefaultNavigationState() {
return {
name: this.navigationName,
params: this.getNavigationParams?.(),
Expand Down
6 changes: 1 addition & 5 deletions packages/screens/src/navigation/simpleScreenNavigator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ export default class SimpleScreenNavigator<
TNavigationParams extends Record<string, string | undefined> = Record<string, string | undefined>
> extends LifecycleScreenNavigatorBase<TScreen, TNavigationParams> {
constructor(screen?: TScreen, navigationPrefix?: string, eventHub?: ScreenLifecycleEventHub<TScreen>) {
super(screen, eventHub);

if (navigationPrefix) {
this.getNavigationState = () => [{ name: navigationPrefix }, this.createDefaultNavigationState()];
}
super(screen, navigationPrefix, eventHub);
}
}

0 comments on commit e774efd

Please sign in to comment.