commit
6428bbb5fc
|
@ -16,6 +16,7 @@ import { ContextLevel } from '@/core/constants';
|
||||||
import { AddonBlog, AddonBlogFilter, AddonBlogPost, AddonBlogProvider } from '@addons/blog/services/blog';
|
import { AddonBlog, AddonBlogFilter, AddonBlogPost, AddonBlogProvider } from '@addons/blog/services/blog';
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { CoreComments } from '@features/comments/services/comments';
|
import { CoreComments } from '@features/comments/services/comments';
|
||||||
|
import { CoreMainMenuDeepLinkManager } from '@features/mainmenu/classes/deep-link-manager';
|
||||||
import { CoreTag } from '@features/tag/services/tag';
|
import { CoreTag } from '@features/tag/services/tag';
|
||||||
import { CoreUser, CoreUserProfile } from '@features/user/services/user';
|
import { CoreUser, CoreUserProfile } from '@features/user/services/user';
|
||||||
import { IonRefresher } from '@ionic/angular';
|
import { IonRefresher } from '@ionic/angular';
|
||||||
|
@ -118,6 +119,9 @@ export class AddonBlogEntriesPage implements OnInit {
|
||||||
this.commentsEnabled = !CoreComments.areCommentsDisabledInSite();
|
this.commentsEnabled = !CoreComments.areCommentsDisabledInSite();
|
||||||
this.tagsEnabled = CoreTag.areTagsAvailableInSite();
|
this.tagsEnabled = CoreTag.areTagsAvailableInSite();
|
||||||
|
|
||||||
|
const deepLinkManager = new CoreMainMenuDeepLinkManager();
|
||||||
|
deepLinkManager.treatLink();
|
||||||
|
|
||||||
await this.fetchEntries();
|
await this.fetchEntries();
|
||||||
|
|
||||||
CoreUtils.ignoreErrors(AddonBlog.logView(this.filter));
|
CoreUtils.ignoreErrors(AddonBlog.logView(this.filter));
|
||||||
|
|
|
@ -33,6 +33,7 @@ import { AddonCalendarFilterPopoverComponent } from '../../components/filter/fil
|
||||||
import { CoreNavigator } from '@services/navigator';
|
import { CoreNavigator } from '@services/navigator';
|
||||||
import { CoreLocalNotifications } from '@services/local-notifications';
|
import { CoreLocalNotifications } from '@services/local-notifications';
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
|
import { CoreMainMenuDeepLinkManager } from '@features/mainmenu/classes/deep-link-manager';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page that displays the calendar events.
|
* Page that displays the calendar events.
|
||||||
|
@ -177,6 +178,9 @@ export class AddonCalendarIndexPage implements OnInit, OnDestroy {
|
||||||
|
|
||||||
this.fetchData(true, false);
|
this.fetchData(true, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const deepLinkManager = new CoreMainMenuDeepLinkManager();
|
||||||
|
deepLinkManager.treatLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { CanActivate, UrlTree } from '@angular/router';
|
import { ActivatedRouteSnapshot, CanActivate, UrlTree } from '@angular/router';
|
||||||
import { Router } from '@singletons';
|
import { Router } from '@singletons';
|
||||||
import { AddonMessagesMainMenuHandlerService } from '../services/handlers/mainmenu';
|
import { AddonMessagesMainMenuHandlerService } from '../services/handlers/mainmenu';
|
||||||
import { AddonMessages } from '../services/messages';
|
import { AddonMessages } from '../services/messages';
|
||||||
|
@ -27,18 +27,22 @@ export class AddonMessagesIndexGuard implements CanActivate {
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
canActivate(): UrlTree {
|
canActivate(route: ActivatedRouteSnapshot): UrlTree {
|
||||||
return this.guard();
|
return this.guard(route);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if there is a pending redirect and trigger it.
|
* Check if there is a pending redirect and trigger it.
|
||||||
*/
|
*/
|
||||||
private guard(): UrlTree {
|
private guard(route: ActivatedRouteSnapshot): UrlTree {
|
||||||
const enabled = AddonMessages.isGroupMessagingEnabled();
|
const enabled = AddonMessages.isGroupMessagingEnabled();
|
||||||
const path = `/main/${AddonMessagesMainMenuHandlerService.PAGE_NAME}/` + ( enabled ? 'group-conversations' : 'index');
|
const path = `/main/${AddonMessagesMainMenuHandlerService.PAGE_NAME}/` + ( enabled ? 'group-conversations' : 'index');
|
||||||
|
|
||||||
return Router.parseUrl(path);
|
const newRoute = Router.parseUrl(path);
|
||||||
|
|
||||||
|
newRoute.queryParams = route.queryParams;
|
||||||
|
|
||||||
|
return newRoute;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import { Translate, Platform } from '@singletons';
|
||||||
import { IonRefresher } from '@ionic/angular';
|
import { IonRefresher } from '@ionic/angular';
|
||||||
import { CoreNavigator } from '@services/navigator';
|
import { CoreNavigator } from '@services/navigator';
|
||||||
import { CoreScreen } from '@services/screen';
|
import { CoreScreen } from '@services/screen';
|
||||||
|
import { CoreMainMenuDeepLinkManager } from '@features/mainmenu/classes/deep-link-manager';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page that displays the list of discussions.
|
* Page that displays the list of discussions.
|
||||||
|
@ -141,12 +142,17 @@ export class AddonMessagesDiscussions35Page implements OnInit, OnDestroy {
|
||||||
this.discussionUserId = CoreNavigator.getRouteNumberParam('userId', { params }) ?? this.discussionUserId;
|
this.discussionUserId = CoreNavigator.getRouteNumberParam('userId', { params }) ?? this.discussionUserId;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const deepLinkManager = new CoreMainMenuDeepLinkManager();
|
||||||
|
|
||||||
await this.fetchData();
|
await this.fetchData();
|
||||||
|
|
||||||
if (!this.discussionUserId && this.discussions.length > 0 && CoreScreen.isTablet) {
|
if (!this.discussionUserId && this.discussions.length > 0 && CoreScreen.isTablet) {
|
||||||
// Take first and load it.
|
// Take first and load it.
|
||||||
this.gotoDiscussion(this.discussions[0].message!.user);
|
await this.gotoDiscussion(this.discussions[0].message!.user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Treat deep link now that the conversation route has been loaded if needed.
|
||||||
|
deepLinkManager.treatLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -247,7 +253,7 @@ export class AddonMessagesDiscussions35Page implements OnInit, OnDestroy {
|
||||||
* @param messageId Message to scroll after loading the discussion. Used when searching.
|
* @param messageId Message to scroll after loading the discussion. Used when searching.
|
||||||
* @param onlyWithSplitView Only go to Discussion if split view is on.
|
* @param onlyWithSplitView Only go to Discussion if split view is on.
|
||||||
*/
|
*/
|
||||||
gotoDiscussion(discussionUserId: number, messageId?: number): void {
|
async gotoDiscussion(discussionUserId: number, messageId?: number): Promise<void> {
|
||||||
this.discussionUserId = discussionUserId;
|
this.discussionUserId = discussionUserId;
|
||||||
|
|
||||||
const params: Params = {
|
const params: Params = {
|
||||||
|
@ -261,7 +267,7 @@ export class AddonMessagesDiscussions35Page implements OnInit, OnDestroy {
|
||||||
const splitViewLoaded = CoreNavigator.isCurrentPathInTablet('**/messages/index/discussion');
|
const splitViewLoaded = CoreNavigator.isCurrentPathInTablet('**/messages/index/discussion');
|
||||||
const path = (splitViewLoaded ? '../' : '') + 'discussion';
|
const path = (splitViewLoaded ? '../' : '') + 'discussion';
|
||||||
|
|
||||||
CoreNavigator.navigate(path, { params });
|
await CoreNavigator.navigate(path, { params });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -36,6 +36,7 @@ import { ActivatedRoute, Params } from '@angular/router';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { CoreNavigator } from '@services/navigator';
|
import { CoreNavigator } from '@services/navigator';
|
||||||
import { CoreScreen } from '@services/screen';
|
import { CoreScreen } from '@services/screen';
|
||||||
|
import { CoreMainMenuDeepLinkManager } from '@features/mainmenu/classes/deep-link-manager';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page that displays the list of conversations, including group conversations.
|
* Page that displays the list of conversations, including group conversations.
|
||||||
|
@ -279,6 +280,8 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const deepLinkManager = new CoreMainMenuDeepLinkManager();
|
||||||
|
|
||||||
await this.fetchData();
|
await this.fetchData();
|
||||||
|
|
||||||
if (!this.selectedConversationId && !this.selectedUserId && CoreScreen.isTablet) {
|
if (!this.selectedConversationId && !this.selectedUserId && CoreScreen.isTablet) {
|
||||||
|
@ -290,10 +293,13 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
|
||||||
conversation = expandedOption.conversations[0];
|
conversation = expandedOption.conversations[0];
|
||||||
|
|
||||||
if (conversation) {
|
if (conversation) {
|
||||||
this.gotoConversation(conversation.id);
|
await this.gotoConversation(conversation.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Treat deep link now that the conversation route has been loaded if needed.
|
||||||
|
deepLinkManager.treatLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -507,7 +513,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
|
||||||
* @param userId User of the conversation. Only if there is no conversationId.
|
* @param userId User of the conversation. Only if there is no conversationId.
|
||||||
* @param messageId Message to scroll after loading the discussion. Used when searching.
|
* @param messageId Message to scroll after loading the discussion. Used when searching.
|
||||||
*/
|
*/
|
||||||
gotoConversation(conversationId?: number, userId?: number, messageId?: number): void {
|
async gotoConversation(conversationId?: number, userId?: number, messageId?: number): Promise<void> {
|
||||||
this.selectedConversationId = conversationId;
|
this.selectedConversationId = conversationId;
|
||||||
this.selectedUserId = userId;
|
this.selectedUserId = userId;
|
||||||
|
|
||||||
|
@ -524,7 +530,8 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
|
||||||
|
|
||||||
const splitViewLoaded = CoreNavigator.isCurrentPathInTablet('**/messages/group-conversations/discussion');
|
const splitViewLoaded = CoreNavigator.isCurrentPathInTablet('**/messages/group-conversations/discussion');
|
||||||
const path = (splitViewLoaded ? '../' : '') + 'discussion';
|
const path = (splitViewLoaded ? '../' : '') + 'discussion';
|
||||||
CoreNavigator.navigate(path, { params });
|
|
||||||
|
await CoreNavigator.navigate(path, { params });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,6 +29,7 @@ import {
|
||||||
AddonNotificationsHelper,
|
AddonNotificationsHelper,
|
||||||
AddonNotificationsNotificationToRender,
|
AddonNotificationsNotificationToRender,
|
||||||
} from '@addons/notifications/services/notifications-helper';
|
} from '@addons/notifications/services/notifications-helper';
|
||||||
|
import { CoreMainMenuDeepLinkManager } from '@features/mainmenu/classes/deep-link-manager';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page that displays the list of notifications.
|
* Page that displays the list of notifications.
|
||||||
|
@ -82,6 +83,9 @@ export class AddonNotificationsListPage implements OnInit, OnDestroy {
|
||||||
this.notificationsLoaded = false;
|
this.notificationsLoaded = false;
|
||||||
this.refreshNotifications();
|
this.refreshNotifications();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const deepLinkManager = new CoreMainMenuDeepLinkManager();
|
||||||
|
deepLinkManager.treatLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -191,6 +191,29 @@ export class CoreContentLinksDelegateService {
|
||||||
action.message = action.message || 'core.view';
|
action.message = action.message || 'core.view';
|
||||||
action.icon = action.icon || 'fas-eye';
|
action.icon = action.icon || 'fas-eye';
|
||||||
action.sites = action.sites || siteIds;
|
action.sites = action.sites || siteIds;
|
||||||
|
|
||||||
|
// Wrap the action function in our own function to treat logged out sites.
|
||||||
|
const actionFunction = action.action;
|
||||||
|
action.action = async (siteId) => {
|
||||||
|
const site = await CoreSites.getSite(siteId);
|
||||||
|
|
||||||
|
if (!site.isLoggedOut()) {
|
||||||
|
// Call the action now.
|
||||||
|
return actionFunction(siteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Site is logged out, authenticate first before treating the URL.
|
||||||
|
const willReload = await CoreSites.logoutForRedirect(siteId, {
|
||||||
|
urlToOpen: url,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!willReload) {
|
||||||
|
// Load the site with the redirect data.
|
||||||
|
await CoreSites.loadSite(siteId, {
|
||||||
|
urlToOpen: url,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add them to the list.
|
// Add them to the list.
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||||
import { CoreBlockComponent } from '@features/block/components/block/block';
|
import { CoreBlockComponent } from '@features/block/components/block/block';
|
||||||
import { CoreCourseBlock } from '@features/course/services/course';
|
import { CoreCourseBlock } from '@features/course/services/course';
|
||||||
import { CoreCoursesDashboard, CoreCoursesDashboardProvider } from '@features/courses/services/dashboard';
|
import { CoreCoursesDashboard, CoreCoursesDashboardProvider } from '@features/courses/services/dashboard';
|
||||||
|
import { CoreMainMenuDeepLinkManager } from '@features/mainmenu/classes/deep-link-manager';
|
||||||
import { IonRefresher } from '@ionic/angular';
|
import { IonRefresher } from '@ionic/angular';
|
||||||
import { CoreNavigator } from '@services/navigator';
|
import { CoreNavigator } from '@services/navigator';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
|
@ -65,6 +66,9 @@ export class CoreCoursesMyCoursesPage implements OnInit, OnDestroy {
|
||||||
this.searchEnabled = !CoreCourses.isSearchCoursesDisabledInSite();
|
this.searchEnabled = !CoreCourses.isSearchCoursesDisabledInSite();
|
||||||
this.downloadCoursesEnabled = !CoreCourses.isDownloadCoursesDisabledInSite();
|
this.downloadCoursesEnabled = !CoreCourses.isDownloadCoursesDisabledInSite();
|
||||||
|
|
||||||
|
const deepLinkManager = new CoreMainMenuDeepLinkManager();
|
||||||
|
deepLinkManager.treatLink();
|
||||||
|
|
||||||
this.loadSiteName();
|
this.loadSiteName();
|
||||||
|
|
||||||
this.loadContent();
|
this.loadContent();
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { CoreLoginHelper } from '@features/login/services/login-helper';
|
||||||
import { CoreSite, CoreSiteIdentityProvider, CoreSitePublicConfigResponse } from '@classes/site';
|
import { CoreSite, CoreSiteIdentityProvider, CoreSitePublicConfigResponse } from '@classes/site';
|
||||||
import { CoreEvents } from '@singletons/events';
|
import { CoreEvents } from '@singletons/events';
|
||||||
import { CoreError } from '@classes/errors/error';
|
import { CoreError } from '@classes/errors/error';
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
import { CoreNavigator, CoreRedirectPayload } from '@services/navigator';
|
||||||
import { CoreForms } from '@singletons/form';
|
import { CoreForms } from '@singletons/form';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,11 +53,10 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
|
||||||
siteId!: string;
|
siteId!: string;
|
||||||
showScanQR = false;
|
showScanQR = false;
|
||||||
|
|
||||||
protected page?: string;
|
|
||||||
protected pageOptions?: CoreNavigationOptions;
|
|
||||||
protected siteConfig?: CoreSitePublicConfigResponse;
|
protected siteConfig?: CoreSitePublicConfigResponse;
|
||||||
protected viewLeft = false;
|
protected viewLeft = false;
|
||||||
protected eventThrown = false;
|
protected eventThrown = false;
|
||||||
|
protected redirectData?: CoreRedirectPayload;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected fb: FormBuilder,
|
protected fb: FormBuilder,
|
||||||
|
@ -77,8 +76,15 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
|
||||||
try {
|
try {
|
||||||
this.siteId = CoreNavigator.getRequiredRouteParam<string>('siteId');
|
this.siteId = CoreNavigator.getRequiredRouteParam<string>('siteId');
|
||||||
|
|
||||||
this.page = CoreNavigator.getRouteParam('pageName');
|
const redirectPath = CoreNavigator.getRouteParam('redirectPath');
|
||||||
this.pageOptions = CoreNavigator.getRouteParam('pageOptions');
|
const urlToOpen = CoreNavigator.getRouteParam('urlToOpen');
|
||||||
|
if (redirectPath || urlToOpen) {
|
||||||
|
this.redirectData = {
|
||||||
|
redirectPath,
|
||||||
|
redirectOptions: CoreNavigator.getRouteParam('redirectOptions'),
|
||||||
|
urlToOpen,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const site = await CoreSites.getSite(this.siteId);
|
const site = await CoreSites.getSite(this.siteId);
|
||||||
|
|
||||||
|
@ -208,9 +214,9 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
|
||||||
this.credForm.controls['password'].reset();
|
this.credForm.controls['password'].reset();
|
||||||
|
|
||||||
// Go to the site initial page.
|
// Go to the site initial page.
|
||||||
this.page
|
await CoreNavigator.navigateToSiteHome({
|
||||||
? await CoreNavigator.navigateToSitePath(this.page, this.pageOptions)
|
params: this.redirectData,
|
||||||
: await CoreNavigator.navigateToSiteHome();
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
CoreLoginHelper.treatUserTokenError(this.siteUrl, error, this.username, password);
|
CoreLoginHelper.treatUserTokenError(this.siteUrl, error, this.username, password);
|
||||||
|
|
||||||
|
@ -242,8 +248,7 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
|
||||||
this.siteUrl,
|
this.siteUrl,
|
||||||
provider,
|
provider,
|
||||||
this.siteConfig?.launchurl,
|
this.siteConfig?.launchurl,
|
||||||
this.page,
|
this.redirectData,
|
||||||
this.pageOptions,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
|
|
@ -32,10 +32,9 @@ import { CoreWSError } from '@classes/errors/wserror';
|
||||||
import { makeSingleton, Translate } from '@singletons';
|
import { makeSingleton, Translate } from '@singletons';
|
||||||
import { CoreLogger } from '@singletons/logger';
|
import { CoreLogger } from '@singletons/logger';
|
||||||
import { CoreUrl } from '@singletons/url';
|
import { CoreUrl } from '@singletons/url';
|
||||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
import { CoreNavigator, CoreRedirectPayload } from '@services/navigator';
|
||||||
import { CoreCanceledError } from '@classes/errors/cancelederror';
|
import { CoreCanceledError } from '@classes/errors/cancelederror';
|
||||||
import { CoreCustomURLSchemes } from '@services/urlschemes';
|
import { CoreCustomURLSchemes } from '@services/urlschemes';
|
||||||
import { CoreSitePlugins } from '@features/siteplugins/services/siteplugins';
|
|
||||||
import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications';
|
import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -132,6 +131,7 @@ export class CoreLoginHelperProvider {
|
||||||
* @param typeOfLogin CoreConstants.LOGIN_SSO_CODE or CoreConstants.LOGIN_SSO_INAPP_CODE.
|
* @param typeOfLogin CoreConstants.LOGIN_SSO_CODE or CoreConstants.LOGIN_SSO_INAPP_CODE.
|
||||||
* @param service The service to use. If not defined, core service will be used.
|
* @param service The service to use. If not defined, core service will be used.
|
||||||
* @param launchUrl The URL to open for SSO. If not defined, default tool mobile launch URL will be used.
|
* @param launchUrl The URL to open for SSO. If not defined, default tool mobile launch URL will be used.
|
||||||
|
* @param redirectData Data of the path/url to open once authenticated. If not defined, site initial page.
|
||||||
* @return Promise resolved when done or if user cancelled.
|
* @return Promise resolved when done or if user cancelled.
|
||||||
*/
|
*/
|
||||||
async confirmAndOpenBrowserForSSOLogin(
|
async confirmAndOpenBrowserForSSOLogin(
|
||||||
|
@ -139,6 +139,7 @@ export class CoreLoginHelperProvider {
|
||||||
typeOfLogin: number,
|
typeOfLogin: number,
|
||||||
service?: string,
|
service?: string,
|
||||||
launchUrl?: string,
|
launchUrl?: string,
|
||||||
|
redirectData?: CoreRedirectPayload,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// Show confirm only if it's needed. Treat "false" (string) as false to prevent typing errors.
|
// Show confirm only if it's needed. Treat "false" (string) as false to prevent typing errors.
|
||||||
const showConfirmation = this.shouldShowSSOConfirm(typeOfLogin);
|
const showConfirmation = this.shouldShowSSOConfirm(typeOfLogin);
|
||||||
|
@ -152,7 +153,7 @@ export class CoreLoginHelperProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.openBrowserForSSOLogin(siteUrl, typeOfLogin, service, launchUrl);
|
this.openBrowserForSSOLogin(siteUrl, typeOfLogin, service, launchUrl, redirectData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -414,17 +415,14 @@ export class CoreLoginHelperProvider {
|
||||||
let params: Params = { openAddSite: true , showKeyboard };
|
let params: Params = { openAddSite: true , showKeyboard };
|
||||||
|
|
||||||
if (CoreSites.isLoggedIn()) {
|
if (CoreSites.isLoggedIn()) {
|
||||||
|
const willReload = await CoreSites.logoutForRedirect(CoreConstants.NO_SITE_ID, {
|
||||||
|
redirectPath: path,
|
||||||
|
redirectOptions: { params },
|
||||||
|
});
|
||||||
|
|
||||||
if (CoreSitePlugins.hasSitePluginsLoaded) {
|
if (willReload) {
|
||||||
// The site has site plugins so the app will be restarted. Store the data and logout.
|
|
||||||
CoreApp.storeRedirect(CoreConstants.NO_SITE_ID, path, { params });
|
|
||||||
|
|
||||||
await CoreSites.logout();
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await CoreSites.logout();
|
|
||||||
} else {
|
} else {
|
||||||
[path, params] = this.getAddSiteRouteInfo(showKeyboard);
|
[path, params] = this.getAddSiteRouteInfo(showKeyboard);
|
||||||
}
|
}
|
||||||
|
@ -477,7 +475,7 @@ export class CoreLoginHelperProvider {
|
||||||
async goToSiteInitialPage(navCtrlUnused?: unknown, page?: string, params?: any, options?: any, url?: string): Promise<void> {
|
async goToSiteInitialPage(navCtrlUnused?: unknown, page?: string, params?: any, options?: any, url?: string): Promise<void> {
|
||||||
await CoreNavigator.navigateToSiteHome({
|
await CoreNavigator.navigateToSiteHome({
|
||||||
...options,
|
...options,
|
||||||
params: {
|
params: <CoreRedirectPayload> {
|
||||||
redirectPath: page,
|
redirectPath: page,
|
||||||
redirectOptions: { params },
|
redirectOptions: { params },
|
||||||
urlToOpen: url,
|
urlToOpen: url,
|
||||||
|
@ -564,23 +562,19 @@ export class CoreLoginHelperProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if current site is logged out, triggering mmCoreEventSessionExpired if it is.
|
* Check if current site is logged out, triggering session expired event if it is.
|
||||||
*
|
*
|
||||||
* @param pageName Name of the page to go once authenticated if logged out. If not defined, site initial page.
|
* @param redirectData Data of the path/url to open once authenticated if logged out. If not defined, site initial page.
|
||||||
* @param options Options of the page to go once authenticated if logged out.
|
|
||||||
* @return True if user is logged out, false otherwise.
|
* @return True if user is logged out, false otherwise.
|
||||||
*/
|
*/
|
||||||
isSiteLoggedOut(pageName?: string, options?: CoreNavigationOptions): boolean {
|
isSiteLoggedOut(redirectData?: CoreRedirectPayload): boolean {
|
||||||
const site = CoreSites.getCurrentSite();
|
const site = CoreSites.getCurrentSite();
|
||||||
if (!site) {
|
if (!site) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (site.isLoggedOut()) {
|
if (site.isLoggedOut()) {
|
||||||
CoreEvents.trigger(CoreEvents.SESSION_EXPIRED, {
|
CoreEvents.trigger(CoreEvents.SESSION_EXPIRED, redirectData || {}, site.getId());
|
||||||
pageName,
|
|
||||||
options,
|
|
||||||
}, site.getId());
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -652,16 +646,14 @@ export class CoreLoginHelperProvider {
|
||||||
* @param siteUrl URL of the site where the login will be performed.
|
* @param siteUrl URL of the site where the login will be performed.
|
||||||
* @param provider The identity provider.
|
* @param provider The identity provider.
|
||||||
* @param launchUrl The URL to open for SSO. If not defined, tool/mobile launch URL will be used.
|
* @param launchUrl The URL to open for SSO. If not defined, tool/mobile launch URL will be used.
|
||||||
* @param pageName Name of the page to go once authenticated. If not defined, site initial page.
|
* @param redirectData Data of the path/url to open once authenticated. If not defined, site initial page.
|
||||||
* @param pageOptions Options of the page to go once authenticated.
|
|
||||||
* @return True if success, false if error.
|
* @return True if success, false if error.
|
||||||
*/
|
*/
|
||||||
openBrowserForOAuthLogin(
|
openBrowserForOAuthLogin(
|
||||||
siteUrl: string,
|
siteUrl: string,
|
||||||
provider: CoreSiteIdentityProvider,
|
provider: CoreSiteIdentityProvider,
|
||||||
launchUrl?: string,
|
launchUrl?: string,
|
||||||
pageName?: string,
|
redirectData?: CoreRedirectPayload,
|
||||||
pageOptions?: CoreNavigationOptions,
|
|
||||||
): boolean {
|
): boolean {
|
||||||
launchUrl = launchUrl || siteUrl + '/admin/tool/mobile/launch.php';
|
launchUrl = launchUrl || siteUrl + '/admin/tool/mobile/launch.php';
|
||||||
if (!provider || !provider.url) {
|
if (!provider || !provider.url) {
|
||||||
|
@ -674,7 +666,7 @@ export class CoreLoginHelperProvider {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const loginUrl = this.prepareForSSOLogin(siteUrl, undefined, launchUrl, pageName, pageOptions, {
|
const loginUrl = this.prepareForSSOLogin(siteUrl, undefined, launchUrl, redirectData, {
|
||||||
oauthsso: params.id,
|
oauthsso: params.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -692,18 +684,16 @@ export class CoreLoginHelperProvider {
|
||||||
* @param typeOfLogin CoreConstants.LOGIN_SSO_CODE or CoreConstants.LOGIN_SSO_INAPP_CODE.
|
* @param typeOfLogin CoreConstants.LOGIN_SSO_CODE or CoreConstants.LOGIN_SSO_INAPP_CODE.
|
||||||
* @param service The service to use. If not defined, core service will be used.
|
* @param service The service to use. If not defined, core service will be used.
|
||||||
* @param launchUrl The URL to open for SSO. If not defined, default tool mobile launch URL will be used.
|
* @param launchUrl The URL to open for SSO. If not defined, default tool mobile launch URL will be used.
|
||||||
* @param pageName Name of the page to go once authenticated. If not defined, site initial page.
|
* @param redirectData Data of the path/url to open once authenticated. If not defined, site initial page.
|
||||||
* @param pageOptions Options of the state to go once authenticated.
|
|
||||||
*/
|
*/
|
||||||
openBrowserForSSOLogin(
|
openBrowserForSSOLogin(
|
||||||
siteUrl: string,
|
siteUrl: string,
|
||||||
typeOfLogin: number,
|
typeOfLogin: number,
|
||||||
service?: string,
|
service?: string,
|
||||||
launchUrl?: string,
|
launchUrl?: string,
|
||||||
pageName?: string,
|
redirectData?: CoreRedirectPayload,
|
||||||
pageOptions?: CoreNavigationOptions,
|
|
||||||
): void {
|
): void {
|
||||||
const loginUrl = this.prepareForSSOLogin(siteUrl, service, launchUrl, pageName, pageOptions);
|
const loginUrl = this.prepareForSSOLogin(siteUrl, service, launchUrl, redirectData);
|
||||||
|
|
||||||
if (this.isSSOEmbeddedBrowser(typeOfLogin)) {
|
if (this.isSSOEmbeddedBrowser(typeOfLogin)) {
|
||||||
CoreUtils.openInApp(loginUrl, {
|
CoreUtils.openInApp(loginUrl, {
|
||||||
|
@ -819,8 +809,7 @@ export class CoreLoginHelperProvider {
|
||||||
siteUrl: string,
|
siteUrl: string,
|
||||||
service?: string,
|
service?: string,
|
||||||
launchUrl?: string,
|
launchUrl?: string,
|
||||||
pageName?: string,
|
redirectData: CoreRedirectPayload = {},
|
||||||
pageOptions?: CoreNavigationOptions,
|
|
||||||
urlParams?: CoreUrlParams,
|
urlParams?: CoreUrlParams,
|
||||||
): string {
|
): string {
|
||||||
|
|
||||||
|
@ -842,8 +831,7 @@ export class CoreLoginHelperProvider {
|
||||||
CoreConfig.set(CoreConstants.LOGIN_LAUNCH_DATA, JSON.stringify(<StoredLoginLaunchData> {
|
CoreConfig.set(CoreConstants.LOGIN_LAUNCH_DATA, JSON.stringify(<StoredLoginLaunchData> {
|
||||||
siteUrl: siteUrl,
|
siteUrl: siteUrl,
|
||||||
passport: passport,
|
passport: passport,
|
||||||
pageName: pageName || '',
|
...redirectData,
|
||||||
pageOptions: pageOptions || {},
|
|
||||||
ssoUrlParams: urlParams || {},
|
ssoUrlParams: urlParams || {},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -909,6 +897,11 @@ export class CoreLoginHelperProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sessionExpiredCheckingSite[siteId || ''] = true;
|
this.sessionExpiredCheckingSite[siteId || ''] = true;
|
||||||
|
const redirectData: CoreRedirectPayload = {
|
||||||
|
redirectPath: data.redirectPath,
|
||||||
|
redirectOptions: data.redirectOptions,
|
||||||
|
urlToOpen: data.urlToOpen,
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Check authentication method.
|
// Check authentication method.
|
||||||
|
@ -930,8 +923,7 @@ export class CoreLoginHelperProvider {
|
||||||
result.code,
|
result.code,
|
||||||
result.service,
|
result.service,
|
||||||
result.config?.launchurl,
|
result.config?.launchurl,
|
||||||
data.pageName,
|
redirectData,
|
||||||
data.options,
|
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// User cancelled, logout him.
|
// User cancelled, logout him.
|
||||||
|
@ -964,8 +956,7 @@ export class CoreLoginHelperProvider {
|
||||||
siteUrl,
|
siteUrl,
|
||||||
providerToUse,
|
providerToUse,
|
||||||
result.config?.launchurl,
|
result.config?.launchurl,
|
||||||
data.pageName,
|
redirectData,
|
||||||
data.options,
|
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// User cancelled, logout him.
|
// User cancelled, logout him.
|
||||||
|
@ -987,8 +978,7 @@ export class CoreLoginHelperProvider {
|
||||||
await CoreUtils.ignoreErrors(CoreNavigator.navigate('/login/reconnect', {
|
await CoreUtils.ignoreErrors(CoreNavigator.navigate('/login/reconnect', {
|
||||||
params: {
|
params: {
|
||||||
siteId,
|
siteId,
|
||||||
pageName: data.pageName,
|
...redirectData,
|
||||||
pageOptions: data.options,
|
|
||||||
},
|
},
|
||||||
reset: true,
|
reset: true,
|
||||||
}));
|
}));
|
||||||
|
@ -1213,8 +1203,9 @@ export class CoreLoginHelperProvider {
|
||||||
siteUrl: launchSiteURL,
|
siteUrl: launchSiteURL,
|
||||||
token: params[1],
|
token: params[1],
|
||||||
privateToken: params[2],
|
privateToken: params[2],
|
||||||
pageName: data.pageName,
|
redirectPath: data.redirectPath,
|
||||||
pageOptions: data.pageOptions,
|
redirectOptions: data.redirectOptions,
|
||||||
|
urlToOpen: data.urlToOpen,
|
||||||
ssoUrlParams: data.ssoUrlParams,
|
ssoUrlParams: data.ssoUrlParams,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
@ -1443,12 +1434,10 @@ export type CoreAccountsList = {
|
||||||
/**
|
/**
|
||||||
* Data related to a SSO authentication.
|
* Data related to a SSO authentication.
|
||||||
*/
|
*/
|
||||||
export interface CoreLoginSSOData {
|
export type CoreLoginSSOData = CoreRedirectPayload & {
|
||||||
siteUrl: string; // The site's URL.
|
siteUrl: string; // The site's URL.
|
||||||
token?: string; // User's token.
|
token?: string; // User's token.
|
||||||
privateToken?: string; // User's private token.
|
privateToken?: string; // User's private token.
|
||||||
pageName?: string; // Name of the page to go after authenticated.
|
|
||||||
pageOptions?: CoreNavigationOptions; // Options of the navigation to the page.
|
|
||||||
ssoUrlParams?: CoreUrlParams; // Other params added to the login url.
|
ssoUrlParams?: CoreUrlParams; // Other params added to the login url.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1531,11 +1520,9 @@ type ResendConfirmationEmailResult = {
|
||||||
warnings?: CoreWSExternalWarning[];
|
warnings?: CoreWSExternalWarning[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type StoredLoginLaunchData = {
|
type StoredLoginLaunchData = CoreRedirectPayload & {
|
||||||
siteUrl: string;
|
siteUrl: string;
|
||||||
passport: number;
|
passport: number;
|
||||||
pageName: string;
|
|
||||||
pageOptions: CoreNavigationOptions;
|
|
||||||
ssoUrlParams: CoreUrlParams;
|
ssoUrlParams: CoreUrlParams;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper';
|
||||||
|
import { CoreCourse } from '@features/course/services/course';
|
||||||
|
import { CoreCourseHelper } from '@features/course/services/course-helper';
|
||||||
|
import { CoreNavigationOptions, CoreNavigator, CoreRedirectPayload } from '@services/navigator';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class to handle opening deep links in a main menu page. There are 2 type of deep links:
|
||||||
|
* -A Moodle URL to treat.
|
||||||
|
* -A combination of path + options.
|
||||||
|
*/
|
||||||
|
export class CoreMainMenuDeepLinkManager {
|
||||||
|
|
||||||
|
protected pendingRedirect?: CoreRedirectPayload;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
const urlToOpen = CoreNavigator.getRouteParam('urlToOpen');
|
||||||
|
const redirectPath = CoreNavigator.getRouteParam('redirectPath');
|
||||||
|
if (urlToOpen || redirectPath) {
|
||||||
|
this.pendingRedirect = {
|
||||||
|
redirectPath,
|
||||||
|
redirectOptions: CoreNavigator.getRouteParam('redirectOptions'),
|
||||||
|
urlToOpen,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether there is a deep link to be treated.
|
||||||
|
*
|
||||||
|
* @return Whether there is a deep link to be treated.
|
||||||
|
*/
|
||||||
|
hasDeepLinkToTreat(): boolean {
|
||||||
|
return !!this.pendingRedirect?.urlToOpen || !!this.pendingRedirect?.redirectPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Treat a deep link if there's any to treat.
|
||||||
|
*/
|
||||||
|
treatLink(): void {
|
||||||
|
if (!this.pendingRedirect) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.pendingRedirect.redirectPath) {
|
||||||
|
this.treatPath(this.pendingRedirect.redirectPath, this.pendingRedirect.redirectOptions);
|
||||||
|
} else if (this.pendingRedirect.urlToOpen) {
|
||||||
|
this.treatUrlToOpen(this.pendingRedirect.urlToOpen);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete this.pendingRedirect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a path.
|
||||||
|
*
|
||||||
|
* @param path Path.
|
||||||
|
* @param navOptions Navigation options.
|
||||||
|
*/
|
||||||
|
protected treatPath(path: string, navOptions: CoreNavigationOptions = {}): void {
|
||||||
|
const params = navOptions.params;
|
||||||
|
const coursePathMatches = path.match(/^course\/(\d+)\/?$/);
|
||||||
|
|
||||||
|
if (coursePathMatches) {
|
||||||
|
if (!params?.course) {
|
||||||
|
CoreCourseHelper.getAndOpenCourse(Number(coursePathMatches[1]), params);
|
||||||
|
} else {
|
||||||
|
CoreCourse.openCourse(params.course, params);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CoreNavigator.navigateToSitePath(path, {
|
||||||
|
...navOptions,
|
||||||
|
preferCurrentTab: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Treat a URL to open.
|
||||||
|
*
|
||||||
|
* @param url URL to open.
|
||||||
|
*/
|
||||||
|
protected async treatUrlToOpen(url: string): Promise<void> {
|
||||||
|
const action = await CoreContentLinksHelper.getFirstValidActionFor(url);
|
||||||
|
if (action?.sites?.[0]) {
|
||||||
|
action.action(action.sites[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -20,13 +20,8 @@ import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||||
import { CoreTabsOutletComponent, CoreTabsOutletTab } from '@components/tabs-outlet/tabs-outlet';
|
import { CoreTabsOutletComponent, CoreTabsOutletTab } from '@components/tabs-outlet/tabs-outlet';
|
||||||
import { CoreMainMenuHomeDelegate, CoreMainMenuHomeHandlerToDisplay } from '../../services/home-delegate';
|
import { CoreMainMenuHomeDelegate, CoreMainMenuHomeHandlerToDisplay } from '../../services/home-delegate';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
|
||||||
import { CoreNavigator, CoreRedirectPayload } from '@services/navigator';
|
|
||||||
import { CoreCourseHelper } from '@features/course/services/course-helper';
|
|
||||||
import { CoreCourse } from '@features/course/services/course';
|
|
||||||
import { CoreContentLinksDelegate } from '@features/contentlinks/services/contentlinks-delegate';
|
|
||||||
import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper';
|
|
||||||
import { CoreMainMenuHomeHandlerService } from '@features/mainmenu/services/handlers/mainmenu';
|
import { CoreMainMenuHomeHandlerService } from '@features/mainmenu/services/handlers/mainmenu';
|
||||||
|
import { CoreMainMenuDeepLinkManager } from '@features/mainmenu/classes/deep-link-manager';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page that displays the Home.
|
* Page that displays the Home.
|
||||||
|
@ -46,28 +41,13 @@ export class CoreMainMenuHomePage implements OnInit {
|
||||||
|
|
||||||
protected subscription?: Subscription;
|
protected subscription?: Subscription;
|
||||||
protected updateSiteObserver?: CoreEventObserver;
|
protected updateSiteObserver?: CoreEventObserver;
|
||||||
protected pendingRedirect?: CoreRedirectPayload;
|
protected deepLinkManager?: CoreMainMenuDeepLinkManager;
|
||||||
protected urlToOpen?: string;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
protected route: ActivatedRoute,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.route.queryParams.subscribe((params: Partial<CoreRedirectPayload> & { urlToOpen?: string }) => {
|
this.deepLinkManager = new CoreMainMenuDeepLinkManager();
|
||||||
this.urlToOpen = params.urlToOpen ?? this.urlToOpen;
|
|
||||||
|
|
||||||
if (params.redirectPath) {
|
|
||||||
this.pendingRedirect = {
|
|
||||||
redirectPath: params.redirectPath,
|
|
||||||
redirectOptions: params.redirectOptions,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.loadSiteName();
|
this.loadSiteName();
|
||||||
|
|
||||||
|
@ -124,55 +104,11 @@ export class CoreMainMenuHomePage implements OnInit {
|
||||||
this.siteName = CoreSites.getRequiredCurrentSite().getSiteName() || '';
|
this.siteName = CoreSites.getRequiredCurrentSite().getSiteName() || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a redirect.
|
|
||||||
*
|
|
||||||
* @param data Data received.
|
|
||||||
*/
|
|
||||||
protected handleRedirect(data: CoreRedirectPayload): void {
|
|
||||||
const params = data.redirectOptions?.params;
|
|
||||||
const coursePathMatches = data.redirectPath.match(/^course\/(\d+)\/?$/);
|
|
||||||
|
|
||||||
if (coursePathMatches) {
|
|
||||||
if (!params?.course) {
|
|
||||||
CoreCourseHelper.getAndOpenCourse(Number(coursePathMatches[1]), params);
|
|
||||||
} else {
|
|
||||||
CoreCourse.openCourse(params.course, params);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
CoreNavigator.navigateToSitePath(data.redirectPath, {
|
|
||||||
...data.redirectOptions,
|
|
||||||
preferCurrentTab: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a URL to open.
|
|
||||||
*
|
|
||||||
* @param url URL to open.
|
|
||||||
*/
|
|
||||||
protected async handleUrlToOpen(url: string): Promise<void> {
|
|
||||||
const actions = await CoreContentLinksDelegate.getActionsFor(url, undefined);
|
|
||||||
|
|
||||||
const action = CoreContentLinksHelper.getFirstValidAction(actions);
|
|
||||||
if (action?.sites?.[0]) {
|
|
||||||
action.action(action.sites[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tab was selected.
|
* Tab was selected.
|
||||||
*/
|
*/
|
||||||
tabSelected(): void {
|
tabSelected(): void {
|
||||||
if (this.pendingRedirect) {
|
this.deepLinkManager?.treatLink();
|
||||||
this.handleRedirect(this.pendingRedirect);
|
|
||||||
} else if (this.urlToOpen) {
|
|
||||||
this.handleUrlToOpen(this.urlToOpen);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete this.pendingRedirect;
|
|
||||||
delete this.urlToOpen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { CoreMainMenuDelegate, CoreMainMenuHandlerToDisplay } from '../../servic
|
||||||
import { Router } from '@singletons';
|
import { Router } from '@singletons';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { CoreAriaRoleTab, CoreAriaRoleTabFindable } from '@classes/aria-role-tab';
|
import { CoreAriaRoleTab, CoreAriaRoleTabFindable } from '@classes/aria-role-tab';
|
||||||
import { CoreNavigator } from '@services/navigator';
|
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
||||||
import { filter } from 'rxjs/operators';
|
import { filter } from 'rxjs/operators';
|
||||||
import { NavigationEnd } from '@angular/router';
|
import { NavigationEnd } from '@angular/router';
|
||||||
import { trigger, state, style, transition, animate } from '@angular/animations';
|
import { trigger, state, style, transition, animate } from '@angular/animations';
|
||||||
|
@ -77,6 +77,9 @@ export class CoreMainMenuPage implements OnInit, OnDestroy {
|
||||||
protected backButtonFunction: (event: BackButtonEvent) => void;
|
protected backButtonFunction: (event: BackButtonEvent) => void;
|
||||||
protected selectHistory: string[] = [];
|
protected selectHistory: string[] = [];
|
||||||
protected firstSelectedTab?: string;
|
protected firstSelectedTab?: string;
|
||||||
|
protected urlToOpen?: string;
|
||||||
|
protected redirectPath?: string;
|
||||||
|
protected redirectOptions?: CoreNavigationOptions;
|
||||||
|
|
||||||
@ViewChild('mainTabs') mainTabs?: IonTabs;
|
@ViewChild('mainTabs') mainTabs?: IonTabs;
|
||||||
|
|
||||||
|
@ -100,6 +103,9 @@ export class CoreMainMenuPage implements OnInit, OnDestroy {
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.showTabs = true;
|
this.showTabs = true;
|
||||||
|
this.urlToOpen = CoreNavigator.getRouteParam('urlToOpen');
|
||||||
|
this.redirectPath = CoreNavigator.getRouteParam('redirectPath');
|
||||||
|
this.redirectOptions = CoreNavigator.getRouteParam('redirectOptions');
|
||||||
|
|
||||||
this.isMainScreen = !this.mainTabs?.outlet.canGoBack();
|
this.isMainScreen = !this.mainTabs?.outlet.canGoBack();
|
||||||
|
|
||||||
|
@ -173,10 +179,22 @@ export class CoreMainMenuPage implements OnInit, OnDestroy {
|
||||||
|
|
||||||
this.loaded = CoreMainMenuDelegate.areHandlersLoaded();
|
this.loaded = CoreMainMenuDelegate.areHandlersLoaded();
|
||||||
|
|
||||||
if (this.loaded && this.tabs[0] && !CoreNavigator.getCurrentMainMenuTab()) {
|
if (this.loaded && !CoreNavigator.getCurrentMainMenuTab()) {
|
||||||
// No tab selected, select the first one.
|
// No tab selected, select the first one.
|
||||||
await CoreUtils.nextTick();
|
await CoreUtils.nextTick();
|
||||||
this.mainTabs?.select(this.tabs[0].page);
|
|
||||||
|
const tabPage = this.tabs[0] ? this.tabs[0].page : this.morePageName;
|
||||||
|
const tabPageParams = this.tabs[0] ? this.tabs[0].pageParams : {};
|
||||||
|
|
||||||
|
// Use navigate instead of mainTabs.select to be able to pass page params.
|
||||||
|
CoreNavigator.navigate(tabPage, {
|
||||||
|
params: {
|
||||||
|
urlToOpen: this.urlToOpen,
|
||||||
|
redirectPath: this.redirectPath,
|
||||||
|
redirectOptions: this.redirectOptions,
|
||||||
|
...tabPageParams,
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import { CoreCustomURLSchemes } from '@services/urlschemes';
|
||||||
import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper';
|
import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper';
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
|
import { CoreMainMenuDeepLinkManager } from '@features/mainmenu/classes/deep-link-manager';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page that displays the more page of the app.
|
* Page that displays the more page of the app.
|
||||||
|
@ -71,6 +72,9 @@ export class CoreMainMenuMorePage implements OnInit, OnDestroy {
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('resize', this.initHandlers.bind(this));
|
window.addEventListener('resize', this.initHandlers.bind(this));
|
||||||
|
|
||||||
|
const deepLinkManager = new CoreMainMenuDeepLinkManager();
|
||||||
|
deepLinkManager.treatLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -23,6 +23,7 @@ import { CoreTagCloud, CoreTagCollection, CoreTagCloudTag, CoreTag } from '@feat
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper';
|
import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper';
|
||||||
import { CoreNavigator } from '@services/navigator';
|
import { CoreNavigator } from '@services/navigator';
|
||||||
|
import { CoreMainMenuDeepLinkManager } from '@features/mainmenu/classes/deep-link-manager';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page that displays most used tags and allows searching.
|
* Page that displays most used tags and allows searching.
|
||||||
|
@ -48,6 +49,9 @@ export class CoreTagSearchPage implements OnInit {
|
||||||
this.collectionId = CoreNavigator.getRouteNumberParam('collectionId') || 0;
|
this.collectionId = CoreNavigator.getRouteNumberParam('collectionId') || 0;
|
||||||
this.query = CoreNavigator.getRouteParam('query') || '';
|
this.query = CoreNavigator.getRouteParam('query') || '';
|
||||||
|
|
||||||
|
const deepLinkManager = new CoreMainMenuDeepLinkManager();
|
||||||
|
deepLinkManager.treatLink();
|
||||||
|
|
||||||
this.fetchData().finally(() => {
|
this.fetchData().finally(() => {
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { CanActivate, CanLoad, UrlTree } from '@angular/router';
|
import { CanActivate, CanLoad, UrlTree } from '@angular/router';
|
||||||
import { CoreMainMenuHomeHandlerService } from '@features/mainmenu/services/handlers/mainmenu';
|
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreApp } from '@services/app';
|
||||||
import { CoreRedirectPayload } from '@services/navigator';
|
import { CoreRedirectPayload } from '@services/navigator';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
|
@ -55,29 +54,31 @@ export class CoreRedirectGuard implements CanLoad, CanActivate {
|
||||||
|
|
||||||
// Redirect to site path.
|
// Redirect to site path.
|
||||||
if (redirect.siteId && redirect.siteId !== CoreConstants.NO_SITE_ID) {
|
if (redirect.siteId && redirect.siteId !== CoreConstants.NO_SITE_ID) {
|
||||||
|
const redirectData: CoreRedirectPayload = {
|
||||||
|
redirectPath: redirect.redirectPath,
|
||||||
|
redirectOptions: redirect.redirectOptions,
|
||||||
|
urlToOpen: redirect.urlToOpen,
|
||||||
|
};
|
||||||
|
|
||||||
const loggedIn = await CoreSites.loadSite(
|
const loggedIn = await CoreSites.loadSite(
|
||||||
redirect.siteId,
|
redirect.siteId,
|
||||||
redirect.page,
|
redirectData,
|
||||||
redirect.options,
|
|
||||||
);
|
);
|
||||||
const route = Router.parseUrl(`/main/${CoreMainMenuHomeHandlerService.PAGE_NAME}`);
|
const route = Router.parseUrl('/main');
|
||||||
|
|
||||||
route.queryParams = {
|
route.queryParams = redirectData;
|
||||||
redirectPath: redirect.page,
|
|
||||||
redirectOptions: redirect.options,
|
|
||||||
} as CoreRedirectPayload;
|
|
||||||
|
|
||||||
return loggedIn ? route : true;
|
return loggedIn ? route : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Abort redirect.
|
// Abort redirect.
|
||||||
if (!redirect.page) {
|
if (!redirect.redirectPath) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redirect to non-site path.
|
// Redirect to non-site path.
|
||||||
const route = Router.parseUrl(redirect.page);
|
const route = Router.parseUrl(redirect.redirectPath);
|
||||||
route.queryParams = redirect.options?.params || {};
|
route.queryParams = redirect.redirectOptions?.params || {};
|
||||||
|
|
||||||
return route;
|
return route;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { CoreLogger } from '@singletons/logger';
|
||||||
import { CoreColors } from '@singletons/colors';
|
import { CoreColors } from '@singletons/colors';
|
||||||
import { DBNAME, SCHEMA_VERSIONS_TABLE_NAME, SCHEMA_VERSIONS_TABLE_SCHEMA, SchemaVersionsDBEntry } from '@services/database/app';
|
import { DBNAME, SCHEMA_VERSIONS_TABLE_NAME, SCHEMA_VERSIONS_TABLE_SCHEMA, SchemaVersionsDBEntry } from '@services/database/app';
|
||||||
import { CoreObject } from '@singletons/object';
|
import { CoreObject } from '@singletons/object';
|
||||||
import { CoreNavigationOptions } from './navigator';
|
import { CoreRedirectPayload } from './navigator';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object responsible of managing schema versions.
|
* Object responsible of managing schema versions.
|
||||||
|
@ -593,16 +593,18 @@ export class CoreAppProvider {
|
||||||
* Store redirect params.
|
* Store redirect params.
|
||||||
*
|
*
|
||||||
* @param siteId Site ID.
|
* @param siteId Site ID.
|
||||||
* @param page Page to go.
|
* @param redirectData Redirect data.
|
||||||
* @param options Navigation options.
|
|
||||||
*/
|
*/
|
||||||
storeRedirect(siteId: string, page: string, options: CoreNavigationOptions): void {
|
storeRedirect(siteId: string, redirectData: CoreRedirectPayload = {}): void {
|
||||||
|
if (!redirectData.redirectPath && !redirectData.urlToOpen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const redirect: CoreRedirectData = {
|
const redirect: CoreRedirectData = {
|
||||||
siteId,
|
siteId,
|
||||||
page,
|
|
||||||
options,
|
|
||||||
timemodified: Date.now(),
|
timemodified: Date.now(),
|
||||||
|
...redirectData,
|
||||||
};
|
};
|
||||||
|
|
||||||
localStorage.setItem('CoreRedirect', JSON.stringify(redirect));
|
localStorage.setItem('CoreRedirect', JSON.stringify(redirect));
|
||||||
|
@ -691,26 +693,9 @@ export const CoreApp = makeSingleton(CoreAppProvider);
|
||||||
/**
|
/**
|
||||||
* Data stored for a redirect to another page/site.
|
* Data stored for a redirect to another page/site.
|
||||||
*/
|
*/
|
||||||
export type CoreRedirectData = {
|
export type CoreRedirectData = CoreRedirectPayload & {
|
||||||
/**
|
siteId?: string; // ID of the site to load.
|
||||||
* ID of the site to load.
|
timemodified?: number; // Timestamp when this redirect was last modified.
|
||||||
*/
|
|
||||||
siteId?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Path of the page to redirect to.
|
|
||||||
*/
|
|
||||||
page?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Options of the navigation.
|
|
||||||
*/
|
|
||||||
options?: CoreNavigationOptions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Timestamp when this redirect was last modified.
|
|
||||||
*/
|
|
||||||
timemodified?: number;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,17 +28,16 @@ import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { makeSingleton, NavController, Router } from '@singletons';
|
import { makeSingleton, NavController, Router } from '@singletons';
|
||||||
import { CoreScreen } from './screen';
|
import { CoreScreen } from './screen';
|
||||||
import { CoreApp } from './app';
|
import { CoreApp } from './app';
|
||||||
import { CoreSitePlugins } from '@features/siteplugins/services/siteplugins';
|
|
||||||
import { CoreError } from '@classes/errors/error';
|
import { CoreError } from '@classes/errors/error';
|
||||||
import { CoreMainMenuDelegate } from '@features/mainmenu/services/mainmenu-delegate';
|
import { CoreMainMenuDelegate } from '@features/mainmenu/services/mainmenu-delegate';
|
||||||
import { CoreMainMenuHomeHandlerService } from '@features/mainmenu/services/handlers/mainmenu';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirect payload.
|
* Redirect payload.
|
||||||
*/
|
*/
|
||||||
export type CoreRedirectPayload = {
|
export type CoreRedirectPayload = {
|
||||||
redirectPath: string;
|
redirectPath?: string; // Path of the page to redirect to.
|
||||||
redirectOptions?: CoreNavigationOptions;
|
redirectOptions?: CoreNavigationOptions; // Options of the navigation using redirectPath.
|
||||||
|
urlToOpen?: string; // URL to open instead of a page + options.
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -208,16 +207,14 @@ export class CoreNavigatorService {
|
||||||
|
|
||||||
// If we are logged into a different site, log out first.
|
// If we are logged into a different site, log out first.
|
||||||
if (CoreSites.isLoggedIn() && CoreSites.getCurrentSiteId() !== siteId) {
|
if (CoreSites.isLoggedIn() && CoreSites.getCurrentSiteId() !== siteId) {
|
||||||
if (CoreSitePlugins.hasSitePluginsLoaded) {
|
const willReload = await CoreSites.logoutForRedirect(siteId, {
|
||||||
// The site has site plugins so the app will be restarted. Store the data and logout.
|
redirectPath: path,
|
||||||
CoreApp.storeRedirect(siteId, path, options || {});
|
redirectOptions: options || {},
|
||||||
|
});
|
||||||
await CoreSites.logout();
|
|
||||||
|
|
||||||
|
if (willReload) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
await CoreSites.logout();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the path doesn't belong to a site, call standard navigation.
|
// If the path doesn't belong to a site, call standard navigation.
|
||||||
|
@ -233,7 +230,10 @@ export class CoreNavigatorService {
|
||||||
const modal = await CoreDomUtils.showModalLoading();
|
const modal = await CoreDomUtils.showModalLoading();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const loggedIn = await CoreSites.loadSite(siteId, path, options.params);
|
const loggedIn = await CoreSites.loadSite(siteId, {
|
||||||
|
redirectPath: path,
|
||||||
|
redirectOptions: options,
|
||||||
|
});
|
||||||
|
|
||||||
if (!loggedIn) {
|
if (!loggedIn) {
|
||||||
// User has been redirected to the login page and will be redirected to the site path after login.
|
// User has been redirected to the login page and will be redirected to the site path after login.
|
||||||
|
@ -560,11 +560,11 @@ export class CoreNavigatorService {
|
||||||
return this.navigate(`/main/${path}`, options);
|
return this.navigate(`/main/${path}`, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open the path within the home tab.
|
// Open the path within in main menu.
|
||||||
return this.navigate(`/main/${CoreMainMenuHomeHandlerService.PAGE_NAME}`, {
|
return this.navigate('/main', {
|
||||||
...options,
|
...options,
|
||||||
params: {
|
params: {
|
||||||
redirectPath: `/main/${CoreMainMenuHomeHandlerService.PAGE_NAME}/${path}`,
|
redirectPath: path,
|
||||||
redirectOptions: options.params || options.nextNavigation ? options : undefined,
|
redirectOptions: options.params || options.nextNavigation ? options : undefined,
|
||||||
} as CoreRedirectPayload,
|
} as CoreRedirectPayload,
|
||||||
});
|
});
|
||||||
|
|
|
@ -49,13 +49,14 @@ import {
|
||||||
} from '@services/database/sites';
|
} from '@services/database/sites';
|
||||||
import { CoreArray } from '../singletons/array';
|
import { CoreArray } from '../singletons/array';
|
||||||
import { CoreNetworkError } from '@classes/errors/network-error';
|
import { CoreNetworkError } from '@classes/errors/network-error';
|
||||||
import { CoreNavigationOptions } from './navigator';
|
import { CoreRedirectPayload } from './navigator';
|
||||||
import { CoreSitesFactory } from './sites-factory';
|
import { CoreSitesFactory } from './sites-factory';
|
||||||
import { CoreText } from '@singletons/text';
|
import { CoreText } from '@singletons/text';
|
||||||
import { CoreLoginHelper } from '@features/login/services/login-helper';
|
import { CoreLoginHelper } from '@features/login/services/login-helper';
|
||||||
import { CoreErrorWithTitle } from '@classes/errors/errorwithtitle';
|
import { CoreErrorWithTitle } from '@classes/errors/errorwithtitle';
|
||||||
import { CoreAjaxError } from '@classes/errors/ajaxerror';
|
import { CoreAjaxError } from '@classes/errors/ajaxerror';
|
||||||
import { CoreAjaxWSError } from '@classes/errors/ajaxwserror';
|
import { CoreAjaxWSError } from '@classes/errors/ajaxwserror';
|
||||||
|
import { CoreSitePlugins } from '@features/siteplugins/services/siteplugins';
|
||||||
|
|
||||||
export const CORE_SITE_SCHEMAS = new InjectionToken<CoreSiteSchema[]>('CORE_SITE_SCHEMAS');
|
export const CORE_SITE_SCHEMAS = new InjectionToken<CoreSiteSchema[]>('CORE_SITE_SCHEMAS');
|
||||||
|
|
||||||
|
@ -781,11 +782,10 @@ export class CoreSitesProvider {
|
||||||
* Login a user to a site from the list of sites.
|
* Login a user to a site from the list of sites.
|
||||||
*
|
*
|
||||||
* @param siteId ID of the site to load.
|
* @param siteId ID of the site to load.
|
||||||
* @param pageName Name of the page to go once authenticated if logged out. If not defined, site initial page.
|
* @param redirectData Data of the path/url to open once authenticated if logged out. If not defined, site initial page.
|
||||||
* @param pageOptions Options of the navigation to pageName.
|
|
||||||
* @return Promise resolved with true if site is loaded, resolved with false if cannot login.
|
* @return Promise resolved with true if site is loaded, resolved with false if cannot login.
|
||||||
*/
|
*/
|
||||||
async loadSite(siteId: string, pageName?: string, pageOptions?: CoreNavigationOptions): Promise<boolean> {
|
async loadSite(siteId: string, redirectData?: CoreRedirectPayload): Promise<boolean> {
|
||||||
this.logger.debug(`Load site ${siteId}`);
|
this.logger.debug(`Load site ${siteId}`);
|
||||||
|
|
||||||
const site = await this.getSite(siteId);
|
const site = await this.getSite(siteId);
|
||||||
|
@ -799,10 +799,7 @@ export class CoreSitesProvider {
|
||||||
|
|
||||||
if (site.isLoggedOut()) {
|
if (site.isLoggedOut()) {
|
||||||
// Logged out, trigger session expired event and stop.
|
// Logged out, trigger session expired event and stop.
|
||||||
CoreEvents.trigger(CoreEvents.SESSION_EXPIRED, {
|
CoreEvents.trigger(CoreEvents.SESSION_EXPIRED, redirectData || {}, site.getId());
|
||||||
pageName,
|
|
||||||
options: pageOptions,
|
|
||||||
}, site.getId());
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1208,6 +1205,28 @@ export class CoreSitesProvider {
|
||||||
CoreEvents.trigger(CoreEvents.LOGOUT, {}, siteId);
|
CoreEvents.trigger(CoreEvents.LOGOUT, {}, siteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logout the user if authenticated to open a page/url in another site.
|
||||||
|
*
|
||||||
|
* @param siteId Site that will be opened after logout.
|
||||||
|
* @param redirectData Page/url to open after logout.
|
||||||
|
* @return Promise resolved with boolean: true if app will be reloaded after logout.
|
||||||
|
*/
|
||||||
|
async logoutForRedirect(siteId: string, redirectData: CoreRedirectPayload): Promise<boolean> {
|
||||||
|
if (!this.currentSite) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CoreSitePlugins.hasSitePluginsLoaded) {
|
||||||
|
// The site has site plugins so the app will be restarted. Store the data and logout.
|
||||||
|
CoreApp.storeRedirect(siteId, redirectData);
|
||||||
|
}
|
||||||
|
|
||||||
|
await CoreSites.logout();
|
||||||
|
|
||||||
|
return CoreSitePlugins.hasSitePluginsLoaded;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restores the session to the previous one so the user doesn't has to login everytime the app is started.
|
* Restores the session to the previous one so the user doesn't has to login everytime the app is started.
|
||||||
*
|
*
|
||||||
|
|
|
@ -108,13 +108,13 @@ describe('CoreNavigator', () => {
|
||||||
expect(navControllerMock.navigateForward).toHaveBeenCalledWith(['/main/users/user/42'], {});
|
expect(navControllerMock.navigateForward).toHaveBeenCalledWith(['/main/users/user/42'], {});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('navigates to site paths using the default tab', async () => {
|
it('navigates to site paths using the main page', async () => {
|
||||||
const success = await navigator.navigateToSitePath('/user/42');
|
const success = await navigator.navigateToSitePath('/user/42');
|
||||||
|
|
||||||
expect(success).toBe(true);
|
expect(success).toBe(true);
|
||||||
expect(navControllerMock.navigateForward).toHaveBeenCalledWith(['/main/home'], {
|
expect(navControllerMock.navigateForward).toHaveBeenCalledWith(['/main'], {
|
||||||
queryParams: {
|
queryParams: {
|
||||||
redirectPath: '/main/home/user/42',
|
redirectPath: 'user/42',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -111,10 +111,13 @@ export class CoreUpdateManagerProvider {
|
||||||
await CoreSites.removeStoredCurrentSite();
|
await CoreSites.removeStoredCurrentSite();
|
||||||
|
|
||||||
// Tell the app to open add site so the user can add the new site.
|
// Tell the app to open add site so the user can add the new site.
|
||||||
CoreApp.storeRedirect(CoreConstants.NO_SITE_ID, '/login/sites', {
|
CoreApp.storeRedirect(CoreConstants.NO_SITE_ID, {
|
||||||
|
redirectPath: '/login/sites',
|
||||||
|
redirectOptions: {
|
||||||
params: {
|
params: {
|
||||||
openAddSite: true,
|
openAddSite: true,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,11 @@ import { CoreWSError } from '@classes/errors/wserror';
|
||||||
import { CoreContentLinksDelegate } from '@features/contentlinks/services/contentlinks-delegate';
|
import { CoreContentLinksDelegate } from '@features/contentlinks/services/contentlinks-delegate';
|
||||||
import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper';
|
import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper';
|
||||||
import { CoreLoginHelper, CoreLoginSSOData } from '@features/login/services/login-helper';
|
import { CoreLoginHelper, CoreLoginSSOData } from '@features/login/services/login-helper';
|
||||||
import { CoreSitePlugins } from '@features/siteplugins/services/siteplugins';
|
|
||||||
import { ApplicationInit, makeSingleton, Translate } from '@singletons';
|
import { ApplicationInit, makeSingleton, Translate } from '@singletons';
|
||||||
import { CoreLogger } from '@singletons/logger';
|
import { CoreLogger } from '@singletons/logger';
|
||||||
import { CoreConstants } from '../constants';
|
import { CoreConstants } from '../constants';
|
||||||
import { CoreApp } from './app';
|
import { CoreApp } from './app';
|
||||||
import { CoreNavigator } from './navigator';
|
import { CoreNavigator, CoreRedirectPayload } from './navigator';
|
||||||
import { CoreSiteCheckResponse, CoreSites } from './sites';
|
import { CoreSiteCheckResponse, CoreSites } from './sites';
|
||||||
import { CoreDomUtils } from './utils/dom';
|
import { CoreDomUtils } from './utils/dom';
|
||||||
import { CoreTextErrorObject, CoreTextUtils } from './utils/text';
|
import { CoreTextErrorObject, CoreTextUtils } from './utils/text';
|
||||||
|
@ -151,12 +150,13 @@ export class CoreCustomURLSchemesProvider {
|
||||||
|
|
||||||
if (data.isSSOToken || (data.isAuthenticationURL && siteId && CoreSites.getCurrentSiteId() == siteId)) {
|
if (data.isSSOToken || (data.isAuthenticationURL && siteId && CoreSites.getCurrentSiteId() == siteId)) {
|
||||||
// Site created and authenticated, open the page to go.
|
// Site created and authenticated, open the page to go.
|
||||||
if (data.pageName) {
|
CoreNavigator.navigateToSiteHome({
|
||||||
// Page defined, go to that page instead of site initial page.
|
params: <CoreRedirectPayload> {
|
||||||
CoreNavigator.navigateToSitePath(data.pageName, data.pageOptions);
|
redirectPath: data.redirectPath,
|
||||||
} else {
|
redirectOptions: data.redirectOptions,
|
||||||
CoreNavigator.navigateToSiteHome();
|
urlToOpen: data.urlToOpen,
|
||||||
}
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -396,20 +396,20 @@ export class CoreCustomURLSchemesProvider {
|
||||||
urlToOpen: data.redirect,
|
urlToOpen: data.redirect,
|
||||||
siteConfig: checkResponse.config,
|
siteConfig: checkResponse.config,
|
||||||
};
|
};
|
||||||
let hasSitePluginsLoaded = false;
|
|
||||||
|
|
||||||
if (CoreSites.isLoggedIn()) {
|
if (CoreSites.isLoggedIn()) {
|
||||||
// Ask the user before changing site.
|
// Ask the user before changing site.
|
||||||
await CoreDomUtils.showConfirm(Translate.instant('core.contentlinks.confirmurlothersite'));
|
await CoreDomUtils.showConfirm(Translate.instant('core.contentlinks.confirmurlothersite'));
|
||||||
|
|
||||||
if (!ssoNeeded) {
|
if (!ssoNeeded) {
|
||||||
hasSitePluginsLoaded = CoreSitePlugins.hasSitePluginsLoaded;
|
const willReload = await CoreSites.logoutForRedirect(CoreConstants.NO_SITE_ID, {
|
||||||
if (hasSitePluginsLoaded) {
|
redirectPath: '/login/credentials',
|
||||||
// Store the redirect since logout will restart the app.
|
redirectOptions: { params: pageParams },
|
||||||
CoreApp.storeRedirect(CoreConstants.NO_SITE_ID, '/login/credentials', { params: pageParams });
|
});
|
||||||
}
|
|
||||||
|
|
||||||
await CoreSites.logout();
|
if (willReload) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,7 +420,7 @@ export class CoreCustomURLSchemesProvider {
|
||||||
checkResponse.service,
|
checkResponse.service,
|
||||||
checkResponse.config?.launchurl,
|
checkResponse.config?.launchurl,
|
||||||
);
|
);
|
||||||
} else if (!hasSitePluginsLoaded) {
|
} else {
|
||||||
await CoreNavigator.navigateToLoginCredentials(pageParams);
|
await CoreNavigator.navigateToLoginCredentials(pageParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { Subject } from 'rxjs';
|
||||||
import { CoreLogger } from '@singletons/logger';
|
import { CoreLogger } from '@singletons/logger';
|
||||||
import { CoreSite, CoreSiteInfoResponse, CoreSitePublicConfigResponse } from '@classes/site';
|
import { CoreSite, CoreSiteInfoResponse, CoreSitePublicConfigResponse } from '@classes/site';
|
||||||
import { CoreFilepoolComponentFileEventData } from '@services/filepool';
|
import { CoreFilepoolComponentFileEventData } from '@services/filepool';
|
||||||
import { CoreNavigationOptions } from '@services/navigator';
|
import { CoreRedirectPayload } from '@services/navigator';
|
||||||
import { CoreCourseModuleCompletionData } from '@features/course/services/course-helper';
|
import { CoreCourseModuleCompletionData } from '@features/course/services/course-helper';
|
||||||
import { CoreScreenOrientation } from '@services/screen';
|
import { CoreScreenOrientation } from '@services/screen';
|
||||||
import { CoreCourseCompletionType } from '@features/course/services/course';
|
import { CoreCourseCompletionType } from '@features/course/services/course';
|
||||||
|
@ -272,10 +272,7 @@ export type CoreEventSiteAddedData = CoreSiteInfoResponse;
|
||||||
/**
|
/**
|
||||||
* Data passed to SESSION_EXPIRED event.
|
* Data passed to SESSION_EXPIRED event.
|
||||||
*/
|
*/
|
||||||
export type CoreEventSessionExpiredData = {
|
export type CoreEventSessionExpiredData = CoreRedirectPayload;
|
||||||
pageName?: string;
|
|
||||||
options?: CoreNavigationOptions;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data passed to CORE_LOADING_CHANGED event.
|
* Data passed to CORE_LOADING_CHANGED event.
|
||||||
|
|
|
@ -17,6 +17,7 @@ information provided here is intended especially for developers.
|
||||||
Some user handler's functions have also changed to accept context + contextId instead of a courseId: isEnabledForUser, getDisplayData, action.
|
Some user handler's functions have also changed to accept context + contextId instead of a courseId: isEnabledForUser, getDisplayData, action.
|
||||||
- CoreCourseHelperProvider.openCourse parameters changed, now it admits CoreNavigationOptions + siteId on the same object that includes Params passed to page.
|
- CoreCourseHelperProvider.openCourse parameters changed, now it admits CoreNavigationOptions + siteId on the same object that includes Params passed to page.
|
||||||
- displaySectionSelector has been deprecated on CoreCourseFormatHandler, use displayCourseIndex instead.
|
- displaySectionSelector has been deprecated on CoreCourseFormatHandler, use displayCourseIndex instead.
|
||||||
|
- Most of the functions or callbacks that handle redirects/deeplinks have been modified to accept an object instead of just path + options. E.g.: CoreLoginHelper.isSiteLoggedOut, CoreLoginHelper.openBrowserForSSOLogin, CoreLoginHelper.openBrowserForOAuthLogin, CoreLoginHelper.prepareForSSOLogin, CoreApp.storeRedirect, CoreSites.loadSite.
|
||||||
|
|
||||||
=== 3.9.5 ===
|
=== 3.9.5 ===
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue