MOBILE-2310 course: Implement singleactivity format
parent
398e7c2bf4
commit
514e9bf132
|
@ -22,13 +22,15 @@ import { CoreCourseFormatComponent } from './format/format';
|
|||
import { CoreCourseModuleComponent } from './module/module';
|
||||
import { CoreCourseModuleCompletionComponent } from './module-completion/module-completion';
|
||||
import { CoreCourseModuleDescriptionComponent } from './module-description/module-description';
|
||||
import { CoreCourseUnsupportedModuleComponent } from './unsupported-module/unsupported-module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
CoreCourseFormatComponent,
|
||||
CoreCourseModuleComponent,
|
||||
CoreCourseModuleCompletionComponent,
|
||||
CoreCourseModuleDescriptionComponent
|
||||
CoreCourseModuleDescriptionComponent,
|
||||
CoreCourseUnsupportedModuleComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
|
@ -43,7 +45,11 @@ import { CoreCourseModuleDescriptionComponent } from './module-description/modul
|
|||
CoreCourseFormatComponent,
|
||||
CoreCourseModuleComponent,
|
||||
CoreCourseModuleCompletionComponent,
|
||||
CoreCourseModuleDescriptionComponent
|
||||
CoreCourseModuleDescriptionComponent,
|
||||
CoreCourseUnsupportedModuleComponent
|
||||
],
|
||||
entryComponents: [
|
||||
CoreCourseUnsupportedModuleComponent
|
||||
]
|
||||
})
|
||||
export class CoreCourseComponentsModule {}
|
||||
|
|
|
@ -210,16 +210,17 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
|||
|
||||
this.componentContainers[type] = container;
|
||||
this.componentInstances[type] = componentRef.instance;
|
||||
this.cdr.detectChanges(); // The instances are used in ngIf, tell Angular that something has changed.
|
||||
|
||||
// Set the Input data.
|
||||
this.componentInstances[type].course = this.course;
|
||||
this.componentInstances[type].sections = this.sections;
|
||||
this.componentInstances[type].downloadEnabled = this.downloadEnabled;
|
||||
|
||||
this.cdr.detectChanges(); // The instances are used in ngIf, tell Angular that something has changed.
|
||||
|
||||
return true;
|
||||
} catch(ex) {
|
||||
this.logger.error('Error creating component', type, ex, componentClass);
|
||||
this.logger.error('Error creating component', type, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<div padding>
|
||||
<core-course-module-description [description]="module.description"></core-course-module-description>
|
||||
<h2 *ngIf="!isDisabledInSite && isSupportedByTheApp">{{ 'core.whoops' | translate }}</h2>
|
||||
<h2 *ngIf="isDisabledInSite || !isSupportedByTheApp">{{ 'core.uhoh' | translate }}</h2>
|
||||
|
||||
<p class="core-big" *ngIf="isDisabledInSite">{{ 'core.course.activitydisabled' | translate }}</p>
|
||||
<p class="core-big" *ngIf="!isDisabledInSite && isSupportedByTheApp">{{ 'core.course.activitynotyetviewablesiteupgradeneeded' | translate }}</p>
|
||||
<p class="core-big" *ngIf="!isDisabledInSite && !isSupportedByTheApp">{{ 'core.course.activitynotyetviewableremoteaddon' | translate }}</p>
|
||||
<p *ngIf="isDisabledInSite || !isSupportedByTheApp"><strong>{{ 'core.course.askadmintosupport' | translate }}</strong></p>
|
||||
|
||||
<div *ngIf="module.url">
|
||||
<p><strong>{{ 'core.course.useactivityonbrowser' | translate }}</strong></p>
|
||||
<a ion-button block icon-end [href]="module.url" core-link>
|
||||
{{ 'core.openinbrowser' | translate }}
|
||||
<ion-icon name="open"></ion-icon>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,48 @@
|
|||
// (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 { Component, Input, OnInit } from '@angular/core';
|
||||
import { IonicPage, NavParams } from 'ionic-angular';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreTextUtilsProvider } from '../../../../providers/utils/text';
|
||||
import { CoreCourseProvider } from '../../providers/course';
|
||||
import { CoreCourseModuleDelegate } from '../../providers/module-delegate';
|
||||
|
||||
/**
|
||||
* Component that displays info about an unsupported module.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'core-course-unsupported-module',
|
||||
templateUrl: 'unsupported-module.html',
|
||||
})
|
||||
export class CoreCourseUnsupportedModuleComponent implements OnInit {
|
||||
@Input() course: any; // The course to module belongs to.
|
||||
@Input() module: any; // The module to render.
|
||||
|
||||
isDisabledInSite: boolean;
|
||||
isSupportedByTheApp: boolean;
|
||||
moduleName: string;
|
||||
|
||||
constructor(navParams: NavParams, private translate: TranslateService, private textUtils: CoreTextUtilsProvider,
|
||||
private courseProvider: CoreCourseProvider, private moduleDelegate: CoreCourseModuleDelegate) {}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit() {
|
||||
this.isDisabledInSite = this.moduleDelegate.isModuleDisabledInSite(this.module.modname);
|
||||
this.isSupportedByTheApp = this.moduleDelegate.hasHandler(this.module.modname);
|
||||
this.moduleName = this.courseProvider.translateModuleName(this.module.modname);
|
||||
}
|
||||
}
|
|
@ -19,12 +19,14 @@ import { CoreCourseFormatDelegate } from './providers/format-delegate';
|
|||
import { CoreCourseModuleDelegate } from './providers/module-delegate';
|
||||
import { CoreCourseModulePrefetchDelegate } from './providers/module-prefetch-delegate';
|
||||
import { CoreCourseFormatDefaultHandler } from './providers/default-format';
|
||||
import { CoreCourseFormatSingleActivityModule } from './formats/singleactivity/singleactivity.module';
|
||||
import { CoreCourseFormatTopicsModule} from './formats/topics/topics.module';
|
||||
import { CoreCourseFormatWeeksModule } from './formats/weeks/weeks.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
imports: [
|
||||
CoreCourseFormatSingleActivityModule,
|
||||
CoreCourseFormatTopicsModule,
|
||||
CoreCourseFormatWeeksModule
|
||||
],
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
// (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 { Component, Input, OnChanges, ViewContainerRef, ComponentFactoryResolver, ChangeDetectorRef,
|
||||
SimpleChange } from '@angular/core';
|
||||
import { CoreLoggerProvider } from '../../../../../providers/logger';
|
||||
import { CoreCourseModuleDelegate } from '../../../providers/module-delegate';
|
||||
import { CoreCourseUnsupportedModuleComponent } from '../../../components/unsupported-module/unsupported-module';
|
||||
|
||||
/**
|
||||
* Component to display single activity format. It will determine the right component to use and instantiate it.
|
||||
*
|
||||
* The instantiated component will receive the course and the module as inputs.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'core-course-format-single-activity',
|
||||
template: ''
|
||||
})
|
||||
export class CoreCourseFormatSingleActivityComponent implements OnChanges {
|
||||
@Input() course: any; // The course to render.
|
||||
@Input() sections: any[]; // List of course sections.
|
||||
@Input() downloadEnabled?: boolean; // Whether the download of sections and modules is enabled.
|
||||
|
||||
protected logger: any;
|
||||
protected module: any;
|
||||
protected componentInstance: any;
|
||||
|
||||
constructor(logger: CoreLoggerProvider, private viewRef: ViewContainerRef, private factoryResolver: ComponentFactoryResolver,
|
||||
private cdr: ChangeDetectorRef, private moduleDelegate: CoreCourseModuleDelegate) {
|
||||
this.logger = logger.getInstance('CoreCourseFormatSingleActivityComponent');
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect changes on input properties.
|
||||
*/
|
||||
ngOnChanges(changes: {[name: string]: SimpleChange}) {
|
||||
if (this.course && this.sections && this.sections.length) {
|
||||
// In single activity the module should only have 1 section and 1 module. Get the module.
|
||||
let module = this.sections[0] && this.sections[0].modules && this.sections[0].modules[0];
|
||||
if (module && !this.componentInstance) {
|
||||
// We haven't created the component yet. Create it now.
|
||||
this.createComponent(module);
|
||||
}
|
||||
|
||||
if (this.componentInstance && this.componentInstance.ngOnChanges) {
|
||||
// Call ngOnChanges of the component.
|
||||
let newChanges: {[name: string]: SimpleChange} = {};
|
||||
|
||||
// Check if course has changed.
|
||||
if (changes.course) {
|
||||
newChanges.course = changes.course
|
||||
this.componentInstance.course = this.course;
|
||||
}
|
||||
|
||||
// Check if module has changed.
|
||||
if (changes.sections && module != this.module) {
|
||||
newChanges.module = {
|
||||
currentValue: module,
|
||||
firstChange: changes.sections.firstChange,
|
||||
previousValue: this.module,
|
||||
isFirstChange: () => {
|
||||
return newChanges.module.firstChange;
|
||||
}
|
||||
};
|
||||
this.componentInstance.module = module;
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
if (Object.keys(newChanges).length) {
|
||||
this.componentInstance.ngOnChanges(newChanges);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the component, add it to the container and set the input data.
|
||||
*
|
||||
* @param {any} module The module.
|
||||
* @return {boolean} Whether the component was successfully created.
|
||||
*/
|
||||
protected createComponent(module: any) : boolean {
|
||||
let componentClass = this.moduleDelegate.getMainComponent(this.course, module) || CoreCourseUnsupportedModuleComponent;
|
||||
if (!componentClass) {
|
||||
// No component to instantiate.
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// Create the component and add it to the container.
|
||||
const factory = this.factoryResolver.resolveComponentFactory(componentClass),
|
||||
componentRef = this.viewRef.createComponent(factory);
|
||||
|
||||
this.componentInstance = componentRef.instance;
|
||||
|
||||
// Set the Input data.
|
||||
this.componentInstance.courseId = this.course.id;
|
||||
this.componentInstance.module = module;
|
||||
|
||||
// this.cdr.detectChanges(); // The instances are used in ngIf, tell Angular that something has changed.
|
||||
|
||||
return true;
|
||||
} catch(ex) {
|
||||
this.logger.error('Error creating component', ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
// (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 } from '@angular/core';
|
||||
import { CoreCourseFormatHandler } from '../../../providers/format-delegate';
|
||||
import { CoreCourseFormatSingleActivityComponent } from '../components/format';
|
||||
|
||||
/**
|
||||
* Handler to support weeks course format.
|
||||
*/
|
||||
@Injectable()
|
||||
export class CoreCourseFormatSingleActivityHandler implements CoreCourseFormatHandler {
|
||||
name = 'singleactivity';
|
||||
|
||||
constructor() {}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled on a site level.
|
||||
*
|
||||
* @return {boolean|Promise<boolean>} True or promise resolved with true if enabled.
|
||||
*/
|
||||
isEnabled() : boolean|Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether it allows seeing all sections at the same time. Defaults to true.
|
||||
*
|
||||
* @param {any} course The course to check.
|
||||
* @type {boolean} Whether it can view all sections.
|
||||
*/
|
||||
canViewAllSections(course: any) : boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title to use in course page. If not defined, course fullname.
|
||||
* This function will be called without sections first, and then call it again when the sections are retrieved.
|
||||
*
|
||||
* @param {any} course The course.
|
||||
* @param {any[]} [sections] List of sections.
|
||||
* @return {string} Title.
|
||||
*/
|
||||
getCourseTitle(course: any, sections?: any[]) : string {
|
||||
if (sections && sections[0] && sections[0].modules && sections[0].modules[0]) {
|
||||
return sections[0].modules[0].name;
|
||||
}
|
||||
return course.fullname || '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the default section selector should be displayed. Defaults to true.
|
||||
*
|
||||
* @param {any} course The course to check.
|
||||
* @type {boolean} Whether the default section selector should be displayed.
|
||||
*/
|
||||
displaySectionSelector(course: any) : boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* If you want to customize the default format there are several methods to customize parts of it.
|
||||
*
|
||||
* @param {any} course The course to render.
|
||||
* @return {any} The component to use, undefined if not found.
|
||||
*/
|
||||
getCourseFormatComponent(course: any) : any {
|
||||
return CoreCourseFormatSingleActivityComponent;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
// (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 { NgModule } from '@angular/core';
|
||||
import { CoreCourseFormatSingleActivityComponent } from './components/format';
|
||||
import { CoreCourseFormatSingleActivityHandler } from './providers/handler';
|
||||
import { CoreCourseFormatDelegate } from '../../providers/format-delegate';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
CoreCourseFormatSingleActivityComponent
|
||||
],
|
||||
imports: [
|
||||
],
|
||||
providers: [
|
||||
CoreCourseFormatSingleActivityHandler
|
||||
],
|
||||
exports: [
|
||||
CoreCourseFormatSingleActivityComponent
|
||||
],
|
||||
entryComponents: [
|
||||
CoreCourseFormatSingleActivityComponent
|
||||
]
|
||||
})
|
||||
export class CoreCourseFormatSingleActivityModule {
|
||||
constructor(formatDelegate: CoreCourseFormatDelegate, handler: CoreCourseFormatSingleActivityHandler) {
|
||||
formatDelegate.registerHandler(handler);
|
||||
}
|
||||
}
|
|
@ -16,9 +16,10 @@
|
|||
</ion-refresher>
|
||||
|
||||
<core-loading [hideUntil]="dataLoaded">
|
||||
<div class="tabs tabs-striped tabs-free mm-tabs-color">
|
||||
<a ion-button class="tab-item">{{ 'core.course.contents' || translate }}</a>
|
||||
<a *ngFor="let handler of courseHandlers" ion-button class="tab-item">{{ handler.data.title || translate }}</a>
|
||||
<!-- @todo: Use core-tabs or a new component. core-tabs might initialize all tabs at start, so we might require a new component. -->
|
||||
<div class="core-tabs-bar">
|
||||
<a aria-selected="true">{{ 'core.course.contents' | translate }}</a>
|
||||
<a *ngFor="let handler of courseHandlers">{{ handler.data.title || translate }}</a>
|
||||
</div>
|
||||
<core-course-format [course]="course" [sections]="sections" [downloadEnabled]="downloadEnabled" (completionChanged)="onCompletionChange()"></core-course-format>
|
||||
</core-loading>
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
page-core-course-section {
|
||||
.core-tabs-bar {
|
||||
@include position(null, null, 0, 0);
|
||||
|
||||
z-index: $z-index-toolbar;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
background: $core-top-tabs-background;
|
||||
|
||||
> a {
|
||||
@extend .tab-button;
|
||||
|
||||
background: $core-top-tabs-background;
|
||||
color: $core-top-tabs-color !important;
|
||||
border-bottom: 1px solid $core-top-tabs-border;
|
||||
font-size: 1.6rem;
|
||||
|
||||
&[aria-selected=true] {
|
||||
color: $core-top-tabs-color-active !important;
|
||||
border-bottom: 2px solid $core-top-tabs-color-active;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -58,9 +58,11 @@ export class CoreCourseSectionPage implements OnDestroy {
|
|||
private textUtils: CoreTextUtilsProvider, private coursesProvider: CoreCoursesProvider,
|
||||
sitesProvider: CoreSitesProvider) {
|
||||
this.course = navParams.get('course');
|
||||
this.title = courseFormatDelegate.getCourseTitle(this.course);
|
||||
this.moduleId = navParams.get('moduleId');
|
||||
|
||||
// Get the title to display. We dont't have sections yet.
|
||||
this.title = courseFormatDelegate.getCourseTitle(this.course);
|
||||
|
||||
this.completionObserver = eventsProvider.on(CoreEventsProvider.COMPLETION_MODULE_VIEWED, (data) => {
|
||||
if (data && data.courseId == this.course.id) {
|
||||
this.refreshAfterCompletionChange();
|
||||
|
@ -150,6 +152,9 @@ export class CoreCourseSectionPage implements OnDestroy {
|
|||
id: CoreCourseProvider.ALL_SECTIONS_ID
|
||||
});
|
||||
}
|
||||
|
||||
// Get the title again now that we have sections.
|
||||
this.title = this.courseFormatDelegate.getCourseTitle(this.course, this.sections);
|
||||
}));
|
||||
}));
|
||||
|
||||
|
|
|
@ -10,21 +10,6 @@
|
|||
</ion-buttons>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
<core-course-module-description [description]="module.description"></core-course-module-description>
|
||||
<h2 *ngIf="!isDisabledInSite && isSupportedByTheApp">{{ 'core.whoops' | translate }}</h2>
|
||||
<h2 *ngIf="isDisabledInSite || !isSupportedByTheApp">{{ 'core.uhoh' | translate }}</h2>
|
||||
|
||||
<p class="core-big" *ngIf="isDisabledInSite">{{ 'core.course.activitydisabled' | translate }}</p>
|
||||
<p class="core-big" *ngIf="!isDisabledInSite && isSupportedByTheApp">{{ 'core.course.activitynotyetviewablesiteupgradeneeded' | translate }}</p>
|
||||
<p class="core-big" *ngIf="!isDisabledInSite && !isSupportedByTheApp">{{ 'core.course.activitynotyetviewableremoteaddon' | translate }}</p>
|
||||
<p *ngIf="isDisabledInSite || !isSupportedByTheApp"><strong>{{ 'core.course.askadmintosupport' | translate }}</strong></p>
|
||||
|
||||
<div *ngIf="module.url">
|
||||
<p><strong>{{ 'core.course.useactivityonbrowser' | translate }}</strong></p>
|
||||
<a ion-button block icon-end [href]="module.url" core-link>
|
||||
{{ 'core.openinbrowser' | translate }}
|
||||
<ion-icon name="open"></ion-icon>
|
||||
</a>
|
||||
</div>
|
||||
<ion-content>
|
||||
<core-course-unsupported-module [module]="module"></core-course-unsupported-module>
|
||||
</ion-content>
|
||||
|
|
|
@ -13,11 +13,9 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavParams } from 'ionic-angular';
|
||||
import { IonicPage, NavParams, NavController } from 'ionic-angular';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreTextUtilsProvider } from '../../../../providers/utils/text';
|
||||
import { CoreCourseProvider } from '../../providers/course';
|
||||
import { CoreCourseModuleDelegate } from '../../providers/module-delegate';
|
||||
|
||||
/**
|
||||
* Page that displays info about an unsupported module.
|
||||
|
@ -28,30 +26,18 @@ import { CoreCourseModuleDelegate } from '../../providers/module-delegate';
|
|||
templateUrl: 'unsupported-module.html',
|
||||
})
|
||||
export class CoreCourseUnsupportedModulePage {
|
||||
|
||||
module: any;
|
||||
isDisabledInSite: boolean;
|
||||
isSupportedByTheApp: boolean;
|
||||
moduleName: string;
|
||||
|
||||
constructor(navParams: NavParams, private translate: TranslateService, private textUtils: CoreTextUtilsProvider,
|
||||
private moduleDelegate: CoreCourseModuleDelegate, private courseProvider: CoreCourseProvider) {
|
||||
private navCtrl: NavController) {
|
||||
this.module = navParams.get('module') || {};
|
||||
}
|
||||
|
||||
/**
|
||||
* View loaded.
|
||||
*/
|
||||
ionViewDidLoad() {
|
||||
this.isDisabledInSite = this.moduleDelegate.isModuleDisabledInSite(this.module.modname);
|
||||
this.isSupportedByTheApp = this.moduleDelegate.hasHandler(this.module.modname);
|
||||
this.moduleName = this.courseProvider.translateModuleName(this.module.modname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand the description.
|
||||
*/
|
||||
expandDescription() {
|
||||
this.textUtils.expandText(this.translate.instant('core.description'), this.module.description, false);
|
||||
this.textUtils.expandText(this.translate.instant('core.description'), this.module.description, false,
|
||||
undefined, undefined, this.navCtrl);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,11 +39,13 @@ export interface CoreCourseFormatHandler {
|
|||
|
||||
/**
|
||||
* Get the title to use in course page. If not defined, course fullname.
|
||||
* This function will be called without sections first, and then call it again when the sections are retrieved.
|
||||
*
|
||||
* @param {any} course The course.
|
||||
* @param {any[]} [sections] List of sections.
|
||||
* @return {string} Title.
|
||||
*/
|
||||
getCourseTitle?(course: any) : string;
|
||||
getCourseTitle?(course: any, sections?: any[]) : string;
|
||||
|
||||
/**
|
||||
* Whether it allows seeing all sections at the same time. Defaults to true.
|
||||
|
@ -227,10 +229,11 @@ export class CoreCourseFormatDelegate {
|
|||
* Given a course, return the title to use in the course page.
|
||||
*
|
||||
* @param {any} course The course to get the title.
|
||||
* @param {any[]} [sections] List of sections.
|
||||
* @return {string} Course title.
|
||||
*/
|
||||
getCourseTitle(course: any) : string {
|
||||
return this.executeFunction(course.format, 'getCourseTitle', [course]);
|
||||
getCourseTitle(course: any, sections?: any[]) : string {
|
||||
return this.executeFunction(course.format, 'getCourseTitle', [course, sections]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -52,6 +52,15 @@ export interface CoreCourseModuleHandler {
|
|||
* @return {CoreCourseModuleHandlerData} Data to render the module.
|
||||
*/
|
||||
getData(module: any, courseId: number, sectionId: number) : CoreCourseModuleHandlerData;
|
||||
|
||||
/**
|
||||
* Get the component to render the module. This is needed to support singleactivity course format.
|
||||
*
|
||||
* @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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -163,6 +172,23 @@ export class CoreCourseModuleDelegate {
|
|||
eventsProvider.on(CoreEventsProvider.REMOTE_ADDONS_LOADED, this.updateHandlers.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the component to render the module.
|
||||
*
|
||||
* @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 {
|
||||
let handler = this.enabledHandlers[module.modname];
|
||||
if (handler && handler.getMainComponent) {
|
||||
let component = handler.getMainComponent(course, module);
|
||||
if (component) {
|
||||
return component;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data required to display the module in the course contents view.
|
||||
*
|
||||
|
|
|
@ -165,7 +165,7 @@ export class CoreFileUploaderDelegate {
|
|||
protected lastUpdateHandlersStart: number;
|
||||
|
||||
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, eventsProvider: CoreEventsProvider) {
|
||||
this.logger = logger.getInstance('CoreCourseModuleDelegate');
|
||||
this.logger = logger.getInstance('CoreFileUploaderDelegate');
|
||||
|
||||
eventsProvider.on(CoreEventsProvider.LOGIN, this.updateHandlers.bind(this));
|
||||
eventsProvider.on(CoreEventsProvider.SITE_UPDATED, this.updateHandlers.bind(this));
|
||||
|
|
|
@ -251,7 +251,7 @@ export class CoreTextUtilsProvider {
|
|||
* @param {boolean} [isModal] Whether it should be opened in a modal (true) or in a new page (false).
|
||||
* @param {string} [component] Component to link the embedded files to.
|
||||
* @param {string|number} [componentId] An ID to use in conjunction with the component.
|
||||
* @param {NavController} [navCtrl] The NavController instance to use.
|
||||
* @param {NavController} [navCtrl] The NavController instance to use. Required if isModal is false.
|
||||
*/
|
||||
expandText(title: string, text: string, isModal?: boolean, component?: string, componentId?: string|number,
|
||||
navCtrl?: NavController) : void {
|
||||
|
|
Loading…
Reference in New Issue