diff --git a/config.xml b/config.xml
index 1ccda30df..f55d8633a 100644
--- a/config.xml
+++ b/config.xml
@@ -124,8 +124,6 @@
-
-
@@ -134,6 +132,8 @@
+
+
diff --git a/package-lock.json b/package-lock.json
index 1ad068cad..4bbadcc5a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1682,6 +1682,11 @@
"integrity": "sha512-EDpX3a7wHMWFA7PUHWPHNWqOxIIRSJetuwl0AS5Oi/5FMV8kWm69RTlgm00GKjBO1xFHMtBbL49yRtMMdticBw==",
"dev": true
},
+ "com-darryncampbell-cordova-plugin-intent": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/com-darryncampbell-cordova-plugin-intent/-/com-darryncampbell-cordova-plugin-intent-1.1.1.tgz",
+ "integrity": "sha512-h+V54+qCFY1h5csX8lAKTxBn5DdbP/8/sm7vS6X0WZPI+OTKycxeoJC+oGtPHhlvTh4gSEVW5/MkDqANRcmaug=="
+ },
"combined-stream": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
@@ -2340,6 +2345,11 @@
"resolved": "https://registry.npmjs.org/cordova-plugin-screen-orientation/-/cordova-plugin-screen-orientation-3.0.1.tgz",
"integrity": "sha1-daNXzik4CB6PYdRgU5S213Rjwfg="
},
+ "cordova-sqlite-evcore-extbuild-free": {
+ "version": "0.9.9",
+ "resolved": "https://registry.npmjs.org/cordova-sqlite-evcore-extbuild-free/-/cordova-sqlite-evcore-extbuild-free-0.9.9.tgz",
+ "integrity": "sha512-69U0JBhtBJd2QLNouaCuhfe2jv9HNClaPYRa+HcNmvdLqt/+DyIrpjBPtwYAsqNe9pxuR9oK1z/umuXw2IJSUw=="
+ },
"core-js": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz",
diff --git a/package.json b/package.json
index a9f2b7140..7e1cecd7b 100644
--- a/package.json
+++ b/package.json
@@ -78,9 +78,11 @@
"@types/node": "^8.0.47",
"@types/promise.prototype.finally": "^2.0.2",
"chart.js": "^2.7.2",
+ "com-darryncampbell-cordova-plugin-intent": "^1.1.1",
"cordova-android": "7.0.0",
"cordova-ios": "4.5.4",
"cordova-plugin-screen-orientation": "^3.0.1",
+ "cordova-sqlite-evcore-extbuild-free": "^0.9.9",
"es6-promise-plugin": "^4.2.2",
"font-awesome": "4.7.0",
"ionic-angular": "^3.9.2",
@@ -121,7 +123,9 @@
"ios"
],
"plugins": {
- "cordova-plugin-screen-orientation": {}
+ "cordova-plugin-screen-orientation": {},
+ "com-darryncampbell-cordova-plugin-intent": {},
+ "cordova-sqlite-evcore-extbuild-free": {}
}
},
"main": "desktop/electron.js",
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 } = {};