MOBILE-2800 course: Wait for format before opening course
This commit is contained in:
		
							parent
							
								
									dafeb4acb8
								
							
						
					
					
						commit
						ba89f9cb30
					
				| @ -36,6 +36,8 @@ import { CoreLoginHelperProvider } from '@core/login/providers/helper'; | |||||||
| import { CoreConstants } from '@core/constants'; | import { CoreConstants } from '@core/constants'; | ||||||
| import { CoreSite } from '@classes/site'; | import { CoreSite } from '@classes/site'; | ||||||
| import * as moment from 'moment'; | 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. |  * Prefetch info of a module. | ||||||
| @ -123,7 +125,8 @@ export class CoreCourseHelperProvider { | |||||||
|         private courseOptionsDelegate: CoreCourseOptionsDelegate, private siteHomeProvider: CoreSiteHomeProvider, |         private courseOptionsDelegate: CoreCourseOptionsDelegate, private siteHomeProvider: CoreSiteHomeProvider, | ||||||
|         private eventsProvider: CoreEventsProvider, private fileHelper: CoreFileHelperProvider, |         private eventsProvider: CoreEventsProvider, private fileHelper: CoreFileHelperProvider, | ||||||
|         private appProvider: CoreAppProvider, private fileProvider: CoreFileProvider, private injector: Injector, |         private appProvider: CoreAppProvider, private fileProvider: CoreFileProvider, private injector: Injector, | ||||||
|         private coursesProvider: CoreCoursesProvider, private courseOffline: CoreCourseOfflineProvider) { } |         private coursesProvider: CoreCoursesProvider, private courseOffline: CoreCourseOfflineProvider, | ||||||
|  |         private courseFormatDelegate: CoreCourseFormatDelegate, private sitePluginsProvider: CoreSitePluginsProvider) { } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * This function treats every module on the sections provided to load the handler data, treat completion |      * This function treats every module on the sections provided to load the handler data, treat completion | ||||||
| @ -1309,4 +1312,42 @@ export class CoreCourseHelperProvider { | |||||||
|         return (typeof section.availabilityinfo != 'undefined' && section.availabilityinfo != '') || |         return (typeof section.availabilityinfo != 'undefined' && section.availabilityinfo != '') || | ||||||
|             section.summary != '' || (section.modules && section.modules.length > 0); |             section.summary != '' || (section.modules && section.modules.length > 0); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 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. | ||||||
|  |      * | ||||||
|  |      * @param {NavController} navCtrl The nav controller to use. | ||||||
|  |      * @param {any} course Course to open | ||||||
|  |      */ | ||||||
|  |     openCourse(navCtrl: NavController, course: any): void { | ||||||
|  |         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(); | ||||||
|  |             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(); | ||||||
|  |                     this.courseFormatDelegate.openCourse(navCtrl, course); | ||||||
|  |                 } else { | ||||||
|  |                     const observer = this.eventsProvider.on(CoreEventsProvider.SITE_PLUGINS_LOADED, () => { | ||||||
|  |                         loading.dismiss(); | ||||||
|  |                         this.courseFormatDelegate.openCourse(navCtrl, course); | ||||||
|  |                         observer && observer.off(); | ||||||
|  |                     }); | ||||||
|  |                 } | ||||||
|  |             }).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); | ||||||
|  |             }); | ||||||
|  |         } else { | ||||||
|  |             // No custom format plugin. We don't need to wait for anything.
 | ||||||
|  |             this.courseFormatDelegate.openCourse(navCtrl, course); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ import { Component, Input, OnInit, Optional } from '@angular/core'; | |||||||
| import { NavController } from 'ionic-angular'; | import { NavController } from 'ionic-angular'; | ||||||
| import { TranslateService } from '@ngx-translate/core'; | import { TranslateService } from '@ngx-translate/core'; | ||||||
| import { CoreCoursesProvider } from '../../providers/courses'; | import { CoreCoursesProvider } from '../../providers/courses'; | ||||||
| import { CoreCourseFormatDelegate } from '@core/course/providers/format-delegate'; | import { CoreCourseHelperProvider } from '@core/course/providers/helper'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * This directive is meant to display an item for a list of courses. |  * This directive is meant to display an item for a list of courses. | ||||||
| @ -33,7 +33,7 @@ export class CoreCoursesCourseListItemComponent implements OnInit { | |||||||
|     @Input() course: any; // The course to render.
 |     @Input() course: any; // The course to render.
 | ||||||
| 
 | 
 | ||||||
|     constructor(@Optional() private navCtrl: NavController, private translate: TranslateService, |     constructor(@Optional() private navCtrl: NavController, private translate: TranslateService, | ||||||
|             private coursesProvider: CoreCoursesProvider, private courseFormatDelegate: CoreCourseFormatDelegate) { |             private coursesProvider: CoreCoursesProvider, private courseHelper: CoreCourseHelperProvider) { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -82,7 +82,7 @@ export class CoreCoursesCourseListItemComponent implements OnInit { | |||||||
|      */ |      */ | ||||||
|     openCourse(course: any): void { |     openCourse(course: any): void { | ||||||
|         if (course.isEnrolled) { |         if (course.isEnrolled) { | ||||||
|             this.courseFormatDelegate.openCourse(this.navCtrl, course); |             this.courseHelper.openCourse(this.navCtrl, course); | ||||||
|         } else { |         } else { | ||||||
|             this.navCtrl.push('CoreCoursesCoursePreviewPage', {course: course}); |             this.navCtrl.push('CoreCoursesCoursePreviewPage', {course: course}); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -19,7 +19,6 @@ import { CoreSitesProvider } from '@providers/sites'; | |||||||
| import { CoreDomUtilsProvider } from '@providers/utils/dom'; | import { CoreDomUtilsProvider } from '@providers/utils/dom'; | ||||||
| import { CoreUserProvider } from '@core/user/providers/user'; | import { CoreUserProvider } from '@core/user/providers/user'; | ||||||
| import { CoreCoursesProvider } from '@core/courses/providers/courses'; | import { CoreCoursesProvider } from '@core/courses/providers/courses'; | ||||||
| import { CoreCourseFormatDelegate } from '@core/course/providers/format-delegate'; |  | ||||||
| import { CoreCourseProvider } from '@core/course/providers/course'; | import { CoreCourseProvider } from '@core/course/providers/course'; | ||||||
| import { CoreCourseHelperProvider } from '@core/course/providers/helper'; | import { CoreCourseHelperProvider } from '@core/course/providers/helper'; | ||||||
| import { CoreCoursesCourseOptionsMenuComponent } from '../course-options-menu/course-options-menu'; | import { CoreCoursesCourseOptionsMenuComponent } from '../course-options-menu/course-options-menu'; | ||||||
| @ -55,7 +54,7 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy { | |||||||
|     protected siteUpdatedObserver; |     protected siteUpdatedObserver; | ||||||
| 
 | 
 | ||||||
|     constructor(@Optional() private navCtrl: NavController, private courseHelper: CoreCourseHelperProvider, |     constructor(@Optional() private navCtrl: NavController, private courseHelper: CoreCourseHelperProvider, | ||||||
|             private courseFormatDelegate: CoreCourseFormatDelegate, private domUtils: CoreDomUtilsProvider, |             private domUtils: CoreDomUtilsProvider, | ||||||
|             private courseProvider: CoreCourseProvider, private eventsProvider: CoreEventsProvider, |             private courseProvider: CoreCourseProvider, private eventsProvider: CoreEventsProvider, | ||||||
|             private sitesProvider: CoreSitesProvider, private coursesProvider: CoreCoursesProvider, |             private sitesProvider: CoreSitesProvider, private coursesProvider: CoreCoursesProvider, | ||||||
|             private popoverCtrl: PopoverController, private userProvider: CoreUserProvider) { } |             private popoverCtrl: PopoverController, private userProvider: CoreUserProvider) { } | ||||||
| @ -64,6 +63,7 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy { | |||||||
|      * Component being initialized. |      * Component being initialized. | ||||||
|      */ |      */ | ||||||
|     ngOnInit(): void { |     ngOnInit(): void { | ||||||
|  | 
 | ||||||
|         this.downloadCourseEnabled = !this.coursesProvider.isDownloadCourseDisabledInSite(); |         this.downloadCourseEnabled = !this.coursesProvider.isDownloadCourseDisabledInSite(); | ||||||
| 
 | 
 | ||||||
|         if (this.downloadCourseEnabled) { |         if (this.downloadCourseEnabled) { | ||||||
| @ -132,7 +132,7 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy { | |||||||
|      * @param {any} course The course to open. |      * @param {any} course The course to open. | ||||||
|      */ |      */ | ||||||
|     openCourse(course: any): void { |     openCourse(course: any): void { | ||||||
|         this.courseFormatDelegate.openCourse(this.navCtrl, course); |         this.courseHelper.openCourse(this.navCtrl, course); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ | |||||||
|     "enrolme": "Enrol me", |     "enrolme": "Enrol me", | ||||||
|     "errorloadcategories": "An error occurred while loading categories.", |     "errorloadcategories": "An error occurred while loading categories.", | ||||||
|     "errorloadcourses": "An error occurred while loading courses.", |     "errorloadcourses": "An error occurred while loading courses.", | ||||||
|  |     "errorloadplugins": "The plugins required by this course could not be loaded correctly. Please restart the app to try again.", | ||||||
|     "errorsearching": "An error occurred while searching.", |     "errorsearching": "An error occurred while searching.", | ||||||
|     "errorselfenrol": "An error occurred while self enrolling.", |     "errorselfenrol": "An error occurred while self enrolling.", | ||||||
|     "filtermycourses": "Filter my courses", |     "filtermycourses": "Filter my courses", | ||||||
|  | |||||||
| @ -102,7 +102,9 @@ export class CoreSitePluginsHelperProvider { | |||||||
|                 // Plugins fetched, check that site hasn't changed.
 |                 // Plugins fetched, check that site hasn't changed.
 | ||||||
|                 if (data.siteId == this.sitesProvider.getCurrentSiteId() && plugins.length) { |                 if (data.siteId == this.sitesProvider.getCurrentSiteId() && plugins.length) { | ||||||
|                     // Site is still the same. Load the plugins and trigger the event.
 |                     // Site is still the same. Load the plugins and trigger the event.
 | ||||||
|                     this.loadSitePlugins(plugins).then(() => { |                     this.loadSitePlugins(plugins).catch((error) => { | ||||||
|  |                         this.logger.error(error); | ||||||
|  |                     }).finally(() => { | ||||||
|                         eventsProvider.trigger(CoreEventsProvider.SITE_PLUGINS_LOADED, {}, data.siteId); |                         eventsProvider.trigger(CoreEventsProvider.SITE_PLUGINS_LOADED, {}, data.siteId); | ||||||
|                     }); |                     }); | ||||||
| 
 | 
 | ||||||
| @ -367,7 +369,9 @@ export class CoreSitePluginsHelperProvider { | |||||||
|         const promises = []; |         const promises = []; | ||||||
| 
 | 
 | ||||||
|         plugins.forEach((plugin) => { |         plugins.forEach((plugin) => { | ||||||
|             promises.push(this.loadSitePlugin(plugin)); |             const pluginPromise = this.loadSitePlugin(plugin); | ||||||
|  |             promises.push(pluginPromise); | ||||||
|  |             this.sitePluginsProvider.registerSitePluginPromise(plugin.component, pluginPromise); | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         return this.utils.allPromises(promises); |         return this.utils.allPromises(promises); | ||||||
| @ -510,7 +514,7 @@ export class CoreSitePluginsHelperProvider { | |||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|         }).catch((err) => { |         }).catch((err) => { | ||||||
|             this.logger.error('Error executing init method', handlerSchema.init, err); |             return Promise.reject('Error executing init method ' + handlerSchema.init + ': ' + err.message); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -24,6 +24,7 @@ import { CoreTextUtilsProvider } from '@providers/utils/text'; | |||||||
| import { CoreUtilsProvider } from '@providers/utils/utils'; | import { CoreUtilsProvider } from '@providers/utils/utils'; | ||||||
| import { CoreConfigConstants } from '../../../configconstants'; | import { CoreConfigConstants } from '../../../configconstants'; | ||||||
| import { CoreCoursesProvider } from '@core/courses/providers/courses'; | import { CoreCoursesProvider } from '@core/courses/providers/courses'; | ||||||
|  | import { CoreEventsProvider } from '@providers/events'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Handler of a site plugin. |  * Handler of a site plugin. | ||||||
| @ -65,13 +66,19 @@ export class CoreSitePluginsProvider { | |||||||
| 
 | 
 | ||||||
|     protected logger; |     protected logger; | ||||||
|     protected sitePlugins: {[name: string]: CoreSitePluginsHandler} = {}; // Site plugins registered.
 |     protected sitePlugins: {[name: string]: CoreSitePluginsHandler} = {}; // Site plugins registered.
 | ||||||
|  |     protected sitePluginPromises: {[name: string]: Promise<any>} = {}; // Promises of loading plugins.
 | ||||||
|     hasSitePluginsLoaded = false; |     hasSitePluginsLoaded = false; | ||||||
|  |     sitePluginsFinishedLoading = false; | ||||||
| 
 | 
 | ||||||
|     constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private utils: CoreUtilsProvider, |     constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private utils: CoreUtilsProvider, | ||||||
|             private langProvider: CoreLangProvider, private appProvider: CoreAppProvider, private platform: Platform, |             private langProvider: CoreLangProvider, private appProvider: CoreAppProvider, private platform: Platform, | ||||||
|             private filepoolProvider: CoreFilepoolProvider, private coursesProvider: CoreCoursesProvider, |             private filepoolProvider: CoreFilepoolProvider, private coursesProvider: CoreCoursesProvider, | ||||||
|             private textUtils: CoreTextUtilsProvider) { |             private textUtils: CoreTextUtilsProvider, private eventsProvider: CoreEventsProvider) { | ||||||
|         this.logger = logger.getInstance('CoreUserProvider'); |         this.logger = logger.getInstance('CoreUserProvider'); | ||||||
|  |         const observer = this.eventsProvider.on(CoreEventsProvider.SITE_PLUGINS_LOADED, () => { | ||||||
|  |             this.sitePluginsFinishedLoading = true; | ||||||
|  |             observer && observer.off(); | ||||||
|  |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -513,4 +520,34 @@ export class CoreSitePluginsProvider { | |||||||
|     setSitePluginHandler(name: string, handler: CoreSitePluginsHandler): void { |     setSitePluginHandler(name: string, handler: CoreSitePluginsHandler): void { | ||||||
|         this.sitePlugins[name] = handler; |         this.sitePlugins[name] = handler; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Store the promise for a plugin that is being initialised. | ||||||
|  |      * | ||||||
|  |      * @param {String} component | ||||||
|  |      * @param {Promise<any>} promise | ||||||
|  |      */ | ||||||
|  |     registerSitePluginPromise(component: string, promise: Promise<any>): void { | ||||||
|  |         this.sitePluginPromises[component] = promise; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Is a plugin being initialised for the specified component? | ||||||
|  |      * | ||||||
|  |      * @param {String} component | ||||||
|  |      * @return {boolean} | ||||||
|  |      */ | ||||||
|  |     sitePluginPromiseExists(component: string): boolean { | ||||||
|  |         return this.sitePluginPromises.hasOwnProperty(component); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get the promise for a plugin that is being initialised. | ||||||
|  |      * | ||||||
|  |      * @param {String} component | ||||||
|  |      * @return {Promise<any>} | ||||||
|  |      */ | ||||||
|  |     sitePluginLoaded(component: string): Promise<any> { | ||||||
|  |         return this.sitePluginPromises[component]; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user