MOBILE-4616 scorm: Move scorm constants to a file
parent
c2caa15175
commit
c0856c0c97
|
@ -19,10 +19,16 @@ import {
|
||||||
AddonModScormCommonEventData,
|
AddonModScormCommonEventData,
|
||||||
AddonModScormDataEntry,
|
AddonModScormDataEntry,
|
||||||
AddonModScormDataValue,
|
AddonModScormDataValue,
|
||||||
AddonModScormProvider,
|
|
||||||
AddonModScormScorm,
|
AddonModScormScorm,
|
||||||
AddonModScormUserDataMap,
|
AddonModScormUserDataMap,
|
||||||
} from '../services/scorm';
|
} from '../services/scorm';
|
||||||
|
import {
|
||||||
|
ADDON_MOD_SCORM_UPDATE_TOC_EVENT,
|
||||||
|
ADDON_MOD_SCORM_LAUNCH_NEXT_SCO_EVENT,
|
||||||
|
ADDON_MOD_SCORM_LAUNCH_PREV_SCO_EVENT,
|
||||||
|
ADDON_MOD_SCORM_GO_OFFLINE_EVENT,
|
||||||
|
AddonModScormMode,
|
||||||
|
} from '../constants';
|
||||||
|
|
||||||
// Standard Data Type Definition.
|
// Standard Data Type Definition.
|
||||||
let CMI_STRING_256 = '^[\\u0000-\\uFFFF]{0,255}$';
|
let CMI_STRING_256 = '^[\\u0000-\\uFFFF]{0,255}$';
|
||||||
|
@ -110,7 +116,7 @@ export class AddonModScormDataModel12 {
|
||||||
protected scoId: number,
|
protected scoId: number,
|
||||||
protected attempt: number,
|
protected attempt: number,
|
||||||
protected userData: AddonModScormUserDataMap,
|
protected userData: AddonModScormUserDataMap,
|
||||||
protected mode = AddonModScormProvider.MODENORMAL,
|
protected mode = AddonModScormMode.NORMAL,
|
||||||
protected offline = false,
|
protected offline = false,
|
||||||
protected canSaveTracks = true,
|
protected canSaveTracks = true,
|
||||||
) {
|
) {
|
||||||
|
@ -595,7 +601,7 @@ export class AddonModScormDataModel12 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define mode and credit.
|
// Define mode and credit.
|
||||||
this.currentUserData[scoId].userdata['cmi.core.credit'] = this.mode == AddonModScormProvider.MODENORMAL ?
|
this.currentUserData[scoId].userdata['cmi.core.credit'] = this.mode === AddonModScormMode.NORMAL ?
|
||||||
'credit' :
|
'credit' :
|
||||||
'no-credit';
|
'no-credit';
|
||||||
this.currentUserData[scoId].userdata['cmi.core.lesson_mode'] = this.mode;
|
this.currentUserData[scoId].userdata['cmi.core.lesson_mode'] = this.mode;
|
||||||
|
@ -620,7 +626,7 @@ export class AddonModScormDataModel12 {
|
||||||
const result = this.storeData(false);
|
const result = this.storeData(false);
|
||||||
|
|
||||||
// Trigger TOC update.
|
// Trigger TOC update.
|
||||||
this.triggerEvent(AddonModScormProvider.UPDATE_TOC_EVENT);
|
this.triggerEvent(ADDON_MOD_SCORM_UPDATE_TOC_EVENT);
|
||||||
|
|
||||||
this.errorCode = result ? '0' : '101';
|
this.errorCode = result ? '0' : '101';
|
||||||
|
|
||||||
|
@ -652,20 +658,20 @@ export class AddonModScormDataModel12 {
|
||||||
const result = this.storeData(true);
|
const result = this.storeData(true);
|
||||||
if (this.getEl('nav.event') != '') {
|
if (this.getEl('nav.event') != '') {
|
||||||
if (this.getEl('nav.event') == 'continue') {
|
if (this.getEl('nav.event') == 'continue') {
|
||||||
this.triggerEvent(AddonModScormProvider.LAUNCH_NEXT_SCO_EVENT);
|
this.triggerEvent(ADDON_MOD_SCORM_LAUNCH_NEXT_SCO_EVENT);
|
||||||
} else {
|
} else {
|
||||||
this.triggerEvent(AddonModScormProvider.LAUNCH_PREV_SCO_EVENT);
|
this.triggerEvent(ADDON_MOD_SCORM_LAUNCH_PREV_SCO_EVENT);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.scorm.auto) {
|
if (this.scorm.auto) {
|
||||||
this.triggerEvent(AddonModScormProvider.LAUNCH_NEXT_SCO_EVENT);
|
this.triggerEvent(ADDON_MOD_SCORM_LAUNCH_NEXT_SCO_EVENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.errorCode = result ? '0' : '101';
|
this.errorCode = result ? '0' : '101';
|
||||||
|
|
||||||
// Trigger TOC update.
|
// Trigger TOC update.
|
||||||
this.triggerEvent(AddonModScormProvider.UPDATE_TOC_EVENT);
|
this.triggerEvent(ADDON_MOD_SCORM_UPDATE_TOC_EVENT);
|
||||||
|
|
||||||
// Conver to string representing a boolean.
|
// Conver to string representing a boolean.
|
||||||
return result ? 'true' : 'false';
|
return result ? 'true' : 'false';
|
||||||
|
@ -986,8 +992,8 @@ export class AddonModScormDataModel12 {
|
||||||
this.setEl('cmi.core.lesson_status', 'completed');
|
this.setEl('cmi.core.lesson_status', 'completed');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.getEl('cmi.core.lesson_mode') == AddonModScormProvider.MODENORMAL) {
|
if (this.getEl('cmi.core.lesson_mode') === AddonModScormMode.NORMAL) {
|
||||||
if (this.getEl('cmi.core.credit') == 'credit') {
|
if (this.getEl('cmi.core.credit') === 'credit') {
|
||||||
if (this.getEl('cmi.student_data.mastery_score') !== '' && this.getEl('cmi.core.score.raw') !== '') {
|
if (this.getEl('cmi.student_data.mastery_score') !== '' && this.getEl('cmi.core.score.raw') !== '') {
|
||||||
if (parseFloat(<string> this.getEl('cmi.core.score.raw')) >=
|
if (parseFloat(<string> this.getEl('cmi.core.score.raw')) >=
|
||||||
parseFloat(<string> this.getEl('cmi.student_data.mastery_score'))) {
|
parseFloat(<string> this.getEl('cmi.student_data.mastery_score'))) {
|
||||||
|
@ -999,7 +1005,7 @@ export class AddonModScormDataModel12 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.getEl('cmi.core.lesson_mode') == AddonModScormProvider.MODEBROWSE) {
|
if (this.getEl('cmi.core.lesson_mode') === AddonModScormMode.BROWSE) {
|
||||||
if (this.dataModel[this.scoId]['cmi.core.lesson_status'].defaultvalue == '' &&
|
if (this.dataModel[this.scoId]['cmi.core.lesson_status'].defaultvalue == '' &&
|
||||||
this.getEl('cmi.core.lesson_status') == 'not attempted') {
|
this.getEl('cmi.core.lesson_status') == 'not attempted') {
|
||||||
this.setEl('cmi.core.lesson_status', 'browsed');
|
this.setEl('cmi.core.lesson_status', 'browsed');
|
||||||
|
@ -1020,7 +1026,7 @@ export class AddonModScormDataModel12 {
|
||||||
|
|
||||||
// Failure storing data in online. Go offline.
|
// Failure storing data in online. Go offline.
|
||||||
this.offline = true;
|
this.offline = true;
|
||||||
this.triggerEvent(AddonModScormProvider.GO_OFFLINE_EVENT);
|
this.triggerEvent(ADDON_MOD_SCORM_GO_OFFLINE_EVENT);
|
||||||
|
|
||||||
return AddonModScorm.saveTracksSync(this.scoId, this.attempt, tracks, this.scorm, this.offline, this.currentUserData);
|
return AddonModScorm.saveTracksSync(this.scoId, this.attempt, tracks, this.scorm, this.offline, this.currentUserData);
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@ import { CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||||
import { AddonModScormModuleHandlerService } from '../../services/handlers/module';
|
|
||||||
import { AddonModScormPrefetchHandler } from '../../services/handlers/prefetch';
|
import { AddonModScormPrefetchHandler } from '../../services/handlers/prefetch';
|
||||||
import {
|
import {
|
||||||
AddonModScorm,
|
AddonModScorm,
|
||||||
|
@ -33,16 +32,23 @@ import {
|
||||||
AddonModScormGetScormAccessInformationWSResponse,
|
AddonModScormGetScormAccessInformationWSResponse,
|
||||||
AddonModScormAttemptGrade,
|
AddonModScormAttemptGrade,
|
||||||
AddonModScormOrganization,
|
AddonModScormOrganization,
|
||||||
AddonModScormProvider,
|
|
||||||
AddonModScormScorm,
|
AddonModScormScorm,
|
||||||
} from '../../services/scorm';
|
} from '../../services/scorm';
|
||||||
import { AddonModScormHelper, AddonModScormTOCScoWithIcon } from '../../services/scorm-helper';
|
import { AddonModScormHelper, AddonModScormTOCScoWithIcon } from '../../services/scorm-helper';
|
||||||
import {
|
import {
|
||||||
AddonModScormAutoSyncEventData,
|
AddonModScormAutoSyncEventData,
|
||||||
AddonModScormSync,
|
AddonModScormSync,
|
||||||
AddonModScormSyncProvider,
|
|
||||||
AddonModScormSyncResult,
|
AddonModScormSyncResult,
|
||||||
} from '../../services/scorm-sync';
|
} from '../../services/scorm-sync';
|
||||||
|
import {
|
||||||
|
ADDON_MOD_SCORM_COMPONENT,
|
||||||
|
AddonModScormForceAttempt,
|
||||||
|
AddonModScormMode,
|
||||||
|
AddonModScormSkipView,
|
||||||
|
ADDON_MOD_SCORM_DATA_SENT_EVENT,
|
||||||
|
ADDON_MOD_SCORM_DATA_AUTO_SYNCED,
|
||||||
|
ADDON_MOD_SCORM_PAGE_NAME,
|
||||||
|
} from '../../constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that displays a SCORM entry page.
|
* Component that displays a SCORM entry page.
|
||||||
|
@ -56,7 +62,7 @@ export class AddonModScormIndexComponent extends CoreCourseModuleMainActivityCom
|
||||||
|
|
||||||
@Input() autoPlayData?: AddonModScormAutoPlayData; // Data to use to play the SCORM automatically.
|
@Input() autoPlayData?: AddonModScormAutoPlayData; // Data to use to play the SCORM automatically.
|
||||||
|
|
||||||
component = AddonModScormProvider.COMPONENT;
|
component = ADDON_MOD_SCORM_COMPONENT;
|
||||||
pluginName = 'scorm';
|
pluginName = 'scorm';
|
||||||
|
|
||||||
scorm?: AddonModScormScorm; // The SCORM object.
|
scorm?: AddonModScormScorm; // The SCORM object.
|
||||||
|
@ -90,7 +96,7 @@ export class AddonModScormIndexComponent extends CoreCourseModuleMainActivityCom
|
||||||
gradesExpanded = false;
|
gradesExpanded = false;
|
||||||
|
|
||||||
protected fetchContentDefaultError = 'addon.mod_scorm.errorgetscorm'; // Default error to show when loading contents.
|
protected fetchContentDefaultError = 'addon.mod_scorm.errorgetscorm'; // Default error to show when loading contents.
|
||||||
protected syncEventName = AddonModScormSyncProvider.AUTO_SYNCED;
|
protected syncEventName = ADDON_MOD_SCORM_DATA_AUTO_SYNCED;
|
||||||
protected attempts?: AddonModScormAttemptCountResult; // Data about online and offline attempts.
|
protected attempts?: AddonModScormAttemptCountResult; // Data about online and offline attempts.
|
||||||
protected lastAttempt?: number; // Last attempt.
|
protected lastAttempt?: number; // Last attempt.
|
||||||
protected lastIsOffline = false; // Whether the last attempt is offline.
|
protected lastIsOffline = false; // Whether the last attempt is offline.
|
||||||
|
@ -201,8 +207,8 @@ export class AddonModScormIndexComponent extends CoreCourseModuleMainActivityCom
|
||||||
||
|
||
|
||||||
(
|
(
|
||||||
this.accessInfo.canskipview && !this.accessInfo.canviewreport &&
|
this.accessInfo.canskipview && !this.accessInfo.canviewreport &&
|
||||||
(this.scorm.skipview ?? 0) >= AddonModScormProvider.SKIPVIEW_FIRST &&
|
(this.scorm.skipview ?? 0) >= AddonModScormSkipView.FIRST &&
|
||||||
(this.scorm.skipview === AddonModScormProvider.SKIPVIEW_ALWAYS || this.lastAttempt === 0)
|
(this.scorm.skipview === AddonModScormSkipView.ALWAYS || this.lastAttempt === 0)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -241,7 +247,7 @@ export class AddonModScormIndexComponent extends CoreCourseModuleMainActivityCom
|
||||||
this.gradeMethodReadable = AddonModScorm.getScormGradeMethod(scorm);
|
this.gradeMethodReadable = AddonModScorm.getScormGradeMethod(scorm);
|
||||||
this.attemptsLeft = AddonModScorm.countAttemptsLeft(scorm, this.attempts.lastAttempt.num);
|
this.attemptsLeft = AddonModScorm.countAttemptsLeft(scorm, this.attempts.lastAttempt.num);
|
||||||
|
|
||||||
if (scorm.forcenewattempt === AddonModScormProvider.SCORM_FORCEATTEMPT_ALWAYS ||
|
if (scorm.forcenewattempt === AddonModScormForceAttempt.ALWAYS ||
|
||||||
(scorm.forcenewattempt && !this.incomplete)) {
|
(scorm.forcenewattempt && !this.incomplete)) {
|
||||||
this.startNewAttempt = true;
|
this.startNewAttempt = true;
|
||||||
}
|
}
|
||||||
|
@ -550,7 +556,7 @@ export class AddonModScormIndexComponent extends CoreCourseModuleMainActivityCom
|
||||||
// Detect if anything was sent to server.
|
// Detect if anything was sent to server.
|
||||||
this.dataSentObserver?.off();
|
this.dataSentObserver?.off();
|
||||||
|
|
||||||
this.dataSentObserver = CoreEvents.on(AddonModScormProvider.DATA_SENT_EVENT, (data) => {
|
this.dataSentObserver = CoreEvents.on(ADDON_MOD_SCORM_DATA_SENT_EVENT, (data) => {
|
||||||
if (data.scormId === this.scorm?.id) {
|
if (data.scormId === this.scorm?.id) {
|
||||||
this.dataSent = true;
|
this.dataSent = true;
|
||||||
|
|
||||||
|
@ -562,10 +568,10 @@ export class AddonModScormIndexComponent extends CoreCourseModuleMainActivityCom
|
||||||
}, this.siteId);
|
}, this.siteId);
|
||||||
|
|
||||||
CoreNavigator.navigateToSitePath(
|
CoreNavigator.navigateToSitePath(
|
||||||
`${AddonModScormModuleHandlerService.PAGE_NAME}/${this.courseId}/${this.module.id}/player`,
|
`${ADDON_MOD_SCORM_PAGE_NAME}/${this.courseId}/${this.module.id}/player`,
|
||||||
{
|
{
|
||||||
params: {
|
params: {
|
||||||
mode: autoPlayData?.mode ?? (preview ? AddonModScormProvider.MODEBROWSE : AddonModScormProvider.MODENORMAL),
|
mode: autoPlayData?.mode ?? (preview ? AddonModScormMode.BROWSE : AddonModScormMode.NORMAL),
|
||||||
moduleUrl: this.module.url,
|
moduleUrl: this.module.url,
|
||||||
newAttempt: autoPlayData?.newAttempt ?? this.startNewAttempt,
|
newAttempt: autoPlayData?.newAttempt ?? this.startNewAttempt,
|
||||||
organizationId: autoPlayData?.organizationId ?? this.currentOrganization.identifier,
|
organizationId: autoPlayData?.organizationId ?? this.currentOrganization.identifier,
|
||||||
|
@ -608,7 +614,7 @@ export class AddonModScormIndexComponent extends CoreCourseModuleMainActivityCom
|
||||||
throw new CoreError('Cannot sync without a scorm.');
|
throw new CoreError('Cannot sync without a scorm.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CoreSync.isBlocked(AddonModScormProvider.COMPONENT, this.scorm.id) && retries < 5) {
|
if (CoreSync.isBlocked(ADDON_MOD_SCORM_COMPONENT, this.scorm.id) && retries < 5) {
|
||||||
// Sync is currently blocked, this can happen when SCORM player is left. Retry in a bit.
|
// Sync is currently blocked, this can happen when SCORM player is left. Retry in a bit.
|
||||||
await CoreUtils.wait(400);
|
await CoreUtils.wait(400);
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,9 @@
|
||||||
|
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { ModalController } from '@singletons';
|
import { ModalController } from '@singletons';
|
||||||
import { AddonModScormGetScormAccessInformationWSResponse, AddonModScormProvider } from '../../services/scorm';
|
import { AddonModScormGetScormAccessInformationWSResponse } from '../../services/scorm';
|
||||||
import { AddonModScormTOCScoWithIcon } from '../../services/scorm-helper';
|
import { AddonModScormTOCScoWithIcon } from '../../services/scorm-helper';
|
||||||
|
import { AddonModScormMode } from '../../constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modal to display the TOC of a SCORM.
|
* Modal to display the TOC of a SCORM.
|
||||||
|
@ -41,8 +42,8 @@ export class AddonModScormTocComponent implements OnInit {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.isBrowse = this.mode === AddonModScormProvider.MODEBROWSE;
|
this.isBrowse = this.mode === AddonModScormMode.BROWSE;
|
||||||
this.isReview = this.mode === AddonModScormProvider.MODEREVIEW;
|
this.isReview = this.mode === AddonModScormMode.REVIEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
export const ADDON_MOD_SCORM_COMPONENT = 'mmaModScorm';
|
||||||
|
export const ADDON_MOD_SCORM_PAGE_NAME = 'mod_scorm';
|
||||||
|
|
||||||
|
// Public constants.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grading method.
|
||||||
|
* The grading method defines how the grade for a single attempt of the activity is determined.
|
||||||
|
*/
|
||||||
|
export const enum AddonModScormGradingMethod {
|
||||||
|
GRADESCOES = 0,
|
||||||
|
GRADEHIGHEST = 1,
|
||||||
|
GRADEAVERAGE = 2,
|
||||||
|
GRADESUM = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts grading methods.
|
||||||
|
* If multiple attempts are allowed, this setting specifies whether the highest, average (mean), first or last completed attempt
|
||||||
|
* is recorded in the gradebook.
|
||||||
|
*/
|
||||||
|
export const enum AddonModScormAttemptsGradingMethod {
|
||||||
|
HIGHESTATTEMPT = 0,
|
||||||
|
AVERAGEATTEMPT = 1,
|
||||||
|
FIRSTATTEMPT = 2,
|
||||||
|
LASTATTEMPT = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const enum AddonModScormMode {
|
||||||
|
BROWSE = 'browse',
|
||||||
|
NORMAL = 'normal',
|
||||||
|
REVIEW = 'review',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const enum AddonModScormForceAttempt {
|
||||||
|
NO = 0,
|
||||||
|
ONCOMPLETE = 1,
|
||||||
|
ALWAYS = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const enum AddonModScormSkipView {
|
||||||
|
NEVER = 0,
|
||||||
|
FIRST = 1,
|
||||||
|
ALWAYS = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Events.
|
||||||
|
export const ADDON_MOD_SCORM_LAUNCH_NEXT_SCO_EVENT = 'addon_mod_scorm_launch_next_sco';
|
||||||
|
export const ADDON_MOD_SCORM_LAUNCH_PREV_SCO_EVENT = 'addon_mod_scorm_launch_prev_sco';
|
||||||
|
export const ADDON_MOD_SCORM_UPDATE_TOC_EVENT = 'addon_mod_scorm_update_toc';
|
||||||
|
export const ADDON_MOD_SCORM_GO_OFFLINE_EVENT = 'addon_mod_scorm_go_offline';
|
||||||
|
export const ADDON_MOD_SCORM_DATA_SENT_EVENT = 'addon_mod_scorm_data_sent';
|
||||||
|
export const ADDON_MOD_SCORM_DATA_AUTO_SYNCED = 'addon_mod_scorm_autom_synced';
|
|
@ -28,7 +28,6 @@ import {
|
||||||
AddonModScorm,
|
AddonModScorm,
|
||||||
AddonModScormAttemptCountResult,
|
AddonModScormAttemptCountResult,
|
||||||
AddonModScormGetScormAccessInformationWSResponse,
|
AddonModScormGetScormAccessInformationWSResponse,
|
||||||
AddonModScormProvider,
|
|
||||||
AddonModScormScorm,
|
AddonModScormScorm,
|
||||||
AddonModScormScoWithData,
|
AddonModScormScoWithData,
|
||||||
AddonModScormUserDataMap,
|
AddonModScormUserDataMap,
|
||||||
|
@ -36,6 +35,14 @@ import {
|
||||||
import { AddonModScormHelper, AddonModScormTOCScoWithIcon } from '../../services/scorm-helper';
|
import { AddonModScormHelper, AddonModScormTOCScoWithIcon } from '../../services/scorm-helper';
|
||||||
import { AddonModScormSync } from '../../services/scorm-sync';
|
import { AddonModScormSync } from '../../services/scorm-sync';
|
||||||
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
|
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
|
||||||
|
import {
|
||||||
|
ADDON_MOD_SCORM_COMPONENT,
|
||||||
|
AddonModScormMode,
|
||||||
|
ADDON_MOD_SCORM_GO_OFFLINE_EVENT,
|
||||||
|
ADDON_MOD_SCORM_LAUNCH_NEXT_SCO_EVENT,
|
||||||
|
ADDON_MOD_SCORM_LAUNCH_PREV_SCO_EVENT,
|
||||||
|
ADDON_MOD_SCORM_UPDATE_TOC_EVENT,
|
||||||
|
} from '../../constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page that allows playing a SCORM.
|
* Page that allows playing a SCORM.
|
||||||
|
@ -63,7 +70,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
navigationItems: CoreNavigationBarItem<AddonModScormTOCScoWithIcon>[] = [];
|
navigationItems: CoreNavigationBarItem<AddonModScormTOCScoWithIcon>[] = [];
|
||||||
|
|
||||||
protected siteId!: string;
|
protected siteId!: string;
|
||||||
protected mode!: string; // Mode to play the SCORM.
|
protected mode!: AddonModScormMode; // Mode to play the SCORM.
|
||||||
protected moduleUrl!: string; // Module URL.
|
protected moduleUrl!: string; // Module URL.
|
||||||
protected newAttempt = false; // Whether to start a new attempt.
|
protected newAttempt = false; // Whether to start a new attempt.
|
||||||
protected organizationId?: string; // Organization ID to load.
|
protected organizationId?: string; // Organization ID to load.
|
||||||
|
@ -92,7 +99,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
try {
|
try {
|
||||||
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
|
||||||
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
|
||||||
this.mode = CoreNavigator.getRouteParam('mode') || AddonModScormProvider.MODENORMAL;
|
this.mode = CoreNavigator.getRouteParam('mode') || AddonModScormMode.NORMAL;
|
||||||
this.moduleUrl = CoreNavigator.getRouteParam('moduleUrl') || '';
|
this.moduleUrl = CoreNavigator.getRouteParam('moduleUrl') || '';
|
||||||
this.newAttempt = !!CoreNavigator.getRouteBooleanParam('newAttempt');
|
this.newAttempt = !!CoreNavigator.getRouteBooleanParam('newAttempt');
|
||||||
this.organizationId = CoreNavigator.getRouteParam('organizationId');
|
this.organizationId = CoreNavigator.getRouteParam('organizationId');
|
||||||
|
@ -150,7 +157,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Block the SCORM so it cannot be synchronized.
|
// Block the SCORM so it cannot be synchronized.
|
||||||
CoreSync.blockOperation(AddonModScormProvider.COMPONENT, this.scorm.id, 'player');
|
CoreSync.blockOperation(ADDON_MOD_SCORM_COMPONENT, this.scorm.id, 'player');
|
||||||
|
|
||||||
// We use SCORM name at start, later we'll use the SCO title.
|
// We use SCORM name at start, later we'll use the SCO title.
|
||||||
this.title = this.scorm.name;
|
this.title = this.scorm.name;
|
||||||
|
@ -169,7 +176,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen for events to update the TOC, navigate through SCOs and go offline.
|
// Listen for events to update the TOC, navigate through SCOs and go offline.
|
||||||
this.tocObserver = CoreEvents.on(AddonModScormProvider.UPDATE_TOC_EVENT, (data) => {
|
this.tocObserver = CoreEvents.on(ADDON_MOD_SCORM_UPDATE_TOC_EVENT, (data) => {
|
||||||
if (data.scormId !== this.scorm.id) {
|
if (data.scormId !== this.scorm.id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -182,7 +189,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
}, this.siteId);
|
}, this.siteId);
|
||||||
|
|
||||||
this.launchNextObserver = CoreEvents.on(AddonModScormProvider.LAUNCH_NEXT_SCO_EVENT, (data) => {
|
this.launchNextObserver = CoreEvents.on(ADDON_MOD_SCORM_LAUNCH_NEXT_SCO_EVENT, (data) => {
|
||||||
if (data.scormId === this.scorm.id && this.currentSco) {
|
if (data.scormId === this.scorm.id && this.currentSco) {
|
||||||
const nextSco = AddonModScormHelper.getNextScoFromToc(this.toc, this.currentSco.id);
|
const nextSco = AddonModScormHelper.getNextScoFromToc(this.toc, this.currentSco.id);
|
||||||
if (nextSco) {
|
if (nextSco) {
|
||||||
|
@ -191,7 +198,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
}, this.siteId);
|
}, this.siteId);
|
||||||
|
|
||||||
this.launchPrevObserver = CoreEvents.on(AddonModScormProvider.LAUNCH_PREV_SCO_EVENT, (data) => {
|
this.launchPrevObserver = CoreEvents.on(ADDON_MOD_SCORM_LAUNCH_PREV_SCO_EVENT, (data) => {
|
||||||
if (data.scormId === this.scorm.id && this.currentSco) {
|
if (data.scormId === this.scorm.id && this.currentSco) {
|
||||||
const previousSco = AddonModScormHelper.getPreviousScoFromToc(this.toc, this.currentSco.id);
|
const previousSco = AddonModScormHelper.getPreviousScoFromToc(this.toc, this.currentSco.id);
|
||||||
if (previousSco) {
|
if (previousSco) {
|
||||||
|
@ -200,7 +207,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
}, this.siteId);
|
}, this.siteId);
|
||||||
|
|
||||||
this.goOfflineObserver = CoreEvents.on(AddonModScormProvider.GO_OFFLINE_EVENT, (data) => {
|
this.goOfflineObserver = CoreEvents.on(ADDON_MOD_SCORM_GO_OFFLINE_EVENT, (data) => {
|
||||||
if (data.scormId !== this.scorm.id || this.offline) {
|
if (data.scormId !== this.scorm.id || this.offline) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -605,7 +612,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
// Unblock the SCORM so it can be synced.
|
// Unblock the SCORM so it can be synced.
|
||||||
CoreSync.unblockOperation(AddonModScormProvider.COMPONENT, this.scorm.id, 'player');
|
CoreSync.unblockOperation(ADDON_MOD_SCORM_COMPONENT, this.scorm.id, 'player');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,4 +42,4 @@ const routes: Routes = [
|
||||||
AddonModScormPlayerPage,
|
AddonModScormPlayerPage,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class AddonModScormLazyModule {}
|
export default class AddonModScormLazyModule {}
|
||||||
|
|
|
@ -26,17 +26,17 @@ import { OFFLINE_SITE_SCHEMA } from './services/database/scorm';
|
||||||
import { AddonModScormGradeLinkHandler } from './services/handlers/grade-link';
|
import { AddonModScormGradeLinkHandler } from './services/handlers/grade-link';
|
||||||
import { AddonModScormIndexLinkHandler } from './services/handlers/index-link';
|
import { AddonModScormIndexLinkHandler } from './services/handlers/index-link';
|
||||||
import { AddonModScormListLinkHandler } from './services/handlers/list-link';
|
import { AddonModScormListLinkHandler } from './services/handlers/list-link';
|
||||||
import { AddonModScormModuleHandler, AddonModScormModuleHandlerService } from './services/handlers/module';
|
import { AddonModScormModuleHandler } from './services/handlers/module';
|
||||||
import { AddonModScormPlayerLinkHandler } from './services/handlers/player-link';
|
import { AddonModScormPlayerLinkHandler } from './services/handlers/player-link';
|
||||||
import { AddonModScormPluginFileHandler } from './services/handlers/pluginfile';
|
import { AddonModScormPluginFileHandler } from './services/handlers/pluginfile';
|
||||||
import { AddonModScormPrefetchHandler } from './services/handlers/prefetch';
|
import { AddonModScormPrefetchHandler } from './services/handlers/prefetch';
|
||||||
import { AddonModScormSyncCronHandler } from './services/handlers/sync-cron';
|
import { AddonModScormSyncCronHandler } from './services/handlers/sync-cron';
|
||||||
import { AddonModScormProvider } from './services/scorm';
|
import { ADDON_MOD_SCORM_COMPONENT, ADDON_MOD_SCORM_PAGE_NAME } from './constants';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: AddonModScormModuleHandlerService.PAGE_NAME,
|
path: ADDON_MOD_SCORM_PAGE_NAME,
|
||||||
loadChildren: () => import('./scorm-lazy.module').then(m => m.AddonModScormLazyModule),
|
loadChildren: () => import('./scorm-lazy.module'),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ const routes: Routes = [
|
||||||
CoreContentLinksDelegate.registerHandler(AddonModScormPlayerLinkHandler.instance);
|
CoreContentLinksDelegate.registerHandler(AddonModScormPlayerLinkHandler.instance);
|
||||||
CorePluginFileDelegate.registerHandler(AddonModScormPluginFileHandler.instance);
|
CorePluginFileDelegate.registerHandler(AddonModScormPluginFileHandler.instance);
|
||||||
|
|
||||||
CoreCourseHelper.registerModuleReminderClick(AddonModScormProvider.COMPONENT);
|
CoreCourseHelper.registerModuleReminderClick(ADDON_MOD_SCORM_COMPONENT);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { Injectable, Type } from '@angular/core';
|
||||||
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
|
import { ADDON_MOD_SCORM_PAGE_NAME } from '../../constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler to support SCORM modules.
|
* Handler to support SCORM modules.
|
||||||
|
@ -24,11 +25,9 @@ import { makeSingleton } from '@singletons';
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModScormModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
export class AddonModScormModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
static readonly PAGE_NAME = 'mod_scorm';
|
|
||||||
|
|
||||||
name = 'AddonModScorm';
|
name = 'AddonModScorm';
|
||||||
modName = 'scorm';
|
modName = 'scorm';
|
||||||
protected pageName = AddonModScormModuleHandlerService.PAGE_NAME;
|
protected pageName = ADDON_MOD_SCORM_PAGE_NAME;
|
||||||
|
|
||||||
supportedFeatures = {
|
supportedFeatures = {
|
||||||
[CoreConstants.FEATURE_GROUPS]: true,
|
[CoreConstants.FEATURE_GROUPS]: true,
|
||||||
|
|
|
@ -24,8 +24,9 @@ import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { CoreWSFile } from '@services/ws';
|
import { CoreWSFile } from '@services/ws';
|
||||||
import { makeSingleton, Translate } from '@singletons';
|
import { makeSingleton, Translate } from '@singletons';
|
||||||
import { AddonModScorm, AddonModScormProvider, AddonModScormScorm } from '../scorm';
|
import { AddonModScorm, AddonModScormScorm } from '../scorm';
|
||||||
import { AddonModScormSync } from '../scorm-sync';
|
import { AddonModScormSync } from '../scorm-sync';
|
||||||
|
import { ADDON_MOD_SCORM_COMPONENT } from '../../constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler to prefetch SCORMs.
|
* Handler to prefetch SCORMs.
|
||||||
|
@ -35,7 +36,7 @@ export class AddonModScormPrefetchHandlerService extends CoreCourseActivityPrefe
|
||||||
|
|
||||||
name = 'AddonModScorm';
|
name = 'AddonModScorm';
|
||||||
modName = 'scorm';
|
modName = 'scorm';
|
||||||
component = AddonModScormProvider.COMPONENT;
|
component = ADDON_MOD_SCORM_COMPONENT;
|
||||||
updatesNames = /^configuration$|^.*files$|^tracks$/;
|
updatesNames = /^configuration$|^.*files$|^tracks$/;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -25,7 +25,6 @@ import {
|
||||||
AddonModScormAttemptCountResult,
|
AddonModScormAttemptCountResult,
|
||||||
AddonModScormDataValue,
|
AddonModScormDataValue,
|
||||||
AddonModScormGetScosWithDataOptions,
|
AddonModScormGetScosWithDataOptions,
|
||||||
AddonModScormProvider,
|
|
||||||
AddonModScormScoIcon,
|
AddonModScormScoIcon,
|
||||||
AddonModScormScorm,
|
AddonModScormScorm,
|
||||||
AddonModScormScoWithData,
|
AddonModScormScoWithData,
|
||||||
|
@ -33,6 +32,7 @@ import {
|
||||||
AddonModScormUserDataMap,
|
AddonModScormUserDataMap,
|
||||||
} from './scorm';
|
} from './scorm';
|
||||||
import { AddonModScormOffline } from './scorm-offline';
|
import { AddonModScormOffline } from './scorm-offline';
|
||||||
|
import { AddonModScormMode } from '../constants';
|
||||||
|
|
||||||
// List of elements we want to ignore when copying attempts (they're calculated).
|
// List of elements we want to ignore when copying attempts (they're calculated).
|
||||||
const elementsToIgnore = [
|
const elementsToIgnore = [
|
||||||
|
@ -229,8 +229,8 @@ export class AddonModScormHelperProvider {
|
||||||
options: AddonModScormGetFirstScoOptions = {},
|
options: AddonModScormGetFirstScoOptions = {},
|
||||||
): Promise<AddonModScormScoWithData | undefined> {
|
): Promise<AddonModScormScoWithData | undefined> {
|
||||||
|
|
||||||
const mode = options.mode || AddonModScormProvider.MODENORMAL;
|
const mode = options.mode || AddonModScormMode.NORMAL;
|
||||||
const isNormalMode = mode === AddonModScormProvider.MODENORMAL;
|
const isNormalMode = mode === AddonModScormMode.NORMAL;
|
||||||
|
|
||||||
let scos = options.toc;
|
let scos = options.toc;
|
||||||
if (!scos || !scos.length) {
|
if (!scos || !scos.length) {
|
||||||
|
|
|
@ -35,7 +35,6 @@ import {
|
||||||
import {
|
import {
|
||||||
AddonModScormDataEntry,
|
AddonModScormDataEntry,
|
||||||
AddonModScormDataValue,
|
AddonModScormDataValue,
|
||||||
AddonModScormProvider,
|
|
||||||
AddonModScormScorm,
|
AddonModScormScorm,
|
||||||
AddonModScormScoUserData,
|
AddonModScormScoUserData,
|
||||||
AddonModScormUserDataMap,
|
AddonModScormUserDataMap,
|
||||||
|
@ -45,6 +44,7 @@ import { lazyMap, LazyMap } from '@/core/utils/lazy-map';
|
||||||
import { asyncInstance, AsyncInstance } from '@/core/utils/async-instance';
|
import { asyncInstance, AsyncInstance } from '@/core/utils/async-instance';
|
||||||
import { CoreDatabaseTable } from '@classes/database/database-table';
|
import { CoreDatabaseTable } from '@classes/database/database-table';
|
||||||
import { CoreDatabaseCachingStrategy } from '@classes/database/database-table-proxy';
|
import { CoreDatabaseCachingStrategy } from '@classes/database/database-table-proxy';
|
||||||
|
import { ADDON_MOD_SCORM_COMPONENT } from '../constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service to handle offline SCORM.
|
* Service to handle offline SCORM.
|
||||||
|
@ -120,7 +120,7 @@ export class AddonModScormOfflineProvider {
|
||||||
this.logger.debug(`Change attempt number from ${attempt} to ${newAttempt} in SCORM ${scormId}`);
|
this.logger.debug(`Change attempt number from ${attempt} to ${newAttempt} in SCORM ${scormId}`);
|
||||||
|
|
||||||
// Block the SCORM so it can't be synced.
|
// Block the SCORM so it can't be synced.
|
||||||
CoreSync.blockOperation(AddonModScormProvider.COMPONENT, scormId, 'changeAttemptNumber', site.id);
|
CoreSync.blockOperation(ADDON_MOD_SCORM_COMPONENT, scormId, 'changeAttemptNumber', site.id);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const currentAttemptConditions = {
|
const currentAttemptConditions = {
|
||||||
|
@ -161,7 +161,7 @@ export class AddonModScormOfflineProvider {
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
// Unblock the SCORM.
|
// Unblock the SCORM.
|
||||||
CoreSync.unblockOperation(AddonModScormProvider.COMPONENT, scormId, 'changeAttemptNumber', site.id);
|
CoreSync.unblockOperation(ADDON_MOD_SCORM_COMPONENT, scormId, 'changeAttemptNumber', site.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ export class AddonModScormOfflineProvider {
|
||||||
this.logger.debug(`Creating new offline attempt ${attempt} in SCORM ${scorm.id}`);
|
this.logger.debug(`Creating new offline attempt ${attempt} in SCORM ${scorm.id}`);
|
||||||
|
|
||||||
// Block the SCORM so it can't be synced.
|
// Block the SCORM so it can't be synced.
|
||||||
CoreSync.blockOperation(AddonModScormProvider.COMPONENT, scorm.id, 'createNewAttempt', site.id);
|
CoreSync.blockOperation(ADDON_MOD_SCORM_COMPONENT, scorm.id, 'createNewAttempt', site.id);
|
||||||
|
|
||||||
// Create attempt in DB.
|
// Create attempt in DB.
|
||||||
const entry: AddonModScormAttemptDBRecord = {
|
const entry: AddonModScormAttemptDBRecord = {
|
||||||
|
@ -230,7 +230,7 @@ export class AddonModScormOfflineProvider {
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
} finally {
|
} finally {
|
||||||
// Unblock the SCORM.
|
// Unblock the SCORM.
|
||||||
CoreSync.unblockOperation(AddonModScormProvider.COMPONENT, scorm.id, 'createNewAttempt', site.id);
|
CoreSync.unblockOperation(ADDON_MOD_SCORM_COMPONENT, scorm.id, 'createNewAttempt', site.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -872,7 +872,7 @@ export class AddonModScormOfflineProvider {
|
||||||
userId = userId || site.getUserId();
|
userId = userId || site.getUserId();
|
||||||
|
|
||||||
// Block the SCORM so it can't be synced.
|
// Block the SCORM so it can't be synced.
|
||||||
CoreSync.blockOperation(AddonModScormProvider.COMPONENT, scorm.id, 'saveTracksOffline', siteId);
|
CoreSync.blockOperation(ADDON_MOD_SCORM_COMPONENT, scorm.id, 'saveTracksOffline', siteId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Insert all the tracks.
|
// Insert all the tracks.
|
||||||
|
@ -889,7 +889,7 @@ export class AddonModScormOfflineProvider {
|
||||||
)));
|
)));
|
||||||
} finally {
|
} finally {
|
||||||
// Unblock the SCORM operation.
|
// Unblock the SCORM operation.
|
||||||
CoreSync.unblockOperation(AddonModScormProvider.COMPONENT, scorm.id, 'saveTracksOffline', siteId);
|
CoreSync.unblockOperation(ADDON_MOD_SCORM_COMPONENT, scorm.id, 'saveTracksOffline', siteId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,11 @@ import {
|
||||||
AddonModScorm,
|
AddonModScorm,
|
||||||
AddonModScormAttemptCountResult,
|
AddonModScormAttemptCountResult,
|
||||||
AddonModScormDataEntry,
|
AddonModScormDataEntry,
|
||||||
AddonModScormProvider,
|
|
||||||
AddonModScormScorm,
|
AddonModScormScorm,
|
||||||
AddonModScormUserDataMap,
|
AddonModScormUserDataMap,
|
||||||
} from './scorm';
|
} from './scorm';
|
||||||
import { AddonModScormOffline } from './scorm-offline';
|
import { AddonModScormOffline } from './scorm-offline';
|
||||||
|
import { ADDON_MOD_SCORM_COMPONENT, ADDON_MOD_SCORM_DATA_AUTO_SYNCED } from '../constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service to sync SCORMs.
|
* Service to sync SCORMs.
|
||||||
|
@ -39,8 +39,6 @@ import { AddonModScormOffline } from './scorm-offline';
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModScormSyncProvider extends CoreCourseActivitySyncBaseProvider<AddonModScormSyncResult> {
|
export class AddonModScormSyncProvider extends CoreCourseActivitySyncBaseProvider<AddonModScormSyncResult> {
|
||||||
|
|
||||||
static readonly AUTO_SYNCED = 'addon_mod_scorm_autom_synced';
|
|
||||||
|
|
||||||
protected componentTranslatableString = 'scorm';
|
protected componentTranslatableString = 'scorm';
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -464,7 +462,7 @@ export class AddonModScormSyncProvider extends CoreCourseActivitySyncBaseProvide
|
||||||
|
|
||||||
// Sync all SCORMs that haven't been synced for a while and that aren't attempted right now.
|
// Sync all SCORMs that haven't been synced for a while and that aren't attempted right now.
|
||||||
await Promise.all(attempts.map(async (attempt) => {
|
await Promise.all(attempts.map(async (attempt) => {
|
||||||
if (treated[attempt.scormid] || CoreSync.isBlocked(AddonModScormProvider.COMPONENT, attempt.scormid, siteId)) {
|
if (treated[attempt.scormid] || CoreSync.isBlocked(ADDON_MOD_SCORM_COMPONENT, attempt.scormid, siteId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,7 +476,7 @@ export class AddonModScormSyncProvider extends CoreCourseActivitySyncBaseProvide
|
||||||
|
|
||||||
if (data !== undefined) {
|
if (data !== undefined) {
|
||||||
// We tried to sync. Send event.
|
// We tried to sync. Send event.
|
||||||
CoreEvents.trigger(AddonModScormSyncProvider.AUTO_SYNCED, {
|
CoreEvents.trigger(ADDON_MOD_SCORM_DATA_AUTO_SYNCED, {
|
||||||
scormId: scorm.id,
|
scormId: scorm.id,
|
||||||
attemptFinished: data.attemptFinished,
|
attemptFinished: data.attemptFinished,
|
||||||
warnings: data.warnings,
|
warnings: data.warnings,
|
||||||
|
@ -586,7 +584,7 @@ export class AddonModScormSyncProvider extends CoreCourseActivitySyncBaseProvide
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that SCORM isn't blocked.
|
// Verify that SCORM isn't blocked.
|
||||||
if (CoreSync.isBlocked(AddonModScormProvider.COMPONENT, scorm.id, siteId)) {
|
if (CoreSync.isBlocked(ADDON_MOD_SCORM_COMPONENT, scorm.id, siteId)) {
|
||||||
this.logger.debug('Cannot sync SCORM ' + scorm.id + ' because it is blocked.');
|
this.logger.debug('Cannot sync SCORM ' + scorm.id + ' because it is blocked.');
|
||||||
|
|
||||||
throw new CoreError(Translate.instant('core.errorsyncblocked', { $a: this.componentTranslate }));
|
throw new CoreError(Translate.instant('core.errorsyncblocked', { $a: this.componentTranslate }));
|
||||||
|
@ -612,7 +610,7 @@ export class AddonModScormSyncProvider extends CoreCourseActivitySyncBaseProvide
|
||||||
let lastOnlineWasFinished = false;
|
let lastOnlineWasFinished = false;
|
||||||
|
|
||||||
// Sync offline logs.
|
// Sync offline logs.
|
||||||
await CoreUtils.ignoreErrors(CoreCourseLogHelper.syncActivity(AddonModScormProvider.COMPONENT, scorm.id, siteId));
|
await CoreUtils.ignoreErrors(CoreCourseLogHelper.syncActivity(ADDON_MOD_SCORM_COMPONENT, scorm.id, siteId));
|
||||||
|
|
||||||
// Get attempts data. We ignore cache for online attempts, so this call will fail if offline or server down.
|
// Get attempts data. We ignore cache for online attempts, so this call will fail if offline or server down.
|
||||||
const attemptsData = await AddonModScorm.getAttemptCount(scorm.id, {
|
const attemptsData = await AddonModScorm.getAttemptCount(scorm.id, {
|
||||||
|
|
|
@ -30,8 +30,21 @@ import { makeSingleton, Translate } from '@singletons';
|
||||||
import { CoreEvents } from '@singletons/events';
|
import { CoreEvents } from '@singletons/events';
|
||||||
import { CorePath } from '@singletons/path';
|
import { CorePath } from '@singletons/path';
|
||||||
import { AddonModScormOffline } from './scorm-offline';
|
import { AddonModScormOffline } from './scorm-offline';
|
||||||
import { AddonModScormAutoSyncEventData, AddonModScormSyncProvider } from './scorm-sync';
|
import { AddonModScormAutoSyncEventData } from './scorm-sync';
|
||||||
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
|
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
|
||||||
|
import {
|
||||||
|
ADDON_MOD_SCORM_COMPONENT,
|
||||||
|
AddonModScormForceAttempt,
|
||||||
|
AddonModScormGradingMethod,
|
||||||
|
AddonModScormMode,
|
||||||
|
AddonModScormAttemptsGradingMethod,
|
||||||
|
ADDON_MOD_SCORM_DATA_SENT_EVENT,
|
||||||
|
ADDON_MOD_SCORM_GO_OFFLINE_EVENT,
|
||||||
|
ADDON_MOD_SCORM_LAUNCH_NEXT_SCO_EVENT,
|
||||||
|
ADDON_MOD_SCORM_LAUNCH_PREV_SCO_EVENT,
|
||||||
|
ADDON_MOD_SCORM_UPDATE_TOC_EVENT,
|
||||||
|
ADDON_MOD_SCORM_DATA_AUTO_SYNCED,
|
||||||
|
} from '../constants';
|
||||||
|
|
||||||
// Private constants.
|
// Private constants.
|
||||||
const VALID_STATUSES = ['notattempted', 'passed', 'completed', 'failed', 'incomplete', 'browsed', 'suspend'];
|
const VALID_STATUSES = ['notattempted', 'passed', 'completed', 'failed', 'incomplete', 'browsed', 'suspend'];
|
||||||
|
@ -65,7 +78,6 @@ const STATUS_TO_ICON = {
|
||||||
suspend: 'fas-pause',
|
suspend: 'fas-pause',
|
||||||
wait: 'far-clock',
|
wait: 'far-clock',
|
||||||
};
|
};
|
||||||
const ROOT_CACHE_KEY = 'mmaModScorm:';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service that provides some features for SCORM.
|
* Service that provides some features for SCORM.
|
||||||
|
@ -73,37 +85,7 @@ const ROOT_CACHE_KEY = 'mmaModScorm:';
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class AddonModScormProvider {
|
export class AddonModScormProvider {
|
||||||
|
|
||||||
static readonly COMPONENT = 'mmaModScorm';
|
protected static readonly ROOT_CACHE_KEY = 'mmaModScorm:';
|
||||||
|
|
||||||
// Public constants.
|
|
||||||
static readonly GRADESCOES = 0;
|
|
||||||
static readonly GRADEHIGHEST = 1;
|
|
||||||
static readonly GRADEAVERAGE = 2;
|
|
||||||
static readonly GRADESUM = 3;
|
|
||||||
|
|
||||||
static readonly HIGHESTATTEMPT = 0;
|
|
||||||
static readonly AVERAGEATTEMPT = 1;
|
|
||||||
static readonly FIRSTATTEMPT = 2;
|
|
||||||
static readonly LASTATTEMPT = 3;
|
|
||||||
|
|
||||||
static readonly MODEBROWSE = 'browse';
|
|
||||||
static readonly MODENORMAL = 'normal';
|
|
||||||
static readonly MODEREVIEW = 'review';
|
|
||||||
|
|
||||||
static readonly SCORM_FORCEATTEMPT_NO = 0;
|
|
||||||
static readonly SCORM_FORCEATTEMPT_ONCOMPLETE = 1;
|
|
||||||
static readonly SCORM_FORCEATTEMPT_ALWAYS = 2;
|
|
||||||
|
|
||||||
static readonly SKIPVIEW_NEVER = 0;
|
|
||||||
static readonly SKIPVIEW_FIRST = 1;
|
|
||||||
static readonly SKIPVIEW_ALWAYS = 2;
|
|
||||||
|
|
||||||
// Events.
|
|
||||||
static readonly LAUNCH_NEXT_SCO_EVENT = 'addon_mod_scorm_launch_next_sco';
|
|
||||||
static readonly LAUNCH_PREV_SCO_EVENT = 'addon_mod_scorm_launch_prev_sco';
|
|
||||||
static readonly UPDATE_TOC_EVENT = 'addon_mod_scorm_update_toc';
|
|
||||||
static readonly GO_OFFLINE_EVENT = 'addon_mod_scorm_go_offline';
|
|
||||||
static readonly DATA_SENT_EVENT = 'addon_mod_scorm_data_sent';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the SCORM grade based on the grading method and the list of attempts scores.
|
* Calculates the SCORM grade based on the grading method and the list of attempts scores.
|
||||||
|
@ -119,10 +101,10 @@ export class AddonModScormProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (scorm.whatgrade) {
|
switch (scorm.whatgrade) {
|
||||||
case AddonModScormProvider.FIRSTATTEMPT:
|
case AddonModScormAttemptsGradingMethod.FIRSTATTEMPT:
|
||||||
return onlineAttempts[1] ? onlineAttempts[1].score : -1;
|
return onlineAttempts[1] ? onlineAttempts[1].score : -1;
|
||||||
|
|
||||||
case AddonModScormProvider.LASTATTEMPT: {
|
case AddonModScormAttemptsGradingMethod.LASTATTEMPT: {
|
||||||
// Search the last completed attempt number.
|
// Search the last completed attempt number.
|
||||||
let lastCompleted = 0;
|
let lastCompleted = 0;
|
||||||
for (const attemptNumber in onlineAttempts) {
|
for (const attemptNumber in onlineAttempts) {
|
||||||
|
@ -141,7 +123,7 @@ export class AddonModScormProvider {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AddonModScormProvider.HIGHESTATTEMPT: {
|
case AddonModScormAttemptsGradingMethod.HIGHESTATTEMPT: {
|
||||||
// Search the highest grade.
|
// Search the highest grade.
|
||||||
let grade = 0;
|
let grade = 0;
|
||||||
for (const attemptNumber in onlineAttempts) {
|
for (const attemptNumber in onlineAttempts) {
|
||||||
|
@ -151,7 +133,7 @@ export class AddonModScormProvider {
|
||||||
return grade;
|
return grade;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AddonModScormProvider.AVERAGEATTEMPT: {
|
case AddonModScormAttemptsGradingMethod.AVERAGEATTEMPT: {
|
||||||
// Calculate the average.
|
// Calculate the average.
|
||||||
let sumGrades = 0;
|
let sumGrades = 0;
|
||||||
let total = 0;
|
let total = 0;
|
||||||
|
@ -217,24 +199,24 @@ export class AddonModScormProvider {
|
||||||
*/
|
*/
|
||||||
determineAttemptAndMode(
|
determineAttemptAndMode(
|
||||||
scorm: AddonModScormScorm,
|
scorm: AddonModScormScorm,
|
||||||
mode: string,
|
mode: AddonModScormMode,
|
||||||
attempt: number,
|
attempt: number,
|
||||||
newAttempt?: boolean,
|
newAttempt?: boolean,
|
||||||
incomplete?: boolean,
|
incomplete?: boolean,
|
||||||
canSaveTracks = true,
|
canSaveTracks = true,
|
||||||
): {mode: string; attempt: number; newAttempt: boolean} {
|
): {mode: AddonModScormMode; attempt: number; newAttempt: boolean} {
|
||||||
if (!canSaveTracks) {
|
if (!canSaveTracks) {
|
||||||
return {
|
return {
|
||||||
mode: scorm.hidebrowse ? AddonModScormProvider.MODENORMAL : mode,
|
mode: scorm.hidebrowse ? AddonModScormMode.NORMAL : mode,
|
||||||
attempt,
|
attempt,
|
||||||
newAttempt: false,
|
newAttempt: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == AddonModScormProvider.MODEBROWSE) {
|
if (mode == AddonModScormMode.BROWSE) {
|
||||||
if (scorm.hidebrowse) {
|
if (scorm.hidebrowse) {
|
||||||
// Prevent Browse mode if hidebrowse is set.
|
// Prevent Browse mode if hidebrowse is set.
|
||||||
mode = AddonModScormProvider.MODENORMAL;
|
mode = AddonModScormMode.NORMAL;
|
||||||
} else {
|
} else {
|
||||||
// We don't need to check attempts as browse mode is set.
|
// We don't need to check attempts as browse mode is set.
|
||||||
if (attempt == 0) {
|
if (attempt == 0) {
|
||||||
|
@ -250,10 +232,10 @@ export class AddonModScormProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scorm.forcenewattempt == AddonModScormProvider.SCORM_FORCEATTEMPT_ALWAYS) {
|
if (scorm.forcenewattempt === AddonModScormForceAttempt.ALWAYS) {
|
||||||
// This SCORM is configured to force a new attempt on every re-entry.
|
// This SCORM is configured to force a new attempt on every re-entry.
|
||||||
return {
|
return {
|
||||||
mode: AddonModScormProvider.MODENORMAL,
|
mode: AddonModScormMode.NORMAL,
|
||||||
attempt: attempt + 1,
|
attempt: attempt + 1,
|
||||||
newAttempt: true,
|
newAttempt: true,
|
||||||
};
|
};
|
||||||
|
@ -273,14 +255,14 @@ export class AddonModScormProvider {
|
||||||
if (newAttempt && (!scorm.maxattempt || attempt < scorm.maxattempt)) {
|
if (newAttempt && (!scorm.maxattempt || attempt < scorm.maxattempt)) {
|
||||||
// Create a new attempt. Force mode normal.
|
// Create a new attempt. Force mode normal.
|
||||||
attempt++;
|
attempt++;
|
||||||
mode = AddonModScormProvider.MODENORMAL;
|
mode = AddonModScormMode.NORMAL;
|
||||||
} else {
|
} else {
|
||||||
if (incomplete) {
|
if (incomplete) {
|
||||||
// We can't review an incomplete attempt.
|
// We can't review an incomplete attempt.
|
||||||
mode = AddonModScormProvider.MODENORMAL;
|
mode = AddonModScormMode.NORMAL;
|
||||||
} else {
|
} else {
|
||||||
// We aren't starting a new attempt and the current one is complete, force review mode.
|
// We aren't starting a new attempt and the current one is complete, force review mode.
|
||||||
mode = AddonModScormProvider.MODEREVIEW;
|
mode = AddonModScormMode.REVIEW;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,7 +397,7 @@ export class AddonModScormProvider {
|
||||||
return Translate.instant('core.none');
|
return Translate.instant('core.none');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scorm.grademethod !== AddonModScormProvider.GRADESCOES && scorm.maxgrade) {
|
if (scorm.grademethod !== AddonModScormGradingMethod.GRADESCOES && scorm.maxgrade) {
|
||||||
grade = (grade / scorm.maxgrade) * 100;
|
grade = (grade / scorm.maxgrade) * 100;
|
||||||
|
|
||||||
return Translate.instant('core.percentagenumber', { $a: CoreTextUtils.roundToDecimals(grade, 2) });
|
return Translate.instant('core.percentagenumber', { $a: CoreTextUtils.roundToDecimals(grade, 2) });
|
||||||
|
@ -473,7 +455,7 @@ export class AddonModScormProvider {
|
||||||
};
|
};
|
||||||
const preSets: CoreSiteWSPreSets = {
|
const preSets: CoreSiteWSPreSets = {
|
||||||
cacheKey: this.getAccessInformationCacheKey(scormId),
|
cacheKey: this.getAccessInformationCacheKey(scormId),
|
||||||
component: AddonModScormProvider.COMPONENT,
|
component: ADDON_MOD_SCORM_COMPONENT,
|
||||||
componentId: options.cmId,
|
componentId: options.cmId,
|
||||||
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||||
};
|
};
|
||||||
|
@ -488,7 +470,7 @@ export class AddonModScormProvider {
|
||||||
* @returns Cache key.
|
* @returns Cache key.
|
||||||
*/
|
*/
|
||||||
protected getAccessInformationCacheKey(scormId: number): string {
|
protected getAccessInformationCacheKey(scormId: number): string {
|
||||||
return ROOT_CACHE_KEY + 'accessInfo:' + scormId;
|
return AddonModScormProvider.ROOT_CACHE_KEY + 'accessInfo:' + scormId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -558,7 +540,7 @@ export class AddonModScormProvider {
|
||||||
* @returns Cache key.
|
* @returns Cache key.
|
||||||
*/
|
*/
|
||||||
protected getAttemptCountCacheKey(scormId: number, userId: number): string {
|
protected getAttemptCountCacheKey(scormId: number, userId: number): string {
|
||||||
return ROOT_CACHE_KEY + 'attemptcount:' + scormId + ':' + userId;
|
return AddonModScormProvider.ROOT_CACHE_KEY + 'attemptcount:' + scormId + ':' + userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -580,7 +562,7 @@ export class AddonModScormProvider {
|
||||||
const preSets: CoreSiteWSPreSets = {
|
const preSets: CoreSiteWSPreSets = {
|
||||||
cacheKey: this.getAttemptCountCacheKey(scormId, userId),
|
cacheKey: this.getAttemptCountCacheKey(scormId, userId),
|
||||||
updateFrequency: CoreSite.FREQUENCY_SOMETIMES,
|
updateFrequency: CoreSite.FREQUENCY_SOMETIMES,
|
||||||
component: AddonModScormProvider.COMPONENT,
|
component: ADDON_MOD_SCORM_COMPONENT,
|
||||||
componentId: options.cmId,
|
componentId: options.cmId,
|
||||||
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||||
};
|
};
|
||||||
|
@ -641,11 +623,11 @@ export class AddonModScormProvider {
|
||||||
let score = 0;
|
let score = 0;
|
||||||
|
|
||||||
switch (scorm.grademethod) {
|
switch (scorm.grademethod) {
|
||||||
case AddonModScormProvider.GRADEHIGHEST:
|
case AddonModScormGradingMethod.GRADEHIGHEST:
|
||||||
score = attemptScore.max;
|
score = attemptScore.max;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AddonModScormProvider.GRADEAVERAGE:
|
case AddonModScormGradingMethod.GRADEAVERAGE:
|
||||||
if (attemptScore.values > 0) {
|
if (attemptScore.values > 0) {
|
||||||
score = attemptScore.sum / attemptScore.values;
|
score = attemptScore.sum / attemptScore.values;
|
||||||
} else {
|
} else {
|
||||||
|
@ -653,11 +635,11 @@ export class AddonModScormProvider {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AddonModScormProvider.GRADESUM:
|
case AddonModScormGradingMethod.GRADESUM:
|
||||||
score = attemptScore.sum;
|
score = attemptScore.sum;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AddonModScormProvider.GRADESCOES:
|
case AddonModScormGradingMethod.GRADESCOES:
|
||||||
score = attemptScore.scos;
|
score = attemptScore.scos;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -797,7 +779,7 @@ export class AddonModScormProvider {
|
||||||
* @returns Cache key.
|
* @returns Cache key.
|
||||||
*/
|
*/
|
||||||
protected getScormUserDataCommonCacheKey(scormId: number): string {
|
protected getScormUserDataCommonCacheKey(scormId: number): string {
|
||||||
return ROOT_CACHE_KEY + 'userdata:' + scormId;
|
return AddonModScormProvider.ROOT_CACHE_KEY + 'userdata:' + scormId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -821,7 +803,7 @@ export class AddonModScormProvider {
|
||||||
};
|
};
|
||||||
const preSets: CoreSiteWSPreSets = {
|
const preSets: CoreSiteWSPreSets = {
|
||||||
cacheKey: this.getScormUserDataCacheKey(scormId, attempt),
|
cacheKey: this.getScormUserDataCacheKey(scormId, attempt),
|
||||||
component: AddonModScormProvider.COMPONENT,
|
component: ADDON_MOD_SCORM_COMPONENT,
|
||||||
componentId: options.cmId,
|
componentId: options.cmId,
|
||||||
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||||
};
|
};
|
||||||
|
@ -854,7 +836,7 @@ export class AddonModScormProvider {
|
||||||
* @returns Cache key.
|
* @returns Cache key.
|
||||||
*/
|
*/
|
||||||
protected getScosCacheKey(scormId: number): string {
|
protected getScosCacheKey(scormId: number): string {
|
||||||
return ROOT_CACHE_KEY + 'scos:' + scormId;
|
return AddonModScormProvider.ROOT_CACHE_KEY + 'scos:' + scormId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -876,7 +858,7 @@ export class AddonModScormProvider {
|
||||||
const preSets: CoreSiteWSPreSets = {
|
const preSets: CoreSiteWSPreSets = {
|
||||||
cacheKey: this.getScosCacheKey(scormId),
|
cacheKey: this.getScosCacheKey(scormId),
|
||||||
updateFrequency: CoreSite.FREQUENCY_SOMETIMES,
|
updateFrequency: CoreSite.FREQUENCY_SOMETIMES,
|
||||||
component: AddonModScormProvider.COMPONENT,
|
component: ADDON_MOD_SCORM_COMPONENT,
|
||||||
componentId: options.cmId,
|
componentId: options.cmId,
|
||||||
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||||
};
|
};
|
||||||
|
@ -1091,7 +1073,7 @@ export class AddonModScormProvider {
|
||||||
* @returns Cache key.
|
* @returns Cache key.
|
||||||
*/
|
*/
|
||||||
protected getScormDataCacheKey(courseId: number): string {
|
protected getScormDataCacheKey(courseId: number): string {
|
||||||
return ROOT_CACHE_KEY + 'scorm:' + courseId;
|
return AddonModScormProvider.ROOT_CACHE_KEY + 'scorm:' + courseId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1118,7 +1100,7 @@ export class AddonModScormProvider {
|
||||||
const preSets: CoreSiteWSPreSets = {
|
const preSets: CoreSiteWSPreSets = {
|
||||||
cacheKey: this.getScormDataCacheKey(courseId),
|
cacheKey: this.getScormDataCacheKey(courseId),
|
||||||
updateFrequency: CoreSite.FREQUENCY_RARELY,
|
updateFrequency: CoreSite.FREQUENCY_RARELY,
|
||||||
component: AddonModScormProvider.COMPONENT,
|
component: ADDON_MOD_SCORM_COMPONENT,
|
||||||
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1185,16 +1167,16 @@ export class AddonModScormProvider {
|
||||||
getScormGradeMethod(scorm: AddonModScormScorm): string {
|
getScormGradeMethod(scorm: AddonModScormScorm): string {
|
||||||
if (scorm.maxattempt == 1) {
|
if (scorm.maxattempt == 1) {
|
||||||
switch (scorm.grademethod) {
|
switch (scorm.grademethod) {
|
||||||
case AddonModScormProvider.GRADEHIGHEST:
|
case AddonModScormGradingMethod.GRADEHIGHEST:
|
||||||
return Translate.instant('addon.mod_scorm.gradehighest');
|
return Translate.instant('addon.mod_scorm.gradehighest');
|
||||||
|
|
||||||
case AddonModScormProvider.GRADEAVERAGE:
|
case AddonModScormGradingMethod.GRADEAVERAGE:
|
||||||
return Translate.instant('addon.mod_scorm.gradeaverage');
|
return Translate.instant('addon.mod_scorm.gradeaverage');
|
||||||
|
|
||||||
case AddonModScormProvider.GRADESUM:
|
case AddonModScormGradingMethod.GRADESUM:
|
||||||
return Translate.instant('addon.mod_scorm.gradesum');
|
return Translate.instant('addon.mod_scorm.gradesum');
|
||||||
|
|
||||||
case AddonModScormProvider.GRADESCOES:
|
case AddonModScormGradingMethod.GRADESCOES:
|
||||||
return Translate.instant('addon.mod_scorm.gradescoes');
|
return Translate.instant('addon.mod_scorm.gradescoes');
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
|
@ -1202,16 +1184,16 @@ export class AddonModScormProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (scorm.whatgrade) {
|
switch (scorm.whatgrade) {
|
||||||
case AddonModScormProvider.HIGHESTATTEMPT:
|
case AddonModScormAttemptsGradingMethod.HIGHESTATTEMPT:
|
||||||
return Translate.instant('addon.mod_scorm.highestattempt');
|
return Translate.instant('addon.mod_scorm.highestattempt');
|
||||||
|
|
||||||
case AddonModScormProvider.AVERAGEATTEMPT:
|
case AddonModScormAttemptsGradingMethod.AVERAGEATTEMPT:
|
||||||
return Translate.instant('addon.mod_scorm.averageattempt');
|
return Translate.instant('addon.mod_scorm.averageattempt');
|
||||||
|
|
||||||
case AddonModScormProvider.FIRSTATTEMPT:
|
case AddonModScormAttemptsGradingMethod.FIRSTATTEMPT:
|
||||||
return Translate.instant('addon.mod_scorm.firstattempt');
|
return Translate.instant('addon.mod_scorm.firstattempt');
|
||||||
|
|
||||||
case AddonModScormProvider.LASTATTEMPT:
|
case AddonModScormAttemptsGradingMethod.LASTATTEMPT:
|
||||||
return Translate.instant('addon.mod_scorm.lastattempt');
|
return Translate.instant('addon.mod_scorm.lastattempt');
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
|
@ -1279,7 +1261,7 @@ export class AddonModScormProvider {
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.invalidateAllScormData(scorm.id, siteId, userId),
|
this.invalidateAllScormData(scorm.id, siteId, userId),
|
||||||
CoreFilepool.invalidateFilesByComponent(siteId, AddonModScormProvider.COMPONENT, moduleId, true),
|
CoreFilepool.invalidateFilesByComponent(siteId, ADDON_MOD_SCORM_COMPONENT, moduleId, true),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1455,7 +1437,7 @@ export class AddonModScormProvider {
|
||||||
return CoreCourseLogHelper.log(
|
return CoreCourseLogHelper.log(
|
||||||
'mod_scorm_launch_sco',
|
'mod_scorm_launch_sco',
|
||||||
params,
|
params,
|
||||||
AddonModScormProvider.COMPONENT,
|
ADDON_MOD_SCORM_COMPONENT,
|
||||||
scormId,
|
scormId,
|
||||||
siteId,
|
siteId,
|
||||||
);
|
);
|
||||||
|
@ -1476,7 +1458,7 @@ export class AddonModScormProvider {
|
||||||
return CoreCourseLogHelper.log(
|
return CoreCourseLogHelper.log(
|
||||||
'mod_scorm_view_scorm',
|
'mod_scorm_view_scorm',
|
||||||
params,
|
params,
|
||||||
AddonModScormProvider.COMPONENT,
|
ADDON_MOD_SCORM_COMPONENT,
|
||||||
id,
|
id,
|
||||||
siteId,
|
siteId,
|
||||||
);
|
);
|
||||||
|
@ -1518,7 +1500,7 @@ export class AddonModScormProvider {
|
||||||
// Tracks have been saved, update cached user data.
|
// Tracks have been saved, update cached user data.
|
||||||
this.updateUserDataAfterSave(scorm.id, attempt, tracks, { cmId: scorm.coursemodule, siteId });
|
this.updateUserDataAfterSave(scorm.id, attempt, tracks, { cmId: scorm.coursemodule, siteId });
|
||||||
|
|
||||||
CoreEvents.trigger(AddonModScormProvider.DATA_SENT_EVENT, {
|
CoreEvents.trigger(ADDON_MOD_SCORM_DATA_SENT_EVENT, {
|
||||||
scormId: scorm.id,
|
scormId: scorm.id,
|
||||||
scoId: scoId,
|
scoId: scoId,
|
||||||
attempt: attempt,
|
attempt: attempt,
|
||||||
|
@ -1554,14 +1536,14 @@ export class AddonModScormProvider {
|
||||||
tracks: tracks,
|
tracks: tracks,
|
||||||
};
|
};
|
||||||
|
|
||||||
CoreSync.blockOperation(AddonModScormProvider.COMPONENT, scormId, 'saveTracksOnline', site.id);
|
CoreSync.blockOperation(ADDON_MOD_SCORM_COMPONENT, scormId, 'saveTracksOnline', site.id);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await site.write<AddonModScormInsertScormTracksWSResponse>('mod_scorm_insert_scorm_tracks', params);
|
const response = await site.write<AddonModScormInsertScormTracksWSResponse>('mod_scorm_insert_scorm_tracks', params);
|
||||||
|
|
||||||
return response.trackids;
|
return response.trackids;
|
||||||
} finally {
|
} finally {
|
||||||
CoreSync.unblockOperation(AddonModScormProvider.COMPONENT, scormId, 'saveTracksOnline', site.id);
|
CoreSync.unblockOperation(ADDON_MOD_SCORM_COMPONENT, scormId, 'saveTracksOnline', site.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1596,7 +1578,7 @@ export class AddonModScormProvider {
|
||||||
// Tracks have been saved, update cached user data.
|
// Tracks have been saved, update cached user data.
|
||||||
this.updateUserDataAfterSave(scorm.id, attempt, tracks, { cmId: scorm.coursemodule });
|
this.updateUserDataAfterSave(scorm.id, attempt, tracks, { cmId: scorm.coursemodule });
|
||||||
|
|
||||||
CoreEvents.trigger(AddonModScormProvider.DATA_SENT_EVENT, {
|
CoreEvents.trigger(ADDON_MOD_SCORM_DATA_SENT_EVENT, {
|
||||||
scormId: scorm.id,
|
scormId: scorm.id,
|
||||||
scoId: scoId,
|
scoId: scoId,
|
||||||
attempt: attempt,
|
attempt: attempt,
|
||||||
|
@ -1658,7 +1640,7 @@ export class AddonModScormProvider {
|
||||||
async shouldDownloadMainFile(scorm: AddonModScormScorm, isOutdated?: boolean, siteId?: string): Promise<boolean> {
|
async shouldDownloadMainFile(scorm: AddonModScormScorm, isOutdated?: boolean, siteId?: string): Promise<boolean> {
|
||||||
siteId = siteId || CoreSites.getCurrentSiteId();
|
siteId = siteId || CoreSites.getCurrentSiteId();
|
||||||
|
|
||||||
const component = AddonModScormProvider.COMPONENT;
|
const component = ADDON_MOD_SCORM_COMPONENT;
|
||||||
|
|
||||||
if (isOutdated === undefined) {
|
if (isOutdated === undefined) {
|
||||||
// Calculate if it's outdated.
|
// Calculate if it's outdated.
|
||||||
|
@ -1916,8 +1898,8 @@ export type AddonModScormScormWSData = {
|
||||||
packageurl?: string; // SCORM zip package URL.
|
packageurl?: string; // SCORM zip package URL.
|
||||||
version?: string; // SCORM version (SCORM_12, SCORM_13, SCORM_AICC).
|
version?: string; // SCORM version (SCORM_12, SCORM_13, SCORM_AICC).
|
||||||
maxgrade?: number; // Max grade.
|
maxgrade?: number; // Max grade.
|
||||||
grademethod?: number; // Grade method.
|
grademethod?: AddonModScormGradingMethod; // Grade method.
|
||||||
whatgrade?: number; // What grade.
|
whatgrade?: AddonModScormAttemptsGradingMethod; // What grade.
|
||||||
maxattempt?: number; // Maximum number of attemtps.
|
maxattempt?: number; // Maximum number of attemtps.
|
||||||
forcecompleted?: boolean; // Status current attempt is forced to "completed".
|
forcecompleted?: boolean; // Status current attempt is forced to "completed".
|
||||||
forcenewattempt?: number; // Controls re-entry behaviour.
|
forcenewattempt?: number; // Controls re-entry behaviour.
|
||||||
|
@ -2100,12 +2082,12 @@ declare module '@singletons/events' {
|
||||||
* @see https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
|
* @see https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
|
||||||
*/
|
*/
|
||||||
export interface CoreEventsData {
|
export interface CoreEventsData {
|
||||||
[AddonModScormProvider.LAUNCH_NEXT_SCO_EVENT]: AddonModScormCommonEventData;
|
[ADDON_MOD_SCORM_LAUNCH_NEXT_SCO_EVENT]: AddonModScormCommonEventData;
|
||||||
[AddonModScormProvider.LAUNCH_PREV_SCO_EVENT]: AddonModScormCommonEventData;
|
[ADDON_MOD_SCORM_LAUNCH_PREV_SCO_EVENT]: AddonModScormCommonEventData;
|
||||||
[AddonModScormProvider.UPDATE_TOC_EVENT]: AddonModScormCommonEventData;
|
[ADDON_MOD_SCORM_UPDATE_TOC_EVENT]: AddonModScormCommonEventData;
|
||||||
[AddonModScormProvider.GO_OFFLINE_EVENT]: AddonModScormCommonEventData;
|
[ADDON_MOD_SCORM_GO_OFFLINE_EVENT]: AddonModScormCommonEventData;
|
||||||
[AddonModScormProvider.DATA_SENT_EVENT]: AddonModScormCommonEventData;
|
[ADDON_MOD_SCORM_DATA_SENT_EVENT]: AddonModScormCommonEventData;
|
||||||
[AddonModScormSyncProvider.AUTO_SYNCED]: AddonModScormAutoSyncEventData;
|
[ADDON_MOD_SCORM_DATA_AUTO_SYNCED]: AddonModScormAutoSyncEventData;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue