MOBILE-2335 book: Implement prefetch handler
This commit is contained in:
		
							parent
							
								
									f8d71dd6ee
								
							
						
					
					
						commit
						7379ca3e71
					
				| @ -16,8 +16,10 @@ import { NgModule } from '@angular/core'; | ||||
| import { AddonModBookProvider } from './providers/book'; | ||||
| import { AddonModBookModuleHandler } from './providers/module-handler'; | ||||
| import { AddonModBookLinkHandler } from './providers/link-handler'; | ||||
| import { AddonModBookPrefetchHandler } from './providers/prefetch-handler'; | ||||
| import { CoreCourseModuleDelegate } from '../../../core/course/providers/module-delegate'; | ||||
| import { CoreContentLinksDelegate } from '../../../core/contentlinks/providers/delegate'; | ||||
| import { CoreCourseModulePrefetchDelegate } from '../../../core/course/providers/module-prefetch-delegate'; | ||||
| 
 | ||||
| @NgModule({ | ||||
|     declarations: [ | ||||
| @ -27,13 +29,16 @@ import { CoreContentLinksDelegate } from '../../../core/contentlinks/providers/d | ||||
|     providers: [ | ||||
|         AddonModBookProvider, | ||||
|         AddonModBookModuleHandler, | ||||
|         AddonModBookLinkHandler | ||||
|         AddonModBookLinkHandler, | ||||
|         AddonModBookPrefetchHandler | ||||
|     ] | ||||
| }) | ||||
| export class AddonModBookModule { | ||||
|     constructor(moduleDelegate: CoreCourseModuleDelegate, moduleHandler: AddonModBookModuleHandler, | ||||
|             contentLinksDelegate: CoreContentLinksDelegate, linkHandler: AddonModBookLinkHandler) { | ||||
|             contentLinksDelegate: CoreContentLinksDelegate, linkHandler: AddonModBookLinkHandler, | ||||
|             prefetchDelegate: CoreCourseModulePrefetchDelegate, prefetchHandler: AddonModBookPrefetchHandler) { | ||||
|         moduleDelegate.registerHandler(moduleHandler); | ||||
|         contentLinksDelegate.registerHandler(linkHandler); | ||||
|         prefetchDelegate.registerHandler(prefetchHandler); | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										103
									
								
								src/addon/mod/book/providers/prefetch-handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								src/addon/mod/book/providers/prefetch-handler.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | ||||
| // (C) Copyright 2015 Martin Dougiamas
 | ||||
| //
 | ||||
| // 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 { Injectable, Injector } from '@angular/core'; | ||||
| import { CoreCourseModulePrefetchHandlerBase } from '../../../../core/course/classes/module-prefetch-handler'; | ||||
| import { AddonModBookProvider } from './book'; | ||||
| 
 | ||||
| /** | ||||
|  * Handler to prefetch books. | ||||
|  */ | ||||
| @Injectable() | ||||
| export class AddonModBookPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { | ||||
|     name = 'book'; | ||||
|     component = AddonModBookProvider.COMPONENT; | ||||
|     updatesNames = /^configuration$|^.*files$|^entries$/; | ||||
|     isResource = true; | ||||
| 
 | ||||
|     constructor(injector: Injector, protected bookProvider: AddonModBookProvider) { | ||||
|         super(injector); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Download or prefetch the content. | ||||
|      * | ||||
|      * @param {any} module The module object returned by WS. | ||||
|      * @param {number} courseId Course ID. | ||||
|      * @param {boolean} [prefetch] True to prefetch, false to download right away. | ||||
|      * @param {string} [dirPath] Path of the directory where to store all the content files. This is to keep the files | ||||
|      *                           relative paths and make the package work in an iframe. Undefined to download the files | ||||
|      *                           in the filepool root folder. | ||||
|      * @return {Promise<any>} Promise resolved when all content is downloaded. Data returned is not reliable. | ||||
|      */ | ||||
|     downloadOrPrefetch(module: any, courseId: number, prefetch?: boolean, dirPath?: string): Promise<any> { | ||||
|         const promises = []; | ||||
| 
 | ||||
|         promises.push(super.downloadOrPrefetch(module, courseId, prefetch)); | ||||
|         promises.push(this.bookProvider.getBook(courseId, module.id)); | ||||
| 
 | ||||
|         return Promise.all(promises); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns module intro files. | ||||
|      * | ||||
|      * @param {any} module The module object returned by WS. | ||||
|      * @param {number} courseId Course ID. | ||||
|      * @return {Promise<any[]>} Promise resolved with list of intro files. | ||||
|      */ | ||||
|     getIntroFiles(module: any, courseId: number): Promise<any[]> { | ||||
|         return this.bookProvider.getBook(courseId, module.id).catch(() => { | ||||
|             // Not found, return undefined so module description is used.
 | ||||
|         }).then((book) => { | ||||
|             return this.getIntroFilesFromInstance(module, book); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Invalidate the prefetched content. | ||||
|      * | ||||
|      * @param {number} moduleId The module ID. | ||||
|      * @param {number} courseId Course ID the module belongs to. | ||||
|      * @return {Promise<any>} Promise resolved when the data is invalidated. | ||||
|      */ | ||||
|     invalidateContent(moduleId: number, courseId: number): Promise<any> { | ||||
|         return this.bookProvider.invalidateContent(moduleId, courseId); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Invalidate WS calls needed to determine module status. | ||||
|      * | ||||
|      * @param {any} module Module. | ||||
|      * @param {number} courseId Course ID the module belongs to. | ||||
|      * @return {Promise<any>} Promise resolved when invalidated. | ||||
|      */ | ||||
|     invalidateModule(module: any, courseId: number): Promise<any> { | ||||
|         const promises = []; | ||||
| 
 | ||||
|         promises.push(this.bookProvider.invalidateBookData(courseId)); | ||||
|         promises.push(this.courseProvider.invalidateModule(module.id)); | ||||
| 
 | ||||
|         return Promise.all(promises); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Whether or not the handler is enabled on a site level. | ||||
|      * | ||||
|      * @return {boolean|Promise<boolean>} A boolean, or a promise resolved with a boolean, indicating if the handler is enabled. | ||||
|      */ | ||||
|     isEnabled(): boolean | Promise<boolean> { | ||||
|         return this.bookProvider.isPluginEnabled(); | ||||
|     } | ||||
| } | ||||
| @ -143,9 +143,9 @@ export class CoreDelegate { | ||||
|      * | ||||
|      * @param  {string} handlerName The handler name. | ||||
|      * @param  {boolean} [enabled]  Only enabled, or any. | ||||
|      * @return {any}                Handler. | ||||
|      * @return {CoreDelegateHandler} Handler. | ||||
|      */ | ||||
|     protected getHandler(handlerName: string, enabled: boolean = false): any { | ||||
|     protected getHandler(handlerName: string, enabled: boolean = false): CoreDelegateHandler { | ||||
|         return enabled ? this.enabledHandlers[handlerName] : this.handlers[handlerName]; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -53,17 +53,11 @@ export type prefetchFunction = (module: any, courseId: number, single: boolean, | ||||
|  * recommended to call the prefetchPackage function since it'll handle changing the status of the module. | ||||
|  */ | ||||
| export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePrefetchHandler { | ||||
|     /** | ||||
|      * A name to identify the addon. | ||||
|      * @type {string} | ||||
|      */ | ||||
|     name = 'CoreCourseModulePrefetchHandlerBase'; | ||||
| 
 | ||||
|     /** | ||||
|      * Name of the module. It should match the "modname" of the module returned in core_course_get_contents. | ||||
|      * @type {string} | ||||
|      */ | ||||
|     modname = ''; | ||||
|     name = ''; | ||||
| 
 | ||||
|     /** | ||||
|      * The handler's component. | ||||
| @ -235,7 +229,7 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref | ||||
|      * @param {number} courseId Course ID the module belongs to. | ||||
|      * @return {number|Promise<number>} Size, or promise resolved with the size. | ||||
|      */ | ||||
|     getDownloadedSize?(module: any, courseId: number): number | Promise<number> { | ||||
|     getDownloadedSize(module: any, courseId: number): number | Promise<number> { | ||||
|         const siteId = this.sitesProvider.getCurrentSiteId(); | ||||
| 
 | ||||
|         return this.filepoolProvider.getFilesSizeByComponent(siteId, this.component, module.id); | ||||
| @ -324,9 +318,10 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref | ||||
|      * Invalidate the prefetched content. | ||||
|      * | ||||
|      * @param {number} moduleId The module ID. | ||||
|      * @param {number} courseId The course ID the module belongs to. | ||||
|      * @return {Promise<any>} Promise resolved when the data is invalidated. | ||||
|      */ | ||||
|     invalidateContent(moduleId: number): Promise<any> { | ||||
|     invalidateContent(moduleId: number, courseId: number): Promise<any> { | ||||
|         const promises = [], | ||||
|             siteId = this.sitesProvider.getCurrentSiteId(); | ||||
| 
 | ||||
|  | ||||
| @ -151,6 +151,18 @@ export class CoreCourseSectionPage implements OnDestroy { | ||||
|             promises.push(promise.then((completionStatus) => { | ||||
|                 // Get all the sections.
 | ||||
|                 promises.push(this.courseProvider.getSections(this.course.id, false, true).then((sections) => { | ||||
|                     if (refresh) { | ||||
|                         // Invalidate the recently downloaded module list. To ensure info can be prefetched.
 | ||||
|                         const modules = this.courseProvider.getSectionsModules(sections); | ||||
| 
 | ||||
|                         return this.prefetchDelegate.invalidateModules(modules, this.course.id).then(() => { | ||||
|                             return sections; | ||||
|                         }); | ||||
|                     } else { | ||||
|                         return sections; | ||||
|                     } | ||||
|                 }).then((sections) => { | ||||
| 
 | ||||
|                     this.courseHelper.addHandlerDataForModules(sections, this.course.id, completionStatus); | ||||
| 
 | ||||
|                     // Format the name of each section and check if it has content.
 | ||||
|  | ||||
| @ -202,9 +202,6 @@ export class CoreCourseModulePrefetchDelegate extends CoreDelegate { | ||||
|     }; | ||||
| 
 | ||||
|     protected ROOT_CACHE_KEY = 'mmCourse:'; | ||||
| 
 | ||||
|     protected handlers: { [s: string]: CoreCourseModulePrefetchHandler } = {}; // All registered handlers.
 | ||||
|     protected enabledHandlers: { [s: string]: CoreCourseModulePrefetchHandler } = {}; // Handlers enabled for the current site.
 | ||||
|     protected statusCache = new CoreCache(); | ||||
| 
 | ||||
|     // Promises for check updates, to prevent performing the same request twice at the same time.
 | ||||
| @ -225,7 +222,7 @@ export class CoreCourseModulePrefetchDelegate extends CoreDelegate { | ||||
|             private courseProvider: CoreCourseProvider, private filepoolProvider: CoreFilepoolProvider, | ||||
|             private timeUtils: CoreTimeUtilsProvider, private fileProvider: CoreFileProvider, | ||||
|             protected eventsProvider: CoreEventsProvider) { | ||||
|         super('CoreCourseModulePrefetchDelegate', loggerProvider, sitesProvider); | ||||
|         super('CoreCourseModulePrefetchDelegate', loggerProvider, sitesProvider, eventsProvider); | ||||
| 
 | ||||
|         this.sitesProvider.createTableFromSchema(this.checkUpdatesTableSchema); | ||||
|     } | ||||
| @ -859,7 +856,7 @@ export class CoreCourseModulePrefetchDelegate extends CoreDelegate { | ||||
|      * @return {CoreCourseModulePrefetchHandler} Prefetch handler. | ||||
|      */ | ||||
|     getPrefetchHandlerFor(module: any): CoreCourseModulePrefetchHandler { | ||||
|         return this.enabledHandlers[module.modname]; | ||||
|         return <CoreCourseModulePrefetchHandler> this.getHandler(module.modname, true); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -99,7 +99,8 @@ export class CoreUserProfileFieldDelegate extends CoreDelegate { | ||||
|      */ | ||||
|     getDataForField(field: any, signup: boolean, registerAuth: string, formValues: any): Promise<any> { | ||||
|         const type = field.type || field.datatype, | ||||
|             handler = this.getHandler(type, !signup); | ||||
|             handler = <CoreUserProfileFieldHandler> this.getHandler(type, !signup); | ||||
| 
 | ||||
|         if (handler) { | ||||
|             const name = 'profile_field_' + field.shortname; | ||||
|             if (handler.getData) { | ||||
|  | ||||
| @ -12,7 +12,7 @@ | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { Directive, Input, OnInit, ElementRef } from '@angular/core'; | ||||
| import { Directive, Input, OnInit, ElementRef, Optional } from '@angular/core'; | ||||
| import { NavController, Content } from 'ionic-angular'; | ||||
| import { CoreSitesProvider } from '../providers/sites'; | ||||
| import { CoreDomUtilsProvider } from '../providers/utils/dom'; | ||||
| @ -40,7 +40,7 @@ export class CoreLinkDirective implements OnInit { | ||||
|     constructor(element: ElementRef, private domUtils: CoreDomUtilsProvider, private utils: CoreUtilsProvider, | ||||
|             private sitesProvider: CoreSitesProvider, private urlUtils: CoreUrlUtilsProvider, | ||||
|             private contentLinksHelper: CoreContentLinksHelperProvider, private navCtrl: NavController, | ||||
|             private content: Content) { | ||||
|             @Optional() private content: Content) { | ||||
|         // This directive can be added dynamically. In that case, the first param is the anchor HTMLElement.
 | ||||
|         this.element = element.nativeElement || element; | ||||
|     } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user