Skip to content

Commit

Permalink
fix(routing): flickering (part 1)
Browse files Browse the repository at this point in the history
  • Loading branch information
manucorporat committed Mar 6, 2018
1 parent 9650bec commit 7b264f9
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 45 deletions.
5 changes: 5 additions & 0 deletions packages/core/src/components/nav/nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@ export class NavControllerBase implements NavOutlet {
return null;
}

@Method()
markVisible() {
return Promise.resolve();
}

@Method()
getContentElement(): HTMLElement {
const active = this.getActive();
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/components/nav/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ Return a view controller
#### insertPages()


#### markVisible()


#### pop()


Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/components/router/utils/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ export function writeNavState(root: HTMLElement, chain: RouteChain, index: numbe
}
const nextEl = node.getContentElement();
if (nextEl) {
return writeNavState(nextEl, chain, index + 1, direction);
return writeNavState(nextEl, chain, index + 1, direction)
.then(() => node.markVisible());
} else {
return node.markVisible();
}
return null;
});
}

Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/components/router/utils/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@

export interface NavOutlet {
setRouteId(id: any, data: any, direction: number): Promise<boolean>;
markVisible(): Promise<void>;
getRouteId(): string;

getContentElement(): HTMLElement | null;
}

Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/components/tab/tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { asyncRaf } from '../../utils/helpers';
export class Tab {

private loaded = false;
@Element() el: HTMLElement;
@Element() el: HTMLIonTabElement;

@State() init = false;

Expand Down Expand Up @@ -92,7 +92,7 @@ export class Tab {
}

@Method()
setActive(): Promise<any> {
setActive(): Promise<HTMLIonTabElement> {
return this.prepareLazyLoaded().then(() => this.showTab());
}

Expand All @@ -104,9 +104,9 @@ export class Tab {
return Promise.resolve();
}

private showTab(): Promise<any|void> {
private showTab(): Promise<HTMLIonTabElement> {
this.active = true;
return Promise.resolve();
return Promise.resolve(this.el);
}

hostData() {
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/components/tabs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,9 @@ Emitted when the tab changes.
#### getTabs()


#### markVisible()


#### select()


Expand Down
96 changes: 57 additions & 39 deletions packages/core/src/components/tabs/tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { Config, NavOutlet } from '../../index';
export class Tabs implements NavOutlet {
private ids = -1;
private transitioning = false;
private routingView: HTMLIonTabElement;

private tabsId: number = (++tabIds);

@Element() el: HTMLElement;
Expand Down Expand Up @@ -73,10 +75,7 @@ export class Tabs implements NavOutlet {
}

componentDidLoad() {
return this.initTabs().then(() => {
const useRouter = !!document.querySelector('ion-router');
return useRouter ? this.initSelect() : Promise.resolve();
});
return this.initTabs().then(() => this.initSelect());
}

componentDidUnload() {
Expand All @@ -95,37 +94,8 @@ export class Tabs implements NavOutlet {
*/
@Method()
select(tabOrIndex: number | HTMLIonTabElement): Promise<boolean> {
if (this.transitioning) {
return Promise.resolve(false);
}
const selectedTab = (typeof tabOrIndex === 'number' ? this.getByIndex(tabOrIndex) : tabOrIndex);
if (!selectedTab) {
return Promise.resolve(false);
}

// Reset rest of tabs
for (const tab of this.tabs) {
if (selectedTab !== tab) {
tab.selected = false;
}
}

const leavingTab = this.selectedTab;
this.transitioning = true;
return selectedTab.setActive().then(() => {
this.transitioning = false;
selectedTab.selected = true;
if (leavingTab !== selectedTab) {
if (leavingTab) {
leavingTab.active = false;
}
this.selectedTab = selectedTab;
this.ionChange.emit(selectedTab);
this.ionNavChanged.emit({isPop: false});
return true;
}
return false;
});
return this.setActive(tabOrIndex)
.then(selectedTab => this.tabSwitch(selectedTab));
}

/**
Expand Down Expand Up @@ -161,9 +131,18 @@ export class Tabs implements NavOutlet {
return Promise.resolve(false);
}
const tab = this.tabs.find(t => id === t.getRouteId());
return this.select(tab).then(() => true);
return this.setActive(tab).then(() => {
this.routingView = tab;
return true;
});
}

@Method()
markVisible(): Promise<void> {
this.tabSwitch(this.routingView);
this.routingView = null;
return Promise.resolve();
}

@Method()
getRouteId(): string|null {
Expand All @@ -176,7 +155,7 @@ export class Tabs implements NavOutlet {

@Method()
getContentElement(): HTMLElement {
return this.selectedTab;
return this.routingView || this.selectedTab;
}

private initTabs() {
Expand All @@ -191,7 +170,7 @@ export class Tabs implements NavOutlet {
return Promise.all(tabPromises);
}

private initSelect() {
private initSelect(): Promise<void> {
if (document.querySelector('ion-router')) {
return Promise.resolve();
}
Expand All @@ -205,7 +184,7 @@ export class Tabs implements NavOutlet {
tab.selected = false;
}
}
const promise = selectedTab ? selectedTab.setActive() : Promise.resolve();
const promise = selectedTab ? selectedTab.setActive() : Promise.resolve(null);
return promise.then(() => {
this.selectedTab = selectedTab;
if (selectedTab) {
Expand All @@ -222,6 +201,45 @@ export class Tabs implements NavOutlet {
}
}

private setActive(tabOrIndex: number | HTMLIonTabElement): Promise<HTMLIonTabElement|null> {
if (this.transitioning) {
return Promise.resolve(null);
}
const selectedTab = (typeof tabOrIndex === 'number' ? this.getByIndex(tabOrIndex) : tabOrIndex);
if (!selectedTab) {
return Promise.resolve(null);
}

// Reset rest of tabs
for (const tab of this.tabs) {
if (selectedTab !== tab) {
tab.selected = false;
}
}

this.transitioning = true;
return selectedTab.setActive();
}

private tabSwitch(selectedTab: HTMLIonTabElement | null): boolean {
this.transitioning = false;
if (!selectedTab) {
return false;
}
const leavingTab = this.selectedTab;
selectedTab.selected = true;
if (leavingTab !== selectedTab) {
if (leavingTab) {
leavingTab.active = false;
}
this.selectedTab = selectedTab;
this.ionChange.emit(selectedTab);
this.ionNavChanged.emit({isPop: false});
return true;
}
return false;
}

render() {
const dom = [
<div class='tabs-inner'>
Expand Down

0 comments on commit 7b264f9

Please sign in to comment.