MOBILE-2341 core: Support split views in course formats
parent
bc71bbbdfc
commit
b34adcaa42
|
@ -84,25 +84,6 @@ export class CoreCourseModuleMainActivityComponent extends CoreCourseModuleMainR
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the data.
|
||||
*
|
||||
* @param {any} [refresher] Refresher.
|
||||
* @param {Function} [done] Function to call when done.
|
||||
* @param {boolean} [showErrors=false] If show errors to the user of hide them.
|
||||
* @return {Promise<any>} Promise resolved when done.
|
||||
*/
|
||||
doRefresh(refresher?: any, done?: () => void, showErrors: boolean = false): Promise<any> {
|
||||
if (this.loaded) {
|
||||
return this.refreshContent(true, showErrors).finally(() => {
|
||||
refresher && refresher.complete();
|
||||
done && done();
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares sync event data with current data to check if refresh content is needed.
|
||||
*
|
||||
|
|
|
@ -17,7 +17,8 @@ import { TranslateService } from '@ngx-translate/core';
|
|||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { CoreCourseHelperProvider } from '@core/course/providers/helper';
|
||||
import { CoreCourseModuleMainComponent } from '@core/course/providers/module-delegate';
|
||||
import { CoreCourseModuleMainComponent, CoreCourseModuleDelegate } from '@core/course/providers/module-delegate';
|
||||
import { CoreCourseSectionPage } from '@core/course/pages/section/section.ts';
|
||||
|
||||
/**
|
||||
* Template class to easily create CoreCourseModuleMainComponent of resources (or activities without syncing).
|
||||
|
@ -50,12 +51,16 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
|
|||
protected courseHelper: CoreCourseHelperProvider;
|
||||
protected translate: TranslateService;
|
||||
protected domUtils: CoreDomUtilsProvider;
|
||||
protected moduleDelegate: CoreCourseModuleDelegate;
|
||||
protected courseSectionPage: CoreCourseSectionPage;
|
||||
|
||||
constructor(injector: Injector) {
|
||||
this.textUtils = injector.get(CoreTextUtilsProvider);
|
||||
this.courseHelper = injector.get(CoreCourseHelperProvider);
|
||||
this.translate = injector.get(TranslateService);
|
||||
this.domUtils = injector.get(CoreDomUtilsProvider);
|
||||
this.moduleDelegate = injector.get(CoreCourseModuleDelegate);
|
||||
this.courseSectionPage = injector.get(CoreCourseSectionPage, null);
|
||||
this.dataRetrieved = new EventEmitter();
|
||||
}
|
||||
|
||||
|
@ -73,15 +78,27 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
|
|||
/**
|
||||
* Refresh the data.
|
||||
*
|
||||
* @param {any} [refresher] Refresher.
|
||||
* @param {Function} [done] Function to call when done.
|
||||
* @param {any} [refresher] Refresher.
|
||||
* @param {Function} [done] Function to call when done.
|
||||
* @param {boolean} [showErrors=false] If show errors to the user of hide them.
|
||||
* @return {Promise<any>} Promise resolved when done.
|
||||
*/
|
||||
doRefresh(refresher?: any, done?: () => void): Promise<any> {
|
||||
doRefresh(refresher?: any, done?: () => void, showErrors: boolean = false): Promise<any> {
|
||||
if (this.loaded) {
|
||||
return this.refreshContent().finally(() => {
|
||||
refresher && refresher.complete();
|
||||
done && done();
|
||||
/* If it's a single activity course and the refresher is displayed within the component,
|
||||
call doRefresh on the section page to refresh the course data. */
|
||||
let promise;
|
||||
if (this.courseSectionPage && !this.moduleDelegate.displayRefresherInSingleActivity(this.module.modname)) {
|
||||
promise = this.courseSectionPage.doRefresh();
|
||||
} else {
|
||||
promise = Promise.resolve();
|
||||
}
|
||||
|
||||
return promise.finally(() => {
|
||||
return this.refreshContent(true, showErrors).finally(() => {
|
||||
refresher && refresher.complete();
|
||||
done && done();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -91,9 +108,11 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
|
|||
/**
|
||||
* Perform the refresh content function.
|
||||
*
|
||||
* @param {boolean} [sync=false] If the refresh needs syncing.
|
||||
* @param {boolean} [showErrors=false] Wether to show errors to the user or hide them.
|
||||
* @return {Promise<any>} Resolved when done.
|
||||
*/
|
||||
protected refreshContent(): Promise<any> {
|
||||
protected refreshContent(sync: boolean = false, showErrors: boolean = false): Promise<any> {
|
||||
this.refreshIcon = 'spinner';
|
||||
|
||||
return this.invalidateContent().catch(() => {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { CoreCourseFormatHandler } from '../../../providers/format-delegate';
|
||||
import { CoreCourseModuleDelegate } from '../../../providers/module-delegate';
|
||||
import { CoreCourseFormatSingleActivityComponent } from '../components/singleactivity';
|
||||
|
||||
/**
|
||||
|
@ -24,7 +25,7 @@ export class CoreCourseFormatSingleActivityHandler implements CoreCourseFormatHa
|
|||
name = 'CoreCourseFormatSingleActivity';
|
||||
format = 'singleactivity';
|
||||
|
||||
constructor() {
|
||||
constructor(private moduleDelegate: CoreCourseModuleDelegate) {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
|
@ -83,6 +84,22 @@ export class CoreCourseFormatSingleActivityHandler implements CoreCourseFormatHa
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the course refresher should be displayed. If it returns false, a refresher must be included in the course format,
|
||||
* and the doRefresh method of CoreCourseSectionPage must be called on refresh. Defaults to true.
|
||||
*
|
||||
* @param {any} course The course to check.
|
||||
* @param {any[]} sections List of course sections.
|
||||
* @return {boolean} Whether the refresher should be displayed.
|
||||
*/
|
||||
displayRefresher(course: any, sections: any[]): boolean {
|
||||
if (sections && sections[0] && sections[0].modules) {
|
||||
return this.moduleDelegate.displayRefresherInSingleActivity(sections[0].modules[0].modname);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the course format instead of using the default one.
|
||||
* Use it if you want to display a format completely different from the default one.
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</core-context-menu>
|
||||
</core-navbar-buttons>
|
||||
<ion-content>
|
||||
<ion-refresher [enabled]="dataLoaded" (ionRefresh)="doRefresh($event)">
|
||||
<ion-refresher [enabled]="dataLoaded && displayRefresher" (ionRefresh)="doRefresh($event)">
|
||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||
</ion-refresher>
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ export class CoreCourseSectionPage implements OnDestroy {
|
|||
};
|
||||
moduleId: number;
|
||||
displayEnableDownload: boolean;
|
||||
displayRefresher: boolean;
|
||||
|
||||
protected module: any;
|
||||
protected completionObserver;
|
||||
|
@ -188,6 +189,9 @@ export class CoreCourseSectionPage implements OnDestroy {
|
|||
|
||||
// Get the title again now that we have sections.
|
||||
this.title = this.courseFormatDelegate.getCourseTitle(this.course, this.sections);
|
||||
|
||||
// Get whether to show the refresher now that we have sections.
|
||||
this.displayRefresher = this.courseFormatDelegate.displayRefresher(this.course, this.sections);
|
||||
});
|
||||
}));
|
||||
|
||||
|
@ -212,13 +216,23 @@ export class CoreCourseSectionPage implements OnDestroy {
|
|||
/**
|
||||
* Refresh the data.
|
||||
*
|
||||
* @param {any} refresher Refresher.
|
||||
* @param {any} [refresher] Refresher.
|
||||
* @return {Promise<any>} Promise resolved when done.
|
||||
*/
|
||||
doRefresh(refresher: any): void {
|
||||
this.invalidateData().finally(() => {
|
||||
this.loadData(true).finally(() => {
|
||||
this.formatComponent.doRefresh(refresher).finally(() => {
|
||||
refresher.complete();
|
||||
doRefresh(refresher?: any): Promise<any> {
|
||||
return this.invalidateData().finally(() => {
|
||||
return this.loadData(true).finally(() => {
|
||||
/* Do not call doRefresh on the format component if the refresher is defined in the format component
|
||||
to prevent an inifinite loop. */
|
||||
let promise;
|
||||
if (this.displayRefresher) {
|
||||
promise = this.formatComponent.doRefresh(refresher);
|
||||
} else {
|
||||
promise = Promise.resolve();
|
||||
}
|
||||
|
||||
return promise.finally(() => {
|
||||
refresher && refresher.complete();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -77,6 +77,18 @@ export class CoreCourseFormatDefaultHandler implements CoreCourseFormatHandler {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the course refresher should be displayed. If it returns false, a refresher must be included in the course format,
|
||||
* and the doRefresh method of CoreCourseSectionPage must be called on refresh. Defaults to true.
|
||||
*
|
||||
* @param {any} course The course to check.
|
||||
* @param {any[]} sections List of course sections.
|
||||
* @return {boolean} Whether the refresher should be displayed.
|
||||
*/
|
||||
displayRefresher?(course: any, sections: any[]): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a list of sections, get the "current" section that should be displayed first.
|
||||
*
|
||||
|
|
|
@ -89,4 +89,14 @@ export class CoreCourseModuleDefaultHandler implements CoreCourseModuleHandler {
|
|||
// We can't inject CoreCourseUnsupportedModuleComponent here due to circular dependencies.
|
||||
// Don't return anything, by default it will use CoreCourseUnsupportedModuleComponent.
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to display the course refresher in single activity course format. If it returns false, a refresher must be
|
||||
* included in the template that calls the doRefresh method of the component. Defaults to true.
|
||||
*
|
||||
* @return {boolean} Whether the refresher should be displayed.
|
||||
*/
|
||||
displayRefresherInSingleActivity(): boolean {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,6 +65,16 @@ export interface CoreCourseFormatHandler extends CoreDelegateHandler {
|
|||
*/
|
||||
displaySectionSelector?(course: any): boolean;
|
||||
|
||||
/**
|
||||
* Whether the course refresher should be displayed. If it returns false, a refresher must be included in the course format,
|
||||
* and the doRefresh method of CoreCourseSectionPage must be called on refresh. Defaults to true.
|
||||
*
|
||||
* @param {any} course The course to check.
|
||||
* @param {any[]} sections List of course sections.
|
||||
* @type {boolean} Whether the refresher should be displayed.
|
||||
*/
|
||||
displayRefresher?(course: any, sections: any[]): boolean;
|
||||
|
||||
/**
|
||||
* Given a list of sections, get the "current" section that should be displayed first. Defaults to first section.
|
||||
*
|
||||
|
@ -183,6 +193,18 @@ export class CoreCourseFormatDelegate extends CoreDelegate {
|
|||
return this.executeFunctionOnEnabled(course.format, 'displayEnableDownload', [course]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the course refresher should be displayed. If it returns false, a refresher must be included in the course format,
|
||||
* and the doRefresh method of CoreCourseSectionPage must be called on refresh. Defaults to true.
|
||||
*
|
||||
* @param {any} course The course to check.
|
||||
* @param {any[]} sections List of course sections.
|
||||
* @return {boolean} Whether the refresher should be displayed.
|
||||
*/
|
||||
displayRefresher(course: any, sections: any[]): boolean {
|
||||
return this.executeFunctionOnEnabled(course.format, 'displayRefresher', [course, sections]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the default section selector should be displayed. Defaults to true.
|
||||
*
|
||||
|
|
|
@ -53,6 +53,14 @@ export interface CoreCourseModuleHandler extends CoreDelegateHandler {
|
|||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getMainComponent(injector: Injector, course: any, module: any): any | Promise<any>;
|
||||
|
||||
/**
|
||||
* Whether to display the course refresher in single activity course format. If it returns false, a refresher must be
|
||||
* included in the template that calls the doRefresh method of the component. Defaults to true.
|
||||
*
|
||||
* @return {boolean} Whether the refresher should be displayed.
|
||||
*/
|
||||
displayRefresherInSingleActivity?(): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -247,4 +255,15 @@ export class CoreCourseModuleDelegate extends CoreDelegate {
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to display the course refresher in single activity course format. If it returns false, a refresher must be
|
||||
* included in the template that calls the doRefresh method of the component. Defaults to true.
|
||||
*
|
||||
* @param {any} modname The name of the module type.
|
||||
* @return {boolean} Whether the refresher should be displayed.
|
||||
*/
|
||||
displayRefresherInSingleActivity(modname: string): boolean {
|
||||
return this.executeFunctionOnEnabled(modname, 'displayRefresherInSingleActivity');
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue