diff --git a/src/app/app.component.ts b/src/app/app.component.ts index ebc4e3bc8..72c1f61d5 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component, ViewChild, AfterViewInit } from '@angular/core'; -import { Platform, Nav } from 'ionic-angular'; +import { Component, OnInit } from '@angular/core'; +import { Platform } from 'ionic-angular'; import { StatusBar } from '@ionic-native/status-bar'; import { SplashScreen } from '@ionic-native/splash-screen'; +import { CoreAppProvider } from '../providers/app'; import { CoreEventsProvider } from '../providers/events'; import { CoreLoggerProvider } from '../providers/logger'; import { CoreLoginHelperProvider } from '../core/login/providers/helper'; @@ -23,8 +24,7 @@ import { CoreLoginHelperProvider } from '../core/login/providers/helper'; @Component({ templateUrl: 'app.html' }) -export class MyApp implements AfterViewInit { - @ViewChild(Nav) navCtrl; +export class MoodleMobileApp implements OnInit { // Use the page name (string) because the page is lazy loaded (Ionic feature). That way we can load pages without // having to import them. The downside is that each page needs to implement a ngModule. rootPage:any = 'CoreLoginInitPage'; @@ -32,7 +32,8 @@ export class MyApp implements AfterViewInit { protected lastUrls = {}; constructor(private platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen, logger: CoreLoggerProvider, - private eventsProvider: CoreEventsProvider, private loginHelper: CoreLoginHelperProvider) { + private eventsProvider: CoreEventsProvider, private loginHelper: CoreLoginHelperProvider, + private appProvider: CoreAppProvider) { this.logger = logger.getInstance('AppComponent'); platform.ready().then(() => { @@ -45,14 +46,12 @@ export class MyApp implements AfterViewInit { } /** - * View has been initialized. + * Component being initialized. */ - ngAfterViewInit() { - this.loginHelper.setNavCtrl(this.navCtrl); - + ngOnInit() { // Go to sites page when user is logged out. this.eventsProvider.on(CoreEventsProvider.LOGOUT, () => { - this.navCtrl.setRoot('CoreLoginSitesPage'); + this.appProvider.getRootNavController().setRoot('CoreLoginSitesPage'); }); // Listen for session expired events. diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 6b6d5c152..5924e2f89 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -25,7 +25,7 @@ import { Keyboard } from '@ionic-native/keyboard'; import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; import { TranslateHttpLoader } from '@ngx-translate/http-loader'; -import { MyApp } from './app.component'; +import { MoodleMobileApp } from './app.component'; import { CoreInterceptor } from '../classes/interceptor'; import { CoreLoggerProvider } from '../providers/logger'; import { CoreDbProvider } from '../providers/db'; @@ -66,13 +66,13 @@ export function createTranslateLoader(http: HttpClient) { @NgModule({ declarations: [ - MyApp + MoodleMobileApp ], imports: [ BrowserModule, HttpClientModule, // HttpClient is used to make JSON requests. It fails for HEAD requests because there is no content. HttpModule, - IonicModule.forRoot(MyApp, { + IonicModule.forRoot(MoodleMobileApp, { pageTransition: 'ios-transition' }), TranslateModule.forRoot({ @@ -90,7 +90,7 @@ export function createTranslateLoader(http: HttpClient) { ], bootstrap: [IonicApp], entryComponents: [ - MyApp + MoodleMobileApp ], providers: [ { diff --git a/src/core/login/pages/credentials/credentials.ts b/src/core/login/pages/credentials/credentials.ts index 50b5d05a1..8d0dc4138 100644 --- a/src/core/login/pages/credentials/credentials.ts +++ b/src/core/login/pages/credentials/credentials.ts @@ -219,7 +219,7 @@ export class CoreLoginCredentialsPage { // } // }); } else { - return this.loginHelper.goToSiteInitialPage(this.navCtrl, true); + return this.loginHelper.goToSiteInitialPage(); } }); }).catch((error) => { diff --git a/src/core/login/pages/init/init.ts b/src/core/login/pages/init/init.ts index 3f12be846..b122908f9 100644 --- a/src/core/login/pages/init/init.ts +++ b/src/core/login/pages/init/init.ts @@ -74,13 +74,13 @@ export class CoreLoginInitPage { protected loadPage() : void { if (this.sitesProvider.isLoggedIn()) { if (!this.loginHelper.isSiteLoggedOut()) { - this.loginHelper.goToSiteInitialPage(this.navCtrl, true); + this.loginHelper.goToSiteInitialPage(); } } else { this.sitesProvider.hasSites().then(() => { this.navCtrl.setRoot('CoreLoginSitesPage'); }, () => { - this.loginHelper.goToAddSite(this.navCtrl, true); + this.loginHelper.goToAddSite(true); }); } } diff --git a/src/core/login/pages/reconnect/reconnect.ts b/src/core/login/pages/reconnect/reconnect.ts index 680f0c1f8..aaa744056 100644 --- a/src/core/login/pages/reconnect/reconnect.ts +++ b/src/core/login/pages/reconnect/reconnect.ts @@ -140,7 +140,7 @@ export class CoreLoginReconnectPage { // Page defined, go to that page instead of site initial page. return this.navCtrl.setRoot(this.pageName, this.pageParams); } else { - return this.loginHelper.goToSiteInitialPage(this.navCtrl, true); + return this.loginHelper.goToSiteInitialPage(); } }).catch((error) => { // Site deleted? Go back to login page. diff --git a/src/core/login/pages/site-policy/site-policy.ts b/src/core/login/pages/site-policy/site-policy.ts index c344efbec..dac709cde 100644 --- a/src/core/login/pages/site-policy/site-policy.ts +++ b/src/core/login/pages/site-policy/site-policy.ts @@ -110,7 +110,7 @@ export class CoreLoginSitePolicyPage { return this.currentSite.invalidateWsCache().catch(() => { // Ignore errors. }).then(() => { - return this.loginHelper.goToSiteInitialPage(this.navCtrl, true); + return this.loginHelper.goToSiteInitialPage(); }); }).catch((error) => { this.domUtils.showErrorModalDefault(error.message, 'Error accepting site policy.'); diff --git a/src/core/login/pages/site/site.ts b/src/core/login/pages/site/site.ts index 26ff5b05d..bd4af2e9b 100644 --- a/src/core/login/pages/site/site.ts +++ b/src/core/login/pages/site/site.ts @@ -74,7 +74,7 @@ export class CoreLoginSitePage { // It's a demo site. this.sitesProvider.getUserToken(siteData.url, siteData.username, siteData.password).then((data) => { return this.sitesProvider.newSite(data.siteUrl, data.token, data.privateToken).then(() => { - return this.loginHelper.goToSiteInitialPage(this.navCtrl, true); + return this.loginHelper.goToSiteInitialPage(); }, (error) => { this.domUtils.showErrorModal(error); }); diff --git a/src/core/login/pages/sites/sites.ts b/src/core/login/pages/sites/sites.ts index d6ba555cd..3e6fa76c7 100644 --- a/src/core/login/pages/sites/sites.ts +++ b/src/core/login/pages/sites/sites.ts @@ -13,7 +13,7 @@ // limitations under the License. import { Component } from '@angular/core'; -import { IonicPage, NavController } from 'ionic-angular'; +import { IonicPage } from 'ionic-angular'; import { TranslateService } from '@ngx-translate/core'; import { CoreLoggerProvider } from '../../../../providers/logger'; import { CoreSitesProvider, CoreSiteBasicInfo } from '../../../../providers/sites'; @@ -34,7 +34,7 @@ export class CoreLoginSitesPage { showDelete: boolean; protected logger; - constructor(private navCtrl: NavController, private domUtils: CoreDomUtilsProvider, private textUtils: CoreTextUtilsProvider, + constructor(private domUtils: CoreDomUtilsProvider, private textUtils: CoreTextUtilsProvider, private sitesProvider: CoreSitesProvider, private loginHelper: CoreLoginHelperProvider, private translate: TranslateService, logger: CoreLoggerProvider) { this.logger = logger.getInstance('CoreLoginSitesPage'); @@ -85,7 +85,7 @@ export class CoreLoginSitesPage { * Go to the page to add a site. */ add() : void { - this.loginHelper.goToAddSite(this.navCtrl, false); + this.loginHelper.goToAddSite(false); } /** @@ -108,7 +108,7 @@ export class CoreLoginSitesPage { // If there are no sites left, go to add site. this.sitesProvider.hasNoSites().then(() => { - this.loginHelper.goToAddSite(this.navCtrl, true); + this.loginHelper.goToAddSite(true); }); }).catch((error) => { this.logger.error('Error deleting site ' + site.id, error); @@ -131,7 +131,7 @@ export class CoreLoginSitesPage { this.sitesProvider.loadSite(siteId).then(() => { if (!this.loginHelper.isSiteLoggedOut()) { - return this.loginHelper.goToSiteInitialPage(this.navCtrl, true); + return this.loginHelper.goToSiteInitialPage(); } }).catch((error) => { this.logger.error('Error loading site ' + siteId, error); diff --git a/src/core/login/providers/helper.ts b/src/core/login/providers/helper.ts index 571319de1..7ffc71213 100644 --- a/src/core/login/providers/helper.ts +++ b/src/core/login/providers/helper.ts @@ -13,7 +13,7 @@ // limitations under the License. import { Injectable } from '@angular/core'; -import { NavController, Platform } from 'ionic-angular'; +import { Platform } from 'ionic-angular'; import { TranslateService } from '@ngx-translate/core'; import { CoreAppProvider } from '../../../providers/app'; import { CoreConfigProvider } from '../../../providers/config'; @@ -46,7 +46,6 @@ export class CoreLoginHelperProvider { protected logger; protected isSSOConfirmShown = false; protected isOpenEditAlertShown = false; - protected navCtrl: NavController; lastInAppUrl: string; waitingForBrowser = false; @@ -142,9 +141,9 @@ export class CoreLoginHelperProvider { }).then(() => { if (siteData.pageName) { // State defined, go to that state instead of site initial page. - this.navCtrl.push(siteData.pageName, siteData.pageParams); + this.appProvider.getRootNavController().push(siteData.pageName, siteData.pageParams); } else { - this.goToSiteInitialPage(this.navCtrl, true); + this.goToSiteInitialPage(); } }).catch((errorMessage) => { if (typeof errorMessage == 'string' && errorMessage != '') { @@ -176,8 +175,9 @@ export class CoreLoginHelperProvider { * Function called when an SSO InAppBrowser is closed or the app is resumed. Check if user needs to be logged out. */ checkLogout() { + let navCtrl = this.appProvider.getRootNavController(); if (!this.appProvider.isSSOAuthenticationOngoing() && this.sitesProvider.isLoggedIn() && - this.sitesProvider.getCurrentSite().isLoggedOut() && this.navCtrl.getActive().name == 'CoreLoginReconnectPage') { + this.sitesProvider.getCurrentSite().isLoggedOut() && navCtrl.getActive().name == 'CoreLoginReconnectPage') { // User must reauthenticate but he closed the InAppBrowser without doing so, logout him. this.sitesProvider.logout(); } @@ -345,11 +345,10 @@ export class CoreLoginHelperProvider { * Go to the page to add a new site. * If a fixed URL is configured, go to credentials instead. * - * @param {NavController} navCtrl The NavController instance to use. * @param {boolean} [setRoot] True to set the new page as root, false to add it to the stack. * @return {Promise} Promise resolved when done. */ - goToAddSite(navCtrl: NavController, setRoot?: boolean) : Promise { + goToAddSite(setRoot?: boolean) : Promise { let pageName, params; @@ -365,25 +364,19 @@ export class CoreLoginHelperProvider { } if (setRoot) { - return navCtrl.setRoot(pageName, params, {animate: false}); + return this.appProvider.getRootNavController().setRoot(pageName, params, {animate: false}); } else { - return navCtrl.push(pageName, params); + return this.appProvider.getRootNavController().push(pageName, params); } } /** * Go to the initial page of a site depending on 'userhomepage' setting. * - * @param {NavController} navCtrl The NavController instance to use. - * @param {boolean} [setRoot] True to set the new page as root, false to add it to the stack. * @return {Promise} Promise resolved when done. */ - goToSiteInitialPage(navCtrl: NavController, setRoot?: boolean) : Promise { - if (setRoot) { - return navCtrl.setRoot('CoreMainMenuPage', {}, {animate: false}); - } else { - return navCtrl.push('CoreMainMenuPage'); - } + goToSiteInitialPage() : Promise { + return this.appProvider.getRootNavController().setRoot('CoreMainMenuPage'); // return this.isMyOverviewEnabled().then((myOverview) => { // let myCourses = !myOverview && this.isMyCoursesEnabled(), // site = this.sitesProvider.getCurrentSite(), @@ -625,7 +618,7 @@ export class CoreLoginHelperProvider { protected loadSiteAndPage(page: string, params: any, siteId: string) : void { if (siteId == CoreConstants.noSiteId) { // Page doesn't belong to a site, just load the page. - this.navCtrl.setRoot(page, params); + this.appProvider.getRootNavController().setRoot(page, params); } else { let modal = this.domUtils.showModalLoading(); this.sitesProvider.loadSite(siteId).then(() => { @@ -634,7 +627,7 @@ export class CoreLoginHelperProvider { } }).catch(() => { // Site doesn't exist. - this.navCtrl.setRoot('CoreLoginSitesPage') + this.appProvider.getRootNavController().setRoot('CoreLoginSitesPage') }).finally(() => { modal.dismiss(); }); @@ -648,7 +641,7 @@ export class CoreLoginHelperProvider { * @param {any} params Params to pass to the page. */ protected loadPageInMainMenu(page: string, params: any) : void { - this.navCtrl.setRoot('CoreMainMenuPage', {redirectPage: page, redirectParams: params}) + this.appProvider.getRootNavController().setRoot('CoreMainMenuPage', {redirectPage: page, redirectParams: params}) } /** @@ -839,7 +832,7 @@ export class CoreLoginHelperProvider { if (siteId) { this.loadSiteAndPage(page, params, siteId); } else { - this.navCtrl.setRoot('CoreLoginSitesPage') + this.appProvider.getRootNavController().setRoot('CoreLoginSitesPage') } } } @@ -919,7 +912,7 @@ export class CoreLoginHelperProvider { } else { let info = currentSite.getInfo(); if (typeof info != 'undefined' && typeof info.username != 'undefined') { - this.navCtrl.setRoot('CoreLoginReconnectPage', { + this.appProvider.getRootNavController().setRoot('CoreLoginReconnectPage', { infoSiteUrl: info.siteurl, siteUrl: result.siteUrl, siteId: siteId, @@ -939,15 +932,6 @@ export class CoreLoginHelperProvider { }); } - /** - * Set a NavController to use. - * - * @param {NavController} navCtrl Nav controller. - */ - setNavCtrl(navCtrl: NavController) : void { - this.navCtrl = navCtrl; - } - /** * Check if a confirm should be shown to open a SSO authentication. * @@ -976,7 +960,7 @@ export class CoreLoginHelperProvider { return; } - this.navCtrl.setRoot('CoreLoginSitePolicyPage', {siteId: siteId}); + this.appProvider.getRootNavController().setRoot('CoreLoginSitePolicyPage', {siteId: siteId}); } /** diff --git a/src/providers/app.ts b/src/providers/app.ts index 46dac2a50..2f343a95e 100644 --- a/src/providers/app.ts +++ b/src/providers/app.ts @@ -13,7 +13,7 @@ // limitations under the License. import { Injectable } from '@angular/core'; -import { Platform } from 'ionic-angular'; +import { Platform, App, NavController } from 'ionic-angular'; import { Keyboard } from '@ionic-native/keyboard'; import { Network } from '@ionic-native/network'; @@ -46,7 +46,7 @@ export class CoreAppProvider { ssoAuthenticationPromise : Promise; isKeyboardShown: boolean = false; - constructor(dbProvider: CoreDbProvider, private platform: Platform, private keyboard: Keyboard, + constructor(dbProvider: CoreDbProvider, private platform: Platform, private keyboard: Keyboard, private appCtrl: App, private network: Network, logger: CoreLoggerProvider) { this.logger = logger.getInstance('CoreAppProvider'); this.db = dbProvider.getDB(this.DBNAME); @@ -76,7 +76,7 @@ export class CoreAppProvider { */ canRecordMedia() : boolean { return !!(window).MediaRecorder; - }; + } /** * Closes the keyboard. @@ -85,7 +85,7 @@ export class CoreAppProvider { if (this.isMobile()) { this.keyboard.close(); } - }; + } /** * Get the application global database. @@ -94,7 +94,17 @@ export class CoreAppProvider { */ getDB() : SQLiteDB { return this.db; - }; + } + + /** + * Get the app's root NavController. + * + * @return {NavController} Root NavController. + */ + getRootNavController() : NavController { + // getRootNav is deprecated. Get the first root nav, there should always be one. + return this.appCtrl.getRootNavs()[0]; + } /** * Checks if the app is running in a desktop environment (not browser). @@ -104,7 +114,7 @@ export class CoreAppProvider { isDesktop() : boolean { let process = (window).process; return !!(process && process.versions && typeof process.versions.electron != 'undefined'); - }; + } /** * Check if the keyboard is visible. @@ -113,7 +123,7 @@ export class CoreAppProvider { */ isKeyboardVisible() : boolean { return this.isKeyboardShown; - }; + } /** * Check if the app is running in a Linux environment. @@ -158,7 +168,7 @@ export class CoreAppProvider { */ isMobile() : boolean { return this.platform.is('cordova'); - }; + } /** * Returns whether we are online. @@ -172,7 +182,7 @@ export class CoreAppProvider { online = true; } return online; - }; + } /* * Check if device uses a limited connection. @@ -188,7 +198,7 @@ export class CoreAppProvider { let limited = [Connection.CELL_2G, Connection.CELL_3G, Connection.CELL_4G, Connection.CELL]; return limited.indexOf(type) > -1; - }; + } /** * Check if the app is running in a Windows environment. @@ -216,7 +226,7 @@ export class CoreAppProvider { if (this.isMobile() && !this.platform.is('ios')) { this.keyboard.show(); } - }; + } /** * Start an SSO authentication process. @@ -243,7 +253,7 @@ export class CoreAppProvider { this.ssoAuthenticationPromise.then(() => { clearTimeout(cancelTimeout); }); - }; + } /** * Finish an SSO authentication process. @@ -253,7 +263,7 @@ export class CoreAppProvider { (this.ssoAuthenticationPromise).resolve && (this.ssoAuthenticationPromise).resolve(); this.ssoAuthenticationPromise = undefined; } - }; + } /** * Check if there's an ongoing SSO authentication process. @@ -262,7 +272,7 @@ export class CoreAppProvider { */ isSSOAuthenticationOngoing() : boolean { return !!this.ssoAuthenticationPromise; - }; + } /** * Returns a promise that will be resolved once SSO authentication finishes. @@ -271,7 +281,7 @@ export class CoreAppProvider { */ waitForSSOAuthentication() : Promise { return this.ssoAuthenticationPromise || Promise.resolve(); - }; + } /** * Retrieve redirect data. @@ -299,7 +309,7 @@ export class CoreAppProvider { } return {}; - }; + } /** * Store redirect params. @@ -317,5 +327,5 @@ export class CoreAppProvider { localStorage.setItem('mmCoreRedirectTime', String(Date.now())); } catch(ex) {} } - }; + } }