From 486ad67a31ef0ad36686e6d0e6bee88b58925ba7 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 23 Apr 2019 13:31:41 +0200 Subject: [PATCH] MOBILE-2928 couse: Use openCourse when opening in current site --- src/addon/mod/feedback/pages/form/form.ts | 8 +- src/assets/lang/en.json | 1 + src/core/course/providers/course.ts | 63 +++++++++++++- src/core/course/providers/default-format.ts | 18 +++- src/core/course/providers/helper.ts | 84 +++++++++---------- .../courses/providers/course-link-handler.ts | 36 +++++--- src/core/login/providers/helper.ts | 55 ++++++++---- src/core/siteplugins/providers/helper.ts | 3 +- src/core/siteplugins/providers/siteplugins.ts | 26 +++++- 9 files changed, 215 insertions(+), 79 deletions(-) diff --git a/src/addon/mod/feedback/pages/form/form.ts b/src/addon/mod/feedback/pages/form/form.ts index 0d8bbf9fa..82e24a29b 100644 --- a/src/addon/mod/feedback/pages/form/form.ts +++ b/src/addon/mod/feedback/pages/form/form.ts @@ -24,6 +24,7 @@ import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreAppProvider } from '@providers/app'; import { CoreEventsProvider } from '@providers/events'; import { CoreCourseProvider } from '@core/course/providers/course'; +import { CoreCourseHelperProvider } from '@core/course/providers/helper'; import { CoreLoginHelperProvider } from '@core/login/providers/helper'; import { CoreContentLinksHelperProvider } from '@core/contentlinks/providers/helper'; import { CoreSitesProvider } from '@providers/sites'; @@ -69,7 +70,7 @@ export class AddonModFeedbackFormPage implements OnDestroy { protected eventsProvider: CoreEventsProvider, protected feedbackSync: AddonModFeedbackSyncProvider, network: Network, protected translate: TranslateService, protected loginHelper: CoreLoginHelperProvider, protected linkHelper: CoreContentLinksHelperProvider, sitesProvider: CoreSitesProvider, - @Optional() private content: Content, zone: NgZone) { + @Optional() private content: Content, zone: NgZone, protected courseHelper: CoreCourseHelperProvider) { this.module = navParams.get('module'); this.courseId = navParams.get('courseId'); @@ -325,10 +326,7 @@ export class AddonModFeedbackFormPage implements OnDestroy { modal.dismiss(); }); } else { - // Use redirect to make the course the new history root (to avoid "loops" in history). - this.loginHelper.redirect('CoreCourseSectionPage', { - course: { id: this.courseId } - }, this.currentSite.getId()); + this.courseHelper.getAndOpenCourse(undefined, this.courseId, {}, this.currentSite.getId()); } } diff --git a/src/assets/lang/en.json b/src/assets/lang/en.json index 8fd9e1499..8e7ff5128 100644 --- a/src/assets/lang/en.json +++ b/src/assets/lang/en.json @@ -1342,6 +1342,7 @@ "core.favourites": "Starred", "core.filename": "Filename", "core.filenameexist": "File name already exists: {{$a}}", + "core.filenotfound": "File not found, sorry.", "core.fileuploader.addfiletext": "Add file", "core.fileuploader.audio": "Audio", "core.fileuploader.camera": "Camera", diff --git a/src/core/course/providers/course.ts b/src/core/course/providers/course.ts index e16318b09..c960b7c51 100644 --- a/src/core/course/providers/course.ts +++ b/src/core/course/providers/course.ts @@ -13,16 +13,20 @@ // limitations under the License. import { Injectable } from '@angular/core'; +import { NavController } from 'ionic-angular'; import { TranslateService } from '@ngx-translate/core'; import { CoreAppProvider } from '@providers/app'; import { CoreEventsProvider } from '@providers/events'; import { CoreLoggerProvider } from '@providers/logger'; import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreTimeUtilsProvider } from '@providers/utils/time'; import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreSiteWSPreSets, CoreSite } from '@classes/site'; import { CoreConstants } from '../../constants'; import { CoreCourseOfflineProvider } from './course-offline'; +import { CoreSitePluginsProvider } from '@core/siteplugins/providers/siteplugins'; +import { CoreCourseFormatDelegate } from './format-delegate'; /** * Service that provides some features regarding a course. @@ -96,7 +100,9 @@ export class CoreCourseProvider { constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private eventsProvider: CoreEventsProvider, private utils: CoreUtilsProvider, private timeUtils: CoreTimeUtilsProvider, private translate: TranslateService, - private courseOffline: CoreCourseOfflineProvider, private appProvider: CoreAppProvider) { + private courseOffline: CoreCourseOfflineProvider, private appProvider: CoreAppProvider, + private courseFormatDelegate: CoreCourseFormatDelegate, private sitePluginsProvider: CoreSitePluginsProvider, + private domUtils: CoreDomUtilsProvider) { this.logger = logger.getInstance('CoreCourseProvider'); this.sitesProvider.registerSiteSchema(this.siteSchema); @@ -899,6 +905,61 @@ export class CoreCourseProvider { return !!module.url; } + /** + * Wait for any course format plugin to load, and open the course page. + * + * If the plugin's promise is resolved, the course page will be opened. If it is rejected, they will see an error. + * If the promise for the plugin is still in progress when the user tries to open the course, a loader + * will be displayed until it is complete, before the course page is opened. If the promise is already complete, + * they will see the result immediately. + * + * This function must be in here instead of course helper to prevent circular dependencies. + * + * @param {NavController} navCtrl The nav controller to use. If not defined, the course will be opened in main menu. + * @param {any} course Course to open + * @param {any} [params] Other params to pass to the course page. + * @return {Promise} Promise resolved when done. + */ + openCourse(navCtrl: NavController, course: any, params?: any): Promise { + const loading = this.domUtils.showModalLoading(); + + // Wait for site plugins to be fetched. + return this.sitePluginsProvider.waitFetchPlugins().then(() => { + if (this.sitePluginsProvider.sitePluginPromiseExists('format_' + course.format)) { + // This course uses a custom format plugin, wait for the format plugin to finish loading. + + return this.sitePluginsProvider.sitePluginLoaded('format_' + course.format).then(() => { + // The format loaded successfully, but the handlers wont be registered until all site plugins have loaded. + if (this.sitePluginsProvider.sitePluginsFinishedLoading) { + return this.courseFormatDelegate.openCourse(navCtrl, course, params); + } else { + // Wait for plugins to be loaded. + const deferred = this.utils.promiseDefer(), + observer = this.eventsProvider.on(CoreEventsProvider.SITE_PLUGINS_LOADED, () => { + observer && observer.off(); + + this.courseFormatDelegate.openCourse(navCtrl, course, params).then((response) => { + deferred.resolve(response); + }).catch((error) => { + deferred.reject(error); + }); + }); + + return deferred.promise; + } + }).catch(() => { + // The site plugin failed to load. The user needs to restart the app to try loading it again. + this.domUtils.showErrorModal('core.courses.errorloadplugins', true); + }); + } else { + // No custom format plugin. We don't need to wait for anything. + return this.courseFormatDelegate.openCourse(navCtrl, course, params); + } + }).finally(() => { + loading.dismiss(); + }); + } + /** * Change the course status, setting it to the previous status. * diff --git a/src/core/course/providers/default-format.ts b/src/core/course/providers/default-format.ts index 6cc8e1562..b445158a9 100644 --- a/src/core/course/providers/default-format.ts +++ b/src/core/course/providers/default-format.ts @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable } from '@angular/core'; +import { Injectable, Injector } from '@angular/core'; import { NavController } from 'ionic-angular'; import { CoreCoursesProvider } from '@core/courses/providers/courses'; +import { CoreLoginHelperProvider } from '@core/login/providers/helper'; import { CoreCourseFormatHandler } from './format-delegate'; /** @@ -25,7 +26,9 @@ export class CoreCourseFormatDefaultHandler implements CoreCourseFormatHandler { name = 'CoreCourseFormatDefault'; format = 'default'; - constructor(private coursesProvider: CoreCoursesProvider) { } + protected loginHelper: CoreLoginHelperProvider; // Inject it later to prevent circular dependencies. + + constructor(protected coursesProvider: CoreCoursesProvider, protected injector: Injector) { } /** * Whether or not the handler is enabled on a site level. @@ -154,7 +157,7 @@ export class CoreCourseFormatDefaultHandler implements CoreCourseFormatHandler { * getCourseFormatComponent because it will display the course handlers at the top. * Your page should include the course handlers using CoreCoursesDelegate. * - * @param {NavController} navCtrl The NavController instance to use. + * @param {NavController} navCtrl The NavController instance to use. If not defined, please use loginHelper.redirect. * @param {any} course The course to open. It should contain a "format" attribute. * @param {any} [params] Params to pass to the course page. * @return {Promise} Promise resolved when done. @@ -163,7 +166,14 @@ export class CoreCourseFormatDefaultHandler implements CoreCourseFormatHandler { params = params || {}; Object.assign(params, { course: course }); - return navCtrl.push('CoreCourseSectionPage', params); + if (navCtrl) { + return navCtrl.push('CoreCourseSectionPage', params); + } else { + // Open the course in the "phantom" tab. + this.loginHelper = this.loginHelper || this.injector.get(CoreLoginHelperProvider); + + return this.loginHelper.redirect('CoreCourseSectionPage', params); + } } /** diff --git a/src/core/course/providers/helper.ts b/src/core/course/providers/helper.ts index be5872490..ba486f2a9 100644 --- a/src/core/course/providers/helper.ts +++ b/src/core/course/providers/helper.ts @@ -36,8 +36,6 @@ import { CoreLoginHelperProvider } from '@core/login/providers/helper'; import { CoreConstants } from '@core/constants'; import { CoreSite } from '@classes/site'; import * as moment from 'moment'; -import { CoreSitePluginsProvider } from '@core/siteplugins/providers/siteplugins'; -import { CoreCourseFormatDelegate } from '@core/course/providers/format-delegate'; /** * Prefetch info of a module. @@ -125,8 +123,7 @@ export class CoreCourseHelperProvider { private courseOptionsDelegate: CoreCourseOptionsDelegate, private siteHomeProvider: CoreSiteHomeProvider, private eventsProvider: CoreEventsProvider, private fileHelper: CoreFileHelperProvider, private appProvider: CoreAppProvider, private fileProvider: CoreFileProvider, private injector: Injector, - private coursesProvider: CoreCoursesProvider, private courseOffline: CoreCourseOfflineProvider, - private courseFormatDelegate: CoreCourseFormatDelegate, private sitePluginsProvider: CoreSitePluginsProvider) { } + private coursesProvider: CoreCoursesProvider, private courseOffline: CoreCourseOfflineProvider) { } /** * This function treats every module on the sections provided to load the handler data, treat completion @@ -794,6 +791,30 @@ export class CoreCourseHelperProvider { }); } + /** + * Get a course, wait for any course format plugin to load, and open the course page. It basically chains the functions + * getCourse and openCourse. + * + * @param {NavController} navCtrl The nav controller to use. If not defined, the course will be opened in main menu. + * @param {number} courseId Course ID. + * @param {any} [params] Other params to pass to the course page. + * @param {string} [siteId] Site ID. If not defined, current site. + */ + getAndOpenCourse(navCtrl: NavController, courseId: number, params?: any, siteId?: string): Promise { + const modal = this.domUtils.showModalLoading(); + + return this.getCourse(courseId, siteId).then((data) => { + return data.course; + }).catch(() => { + // Cannot get course, return a "fake". + return { id: courseId }; + }).then((course) => { + modal.dismiss(); + + return this.openCourse(navCtrl, course, params, siteId); + }); + } + /** * Check if the course has a block with that name. * @@ -1121,14 +1142,17 @@ export class CoreCourseHelperProvider { // Check if site home is available. return this.siteHomeProvider.isAvailable().then(() => { this.loginHelper.redirect('CoreSiteHomeIndexPage', params, siteId); + }).finally(() => { + modal.dismiss(); }); } else { - this.loginHelper.redirect('CoreCourseSectionPage', params, siteId); + modal.dismiss(); + + return this.getAndOpenCourse(undefined, courseId, params, siteId); } }).catch((error) => { - this.domUtils.showErrorModalDefault(error, 'core.course.errorgetmodule', true); - }).finally(() => { modal.dismiss(); + this.domUtils.showErrorModalDefault(error, 'core.course.errorgetmodule', true); }); } @@ -1399,46 +1423,22 @@ export class CoreCourseHelperProvider { * will be displayed until it is complete, before the course page is opened. If the promise is already complete, * they will see the result immediately. * - * @param {NavController} navCtrl The nav controller to use. + * @param {NavController} navCtrl The nav controller to use. If not defined, the course will be opened in main menu. * @param {any} course Course to open * @param {any} [params] Params to pass to the course page. + * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when done. */ - openCourse(navCtrl: NavController, course: any, params?: any): Promise { - if (this.sitePluginsProvider.sitePluginPromiseExists('format_' + course.format)) { - // This course uses a custom format plugin, wait for the format plugin to finish loading. - const loading = this.domUtils.showModalLoading(); - - return this.sitePluginsProvider.sitePluginLoaded('format_' + course.format).then(() => { - // The format loaded successfully, but the handlers wont be registered until all site plugins have loaded. - if (this.sitePluginsProvider.sitePluginsFinishedLoading) { - loading.dismiss(); - - return this.courseFormatDelegate.openCourse(navCtrl, course, params); - } else { - // Wait for plugins to be loaded. - const deferred = this.utils.promiseDefer(), - observer = this.eventsProvider.on(CoreEventsProvider.SITE_PLUGINS_LOADED, () => { - loading.dismiss(); - observer && observer.off(); - - this.courseFormatDelegate.openCourse(navCtrl, course, params).then((response) => { - deferred.resolve(response); - }).catch((error) => { - deferred.reject(error); - }); - }); - - return deferred.promise; - } - }).catch(() => { - // The site plugin failed to load. The user needs to restart the app to try loading it again. - loading.dismiss(); - this.domUtils.showErrorModal('core.courses.errorloadplugins', true); - }); + openCourse(navCtrl: NavController, course: any, params?: any, siteId?: string): Promise { + if (!siteId || siteId == this.sitesProvider.getCurrentSiteId()) { + // Current site, we can open the course. + return this.courseProvider.openCourse(navCtrl, course, params); } else { - // No custom format plugin. We don't need to wait for anything. - return this.courseFormatDelegate.openCourse(navCtrl, course, params); + // We need to load the site first. + params = params || {}; + Object.assign(params, { course: course }); + + return this.loginHelper.redirect(CoreLoginHelperProvider.OPEN_COURSE, params, siteId); } } } diff --git a/src/core/courses/providers/course-link-handler.ts b/src/core/courses/providers/course-link-handler.ts index 092ac130d..010dcdbb2 100644 --- a/src/core/courses/providers/course-link-handler.ts +++ b/src/core/courses/providers/course-link-handler.ts @@ -19,8 +19,8 @@ import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreContentLinksHandlerBase } from '@core/contentlinks/classes/base-handler'; import { CoreContentLinksAction } from '@core/contentlinks/providers/delegate'; -import { CoreLoginHelperProvider } from '@core/login/providers/helper'; import { CoreCourseProvider } from '@core/course/providers/course'; +import { CoreCourseHelperProvider } from '@core/course/providers/helper'; import { CoreCoursesProvider } from './courses'; /** @@ -34,9 +34,9 @@ export class CoreCoursesCourseLinkHandler extends CoreContentLinksHandlerBase { protected waitStart = 0; constructor(private sitesProvider: CoreSitesProvider, private coursesProvider: CoreCoursesProvider, - private loginHelper: CoreLoginHelperProvider, private domUtils: CoreDomUtilsProvider, + private domUtils: CoreDomUtilsProvider, private translate: TranslateService, private courseProvider: CoreCourseProvider, - private textUtils: CoreTextUtilsProvider) { + private textUtils: CoreTextUtilsProvider, private courseHelper: CoreCourseHelperProvider) { super(); } @@ -55,7 +55,6 @@ export class CoreCoursesCourseLinkHandler extends CoreContentLinksHandlerBase { const sectionId = params.sectionid ? parseInt(params.sectionid, 10) : null, pageParams: any = { - course: { id: courseId }, sectionId: sectionId || null }; let sectionNumber = typeof params.section != 'undefined' ? parseInt(params.section, 10) : NaN; @@ -80,8 +79,8 @@ export class CoreCoursesCourseLinkHandler extends CoreContentLinksHandlerBase { // Ignore errors. }); } else { - // Use redirect to make the course the new history root (to avoid "loops" in history). - this.loginHelper.redirect('CoreCourseSectionPage', pageParams, siteId); + // Don't pass the navCtrl to make the course the new history root (to avoid "loops" in history). + this.courseHelper.getAndOpenCourse(undefined, courseId, pageParams, siteId); } } }]; @@ -121,9 +120,12 @@ export class CoreCoursesCourseLinkHandler extends CoreContentLinksHandlerBase { protected actionEnrol(courseId: number, url: string, pageParams: any): Promise { const modal = this.domUtils.showModalLoading(), isEnrolUrl = !!url.match(/(\/enrol\/index\.php)|(\/course\/enrol\.php)/); + let course; // Check if user is enrolled in the course. - return this.coursesProvider.getUserCourse(courseId).catch(() => { + return this.coursesProvider.getUserCourse(courseId).then((courseObj) => { + course = courseObj; + }).catch(() => { // User is not enrolled in the course. Check if can self enrol. return this.canSelfEnrol(courseId).then(() => { modal.dismiss(); @@ -134,7 +136,9 @@ export class CoreCoursesCourseLinkHandler extends CoreContentLinksHandlerBase { return promise.then(() => { // Enrol URL or user confirmed. - return this.selfEnrol(courseId).catch((error) => { + return this.selfEnrol(courseId).then((courseObj) => { + course = courseObj; + }).catch((error) => { if (error) { this.domUtils.showErrorModal(error); } @@ -170,10 +174,22 @@ export class CoreCoursesCourseLinkHandler extends CoreContentLinksHandlerBase { }); }); }).then(() => { + // Check if we need to retrieve the course. + if (!course) { + return this.courseHelper.getCourse(courseId).then((data) => { + return data.course; + }).catch(() => { + // Cannot get course, return a "fake". + return { id: courseId }; + }); + } + + return course; + }).then((course) => { modal.dismiss(); - // Use redirect to make the course the new history root (to avoid "loops" in history). - this.loginHelper.redirect('CoreCourseSectionPage', pageParams, this.sitesProvider.getCurrentSiteId()); + // Now open the course. + this.courseHelper.openCourse(undefined, course, pageParams); }); } diff --git a/src/core/login/providers/helper.ts b/src/core/login/providers/helper.ts index 21154313c..25e312ab8 100644 --- a/src/core/login/providers/helper.ts +++ b/src/core/login/providers/helper.ts @@ -28,6 +28,7 @@ import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreUrlUtilsProvider } from '@providers/utils/url'; import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreSitePluginsProvider } from '@core/siteplugins/providers/siteplugins'; +import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreConfigConstants } from '../../../configconstants'; import { CoreConstants } from '@core/constants'; import { Md5 } from 'ts-md5/dist/md5'; @@ -72,6 +73,8 @@ export interface CoreLoginSSOData { */ @Injectable() export class CoreLoginHelperProvider { + static OPEN_COURSE = 'open_course'; + protected logger; protected isSSOConfirmShown = false; protected isOpenEditAlertShown = false; @@ -83,7 +86,7 @@ export class CoreLoginHelperProvider { private eventsProvider: CoreEventsProvider, private appProvider: CoreAppProvider, private utils: CoreUtilsProvider, private urlUtils: CoreUrlUtilsProvider, private configProvider: CoreConfigProvider, private platform: Platform, private initDelegate: CoreInitDelegate, private sitePluginsProvider: CoreSitePluginsProvider, - private location: Location, private alertCtrl: AlertController) { + private location: Location, private alertCtrl: AlertController, private courseProvider: CoreCourseProvider) { this.logger = logger.getInstance('CoreLoginHelper'); } @@ -423,13 +426,7 @@ export class CoreLoginHelperProvider { * @return {Promise} Promise resolved when done. */ goToSiteInitialPage(navCtrl?: NavController, page?: string, params?: any, options?: NavOptions): Promise { - navCtrl = navCtrl || this.appProvider.getRootNavController(); - - // 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(''); - - return navCtrl.setRoot('CoreMainMenuPage', { redirectPage: page, redirectParams: params }, options); + return this.openMainMenu(navCtrl, page, params, options); } /** @@ -604,11 +601,7 @@ export class CoreLoginHelperProvider { return this.sitesProvider.loadSite(siteId, page, params).then((loggedIn) => { if (loggedIn) { - // 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(''); - - return navCtrl.setRoot('CoreMainMenuPage', { redirectPage: page, redirectParams: params }); + return this.openMainMenu(navCtrl, page, params); } }).catch((error) => { // Site doesn't exist. @@ -626,7 +619,39 @@ export class CoreLoginHelperProvider { * @param {any} params Params to pass to the page. */ protected loadPageInMainMenu(page: string, params: any): void { - this.eventsProvider.trigger(CoreEventsProvider.LOAD_PAGE_MAIN_MENU, { redirectPage: page, redirectParams: params }); + if (page == CoreLoginHelperProvider.OPEN_COURSE) { + // Use the openCourse function. + this.courseProvider.openCourse(undefined, params.course, params); + } else { + this.eventsProvider.trigger(CoreEventsProvider.LOAD_PAGE_MAIN_MENU, { redirectPage: page, redirectParams: params }); + } + } + + /** + * Open the main menu, loading a certain page. + * + * @param {NavController} navCtrl NavController. + * @param {string} page Name of the page to load. + * @param {any} params Params to pass to the page. + * @param {NavOptions} [options] Navigation options. + * @return {Promise} Promise resolved when done. + */ + protected openMainMenu(navCtrl: NavController, page: string, params: any, options?: NavOptions): Promise { + navCtrl = navCtrl || this.appProvider.getRootNavController(); + + // 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(''); + + if (page == CoreLoginHelperProvider.OPEN_COURSE) { + // Load the main menu first, and then open the course. + return navCtrl.setRoot('CoreMainMenuPage').finally(() => { + return this.courseProvider.openCourse(undefined, params.course, params); + }); + } else { + // Open the main menu. + return navCtrl.setRoot('CoreMainMenuPage', { redirectPage: page, redirectParams: params }, options); + } } /** @@ -793,7 +818,7 @@ export class CoreLoginHelperProvider { /** * Redirect to a new page, setting it as the root page and loading the right site if needed. * - * @param {string} page Name of the page to load. + * @param {string} page Name of the page to load. Special cases: OPEN_COURSE (to open course page). * @param {any} params Params to pass to the page. * @param {string} [siteId] Site to load. If not defined, current site. * @return {Promise} Promise resolved when done. diff --git a/src/core/siteplugins/providers/helper.ts b/src/core/siteplugins/providers/helper.ts index cc78d9509..395b777d5 100644 --- a/src/core/siteplugins/providers/helper.ts +++ b/src/core/siteplugins/providers/helper.ts @@ -107,8 +107,9 @@ export class CoreSitePluginsHelperProvider { }).finally(() => { eventsProvider.trigger(CoreEventsProvider.SITE_PLUGINS_LOADED, {}, data.siteId); }); - } + }).finally(() => { + this.sitePluginsProvider.setPluginsFetched(); }); }); diff --git a/src/core/siteplugins/providers/siteplugins.ts b/src/core/siteplugins/providers/siteplugins.ts index 43fd975c7..20036c9be 100644 --- a/src/core/siteplugins/providers/siteplugins.ts +++ b/src/core/siteplugins/providers/siteplugins.ts @@ -21,7 +21,7 @@ import { CoreLoggerProvider } from '@providers/logger'; import { CoreSite, CoreSiteWSPreSets } from '@classes/site'; import { CoreSitesProvider } from '@providers/sites'; import { CoreTextUtilsProvider } from '@providers/utils/text'; -import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreUtilsProvider, PromiseDefer } from '@providers/utils/utils'; import { CoreConfigConstants } from '../../../configconstants'; import { CoreCoursesProvider } from '@core/courses/providers/courses'; import { CoreEventsProvider } from '@providers/events'; @@ -67,6 +67,7 @@ export class CoreSitePluginsProvider { protected logger; protected sitePlugins: {[name: string]: CoreSitePluginsHandler} = {}; // Site plugins registered. protected sitePluginPromises: {[name: string]: Promise} = {}; // Promises of loading plugins. + protected fetchPluginsDeferred: PromiseDefer; hasSitePluginsLoaded = false; sitePluginsFinishedLoading = false; @@ -75,10 +76,17 @@ export class CoreSitePluginsProvider { private filepoolProvider: CoreFilepoolProvider, private coursesProvider: CoreCoursesProvider, private textUtils: CoreTextUtilsProvider, private eventsProvider: CoreEventsProvider) { this.logger = logger.getInstance('CoreUserProvider'); + const observer = this.eventsProvider.on(CoreEventsProvider.SITE_PLUGINS_LOADED, () => { this.sitePluginsFinishedLoading = true; observer && observer.off(); }); + + // Initialize deferred at start and on logout. + this.fetchPluginsDeferred = this.utils.promiseDefer(); + eventsProvider.on(CoreEventsProvider.LOGOUT, () => { + this.fetchPluginsDeferred = this.utils.promiseDefer(); + }); } /** @@ -531,6 +539,13 @@ export class CoreSitePluginsProvider { this.sitePluginPromises[component] = promise; } + /** + * Set plugins fetched. + */ + setPluginsFetched(): void { + this.fetchPluginsDeferred.resolve(); + } + /** * Is a plugin being initialised for the specified component? * @@ -550,4 +565,13 @@ export class CoreSitePluginsProvider { sitePluginLoaded(component: string): Promise { return this.sitePluginPromises[component]; } + + /** + * Wait for fetch plugins to be done. + * + * @return {Promise} Promise resolved when site plugins have been fetched. + */ + waitFetchPlugins(): Promise { + return this.fetchPluginsDeferred.promise; + } }