MOBILE-2795 core: Fix redirect to other sites

main
Dani Palou 2019-01-04 11:18:29 +01:00
parent bdf3ec6fa7
commit c41cb6bb19
6 changed files with 117 additions and 35 deletions

View File

@ -107,11 +107,14 @@ export class AddonMessagesModule {
}
messagesProvider.invalidateDiscussionsCache(notification.site).finally(() => {
let pageName = 'AddonMessagesIndexPage';
if (messagesProvider.isGroupMessagingEnabled()) {
pageName = 'AddonMessagesGroupConversationsPage';
}
linkHelper.goInSite(undefined, pageName, undefined, notification.site);
// Check if group messaging is enabled, to determine which page should be loaded.
messagesProvider.isGroupMessagingEnabledInSite(notification.site).then((enabled) => {
let pageName = 'AddonMessagesIndexPage';
if (enabled) {
pageName = 'AddonMessagesGroupConversationsPage';
}
linkHelper.goInSite(undefined, pageName, undefined, notification.site);
});
});
});
});
@ -125,7 +128,10 @@ export class AddonMessagesModule {
// Register push notification clicks.
pushNotificationsDelegate.on('click').subscribe((notification) => {
if (utils.isFalseOrZero(notification.notif)) {
notificationClicked(notification);
// Execute the callback in the Angular zone, so change detection doesn't stop working.
zone.run(() => {
notificationClicked(notification);
});
return true;
}

View File

@ -1770,17 +1770,32 @@ export class AddonMessagesProvider {
/**
* Returns whether or not group messaging is supported.
*
* @return {boolean} If related WS is avalaible on current site.
* @return {boolean} If related WS is available on current site.
* @since 3.6
*/
isGroupMessagingEnabled(): boolean {
return this.sitesProvider.wsAvailableInCurrentSite('core_message_get_conversations');
}
/**
* Returns whether or not group messaging is supported in a certain site.
*
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<boolean>} Promise resolved with boolean: whether related WS is available on a certain site.
* @since 3.6
*/
isGroupMessagingEnabledInSite(siteId?: string): Promise<boolean> {
return this.sitesProvider.getSite(siteId).then((site) => {
return site.wsAvailable('core_message_get_conversations');
}).catch(() => {
return false;
});
}
/**
* Returns whether or not we can mark all messages as read.
*
* @return {boolean} If related WS is avalaible on current site.
* @return {boolean} If related WS is available on current site.
* @since 3.2
*/
isMarkAllMessagesReadEnabled(): boolean {

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { NgModule } from '@angular/core';
import { NgModule, NgZone } from '@angular/core';
import { AddonNotificationsProvider } from './providers/notifications';
import { AddonNotificationsMainMenuHandler } from './providers/mainmenu-handler';
import { AddonNotificationsSettingsHandler } from './providers/settings-handler';
@ -47,7 +47,7 @@ export const ADDON_NOTIFICATIONS_PROVIDERS: any[] = [
export class AddonNotificationsModule {
constructor(mainMenuDelegate: CoreMainMenuDelegate, mainMenuHandler: AddonNotificationsMainMenuHandler,
settingsDelegate: CoreSettingsDelegate, settingsHandler: AddonNotificationsSettingsHandler,
cronDelegate: CoreCronDelegate, cronHandler: AddonNotificationsCronHandler,
cronDelegate: CoreCronDelegate, cronHandler: AddonNotificationsCronHandler, zone: NgZone,
appProvider: CoreAppProvider, utils: CoreUtilsProvider, sitesProvider: CoreSitesProvider,
notificationsProvider: AddonNotificationsProvider, localNotifications: CoreLocalNotificationsProvider,
linkHelper: CoreContentLinksHelperProvider, pushNotificationsDelegate: AddonPushNotificationsDelegate) {
@ -76,7 +76,10 @@ export class AddonNotificationsModule {
// Register push notification clicks.
pushNotificationsDelegate.on('click').subscribe((notification) => {
if (utils.isTrueOrOne(notification.notif)) {
notificationClicked(notification);
// Execute the callback in the Angular zone, so change detection doesn't stop working.
zone.run(() => {
notificationClicked(notification);
});
return true;
}

View File

@ -14,9 +14,11 @@
import { Component, Optional, ElementRef, Renderer, ViewEncapsulation, forwardRef, ViewChild, Input,
OnDestroy } from '@angular/core';
import { Tabs, NavController, ViewController, App, Config, Platform, DeepLinker, Keyboard, RootNode } from 'ionic-angular';
import {
Tabs, Tab, NavController, ViewController, App, Config, Platform, DeepLinker, Keyboard, RootNode, NavOptions
} from 'ionic-angular';
import { CoreIonTabComponent } from './ion-tab';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreUtilsProvider, PromiseDefer } from '@providers/utils/utils';
import { CoreAppProvider } from '@providers/app';
/**
@ -66,6 +68,7 @@ export class CoreIonTabsComponent extends Tabs implements OnDestroy {
protected firstSelectedTab: string;
protected unregisterBackButtonAction: any;
protected selectTabPromiseDefer: PromiseDefer;
constructor(protected utils: CoreUtilsProvider, protected appProvider: CoreAppProvider, @Optional() parent: NavController,
@Optional() viewCtrl: ViewController, _app: App, config: Config, elementRef: ElementRef, _plt: Platform,
@ -148,20 +151,18 @@ 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)) {
this.select(tab);
}
} else {
// Select first tab on init.
const tab = this._tabs.find((tab) => {
return tab.enabled;
});
if (tab) {
if (tab && !tab.enabled) {
this.select(tab);
}
}
this.firstSelectedTab = this._selectHistory[0] || null;
}).finally(() => {
// If there was a select promise pending to be resolved, do it now.
if (this.selectTabPromiseDefer) {
this.selectTabPromiseDefer.resolve();
delete this.selectTabPromiseDefer;
}
});
} else {
// Tabs not loaded yet. Set the tab bar position so the tab bar is shown, it'll have a spinner.
@ -265,20 +266,62 @@ export class CoreIonTabsComponent extends Tabs implements OnDestroy {
}
}
/**
* Select a tab.
*
* @param {number|Tab} tabOrIndex Index, or the Tab instance, of the tab to select.
* @param {NavOptions} Nav options.
* @param {boolean} [fromUrl=true] Whether to load from a URL.
* @return {Promise<any>} Promise resolved when selected.
*/
select(tabOrIndex: number | Tab, opts: NavOptions = {}, fromUrl: boolean = false): Promise<any> {
if (this.initialized) {
// Tabs have been initialized, select the tab.
return super.select(tabOrIndex, opts, fromUrl);
} else {
// Tabs not initialized yet. Mark it as "selectedIndex" input so it's treated when the tabs are initialized.
if (typeof tabOrIndex == 'number') {
this.selectedIndex = tabOrIndex;
} else {
this.selectedIndex = this.getIndex(tabOrIndex);
}
// Don't resolve the Promise until the tab is really selected (tabs are initialized).
this.selectTabPromiseDefer = this.selectTabPromiseDefer || this.utils.promiseDefer();
return this.selectTabPromiseDefer.promise;
}
}
/**
* Select a tab by Index. First it will reset the status of the tab.
*
* @param {number} index Index of the tab.
* @return {Promise<any>} Promise resolved when selected.
*/
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});
}
});
selectTabRootByIndex(index: number): Promise<any> {
if (this.initialized) {
const tab = this.getByIndex(index);
if (tab) {
return tab.goToRoot({animate: false, updateUrl: true, isNavRoot: true}).then(() => {
// Tab not previously selected. Select it after going to root.
if (!tab.isSelected) {
return this.select(tab, {animate: false, updateUrl: true, isNavRoot: true});
}
});
}
// Not found.
return Promise.reject(null);
} else {
// Tabs not initialized yet. Mark it as "selectedIndex" input so it's treated when the tabs are initialized.
this.selectedIndex = index;
// Don't resolve the Promise until the tab is really selected (tabs are initialized).
this.selectTabPromiseDefer = this.selectTabPromiseDefer || this.utils.promiseDefer();
return this.selectTabPromiseDefer.promise;
}
}

View File

@ -587,18 +587,24 @@ export class CoreLoginHelperProvider {
* @param {string} siteId Site to load.
*/
protected loadSiteAndPage(page: string, params: any, siteId: string): void {
const navCtrl = this.appProvider.getRootNavController();
if (siteId == CoreConstants.NO_SITE_ID) {
// Page doesn't belong to a site, just load the page.
this.appProvider.getRootNavController().setRoot(page, params);
navCtrl.setRoot(page, params);
} else {
const modal = this.domUtils.showModalLoading();
this.sitesProvider.loadSite(siteId, page, params).then((loggedIn) => {
if (loggedIn) {
this.loadPageInMainMenu(page, params);
// 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('');
navCtrl.setRoot('CoreMainMenuPage', { redirectPage: page, redirectParams: params });
}
}).catch(() => {
}).catch((error) => {
// Site doesn't exist.
this.appProvider.getRootNavController().setRoot('CoreLoginSitesPage');
navCtrl.setRoot('CoreLoginSitesPage');
}).finally(() => {
modal.dismiss();
});

View File

@ -43,6 +43,15 @@ export class CoreMainMenuPage implements OnDestroy {
constructor(private menuDelegate: CoreMainMenuDelegate, private sitesProvider: CoreSitesProvider, navParams: NavParams,
private navCtrl: NavController, private eventsProvider: CoreEventsProvider) {
// Check if the menu was loaded with a redirect.
const redirectPage = navParams.get('redirectPage');
if (redirectPage) {
this.pendingRedirect = {
redirectPage: redirectPage,
redirectParams: navParams.get('redirectParams')
};
}
}
/**