fcad-core-dragon 2.0.0-beta.5 → 2.0.0-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +33 -33
- package/.eslintignore +29 -29
- package/.eslintrc.cjs +81 -81
- package/CHANGELOG +395 -377
- package/README.md +71 -71
- package/bk.scss +117 -117
- package/package.json +61 -61
- package/src/$locales/en.json +23 -25
- package/src/$locales/fr.json +22 -23
- package/src/assets/data/onboardingMessages.json +47 -47
- package/src/components/AppBase.vue +166 -99
- package/src/components/AppBaseButton.vue +2 -0
- package/src/components/AppBaseErrorDisplay.vue +438 -438
- package/src/components/AppBaseFlipCard.vue +84 -84
- package/src/components/AppBaseModule.vue +124 -106
- package/src/components/AppBasePage.vue +14 -4
- package/src/components/AppBasePopover.vue +41 -41
- package/src/components/AppCompAudio.vue +20 -48
- package/src/components/AppCompBranchButtons.vue +7 -53
- package/src/components/{AppCompTranscript.vue → AppCompContainer.vue} +8 -1
- package/src/components/AppCompInputRadioNext.vue +152 -152
- package/src/components/AppCompInputTextToFillNext.vue +171 -171
- package/src/components/AppCompJauge.vue +74 -74
- package/src/components/AppCompMenu.vue +429 -428
- package/src/components/AppCompMenuItem.vue +228 -228
- package/src/components/AppCompNavigation.vue +2 -2
- package/src/components/AppCompPlayBarNext.vue +5 -0
- package/src/components/AppCompPlayBarProgress.vue +82 -82
- package/src/components/AppCompSVGNext.vue +2 -3
- package/src/components/AppCompSettingsMenu.vue +172 -172
- package/src/components/AppCompVideoPlayer.vue +17 -15
- package/src/composables/useQuiz.js +206 -206
- package/src/externalComps/ModuleView.vue +22 -22
- package/src/externalComps/SummaryView.vue +91 -91
- package/src/main.js +34 -29
- package/src/mixins/$mediaMixins.js +819 -819
- package/src/mixins/timerMixin.js +155 -155
- package/src/module/stores/appStore.js +1 -1
- package/src/module/xapi/ADL.js +144 -4
- package/src/module/xapi/Crypto/Hasher.js +241 -241
- package/src/module/xapi/Crypto/WordArray.js +278 -278
- package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +103 -103
- package/src/module/xapi/Crypto/algorithms/C_algo.js +315 -315
- package/src/module/xapi/Crypto/algorithms/HMAC.js +9 -9
- package/src/module/xapi/Crypto/algorithms/SHA1.js +9 -9
- package/src/module/xapi/Crypto/encoders/Base.js +105 -105
- package/src/module/xapi/Crypto/encoders/Base64.js +99 -99
- package/src/module/xapi/Crypto/encoders/Hex.js +61 -61
- package/src/module/xapi/Crypto/encoders/Latin1.js +61 -61
- package/src/module/xapi/Crypto/encoders/Utf8.js +45 -45
- package/src/module/xapi/Statement/agent.js +55 -55
- package/src/module/xapi/Statement/index.js +259 -259
- package/src/module/xapi/Statement/statement.js +253 -253
- package/src/module/xapi/utils.js +167 -167
- package/src/module/xapi/verbs.js +294 -294
- package/src/module/xapi/wrapper copy.js +1963 -0
- package/src/module/xapi/wrapper.js +121 -188
- package/src/module/xapi/xapiStatement.js +444 -444
- package/src/plugins/bus.js +8 -8
- package/src/plugins/gsap.js +14 -14
- package/src/plugins/helper.js +0 -1
- package/src/plugins/i18n.js +44 -44
- package/src/plugins/save.js +37 -37
- package/src/plugins/scorm.js +287 -287
- package/src/plugins/xapi.js +11 -11
- package/src/public/index.html +33 -33
- package/src/router/index.js +2 -1
- package/src/shared/generalfuncs.js +210 -210
- package/src/shared/validators.js +2 -0
- package/src/components/AppCompPlayBar.vue +0 -1217
package/src/$locales/fr.json
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"button": {
|
|
3
|
-
"alert_close":"Fermer cette fenêtre",
|
|
4
|
-
"cancel_pop": "Annuler",
|
|
5
3
|
"carousel_next": "Suivant",
|
|
6
4
|
"carousel_prev": "Précédent",
|
|
7
5
|
"confirm_pop": "Confirmer",
|
|
8
|
-
"full_screen_on": "Plein
|
|
9
|
-
"full_screen_off": "Quitter le mode plein
|
|
6
|
+
"full_screen_on": "Plein écran",
|
|
7
|
+
"full_screen_off": "Quitter le mode plein écran",
|
|
10
8
|
"go_to_first_page": "Aller à la première page",
|
|
11
9
|
"go_to_next_page": "Aller à la page suivante",
|
|
12
10
|
"go_to_previous_page": "Aller à la page précédente",
|
|
13
|
-
"go_to_lesson"
|
|
11
|
+
"go_to_lesson": "Aller à la leçon suivante",
|
|
14
12
|
"go_to_menu": "Aller au sommaire de la leçon",
|
|
15
13
|
"info": "Info",
|
|
16
14
|
"menu": "Début",
|
|
@@ -30,20 +28,21 @@
|
|
|
30
28
|
"subtitle_off": "Masquer les sous-titres",
|
|
31
29
|
"subtitle_on": "Afficher les sous-titres",
|
|
32
30
|
"submit": "Valider",
|
|
33
|
-
"toc":"Progression",
|
|
34
|
-
"
|
|
31
|
+
"toc": "Progression",
|
|
32
|
+
"toc_title": "Afficher la table des matières de l’activité",
|
|
33
|
+
"transcript_off": "Masquer la transcription",
|
|
35
34
|
"transcript_on": "Afficher la transcription",
|
|
36
35
|
"unmute": "Activer le son",
|
|
37
36
|
"volume": "Volume",
|
|
38
37
|
"closePopUp": "Fermer"
|
|
39
38
|
},
|
|
40
39
|
"label": {
|
|
41
|
-
"side_panel":"fenêtre latérale",
|
|
42
|
-
"timer":"temps estimé"
|
|
40
|
+
"side_panel": "fenêtre latérale",
|
|
41
|
+
"timer": "temps estimé"
|
|
43
42
|
},
|
|
44
43
|
"message": {
|
|
45
44
|
"err_download_file": "Le téléchargement de ce fichier a échoué.",
|
|
46
|
-
"dropdown_list":"Liste déroulante",
|
|
45
|
+
"dropdown_list": "Liste déroulante",
|
|
47
46
|
"first_option_dropdown": "Choisir une option",
|
|
48
47
|
"no_attempts": "Vous n'avez plus d'essai.",
|
|
49
48
|
"loading_state_msg": "Chargement. Veuillez patienter...",
|
|
@@ -58,11 +57,11 @@
|
|
|
58
57
|
"text": {
|
|
59
58
|
"activity": "Activité",
|
|
60
59
|
"activity_title": "Mes activités",
|
|
61
|
-
"activity_progress":"État d’avancement :",
|
|
62
|
-
"carousel":"Carrousel",
|
|
60
|
+
"activity_progress": "État d’avancement :",
|
|
61
|
+
"carousel": "Carrousel",
|
|
63
62
|
"conclusion": "Conclusion",
|
|
64
63
|
"complete": "Terminé",
|
|
65
|
-
"error":"erreur",
|
|
64
|
+
"error": "erreur",
|
|
66
65
|
"introduction": "Introduction",
|
|
67
66
|
"lesson": "Leçon",
|
|
68
67
|
"quiz": "Mot complétant la phrase",
|
|
@@ -71,15 +70,15 @@
|
|
|
71
70
|
"for_textarea": "Écrivez ici.",
|
|
72
71
|
"for_title_btn_progress": "Cliquer pour découvrir le contenu"
|
|
73
72
|
},
|
|
74
|
-
"of":"de",
|
|
75
|
-
"slide":"Diapositive",
|
|
73
|
+
"of": "de",
|
|
74
|
+
"slide": "Diapositive",
|
|
76
75
|
"title_note": "Note(s)",
|
|
77
76
|
"title_credit": "Source(s)",
|
|
78
77
|
"err_credit": "Le texte de la page ne comporte pas d’appel de note correspondant à cette note-ci. Un appel de note doit être ajouté.",
|
|
79
78
|
"title_link_bas": "Revenir au texte",
|
|
80
79
|
"title_link_call": "Accéder à la note",
|
|
81
|
-
"title_content_view":"Sommaire
|
|
82
|
-
"toc":"Table des matières",
|
|
80
|
+
"title_content_view": "Sommaire",
|
|
81
|
+
"toc": "Table des matières",
|
|
83
82
|
"transcript": "Transcription"
|
|
84
83
|
},
|
|
85
84
|
"user_settings": {
|
|
@@ -89,11 +88,11 @@
|
|
|
89
88
|
"subtitles": "Activer le soutitrage par défault",
|
|
90
89
|
"title": "Paramètres"
|
|
91
90
|
},
|
|
92
|
-
"quizState":{
|
|
93
|
-
"goodAnswer":"Bonne réponse",
|
|
94
|
-
"badAnswer":"Mauvaise réponse",
|
|
95
|
-
"neutralAnswer":"Réponse neutre",
|
|
96
|
-
"answers"
|
|
91
|
+
"quizState": {
|
|
92
|
+
"goodAnswer": "Bonne réponse",
|
|
93
|
+
"badAnswer": "Mauvaise réponse",
|
|
94
|
+
"neutralAnswer": "Réponse neutre",
|
|
95
|
+
"answers": "Choix de réponses"
|
|
97
96
|
},
|
|
98
97
|
"a11y_sr": {
|
|
99
98
|
"time": {
|
|
@@ -104,4 +103,4 @@
|
|
|
104
103
|
"seek_slider": "Barre de lecture",
|
|
105
104
|
"range_expression": "à %x sur %y."
|
|
106
105
|
}
|
|
107
|
-
}
|
|
106
|
+
}
|
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
{
|
|
2
|
-
"message_1": {
|
|
3
|
-
"type": "popup-avert",
|
|
4
|
-
"value": {
|
|
5
|
-
"title": "Bienvenue dans la visite guidée du FCAD !",
|
|
6
|
-
"hypertext_1": "<p>Le bouton Confirmer vous fera passer à la prochaine étape de la visite.</p><p>Vous pouvez y mettre fin en tout temps avec le bouton Annuler.</p>"
|
|
7
|
-
}
|
|
8
|
-
},
|
|
9
|
-
"message_2": {
|
|
10
|
-
"type": "tooltip",
|
|
11
|
-
"value": {
|
|
12
|
-
"target": "activity_progress",
|
|
13
|
-
"title": "Navigation secondaire",
|
|
14
|
-
"content": "<p>Les flèches permettent de passer à la page précédente ou suivante de l'activité.</p><p>Les rectangles représentent une section de l'activité.</p>"
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"message_3": {
|
|
18
|
-
"type": "tooltip",
|
|
19
|
-
"value": {
|
|
20
|
-
"target": "btn_back_summary",
|
|
21
|
-
"title": "Navigation secondaire",
|
|
22
|
-
"content": "<p>Ce bouton permet de retourner au sommaire de l'activité en tout temps.</p>"
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
"message_4": {
|
|
26
|
-
"type": "tooltip",
|
|
27
|
-
"value": {
|
|
28
|
-
"target": "primary_activity",
|
|
29
|
-
"title": "Navigation principale",
|
|
30
|
-
"content": "<p>La navigation principale permet de valider ses réponses de quiz et de passer à la page suivante.</p>"
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
"message_5": {
|
|
34
|
-
"type": "popup-avert",
|
|
35
|
-
"value": {
|
|
36
|
-
"title": "Visite guidée",
|
|
37
|
-
"hypertext_1": "<p>Message pour la barre de lecture.</p>"
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
"message_6": {
|
|
41
|
-
"type": "popup-avert",
|
|
42
|
-
"value": {
|
|
43
|
-
"title": "Visite guidée",
|
|
44
|
-
"hypertext_1": "<p>Message pour les Paramètres.</p>"
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"message_1": {
|
|
3
|
+
"type": "popup-avert",
|
|
4
|
+
"value": {
|
|
5
|
+
"title": "Bienvenue dans la visite guidée du FCAD !",
|
|
6
|
+
"hypertext_1": "<p>Le bouton Confirmer vous fera passer à la prochaine étape de la visite.</p><p>Vous pouvez y mettre fin en tout temps avec le bouton Annuler.</p>"
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"message_2": {
|
|
10
|
+
"type": "tooltip",
|
|
11
|
+
"value": {
|
|
12
|
+
"target": "activity_progress",
|
|
13
|
+
"title": "Navigation secondaire",
|
|
14
|
+
"content": "<p>Les flèches permettent de passer à la page précédente ou suivante de l'activité.</p><p>Les rectangles représentent une section de l'activité.</p>"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"message_3": {
|
|
18
|
+
"type": "tooltip",
|
|
19
|
+
"value": {
|
|
20
|
+
"target": "btn_back_summary",
|
|
21
|
+
"title": "Navigation secondaire",
|
|
22
|
+
"content": "<p>Ce bouton permet de retourner au sommaire de l'activité en tout temps.</p>"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"message_4": {
|
|
26
|
+
"type": "tooltip",
|
|
27
|
+
"value": {
|
|
28
|
+
"target": "primary_activity",
|
|
29
|
+
"title": "Navigation principale",
|
|
30
|
+
"content": "<p>La navigation principale permet de valider ses réponses de quiz et de passer à la page suivante.</p>"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"message_5": {
|
|
34
|
+
"type": "popup-avert",
|
|
35
|
+
"value": {
|
|
36
|
+
"title": "Visite guidée",
|
|
37
|
+
"hypertext_1": "<p>Message pour la barre de lecture.</p>"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"message_6": {
|
|
41
|
+
"type": "popup-avert",
|
|
42
|
+
"value": {
|
|
43
|
+
"title": "Visite guidée",
|
|
44
|
+
"hypertext_1": "<p>Message pour les Paramètres.</p>"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
<div
|
|
26
26
|
v-if="showBuildInfo && !buildInfoClicked"
|
|
27
27
|
id="build-info"
|
|
28
|
+
aria-hidden="true"
|
|
28
29
|
@click="buildInfoClicked = true"
|
|
29
30
|
>
|
|
30
31
|
<span>{{ getModuleInfo.courseID.toUpperCase() }}</span>
|
|
@@ -106,7 +107,9 @@ export default {
|
|
|
106
107
|
'getAppConfigs',
|
|
107
108
|
'getErrorMenu',
|
|
108
109
|
'getRouteHistory',
|
|
109
|
-
'getBookmarkEnabled'
|
|
110
|
+
'getBookmarkEnabled',
|
|
111
|
+
'getApplicationSettings',
|
|
112
|
+
'getCompStatusTracker'
|
|
110
113
|
]),
|
|
111
114
|
getwidth() {
|
|
112
115
|
return window.innerWidth
|
|
@@ -165,7 +168,11 @@ export default {
|
|
|
165
168
|
* https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon
|
|
166
169
|
*/
|
|
167
170
|
|
|
168
|
-
if (!this.getConnectionInfo)
|
|
171
|
+
if (!this.getConnectionInfo)
|
|
172
|
+
return setTimeout(() => {
|
|
173
|
+
this.setProgress()
|
|
174
|
+
}, 200)
|
|
175
|
+
|
|
169
176
|
if (this.getIsMobile) {
|
|
170
177
|
document.addEventListener(
|
|
171
178
|
'visibilitychange',
|
|
@@ -178,8 +185,12 @@ export default {
|
|
|
178
185
|
)
|
|
179
186
|
}
|
|
180
187
|
// initialize scorm Commuinication with LMS || xAPI LRS
|
|
181
|
-
if (this.getModuleInfo.packageType === 'scorm')
|
|
182
|
-
|
|
188
|
+
if (this.getModuleInfo.packageType === 'scorm') {
|
|
189
|
+
this.$scorm.Initialize()
|
|
190
|
+
setTimeout(() => {
|
|
191
|
+
this.setProgress()
|
|
192
|
+
}, 200)
|
|
193
|
+
} else if (
|
|
183
194
|
this.getModuleInfo.packageType === 'xapi' &&
|
|
184
195
|
this.getConnectionInfo &&
|
|
185
196
|
this.getConnectionInfo.actor &&
|
|
@@ -207,13 +218,12 @@ export default {
|
|
|
207
218
|
}, 200)
|
|
208
219
|
})
|
|
209
220
|
}, 200)
|
|
210
|
-
}
|
|
221
|
+
}
|
|
211
222
|
}
|
|
212
223
|
}
|
|
213
224
|
},
|
|
214
225
|
|
|
215
226
|
created() {
|
|
216
|
-
this.bookmarkActive
|
|
217
227
|
if (import.meta.env.DEV) {
|
|
218
228
|
this.checkForErrors()
|
|
219
229
|
}
|
|
@@ -301,6 +311,8 @@ export default {
|
|
|
301
311
|
else if (lang === 'english' || lang === 'anglais') lang = 'en'
|
|
302
312
|
else lang = lang.substring(0, 2).toLowerCase()
|
|
303
313
|
this.$i18n.locale = lang
|
|
314
|
+
//Set vuetify locale
|
|
315
|
+
this.$vuetify.locale.current = lang
|
|
304
316
|
}
|
|
305
317
|
},
|
|
306
318
|
|
|
@@ -366,36 +378,53 @@ export default {
|
|
|
366
378
|
if (this.getModuleInfo.packageType !== 'xapi') return
|
|
367
379
|
if (!this.getConnectionInfo || !this.getConnectionInfo.remote) return
|
|
368
380
|
|
|
369
|
-
const
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
const { routeHistory = [], ...userProgress } = progress
|
|
381
|
+
const actorMbox = this.getConnectionInfo.actor.mbox.replace('mailto:', '')
|
|
382
|
+
const activityId = this.getConnectionInfo.activity_id
|
|
383
|
+
const _url = new URL(activityId)
|
|
384
|
+
const parentID = `${_url.origin}/${this.getModuleInfo.courseID}` // redefining activity id for statement
|
|
374
385
|
|
|
375
|
-
const
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
386
|
+
const lessonProgressParam = { email: actorMbox, activityId }
|
|
387
|
+
const lessonStateParam = {
|
|
388
|
+
email: actorMbox,
|
|
389
|
+
activityId,
|
|
390
|
+
verb: 'completed'
|
|
391
|
+
}
|
|
392
|
+
const lessonPosionParam = {
|
|
393
|
+
email: actorMbox,
|
|
394
|
+
activityId
|
|
395
|
+
}
|
|
396
|
+
const playbarParam = {
|
|
397
|
+
email: actorMbox,
|
|
398
|
+
activityId,
|
|
399
|
+
verb: 'played'
|
|
400
|
+
}
|
|
401
|
+
const preferencesParam = {
|
|
402
|
+
email: actorMbox,
|
|
403
|
+
activityId: parentID,
|
|
404
|
+
verb: 'preferred'
|
|
405
|
+
}
|
|
379
406
|
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
const
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
407
|
+
const fetchParams = [
|
|
408
|
+
lessonProgressParam,
|
|
409
|
+
lessonStateParam,
|
|
410
|
+
lessonPosionParam,
|
|
411
|
+
playbarParam,
|
|
412
|
+
preferencesParam
|
|
413
|
+
]
|
|
414
|
+
|
|
415
|
+
const {
|
|
416
|
+
userData,
|
|
417
|
+
savedPoint,
|
|
418
|
+
preferredSettings,
|
|
419
|
+
playbarValues,
|
|
420
|
+
lessonStatus
|
|
421
|
+
} = await this.$xapi._getBulkData(fetchParams)
|
|
392
422
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
)
|
|
423
|
+
const { routeHistory = [], ...userProgress } = userData
|
|
424
|
+
|
|
425
|
+
const completedState = lessonStatus || {}
|
|
426
|
+
const lessonPosition = savedPoint || ''
|
|
427
|
+
const applicationSettings = preferredSettings || {}
|
|
399
428
|
//Update the App Store data
|
|
400
429
|
this.updateDataFetchFromServer({
|
|
401
430
|
userProgress,
|
|
@@ -405,15 +434,6 @@ export default {
|
|
|
405
434
|
playbarValues,
|
|
406
435
|
applicationSettings
|
|
407
436
|
}).then(() => {
|
|
408
|
-
// console.log('DATA FROM SERVER', {
|
|
409
|
-
// userProgress,
|
|
410
|
-
// routeHistory,
|
|
411
|
-
// lessonPosition,
|
|
412
|
-
// completedState,
|
|
413
|
-
// playbarValues,
|
|
414
|
-
// applicationSettings
|
|
415
|
-
// })// for testing
|
|
416
|
-
|
|
417
437
|
this.updateTracker('appBase_fetch', 'ready')
|
|
418
438
|
})
|
|
419
439
|
},
|
|
@@ -423,8 +443,7 @@ export default {
|
|
|
423
443
|
this.getModuleInfo.packageType === 'scorm' &&
|
|
424
444
|
this.$scorm.initialized
|
|
425
445
|
) {
|
|
426
|
-
this.$bus.$emit('save-to-scorm') // emit event to save to scorm before closing the app
|
|
427
|
-
this.$scorm.Finish()
|
|
446
|
+
this.$bus.$emit('save-to-scorm', 'disconnect') // emit event to save to scorm before closing the app
|
|
428
447
|
}
|
|
429
448
|
//Xapi context
|
|
430
449
|
else if (
|
|
@@ -439,41 +458,59 @@ export default {
|
|
|
439
458
|
|
|
440
459
|
async setProgress() {
|
|
441
460
|
const packageType = this.getModuleInfo.packageType
|
|
442
|
-
|
|
443
461
|
switch (packageType) {
|
|
444
462
|
case 'scorm':
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
const
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
//
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
463
|
+
{
|
|
464
|
+
// Get saved data from suspend_data or from localStorage to update the store:
|
|
465
|
+
// LMS is connected
|
|
466
|
+
if (this.$scorm.initialized) {
|
|
467
|
+
// launching the lesson (if the lesson is not already completed)
|
|
468
|
+
const lessonStatus = this.$scorm.GetValue(
|
|
469
|
+
'cmi.core.lesson_status',
|
|
470
|
+
true
|
|
471
|
+
)
|
|
472
|
+
if (lessonStatus === 'unknown') {
|
|
473
|
+
this.$scorm.setValue('cmi.core.lesson_status', 'incomplete') // set the lesson status to in complete
|
|
474
|
+
this.$scorm.Commit() // persist data
|
|
475
|
+
}
|
|
476
|
+
// chacked if there is a existing record in the LMS
|
|
477
|
+
if (this.$scorm.GetValue('cmi.suspend_data') !== '') {
|
|
478
|
+
const scormRecord = this.$scorm
|
|
479
|
+
.GetValue('cmi.suspend_data')
|
|
480
|
+
.replace(/\\/g, '')
|
|
481
|
+
const { userData, routeHistory, userSettings } =
|
|
482
|
+
JSON.parse(scormRecord)
|
|
483
|
+
|
|
484
|
+
this.setUserMetaData(userData)
|
|
485
|
+
this.setRouteHistory(routeHistory) // update store recored with existing record
|
|
486
|
+
this.setApplicationSettings(userSettings) // update store recored with existing record
|
|
487
|
+
}
|
|
488
|
+
// check for the bookmark existance in LMS
|
|
489
|
+
if (
|
|
490
|
+
this.$scorm.GetValue('cmi.core.lesson_location', false) !== ''
|
|
491
|
+
) {
|
|
492
|
+
let lessonPosition = this.$scorm.GetValue(
|
|
493
|
+
'cmi.core.lesson_location',
|
|
494
|
+
false
|
|
495
|
+
)
|
|
496
|
+
if (this.bookmarkActive && lessonPosition)
|
|
497
|
+
this.$router.push({ name: lessonPosition }) //Should Redirect to bookmark
|
|
498
|
+
}
|
|
462
499
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
500
|
+
// No LMS use LocalStorage record
|
|
501
|
+
} else {
|
|
502
|
+
this.$idb.openDB().then(() => {
|
|
503
|
+
this.$idb.getFromDB(this.getModuleInfo.idbID).then((res) => {
|
|
504
|
+
if (res && res.$record) {
|
|
505
|
+
const { routeHistory, userSettings, progress } = res.$record
|
|
506
|
+
this.setUserMetaData(progress) // update store record with existing record
|
|
507
|
+
this.setRouteHistory(routeHistory) // update store record with existing route info
|
|
508
|
+
if (userSettings) this.setApplicationSettings(userSettings) // update store record with existing user settings
|
|
509
|
+
}
|
|
510
|
+
})
|
|
473
511
|
})
|
|
474
|
-
}
|
|
512
|
+
}
|
|
475
513
|
}
|
|
476
|
-
|
|
477
514
|
break
|
|
478
515
|
|
|
479
516
|
case 'xapi':
|
|
@@ -576,7 +613,6 @@ export default {
|
|
|
576
613
|
* The statement is sent at module level. there is no id
|
|
577
614
|
* the Statement must be sent at the course level: There course_id exist and id is the course_id
|
|
578
615
|
*/
|
|
579
|
-
|
|
580
616
|
if (id && id !== crsParams.courseID)
|
|
581
617
|
activityId = `${this.getConnectionInfo.activity_id}/${id}`
|
|
582
618
|
else if (crsParams.courseID && id === crsParams.courseID)
|
|
@@ -758,7 +794,7 @@ export default {
|
|
|
758
794
|
|
|
759
795
|
stmt.object.definition['extensions'] = {
|
|
760
796
|
...stmt.object.definition['extensions'],
|
|
761
|
-
[`${
|
|
797
|
+
[`${activityId}/${e.id}`]: e.content
|
|
762
798
|
}
|
|
763
799
|
})
|
|
764
800
|
}
|
|
@@ -778,6 +814,7 @@ export default {
|
|
|
778
814
|
endLesson(cb, option = true) {
|
|
779
815
|
cb = cb || null
|
|
780
816
|
let text
|
|
817
|
+
|
|
781
818
|
//Defining the text to display for stmt description and definition
|
|
782
819
|
switch (this.$i18n.locale) {
|
|
783
820
|
case 'fr':
|
|
@@ -832,10 +869,6 @@ export default {
|
|
|
832
869
|
//================================STATEMENT FOR THE PLAYBAR ===============================================
|
|
833
870
|
//Creating custom statement
|
|
834
871
|
const stmtPlaybar = {
|
|
835
|
-
id: (() => {
|
|
836
|
-
if (this.getModuleInfo.courseID) return this.getModuleInfo.courseID
|
|
837
|
-
else return null
|
|
838
|
-
})(),
|
|
839
872
|
verb: 'played',
|
|
840
873
|
definition: text,
|
|
841
874
|
description: text,
|
|
@@ -853,8 +886,8 @@ export default {
|
|
|
853
886
|
//Creating custom statement
|
|
854
887
|
const stmtUserSettings = {
|
|
855
888
|
id: (() => {
|
|
856
|
-
if (this.getModuleInfo.courseID) return
|
|
857
|
-
|
|
889
|
+
if (!this.getModuleInfo.courseID) return null
|
|
890
|
+
return this.getModuleInfo.courseID
|
|
858
891
|
})(),
|
|
859
892
|
verb: 'preferred',
|
|
860
893
|
definition: text,
|
|
@@ -968,27 +1001,60 @@ export default {
|
|
|
968
1001
|
this.sendXapiStatements([stmtUserSettings, exitStmt, endStmt])
|
|
969
1002
|
|
|
970
1003
|
this.$bus.$emit('set-comp-status', 'appBase', 'ready')
|
|
971
|
-
|
|
1004
|
+
const actorMbox = this.getConnectionInfo.actor.mbox.replace('mailto:', '')
|
|
1005
|
+
const activityId = this.getConnectionInfo.activity_id
|
|
972
1006
|
// Creating a asynchronous fecth method that would resolve after a 2 second
|
|
973
1007
|
const fetchData = async () => {
|
|
974
1008
|
//funtion that will make a multiple request on the server
|
|
975
1009
|
const requests = async () => {
|
|
976
|
-
const _url = new URL(
|
|
1010
|
+
const _url = new URL(activityId)
|
|
977
1011
|
const parentID = `${_url.origin}/${this.getModuleInfo.courseID}` // redefining activity id for statement
|
|
978
1012
|
|
|
979
|
-
const
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1013
|
+
const lessonProgressParam = { email: actorMbox, activityId }
|
|
1014
|
+
const lessonStateParam = {
|
|
1015
|
+
email: actorMbox,
|
|
1016
|
+
activityId,
|
|
1017
|
+
verb: 'suspended'
|
|
1018
|
+
}
|
|
1019
|
+
const lessonPosionParam = {
|
|
1020
|
+
email: actorMbox,
|
|
1021
|
+
activityId
|
|
1022
|
+
}
|
|
1023
|
+
const playbarParam = {
|
|
1024
|
+
email: actorMbox,
|
|
1025
|
+
activityId,
|
|
1026
|
+
verb: 'played'
|
|
1027
|
+
}
|
|
1028
|
+
const preferencesParam = {
|
|
1029
|
+
email: actorMbox,
|
|
1030
|
+
activityId: parentID,
|
|
1031
|
+
verb: 'preferred'
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
const fetchParams = [
|
|
1035
|
+
lessonProgressParam,
|
|
1036
|
+
lessonStateParam,
|
|
1037
|
+
lessonPosionParam,
|
|
1038
|
+
playbarParam,
|
|
1039
|
+
preferencesParam
|
|
1040
|
+
]
|
|
1041
|
+
|
|
1042
|
+
// Using Promise.all to make parallel requests
|
|
1043
|
+
const {
|
|
1044
|
+
userData,
|
|
1045
|
+
savedPoint,
|
|
1046
|
+
preferredSettings,
|
|
1047
|
+
playbarValues,
|
|
1048
|
+
lessonStatus
|
|
1049
|
+
} = await this.$xapi._getBulkData(fetchParams)
|
|
1050
|
+
|
|
1051
|
+
return {
|
|
1052
|
+
userData,
|
|
1053
|
+
savedPoint,
|
|
1054
|
+
preferredSettings,
|
|
1055
|
+
playbarValues,
|
|
1056
|
+
lessonStatus
|
|
1057
|
+
}
|
|
992
1058
|
}
|
|
993
1059
|
return new Promise((resolve) => {
|
|
994
1060
|
setTimeout(() => resolve(requests()), 2000)
|
|
@@ -996,11 +1062,12 @@ export default {
|
|
|
996
1062
|
}
|
|
997
1063
|
|
|
998
1064
|
// Make request over user current data after sending statement to assure that the resetting worked
|
|
1065
|
+
|
|
999
1066
|
const usrData = await fetchData()
|
|
1000
1067
|
this.$bus.$emit('reset-complete')
|
|
1001
1068
|
console.warn('😄 USER STATUS: ', {
|
|
1002
|
-
|
|
1003
|
-
|
|
1069
|
+
userID: actorMbox,
|
|
1070
|
+
activityId,
|
|
1004
1071
|
Record: usrData
|
|
1005
1072
|
})
|
|
1006
1073
|
},
|