MOBILE-2335 book: Implement prefetch handler
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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…
Reference in New Issue