From 8ccd5a65ae3d64035dd57efb2cf521ee29fbf8e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 22 Nov 2018 16:44:52 +0100 Subject: [PATCH] MOBILE-2761 mainmenu: Avoid reloading menu when going to phantom tab --- src/components/ion-tabs/ion-tabs.ts | 50 ++++++++++++--- src/core/course/providers/log-cron-handler.ts | 4 +- src/core/login/providers/helper.ts | 6 +- src/core/mainmenu/pages/menu/menu.html | 2 +- src/core/mainmenu/pages/menu/menu.ts | 62 +++++++++---------- src/providers/events.ts | 1 + 6 files changed, 75 insertions(+), 50 deletions(-) diff --git a/src/components/ion-tabs/ion-tabs.ts b/src/components/ion-tabs/ion-tabs.ts index 33f8f60c0..9de17f576 100644 --- a/src/components/ion-tabs/ion-tabs.ts +++ b/src/components/ion-tabs/ion-tabs.ts @@ -148,8 +148,15 @@ export class CoreIonTabsComponent extends Tabs implements OnDestroy { // Tabs initialized. Force select the tab if it's not enabled. if (this.selectedDisabled && typeof this.selectedIndex != 'undefined') { const tab = this.getByIndex(this.selectedIndex); - - if (tab && (!tab.enabled || !tab.show)) { + if (tab && (!tab.enabled)) { + this.select(tab); + } + } else { + // Select first tab on init. + const tab = this._tabs.find((tab) => { + return tab.enabled; + }); + if (tab) { this.select(tab); } } @@ -170,17 +177,25 @@ export class CoreIonTabsComponent extends Tabs implements OnDestroy { protected registerBackButtonAction(): void { this.unregisterBackButtonAction = this.appProvider.registerBackButtonAction(() => { let tab = this.previousTab(true); + if (tab) { const selectedTab = this.getSelected(); - // Remove curent and previous tabs from history. - this._selectHistory = this._selectHistory.filter((tabId) => { - return selectedTab.id != tabId && tab.id != tabId; - }); + // It can happen when the previous is a phantom tab. + if (tab.id == selectedTab.id) { + tab = this.previousTab(true); + } - this.select(tab); + if (tab) { + // Remove curent and previous tabs from history. + this._selectHistory = this._selectHistory.filter((tabId) => { + return selectedTab.id != tabId && tab.id != tabId; + }); - return true; + this.select(tab); + + return true; + } } else { const selected = this.getSelected(); if (selected && this.firstSelectedTab && selected.id != this.firstSelectedTab) { @@ -188,7 +203,7 @@ export class CoreIonTabsComponent extends Tabs implements OnDestroy { this._selectHistory = []; tab = this._tabs.find((t) => { return t.id === this.firstSelectedTab; }); - if (tab && tab.enabled && tab.show) { + if (tab && tab.enabled) { this.select(tab); return true; @@ -250,6 +265,23 @@ export class CoreIonTabsComponent extends Tabs implements OnDestroy { } } + /** + * Select a tab by Index. First it will reset the status of the tab. + * + * @param {number} index Index of the tab. + */ + selectTabRootByIndex(index: number): void { + const tab = this.getByIndex(index); + if (tab) { + tab.goToRoot({animate: false, updateUrl: true, isNavRoot: true}).then(() => { + // Tab not previously selected. Select it after going to root. + if (!tab.isSelected) { + this.select(tab, {animate: false, updateUrl: true, isNavRoot: true}); + } + }); + } + } + /** * Component destroyed. */ diff --git a/src/core/course/providers/log-cron-handler.ts b/src/core/course/providers/log-cron-handler.ts index 108c8765d..c04dea1b7 100644 --- a/src/core/course/providers/log-cron-handler.ts +++ b/src/core/course/providers/log-cron-handler.ts @@ -24,7 +24,7 @@ import { CoreCourseProvider } from '@core/course/providers/course'; export class CoreCourseLogCronHandler implements CoreCronHandler { name = 'CoreCourseLogCronHandler'; - constructor(private coreProvider: CoreCourseProvider, private sitesProvider: CoreSitesProvider) {} + constructor(private courseProvider: CoreCourseProvider, private sitesProvider: CoreSitesProvider) {} /** * Execute the process. @@ -35,7 +35,7 @@ export class CoreCourseLogCronHandler implements CoreCronHandler { */ execute(siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { - return this.coreProvider.logView(site.getSiteHomeId(), undefined, site.getId()); + return this.courseProvider.logView(site.getSiteHomeId(), undefined, site.getId()); }); } diff --git a/src/core/login/providers/helper.ts b/src/core/login/providers/helper.ts index 9c51e160f..1bc8118c1 100644 --- a/src/core/login/providers/helper.ts +++ b/src/core/login/providers/helper.ts @@ -611,11 +611,7 @@ export class CoreLoginHelperProvider { * @param {any} params Params to pass to the page. */ protected loadPageInMainMenu(page: string, params: any): void { - // Due to DeepLinker, we need to remove the path from the URL before going to main menu. - // IonTabs checks the URL to determine which path to load for deep linking, so we clear the URL. - this.location.replaceState(''); - - this.appProvider.getRootNavController().setRoot('CoreMainMenuPage', { redirectPage: page, redirectParams: params }); + this.eventsProvider.trigger(CoreEventsProvider.LOAD_PAGE_MAIN_MENU, { redirectPage: page, redirectParams: params }); } /** diff --git a/src/core/mainmenu/pages/menu/menu.html b/src/core/mainmenu/pages/menu/menu.html index b12930640..9faebad6f 100644 --- a/src/core/mainmenu/pages/menu/menu.html +++ b/src/core/mainmenu/pages/menu/menu.html @@ -1,4 +1,4 @@ - + diff --git a/src/core/mainmenu/pages/menu/menu.ts b/src/core/mainmenu/pages/menu/menu.ts index 19b2bc3cf..5f0a2a647 100644 --- a/src/core/mainmenu/pages/menu/menu.ts +++ b/src/core/mainmenu/pages/menu/menu.ts @@ -12,9 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component, OnDestroy } from '@angular/core'; +import { Component, OnDestroy, ViewChild } from '@angular/core'; import { IonicPage, NavController, NavParams } from 'ionic-angular'; import { CoreSitesProvider } from '@providers/sites'; +import { CoreEventsProvider } from '@providers/events'; +import { CoreIonTabsComponent } from '@components/ion-tabs/ion-tabs'; import { CoreMainMenuProvider } from '../../providers/mainmenu'; import { CoreMainMenuDelegate, CoreMainMenuHandlerToDisplay } from '../../providers/delegate'; @@ -31,16 +33,15 @@ export class CoreMainMenuPage implements OnDestroy { loaded = false; redirectPage: string; redirectParams: any; - initialTab: number; showTabs = false; protected subscription; - protected redirectPageLoaded = false; + protected redirectObs: any; + + @ViewChild('mainTabs') mainTabs: CoreIonTabsComponent; constructor(private menuDelegate: CoreMainMenuDelegate, private sitesProvider: CoreSitesProvider, navParams: NavParams, - private navCtrl: NavController) { - this.redirectPage = navParams.get('redirectPage'); - this.redirectParams = navParams.get('redirectParams'); + private navCtrl: NavController, private eventsProvider: CoreEventsProvider) { } /** @@ -55,6 +56,27 @@ export class CoreMainMenuPage implements OnDestroy { this.showTabs = true; + this.redirectObs = this.eventsProvider.on(CoreEventsProvider.LOAD_PAGE_MAIN_MENU, (data) => { + // Check if the redirect page is the root page of any of the tabs. + const i = this.tabs.findIndex((tab, i) => { + return tab.page == data.redirectPage; + }); + + if (i >= 0) { + // Tab found. Set the params. + this.tabs[i].pageParams = Object.assign({}, data.redirectParams); + } else { + // Tab not found, use a phantom tab. + this.redirectPage = data.redirectPage; + this.redirectParams = data.redirectParams; + } + + setTimeout(() => { + // Let the tab load the params before navigating. + this.mainTabs.selectTabRootByIndex(i + 1); + }); + }); + this.subscription = this.menuDelegate.getHandlers().subscribe((handlers) => { // Remove the handlers that should only appear in the More menu. handlers = handlers.filter((handler) => { @@ -83,33 +105,6 @@ export class CoreMainMenuPage implements OnDestroy { return b.priority - a.priority; }); - if (typeof this.initialTab == 'undefined' && !this.loaded) { - this.initialTab = 0; - - // Calculate the tab to load. - if (this.redirectPage) { - // Check if the redirect page is the root page of any of the tabs. - const i = this.tabs.findIndex((tab, i) => { - return tab.page == this.redirectPage; - }); - if (i >= 0) { - // Tab found. Set the params and unset the redirect page. - this.initialTab = i + 1; - this.tabs[i].pageParams = Object.assign(this.tabs[i].pageParams || {}, this.redirectParams); - this.redirectPage = null; - this.redirectParams = null; - } - } else { - const i = handlers.findIndex((handler, i) => { - return handler.name == 'CoreDashboard'; - }); - - if (i >= 0) { - this.initialTab = i; - } - } - } - this.loaded = this.menuDelegate.areHandlersLoaded(); }); } @@ -119,5 +114,6 @@ export class CoreMainMenuPage implements OnDestroy { */ ngOnDestroy(): void { this.subscription && this.subscription.unsubscribe(); + this.redirectObs && this.redirectObs.off(); } } diff --git a/src/providers/events.ts b/src/providers/events.ts index a523a7b8c..55def12a0 100644 --- a/src/providers/events.ts +++ b/src/providers/events.ts @@ -57,6 +57,7 @@ export class CoreEventsProvider { static KEYBOARD_CHANGE = 'keyboard_change'; static CORE_LOADING_CHANGED = 'core_loading_changed'; static ORIENTATION_CHANGE = 'orientation_change'; + static LOAD_PAGE_MAIN_MENU = 'load_page_main_menu'; protected logger; protected observables: { [s: string]: Subject } = {};