MOBILE-2335 book: Support single activity format with book
parent
4bcecc81dd
commit
aa95a20287
|
@ -20,6 +20,7 @@ import { CoreDomUtilsProvider } from '../../../../../providers/utils/dom';
|
|||
import { CoreTextUtilsProvider } from '../../../../../providers/utils/text';
|
||||
import { CoreCourseProvider } from '../../../../../core/course/providers/course';
|
||||
import { CoreCourseHelperProvider } from '../../../../../core/course/providers/helper';
|
||||
import { CoreCourseModuleMainComponent } from '../../../../../core/course/providers/module-delegate';
|
||||
import { AddonModBookProvider, AddonModBookContentsMap, AddonModBookTocChapter } from '../../providers/book';
|
||||
import { AddonModBookPrefetchHandler } from '../../providers/prefetch-handler';
|
||||
import { AddonModBookTocPopoverComponent } from '../../components/toc-popover/toc-popover';
|
||||
|
@ -31,7 +32,7 @@ import { AddonModBookTocPopoverComponent } from '../../components/toc-popover/to
|
|||
selector: 'addon-mod-book-index',
|
||||
templateUrl: 'index.html',
|
||||
})
|
||||
export class AddonModBookIndexComponent implements OnInit {
|
||||
export class AddonModBookIndexComponent implements OnInit, CoreCourseModuleMainComponent {
|
||||
@Input() module: any; // The module of the book.
|
||||
@Input() courseId: number; // Course ID the book belongs to.
|
||||
@Output() bookRetrieved?: EventEmitter<any>;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { NavController, NavOptions } from 'ionic-angular';
|
||||
import { AddonModBookProvider } from './book';
|
||||
import { AddonModBookIndexComponent } from '../components/index/index';
|
||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '../../../../core/course/providers/module-delegate';
|
||||
import { CoreCourseProvider } from '../../../../core/course/providers/course';
|
||||
|
||||
|
@ -57,12 +58,13 @@ export class AddonModBookModuleHandler implements CoreCourseModuleHandler {
|
|||
|
||||
/**
|
||||
* Get the component to render the module. This is needed to support singleactivity course format.
|
||||
* The component returned must implement CoreCourseModuleMainComponent.
|
||||
*
|
||||
* @param {any} course The course object.
|
||||
* @param {any} module The module object.
|
||||
* @return {any} The component to use, undefined if not found.
|
||||
*/
|
||||
getMainComponent(course: any, module: any): any {
|
||||
// @todo
|
||||
return AddonModBookIndexComponent;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ export class AddonModLabelModuleHandler implements CoreCourseModuleHandler {
|
|||
|
||||
/**
|
||||
* Get the component to render the module. This is needed to support singleactivity course format.
|
||||
* The component returned must implement CoreCourseModuleMainComponent.
|
||||
*
|
||||
* @param {any} course The course object.
|
||||
* @param {any} module The module object.
|
||||
|
|
|
@ -134,7 +134,7 @@ export class CoreDelegate {
|
|||
if (handler && handler[fnName]) {
|
||||
return handler[fnName].apply(handler, params);
|
||||
} else if (this.defaultHandler && this.defaultHandler[fnName]) {
|
||||
return this.defaultHandler[fnName].apply(this, params);
|
||||
return this.defaultHandler[fnName].apply(this.defaultHandler, params);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -99,6 +99,19 @@ export class CoreDynamicComponent implements OnInit, OnChanges, DoCheck {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a certain function on the component.
|
||||
*
|
||||
* @param {string} name Name of the function to call.
|
||||
* @param {any[]} params List of params to send to the function.
|
||||
* @return {any} Result of the call. Undefined if no component instance or the function doesn't exist.
|
||||
*/
|
||||
callComponentFunction(name: string, params: any[]): any {
|
||||
if (this.instance && typeof this.instance[name] == 'function') {
|
||||
return this.instance[name].apply(this.instance, params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a component, add it to a container and set the input data.
|
||||
*
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, Input, OnInit, OnChanges, OnDestroy, SimpleChange, Output, EventEmitter } from '@angular/core';
|
||||
import {
|
||||
Component, Input, OnInit, OnChanges, OnDestroy, SimpleChange, Output, EventEmitter, ViewChildren, QueryList
|
||||
} from '@angular/core';
|
||||
import { Content } from 'ionic-angular';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreEventsProvider } from '../../../../providers/events';
|
||||
|
@ -22,6 +24,7 @@ import { CoreCourseProvider } from '../../../course/providers/course';
|
|||
import { CoreCourseHelperProvider } from '../../../course/providers/helper';
|
||||
import { CoreCourseFormatDelegate } from '../../../course/providers/format-delegate';
|
||||
import { CoreCourseModulePrefetchDelegate } from '../../../course/providers/module-prefetch-delegate';
|
||||
import { CoreDynamicComponent } from '../../../../components/dynamic-component/dynamic-component';
|
||||
|
||||
/**
|
||||
* Component to display course contents using a certain format. If the format isn't found, use default one.
|
||||
|
@ -46,6 +49,8 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
|||
@Input() moduleId?: number; // The module ID to scroll to. Must be inside the initial selected section.
|
||||
@Output() completionChanged?: EventEmitter<void>; // Will emit an event when any module completion changes.
|
||||
|
||||
@ViewChildren(CoreDynamicComponent) dynamicComponents: QueryList<CoreDynamicComponent>;
|
||||
|
||||
// All the possible component classes.
|
||||
courseFormatComponent: any;
|
||||
courseSummaryComponent: any;
|
||||
|
@ -286,6 +291,23 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the data.
|
||||
*
|
||||
* @param {any} [refresher] Refresher.
|
||||
* @param {Function} [done] Function to call when done.
|
||||
* @return {Promise<any>} Promise resolved when done.
|
||||
*/
|
||||
doRefresh(refresher?: any, done?: () => void): Promise<any> {
|
||||
const promises = [];
|
||||
|
||||
this.dynamicComponents.forEach((component) => {
|
||||
promises.push(Promise.resolve(component.callComponentFunction('doRefresh', [refresher, done])));
|
||||
});
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component destroyed.
|
||||
*/
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, Input, OnChanges, SimpleChange } from '@angular/core';
|
||||
import { Component, Input, OnChanges, SimpleChange, ViewChild } from '@angular/core';
|
||||
import { CoreCourseModuleDelegate } from '../../../providers/module-delegate';
|
||||
import { CoreCourseUnsupportedModuleComponent } from '../../../components/unsupported-module/unsupported-module';
|
||||
import { CoreDynamicComponent } from '../../../../../components/dynamic-component/dynamic-component';
|
||||
|
||||
/**
|
||||
* Component to display single activity format. It will determine the right component to use and instantiate it.
|
||||
|
@ -30,6 +31,8 @@ export class CoreCourseFormatSingleActivityComponent implements OnChanges {
|
|||
@Input() sections: any[]; // List of course sections.
|
||||
@Input() downloadEnabled?: boolean; // Whether the download of sections and modules is enabled.
|
||||
|
||||
@ViewChild(CoreDynamicComponent) dynamicComponent: CoreDynamicComponent;
|
||||
|
||||
componentClass: any; // The class of the component to render.
|
||||
data: any = {}; // Data to pass to the component.
|
||||
|
||||
|
@ -52,4 +55,15 @@ export class CoreCourseFormatSingleActivityComponent implements OnChanges {
|
|||
this.data.module = module;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the data.
|
||||
*
|
||||
* @param {any} [refresher] Refresher.
|
||||
* @param {Function} [done] Function to call when done.
|
||||
* @return {Promise<any>} Promise resolved when done.
|
||||
*/
|
||||
doRefresh(refresher?: any, done?: () => void): Promise<any> {
|
||||
return Promise.resolve(this.dynamicComponent.callComponentFunction('doRefresh', [refresher, done]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import { CoreCourseHelperProvider } from '../../providers/helper';
|
|||
import { CoreCourseFormatDelegate } from '../../providers/format-delegate';
|
||||
import { CoreCourseModulePrefetchDelegate } from '../../providers/module-prefetch-delegate';
|
||||
import { CoreCourseOptionsDelegate, CoreCourseOptionsHandlerToDisplay } from '../../providers/options-delegate';
|
||||
import { CoreCourseFormatComponent } from '../../components/format/format';
|
||||
import { CoreCoursesProvider } from '../../../courses/providers/courses';
|
||||
|
||||
/**
|
||||
|
@ -36,6 +37,7 @@ import { CoreCoursesProvider } from '../../../courses/providers/courses';
|
|||
})
|
||||
export class CoreCourseSectionPage implements OnDestroy {
|
||||
@ViewChild(Content) content: Content;
|
||||
@ViewChild(CoreCourseFormatComponent) formatComponent: CoreCourseFormatComponent;
|
||||
|
||||
title: string;
|
||||
course: any;
|
||||
|
@ -150,7 +152,7 @@ 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) => {
|
||||
return 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);
|
||||
|
@ -185,7 +187,7 @@ export class CoreCourseSectionPage implements OnDestroy {
|
|||
|
||||
// Get the title again now that we have sections.
|
||||
this.title = this.courseFormatDelegate.getCourseTitle(this.course, this.sections);
|
||||
}));
|
||||
});
|
||||
}));
|
||||
|
||||
// Load the course handlers.
|
||||
|
@ -207,7 +209,9 @@ export class CoreCourseSectionPage implements OnDestroy {
|
|||
doRefresh(refresher: any): void {
|
||||
this.invalidateData().finally(() => {
|
||||
this.loadData(true).finally(() => {
|
||||
refresher.complete();
|
||||
this.formatComponent.doRefresh(refresher).finally(() => {
|
||||
refresher.complete();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ export interface CoreCourseModuleHandler extends CoreDelegateHandler {
|
|||
|
||||
/**
|
||||
* Get the component to render the module. This is needed to support singleactivity course format.
|
||||
* The component returned must implement CoreCourseModuleMainComponent.
|
||||
*
|
||||
* @param {any} course The course object.
|
||||
* @param {any} module The module object.
|
||||
|
@ -91,6 +92,20 @@ export interface CoreCourseModuleHandlerData {
|
|||
action?(event: Event, navCtrl: NavController, module: any, courseId: number, options?: NavOptions): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface that all the components to render the module in singleactivity must implement.
|
||||
*/
|
||||
export interface CoreCourseModuleMainComponent {
|
||||
/**
|
||||
* Refresh the data.
|
||||
*
|
||||
* @param {any} [refresher] Refresher.
|
||||
* @param {Function} [done] Function to call when done.
|
||||
* @return {Promise<any>} Promise resolved when done.
|
||||
*/
|
||||
doRefresh(refresher?: any, done?: () => void): Promise<any>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A button to display in a module item.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue