diff --git a/src/addon/mod/lesson/components/components.module.ts b/src/addon/mod/lesson/components/components.module.ts new file mode 100644 index 000000000..0acaaf970 --- /dev/null +++ b/src/addon/mod/lesson/components/components.module.ts @@ -0,0 +1,45 @@ +// (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 { CommonModule } from '@angular/common'; +import { IonicModule } from 'ionic-angular'; +import { TranslateModule } from '@ngx-translate/core'; +import { CoreComponentsModule } from '@components/components.module'; +import { CoreDirectivesModule } from '@directives/directives.module'; +import { CoreCourseComponentsModule } from '@core/course/components/components.module'; +import { AddonModLessonIndexComponent } from './index/index'; + +@NgModule({ + declarations: [ + AddonModLessonIndexComponent + ], + imports: [ + CommonModule, + IonicModule, + TranslateModule.forChild(), + CoreComponentsModule, + CoreDirectivesModule, + CoreCourseComponentsModule + ], + providers: [ + ], + exports: [ + AddonModLessonIndexComponent + ], + entryComponents: [ + AddonModLessonIndexComponent + ] +}) +export class AddonModLessonComponentsModule {} diff --git a/src/addon/mod/lesson/components/index/index.html b/src/addon/mod/lesson/components/index/index.html new file mode 100644 index 000000000..3778166d7 --- /dev/null +++ b/src/addon/mod/lesson/components/index/index.html @@ -0,0 +1,247 @@ + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ + {{ 'core.hasdatatosync' | translate: {$a: moduleName} }} +
+ + + +
+ + + {{ 'addon.mod_lesson.enterpassword' | translate }} + + + + + + +
+
+ + + + + +

{{ 'addon.mod_lesson.retakefinishedinsync' | translate }}

+ {{ 'addon.mod_lesson.review' | translate }} +
+ + + +

+ + + + {{ 'core.no' | translate }} + + + {{ 'core.yes' | translate }} + + + +
+ + + +

+ + {{ 'addon.mod_lesson.continue' | translate }} + + +
+ + + +

+
+ + + + + {{ 'core.start' | translate }} + + + + {{ 'addon.mod_lesson.preview' | translate }} + + + +
+
+
+
+ + + + + + + + {{ 'core.groupsseparate' | translate }} + {{ 'core.groupsvisible' | translate }} + + {{groupOpt.name}} + + + + + + + + + + + + + {{ 'addon.mod_lesson.lessonstats' | translate }} + + + + + + + +

{{ 'addon.mod_lesson.averagescore' | translate }}

+

{{ 'core.percentagenumber' | translate:{$a: overview.avescore} }}

+

{{ 'addon.mod_lesson.notcompleted' | translate }}

+
+ + +

{{ 'addon.mod_lesson.highscore' | translate }}

+

{{ 'core.percentagenumber' | translate:{$a: overview.highscore} }}

+

{{ 'addon.mod_lesson.notcompleted' | translate }}

+
+ + +

{{ 'addon.mod_lesson.lowscore' | translate }}

+

{{ 'core.percentagenumber' | translate:{$a: overview.lowscore} }}

+

{{ 'addon.mod_lesson.notcompleted' | translate }}

+
+
+
+ + + + +

{{ 'addon.mod_lesson.averagetime' | translate }}

+

{{ overview.avetimeReadable }}

+

{{ 'addon.mod_lesson.notcompleted' | translate }}

+
+ + +

{{ 'addon.mod_lesson.hightime' | translate }}

+

{{ overview.hightimeReadable }}

+

{{ 'addon.mod_lesson.notcompleted' | translate }}

+
+ + +

{{ 'addon.mod_lesson.lowtime' | translate }}

+

{{ overview.lowtimeReadable }}

+

{{ 'addon.mod_lesson.notcompleted' | translate }}

+
+
+
+
+ + + + + + +

{{ 'addon.mod_lesson.averagescore' | translate }}

+

{{ 'core.percentagenumber' | translate:{$a: overview.avescore} }}

+

{{ 'addon.mod_lesson.notcompleted' | translate }}

+
+ + +

{{ 'addon.mod_lesson.averagetime' | translate }}

+

{{ overview.avetimeReadable }}

+

{{ 'addon.mod_lesson.notcompleted' | translate }}

+
+
+
+ + + + +

{{ 'addon.mod_lesson.highscore' | translate }}

+

{{ 'core.percentagenumber' | translate:{$a: overview.highscore} }}

+

{{ 'addon.mod_lesson.notcompleted' | translate }}

+
+ + +

{{ 'addon.mod_lesson.hightime' | translate }}

+

{{ overview.hightimeReadable }}

+

{{ 'addon.mod_lesson.notcompleted' | translate }}

+
+
+
+ + + + +

{{ 'addon.mod_lesson.lowscore' | translate }}

+

{{ 'core.percentagenumber' | translate:{$a: overview.lowscore} }}

+

{{ 'addon.mod_lesson.notcompleted' | translate }}

+
+ + +

{{ 'addon.mod_lesson.lowtime' | translate }}

+

{{ overview.lowtimeReadable }}

+

{{ 'addon.mod_lesson.notcompleted' | translate }}

+
+
+
+
+
+ + + + + {{ 'addon.mod_lesson.overview' | translate }} + + + + + + +

{{ student.fullname }}

+ +
+
+
+
+
+
+
diff --git a/src/addon/mod/lesson/components/index/index.scss b/src/addon/mod/lesson/components/index/index.scss new file mode 100644 index 000000000..bee1246fe --- /dev/null +++ b/src/addon/mod/lesson/components/index/index.scss @@ -0,0 +1,2 @@ +addon-mod-lesson-index { +} diff --git a/src/addon/mod/lesson/components/index/index.ts b/src/addon/mod/lesson/components/index/index.ts new file mode 100644 index 000000000..b3b21b9da --- /dev/null +++ b/src/addon/mod/lesson/components/index/index.ts @@ -0,0 +1,552 @@ +// (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, Optional, Injector, Input } from '@angular/core'; +import { Content, NavController } from 'ionic-angular'; +import { CoreGroupsProvider, CoreGroupInfo } from '@providers/groups'; +import { CoreTimeUtilsProvider } from '@providers/utils/time'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseModuleMainActivityComponent } from '@core/course/classes/main-activity-component'; +import { CoreUserProvider } from '@core/user/providers/user'; +import { AddonModLessonProvider } from '../../providers/lesson'; +import { AddonModLessonOfflineProvider } from '../../providers/lesson-offline'; +import { AddonModLessonSyncProvider } from '../../providers/lesson-sync'; +import { AddonModLessonPrefetchHandler } from '../../providers/prefetch-handler'; +import { CoreConstants } from '@core/constants'; + +/** + * Component that displays a lesson entry page. + */ +@Component({ + selector: 'addon-mod-lesson-index', + templateUrl: 'index.html', +}) +export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityComponent { + @Input() group: number; // The group to display. + @Input() action: string; // The "action" to display first. + + component = AddonModLessonProvider.COMPONENT; + moduleName = 'lesson'; + + lesson: any; // The lesson. + selectedTab: number; // The initial selected tab. + askPassword: boolean; // Whether to ask the password. + canManage: boolean; // Whether the user can manage the lesson. + canViewReports: boolean; // Whether the user can view the lesson reports. + showSpinner: boolean; // Whether to display a spinner. + hasOffline: boolean; // Whether there's offline data. + retakeToReview: any; // A retake to review. + preventMessages: string[]; // List of messages that prevent the lesson from being seen. + leftDuringTimed: boolean; // Whether the user has started and left a retake. + groupInfo: CoreGroupInfo; // The group info. + reportLoaded: boolean; // Whether the report data has been loaded. + selectedGroupName: string; // The name of the selected group. + overview: any; // Reports overview data. + + protected syncEventName = AddonModLessonSyncProvider.AUTO_SYNCED; + protected accessInfo: any; // Lesson access info. + protected password: string; // The password for the lesson. + protected hasPlayed: boolean; // Whether the user has gone to the lesson player (attempted). + + constructor(injector: Injector, protected lessonProvider: AddonModLessonProvider, @Optional() content: Content, + protected groupsProvider: CoreGroupsProvider, protected lessonOffline: AddonModLessonOfflineProvider, + protected lessonSync: AddonModLessonSyncProvider, protected utils: CoreUtilsProvider, + protected prefetchHandler: AddonModLessonPrefetchHandler, protected navCtrl: NavController, + protected timeUtils: CoreTimeUtilsProvider, protected userProvider: CoreUserProvider) { + super(injector, content); + } + + /** + * Component being initialized. + */ + ngOnInit(): void { + super.ngOnInit(); + + this.selectedTab = this.action == 'report' ? 1 : 0; + + this.loadContent(false, true).then(() => { + if (!this.lesson || (this.preventMessages && this.preventMessages.length)) { + return; + } + + this.logView(); + }); + } + + /** + * Change the group displayed. + * + * @param {number} groupId Group ID to display. + */ + changeGroup(groupId: number): void { + this.reportLoaded = false; + + this.setGroup(groupId).catch((error) => { + this.domUtils.showErrorModalDefault(error, 'Error getting report.'); + }).finally(() => { + this.reportLoaded = true; + }); + } + + /** + * Get the lesson data. + * + * @param {boolean} [refresh=false] If it's refreshing content. + * @param {boolean} [sync=false] If the refresh is needs syncing. + * @param {boolean} [showErrors=false] If show errors to the user of hide them. + * @return {Promise} Promise resolved when done. + */ + protected fetchContent(refresh: boolean = false, sync: boolean = false, showErrors: boolean = false): Promise { + + let lessonReady = true; + this.askPassword = false; + + return this.lessonProvider.getLesson(this.courseId, this.module.id).then((lessonData) => { + this.lesson = lessonData; + + this.dataRetrieved.emit(this.lesson); + this.description = this.lesson.intro; // Show description only if intro is present. + + if (sync) { + // Try to synchronize the lesson. + return this.syncActivity(showErrors); + } + }).then(() => { + return this.lessonProvider.getAccessInformation(this.lesson.id); + }).then((info) => { + const promises = []; + + this.accessInfo = info; + this.canManage = info.canmanage; + this.canViewReports = info.canviewreports; + + if (this.lessonProvider.isLessonOffline(this.lesson)) { + // Handle status. + this.setStatusListener(); + + // Check if there is offline data. + promises.push(this.lessonSync.hasDataToSync(this.lesson.id, info.attemptscount).then((hasOffline) => { + this.hasOffline = hasOffline; + })); + + // Check if there is a retake finished in a synchronization. + promises.push(this.lessonSync.getRetakeFinishedInSync(this.lesson.id).then((retake) => { + if (retake && retake.retake == info.attemptscount - 1) { + // The retake finished is still the last retake. Allow reviewing it. + this.retakeToReview = retake; + } else { + this.retakeToReview = undefined; + if (retake) { + this.lessonSync.deleteRetakeFinishedInSync(this.lesson.id); + } + } + })); + + // Update the list of content pages viewed and question attempts. + promises.push(this.lessonProvider.getContentPagesViewedOnline(this.lesson.id, info.attemptscount)); + promises.push(this.lessonProvider.getQuestionsAttemptsOnline(this.lesson.id, info.attemptscount)); + } + + if (info.preventaccessreasons && info.preventaccessreasons.length) { + const askPassword = info.preventaccessreasons.length == 1 && this.lessonProvider.isPasswordProtected(info); + + if (askPassword) { + // The lesson requires a password. Check if there is one in memory or DB. + const promise = this.password ? Promise.resolve(this.password) : + this.lessonProvider.getStoredPassword(this.lesson.id); + + promises.push(promise.then((password) => { + return this.validatePassword(password); + }).catch(() => { + // No password or the validation failed. Show password form. + this.askPassword = true; + this.preventMessages = info.preventaccessreasons; + lessonReady = false; + })); + } else { + // Lesson cannot be started. + this.preventMessages = info.preventaccessreasons; + lessonReady = false; + } + } + + if (this.selectedTab == 1 && this.canViewReports) { + // Only fetch the report data if the tab is selected. + promises.push(this.fetchReportData()); + } + + return Promise.all(promises).then(() => { + if (lessonReady) { + // Lesson can be started, don't ask the password and don't show prevent messages. + this.lessonReady(refresh); + } + }); + }); + } + + /** + * Fetch the reports data. + * + * @return {Promise} Promise resolved when done. + */ + protected fetchReportData(): Promise { + return this.groupsProvider.getActivityGroupInfo(this.module.id).then((groupInfo) => { + this.groupInfo = groupInfo; + + return this.setGroup(this.group || 0); + }).finally(() => { + this.reportLoaded = true; + }); + } + + /** + * Checks if sync has succeed from result sync data. + * + * @param {any} result Data returned on the sync function. + * @return {boolean} If suceed or not. + */ + protected hasSyncSucceed(result: any): boolean { + return result.updated; + } + + /** + * User entered the page that contains the component. + */ + ionViewDidEnter(): void { + super.ionViewDidEnter(); + + // Update data when we come back from the player since the status could have changed. + if (this.hasPlayed) { + this.hasPlayed = false; + + this.showLoadingAndRefresh(true, false); + } + } + + /** + * User left the page that contains the component. + */ + ionViewDidLeave(): void { + super.ionViewDidLeave(); + + if (this.navCtrl.getActive().component.name == 'AddonModLessonPlayerPage') { + this.hasPlayed = true; + } + } + + /** + * Perform the invalidate content function. + * + * @return {Promise} Resolved when done. + */ + protected invalidateContent(): Promise { + const promises = []; + + promises.push(this.lessonProvider.invalidateLessonData(this.courseId)); + + if (this.lesson) { + promises.push(this.lessonProvider.invalidateAccessInformation(this.lesson.id)); + promises.push(this.lessonProvider.invalidatePages(this.lesson.id)); + promises.push(this.lessonProvider.invalidateLessonWithPassword(this.lesson.id)); + promises.push(this.lessonProvider.invalidateTimers(this.lesson.id)); + promises.push(this.lessonProvider.invalidateContentPagesViewed(this.lesson.id)); + promises.push(this.lessonProvider.invalidateQuestionsAttempts(this.lesson.id)); + promises.push(this.lessonProvider.invalidateRetakesOverview(this.lesson.id)); + promises.push(this.groupsProvider.invalidateActivityGroupInfo(this.module.id)); + } + + return Promise.all(promises); + } + + /** + * Compares sync event data with current data to check if refresh content is needed. + * + * @param {any} syncEventData Data receiven on sync observer. + * @return {boolean} True if refresh is needed, false otherwise. + */ + protected isRefreshSyncNeeded(syncEventData: any): boolean { + return this.lesson && syncEventData.lessonId == this.lesson.id; + } + + /** + * Function called when the lesson is ready to be seen (no pending prevent access reasons). + * + * @param {boolean} [refresh=false] If it's refreshing content. + */ + protected lessonReady(refresh?: boolean): void { + this.askPassword = false; + this.preventMessages = []; + this.leftDuringTimed = this.hasOffline || this.lessonProvider.leftDuringTimed(this.accessInfo); + + if (this.password) { + // Store the password in DB. + this.lessonProvider.storePassword(this.lesson.id, this.password); + } + + // All data obtained, now fill the context menu. + this.fillContextMenu(refresh); + } + + /** + * Log viewing the lesson. + */ + protected logView(): void { + this.lessonProvider.logViewLesson(this.lesson.id, this.password).then(() => { + this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); + }).catch((error) => { + // Ignore errors. + }); + } + + /** + * Open the lesson player. + * + * @param {boolean} continueLast Whether to continue the last retake. + * @return {Promise} Promise resolved when done. + */ + protected playLesson(continueLast: boolean): Promise { + // Calculate the pageId to load. If there is timelimit, lesson is always restarted from the start. + let promise; + + if (this.hasOffline) { + if (continueLast) { + promise = this.lessonProvider.getLastPageSeen(this.lesson.id, this.accessInfo.attemptscount); + } else { + promise = Promise.resolve(this.accessInfo.firstpageid); + } + } else if (this.leftDuringTimed && !this.lesson.timelimit) { + promise = Promise.resolve(continueLast ? this.accessInfo.lastpageseen : this.accessInfo.firstpageid); + } else { + promise = Promise.resolve(); + } + + return promise.then((pageId) => { + this.navCtrl.push('AddonModLessonPlayerPage', { + courseId: this.courseId, + lessonId: this.lesson.id, + pageId: pageId, + password: this.password + }); + }); + } + + /** + * Reports tab selected. + */ + reportsSelected(): void { + if (!this.groupInfo) { + this.fetchReportData().catch((error) => { + this.domUtils.showErrorModalDefault(error, 'Error getting report.'); + }); + } + } + + /** + * Review the lesson. + */ + review(): void { + if (!this.retakeToReview) { + // No retake to review, stop. + return; + } + + this.navCtrl.push('AddonModLessonPlayerPage', { + courseId: this.courseId, + lessonId: this.lesson.id, + pageId: this.retakeToReview.pageId, + password: this.password, + review: true, + retake: this.retakeToReview.retake + }); + } + + /** + * Set a group to view the reports. + * + * @param {number} groupId Group ID. + * @return {Promise} Promise resolved when done. + */ + protected setGroup(groupId: number): Promise { + this.group = groupId; + this.selectedGroupName = ''; + + // Search the name of the group if it isn't all participants. + if (groupId && this.groupInfo && this.groupInfo.groups) { + for (let i = 0; i < this.groupInfo.groups.length; i++) { + const group = this.groupInfo.groups[i]; + if (groupId == group.id) { + this.selectedGroupName = group.name; + break; + } + } + } + + // Get the overview of retakes for the group. + return this.lessonProvider.getRetakesOverview(this.lesson.id, groupId).then((data) => { + const promises = []; + + // Format times and grades. + if (data && data.avetime != null && data.numofattempts) { + data.avetime = Math.floor(data.avetime / data.numofattempts); + data.avetimeReadable = this.timeUtils.formatTime(data.avetime); + } + + if (data && data.hightime != null) { + data.hightimeReadable = this.timeUtils.formatTime(data.hightime); + } + + if (data && data.lowtime != null) { + data.lowtimeReadable = this.timeUtils.formatTime(data.lowtime); + } + + if (data && data.lessonscored) { + if (data.numofattempts) { + data.avescore = this.textUtils.roundToDecimals(data.avescore, 2); + } + if (data.highscore != null) { + data.highscore = this.textUtils.roundToDecimals(data.highscore, 2); + } + if (data.lowscore != null) { + data.lowscore = this.textUtils.roundToDecimals(data.lowscore, 2); + } + } + + if (data && data.students) { + // Get the user data for each student returned. + data.students.forEach((student) => { + student.bestgrade = this.textUtils.roundToDecimals(student.bestgrade, 2); + + promises.push(this.userProvider.getProfile(student.id, this.courseId, true).then((user) => { + student.profileimageurl = user.profileimageurl; + }).catch(() => { + // Error getting profile, resolve promise without adding any extra data. + })); + }); + } + + return this.utils.allPromises(promises).catch(() => { + // Shouldn't happen. + }).then(() => { + this.overview = data; + }); + }); + } + + /** + * Displays some data based on the current status. + * + * @param {string} status The current status. + * @param {string} [previousStatus] The previous status. If not defined, there is no previous status. + */ + protected showStatus(status: string, previousStatus?: string): void { + this.showSpinner = status == CoreConstants.DOWNLOADING; + } + + /** + * Start the lesson. + * + * @param {boolean} [continueLast] Whether to continue the last attempt. + */ + start(continueLast?: boolean): void { + if (this.showSpinner) { + // Lesson is being downloaded, abort. + return; + } + + if (this.lessonProvider.isLessonOffline(this.lesson)) { + // Lesson supports offline, check if it needs to be downloaded. + if (this.currentStatus != CoreConstants.DOWNLOADED) { + // Prefetch the lesson. + this.showSpinner = true; + + this.prefetchHandler.prefetch(this.module, this.courseId, true).then(() => { + // Success downloading, open lesson. + this.playLesson(continueLast); + }).catch((error) => { + if (this.hasOffline) { + // Error downloading but there is something offline, allow continuing it. + this.playLesson(continueLast); + } else { + this.domUtils.showErrorModalDefault(error, 'core.errordownloading', true); + } + }).finally(() => { + this.showSpinner = false; + }); + } else { + // Already downloaded, open it. + this.playLesson(continueLast); + } + } else { + this.playLesson(continueLast); + } + } + + /** + * Submit password for password protected lessons. + * + * @param {HTMLInputElement} passwordEl The password input. + */ + submitPassword(passwordEl: HTMLInputElement): void { + const password = passwordEl && passwordEl.value; + if (!password) { + this.domUtils.showErrorModal('addon.mod_lesson.emptypassword', true); + + return; + } + + this.loaded = false; + this.refreshIcon = 'spinner'; + this.syncIcon = 'spinner'; + + this.validatePassword(password).then(() => { + // Password validated. + this.lessonReady(false); + + // Log view now that we have the password. + this.logView(); + }).catch((error) => { + this.domUtils.showErrorModal(error); + }).finally(() => { + this.loaded = true; + this.refreshIcon = 'refresh'; + this.syncIcon = 'sync'; + }); + } + + /** + * Performs the sync of the activity. + * + * @return {Promise} Promise resolved when done. + */ + protected sync(): Promise { + return this.lessonSync.syncLesson(this.lesson.id, true); + } + + /** + * Validate a password and retrieve extra data. + * + * @param {string} password The password to validate. + * @return {Promise} Promise resolved when done. + */ + protected validatePassword(password: string): Promise { + return this.lessonProvider.getLessonWithPassword(this.lesson.id, password).then((lessonData) => { + this.lesson = lessonData; + this.password = password; + }).catch((error) => { + this.password = ''; + + return Promise.reject(error); + }); + } +} diff --git a/src/addon/mod/lesson/pages/index/index.html b/src/addon/mod/lesson/pages/index/index.html new file mode 100644 index 000000000..80022b30e --- /dev/null +++ b/src/addon/mod/lesson/pages/index/index.html @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/src/addon/mod/lesson/pages/index/index.module.ts b/src/addon/mod/lesson/pages/index/index.module.ts new file mode 100644 index 000000000..890814b05 --- /dev/null +++ b/src/addon/mod/lesson/pages/index/index.module.ts @@ -0,0 +1,33 @@ +// (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 { IonicPageModule } from 'ionic-angular'; +import { TranslateModule } from '@ngx-translate/core'; +import { CoreDirectivesModule } from '@directives/directives.module'; +import { AddonModLessonComponentsModule } from '../../components/components.module'; +import { AddonModLessonIndexPage } from './index'; + +@NgModule({ + declarations: [ + AddonModLessonIndexPage, + ], + imports: [ + CoreDirectivesModule, + AddonModLessonComponentsModule, + IonicPageModule.forChild(AddonModLessonIndexPage), + TranslateModule.forChild() + ], +}) +export class AddonModLessonIndexPageModule {} diff --git a/src/addon/mod/lesson/pages/index/index.ts b/src/addon/mod/lesson/pages/index/index.ts new file mode 100644 index 000000000..838cbe8a3 --- /dev/null +++ b/src/addon/mod/lesson/pages/index/index.ts @@ -0,0 +1,66 @@ +// (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, ViewChild } from '@angular/core'; +import { IonicPage, NavParams } from 'ionic-angular'; +import { AddonModLessonIndexComponent } from '../../components/index/index'; + +/** + * Page that displays the lesson entry page. + */ +@IonicPage({ segment: 'addon-mod-lesson-index' }) +@Component({ + selector: 'page-addon-mod-lesson-index', + templateUrl: 'index.html', +}) +export class AddonModLessonIndexPage { + @ViewChild(AddonModLessonIndexComponent) lessonComponent: AddonModLessonIndexComponent; + + title: string; + module: any; + courseId: number; + group: number; // The group to display. + action: string; // The "action" to display first. + + constructor(navParams: NavParams) { + this.module = navParams.get('module') || {}; + this.courseId = navParams.get('courseId'); + this.group = navParams.get('group'); + this.action = navParams.get('action'); + this.title = this.module.name; + } + + /** + * Update some data based on the lesson instance. + * + * @param {any} lesson Lesson instance. + */ + updateData(lesson: any): void { + this.title = lesson.name || this.title; + } + + /** + * User entered the page. + */ + ionViewDidEnter(): void { + this.lessonComponent.ionViewDidEnter(); + } + + /** + * User left the page. + */ + ionViewDidLeave(): void { + this.lessonComponent.ionViewDidLeave(); + } +}