fcad-core-dragon 2.0.0-beta.1 → 2.0.0-beta.3

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.
Files changed (118) hide show
  1. package/.editorconfig +33 -33
  2. package/.eslintignore +29 -29
  3. package/{.eslintrc.js → .eslintrc.cjs} +81 -86
  4. package/CHANGELOG +364 -364
  5. package/README.md +71 -71
  6. package/bk.scss +117 -0
  7. package/package.json +61 -63
  8. package/src/$locales/en.json +143 -179
  9. package/src/$locales/fr.json +105 -181
  10. package/src/assets/data/onboardingMessages.json +47 -47
  11. package/src/components/AppBase.vue +1054 -614
  12. package/src/components/AppBaseButton.vue +87 -63
  13. package/src/components/AppBaseErrorDisplay.vue +438 -420
  14. package/src/components/AppBaseFlipCard.vue +84 -83
  15. package/src/components/AppBaseModule.vue +1673 -1842
  16. package/src/components/AppBasePage.vue +779 -312
  17. package/src/components/AppBasePopover.vue +41 -0
  18. package/src/components/AppCompAudio.vue +234 -0
  19. package/src/components/AppCompBranchButtons.vue +552 -582
  20. package/src/components/AppCompButtonProgress.vue +126 -147
  21. package/src/components/AppCompCarousel.vue +298 -192
  22. package/src/components/AppCompInputCheckBoxNext.vue +195 -0
  23. package/src/components/AppCompInputDropdownNext.vue +159 -0
  24. package/src/components/AppCompInputRadioNext.vue +152 -0
  25. package/src/components/{AppCompInputTextBox.vue → AppCompInputTextNext.vue} +106 -91
  26. package/src/components/AppCompInputTextTableNext.vue +141 -0
  27. package/src/components/AppCompInputTextToFillDropdownNext.vue +230 -0
  28. package/src/components/{AppCompInputTextToFillText.vue → AppCompInputTextToFillNext.vue} +171 -164
  29. package/src/components/AppCompJauge.vue +74 -55
  30. package/src/components/AppCompMenu.vue +413 -209
  31. package/src/components/AppCompMenuItem.vue +228 -174
  32. package/src/components/AppCompNavigation.vue +960 -949
  33. package/src/components/AppCompNoteCall.vue +133 -126
  34. package/src/components/AppCompNoteCredit.vue +292 -164
  35. package/src/components/AppCompPlayBar.vue +1218 -1319
  36. package/src/components/AppCompPlayBarNext.vue +2052 -0
  37. package/src/components/AppCompPlayBarProgress.vue +82 -0
  38. package/src/components/AppCompPopUpNext.vue +503 -0
  39. package/src/components/{AppCompQuiz.vue → AppCompQuizNext.vue} +2904 -2989
  40. package/src/components/AppCompQuizRecall.vue +276 -250
  41. package/src/components/AppCompSVGNext.vue +347 -0
  42. package/src/components/AppCompSettingsMenu.vue +172 -171
  43. package/src/components/AppCompTableOfContent.vue +387 -264
  44. package/src/components/AppCompTranscript.vue +24 -19
  45. package/src/components/AppCompVideoPlayer.vue +368 -336
  46. package/src/components/AppCompViewDisplay.vue +6 -6
  47. package/src/components/BaseModule.vue +72 -67
  48. package/src/composables/useQuiz.js +206 -0
  49. package/src/externalComps/ModuleView.vue +22 -0
  50. package/src/externalComps/SummaryView.vue +91 -0
  51. package/src/main.js +272 -227
  52. package/src/mixins/$mediaMixins.js +819 -0
  53. package/src/mixins/timerMixin.js +155 -156
  54. package/src/module/stores/appStore.js +893 -0
  55. package/src/module/xapi/ADL.js +376 -339
  56. package/src/module/xapi/Crypto/Hasher.js +241 -241
  57. package/src/module/xapi/Crypto/WordArray.js +278 -278
  58. package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +103 -103
  59. package/src/module/xapi/Crypto/algorithms/C_algo.js +315 -319
  60. package/src/module/xapi/Crypto/algorithms/HMAC.js +9 -9
  61. package/src/module/xapi/Crypto/algorithms/SHA1.js +9 -9
  62. package/src/module/xapi/Crypto/encoders/Base.js +105 -105
  63. package/src/module/xapi/Crypto/encoders/Base64.js +99 -99
  64. package/src/module/xapi/Crypto/encoders/Hex.js +61 -61
  65. package/src/module/xapi/Crypto/encoders/Latin1.js +61 -61
  66. package/src/module/xapi/Crypto/encoders/Utf8.js +45 -45
  67. package/src/module/xapi/Crypto/index.js +53 -53
  68. package/src/module/xapi/Statement/activity.js +47 -47
  69. package/src/module/xapi/Statement/agent.js +55 -55
  70. package/src/module/xapi/Statement/group.js +26 -26
  71. package/src/module/xapi/Statement/index.js +259 -259
  72. package/src/module/xapi/Statement/statement.js +253 -253
  73. package/src/module/xapi/Statement/statementRef.js +23 -23
  74. package/src/module/xapi/Statement/substatement.js +22 -22
  75. package/src/module/xapi/Statement/verb.js +36 -36
  76. package/src/module/xapi/activitytypes.js +17 -17
  77. package/src/module/xapi/launch.js +157 -157
  78. package/src/module/xapi/utils.js +167 -167
  79. package/src/module/xapi/verbs.js +294 -294
  80. package/src/module/xapi/wrapper.js +1963 -1890
  81. package/src/module/xapi/xapiStatement.js +444 -444
  82. package/src/plugins/bus.js +8 -3
  83. package/src/plugins/gsap.js +14 -17
  84. package/src/plugins/helper.js +308 -295
  85. package/src/plugins/i18n.js +44 -31
  86. package/src/plugins/idb.js +219 -212
  87. package/src/plugins/save.js +37 -37
  88. package/src/plugins/scorm.js +287 -287
  89. package/src/plugins/xapi.js +11 -11
  90. package/src/public/index.html +33 -21
  91. package/src/router/index.js +43 -41
  92. package/src/router/routes.js +312 -337
  93. package/src/shared/generalfuncs.js +210 -188
  94. package/src/shared/validators.js +1069 -249
  95. package/vite.config.js +27 -0
  96. package/.prettierrc.js +0 -5
  97. package/babel.config.js +0 -3
  98. package/src/components/AppBaseDragChoice.vue +0 -91
  99. package/src/components/AppBaseDropZone.vue +0 -112
  100. package/src/components/AppCompBif.vue +0 -120
  101. package/src/components/AppCompDragAndDrop.vue +0 -339
  102. package/src/components/AppCompInputAssociation.vue +0 -332
  103. package/src/components/AppCompInputCheckBox.vue +0 -227
  104. package/src/components/AppCompInputDropdown.vue +0 -184
  105. package/src/components/AppCompInputRadio.vue +0 -169
  106. package/src/components/AppCompInputTextTable.vue +0 -155
  107. package/src/components/AppCompInputTextToFillDropdown.vue +0 -255
  108. package/src/components/AppCompMediaPlayer.vue +0 -397
  109. package/src/components/AppCompPopUp.vue +0 -522
  110. package/src/components/AppCompPopover.vue +0 -27
  111. package/src/components/AppCompSVG.vue +0 -309
  112. package/src/mixins/$pageMixins.js +0 -459
  113. package/src/mixins/$quizMixins.js +0 -456
  114. package/src/module/store.js +0 -895
  115. package/src/plugins/timeManager.js +0 -77
  116. package/src/routes_bckp.js +0 -313
  117. package/src/routes_static.js +0 -344
  118. package/vue.config.js +0 -83
@@ -1,336 +1,368 @@
1
- <!--
2
- @ Description: This component is used to display video element video
3
- @ What it does: The component create the HTMLMediaElement video tag from data provided by user.
4
- Once the HTMLMediaElement tag is created, the component save the HTMLMediaElement to store and
5
- make it available to all other component that will need id
6
- -->
7
-
8
- <template>
9
- <div
10
- v-if="vidData"
11
- id="app-video-player"
12
- class="v-media __media-container"
13
- :class="[{ FS: fullScreen }, CCBrowser]"
14
- tabindex="0"
15
- >
16
- <b-row v-show="hasErr.length" class="warning-error">
17
- <b-col class="box-error">
18
- <div class="yellow-box">
19
- <h2>
20
- <b-icon icon="exclamation-triangle" />
21
- Erreure: COMPOSANT VIDEO
22
- </h2>
23
- </div>
24
- <div class="box">
25
- <p>
26
- Vous avez une/des erreur(s) pour la création de votre composant.
27
- Veuillez corriger les erreurs ci-dessous:
28
- <br />
29
- </p>
30
- <ul>
31
- <li v-for="(err, index) in hasErr" :key="`error_type_${index}`">
32
- {{ err }}
33
- </li>
34
- </ul>
35
- </div>
36
- </b-col>
37
- </b-row>
38
- <!------------------video section --------------------------->
39
- <template v-show="!hasErr.length">
40
- <div class="vid-wrapper" @click="handlePlayBack">
41
- <div class="playback-animation">
42
- <svg class="app-icons-svg">
43
- <use v-show="!isPlaying" href="#play-icon" />
44
- <use v-show="isPlaying" href="#pause-icon" />
45
- </svg>
46
- </div>
47
- <video
48
- :id="id"
49
- ref="m-video"
50
- :poster="vidPoster"
51
- @loadedmetadata="updateMediaData($event)"
52
- >
53
- <source
54
- v-for="(aSource, index) in vidSources"
55
- :key="index"
56
- :src="`${aSource.src}`"
57
- :type="`video/${aSource.type}`"
58
- />
59
- <track
60
- v-for="(subtitle, index) in vidSubtitles"
61
- :key="`subtitle_${index + 1}`"
62
- :src="subtitle.src"
63
- :srclang="subtitle.srclang"
64
- :label="subtitle.label"
65
- />
66
- </video>
67
- </div>
68
- <app-comp-play-bar v-if="$vidElement" :media-to-play="$vidElement" />
69
- </template>
70
- </div>
71
- </template>
72
-
73
- <script>
74
- import { mapGetters } from 'vuex'
75
- import { validateVideoData } from '../shared/validators'
76
-
77
- export default {
78
- props: {
79
- vidData: {
80
- type: Object,
81
- required: true,
82
- validator: (value) => {
83
- return validateVideoData(value).length === 0
84
- }
85
- },
86
- fullScreen: {
87
- type: Boolean,
88
- default: true
89
- }
90
- },
91
-
92
- data() {
93
- return {
94
- id: null,
95
- vidSources: [],
96
- vidSubtitles: [],
97
- vidPoster: null,
98
- vidTranscript: null,
99
- hasErr: validateVideoData(this.vidData),
100
- isSet: false,
101
- isPlaying: false,
102
- playClicked: false
103
- }
104
- },
105
- computed: {
106
- ...mapGetters(['getCurrentBrowser']),
107
-
108
- setTimeout() {
109
- return window.setTimeout
110
- },
111
-
112
- CCBrowser() {
113
- let browser = this.getCurrentBrowser
114
-
115
- if (browser === 'Safari') {
116
- return 'safari'
117
- } else {
118
- return 'chrome'
119
- }
120
- },
121
-
122
- mediaA11Y() {
123
- let m = {
124
- srTxt: '',
125
- skipToTxt: ''
126
- }
127
-
128
- this.$i18n.locale === 'fr'
129
- ? (m = {
130
- srTxt:
131
- "Le contenu d'apprentissage sera seulement disponible à la fin de la narration. Appuyez le bouton jouer, pour lancer l'animation.",
132
- skipToTxt: 'Passer au controleur de media'
133
- })
134
- : (m = {
135
- srTxt:
136
- 'The learning content will be available only at the end of the narration. Press the play button to start the animation',
137
- skipToTxt: 'Skip to play-bar'
138
- })
139
-
140
- return m
141
- },
142
- $vidElement() {
143
- if (!this.isSet) return null
144
- const { mTranscript, mSubtitles } = this.vidData
145
- return {
146
- mTranscript,
147
- mType: 'video',
148
- mSubtitles,
149
- mElement: this.$refs['m-video']
150
- }
151
- }
152
- },
153
-
154
- mounted() {
155
- this.initVideo()
156
- },
157
-
158
- beforeDestroy() {
159
- this.$bus.$off('hide-playback', this.hideAnimation)
160
- this.$bus.$off('resize-media', this.resizeVideo)
161
- },
162
-
163
- methods: {
164
- initVideo() {
165
- const { mSources, mPoster, mSubtitles, mTranscript } = this.vidData
166
-
167
- if (mSources) this.vidSources = mSources
168
- if (mPoster) this.vidPoster = mPoster
169
- if (mSubtitles) this.vidSubtitles = mSubtitles
170
- if (mTranscript) this.vidTranscript = mTranscript
171
-
172
- setTimeout(() => {
173
- this.isSet = true
174
- this.isPlaying = !this.$vidElement.mElement.paused
175
- this.vidPaused = this.$vidElement.mElement.paused
176
- }, 200)
177
- this.$bus.$on('resize-media', this.resizeVideo)
178
- this.$bus.$on('hide-playback', this.hideAnimation)
179
- },
180
-
181
- /**
182
- * @description update the information for the mediaElement in the store
183
- * @param {htmlElement} e
184
- * @fires update-page to AppBaseModule.vue
185
- */
186
- updateMediaData(e) {
187
- //dispatch loading status of for this component
188
- this.$bus.$emit('set-comp-status', 'AppCompMediaPlayer', 'loading')
189
- this.$bus.$emit('update-media-duration')
190
-
191
- this.$store
192
- .dispatch('updateCurrentMediaElement', e.target)
193
- .then(() => {
194
- this.$bus.$emit('update-page')
195
- })
196
- .then(() =>
197
- this.$bus.$emit('set-comp-status', 'AppCompMediaPlayer', 'ready')
198
- )
199
- },
200
- /**
201
- *@description - small animation over the playback button
202
- * Play a little animation on the svg and then send a play event
203
- *@emits play-media - To AppComPLayBar
204
- */
205
- runPlaybackAnimation() {
206
- this.isPlaying = !this.$vidElement.mElement.paused
207
-
208
- let animation = this.$gsap.fromTo(
209
- '.playback-animation',
210
- { opacity: 1, scale: 0.8 },
211
- {
212
- opacity: 0,
213
- scale: 1.3,
214
- duration: 0.8,
215
- ease: 'power2.out'
216
- }
217
- )
218
- animation.play()
219
- },
220
-
221
- /**
222
- * @description initiate play back of media when click on the video Element with animation
223
- * @emits play-media to AppComplayBar
224
- *
225
- */
226
- handlePlayBack() {
227
- this.runPlaybackAnimation()
228
- this.$bus.$emit('play-media', 'k')
229
- },
230
- /**
231
- * @description hide the animation when the media is played with click on playbar play button
232
- * this ensures that animation does not run every time user controls the media via the playbar controls
233
- */
234
- hideAnimation() {
235
- if (this.playClicked) return
236
- this.runPlaybackAnimation()
237
- this.playClicked = true
238
- },
239
-
240
- /**
241
- * @description- Skip directly to the specify containt/region*
242
- * main content is Node with defined ID
243
- * @param {String} targetID- Css selector for the target element
244
- */
245
-
246
- skipTo(targetID) {
247
- let skipTo = document.querySelector(`#wrapper-content`) //default definition of main element
248
-
249
- if (targetID) {
250
- let targetEl = document.querySelector(`#${targetID}`) // search for node element specified as main
251
-
252
- if (targetEl) skipTo = targetEl
253
- }
254
- let targetTop = skipTo.offsetTop
255
-
256
- let scrollOpt = {
257
- top: targetTop - 100,
258
- left: 0,
259
- behavior: 'auto' //auto
260
- }
261
-
262
- // Allowing accessibility control with keyboard
263
- skipTo.setAttribute('tabIndex', -1)
264
- window.scrollTo(scrollOpt)
265
- skipTo.focus()
266
- },
267
-
268
- /**
269
- * @description -set the size of the video element when transcript is open or closed
270
- */
271
-
272
- resizeVideo(size) {
273
- let defaultSize = 98
274
- if (size == 'sm') defaultSize = 68
275
- const videoElement = document.querySelector('.__media-container')
276
- setTimeout(() => {
277
- videoElement.style.width = `${defaultSize}%`
278
- }, 100)
279
- }
280
- }
281
- }
282
- </script>
283
- <style lang="scss">
284
- $widthVideo: 100%;
285
-
286
- .__media-container,
287
- .vid-wrapper {
288
- display: flex;
289
- align-items: center;
290
- justify-content: center;
291
- }
292
-
293
- .__media-container {
294
- width: 98%;
295
- user-select: none;
296
- overflow: hidden;
297
- max-width: 900px;
298
- border-radius: 5px;
299
- background: #000;
300
-
301
- position: relative;
302
- box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
303
- transition: all 0.3s ease;
304
-
305
- video,
306
- .vid-wrapper {
307
- width: $widthVideo;
308
- }
309
-
310
- .playback-animation {
311
- cursor: pointer;
312
- position: absolute;
313
- display: flex;
314
- align-items: center;
315
- justify-content: center;
316
-
317
- -webkit-box-shadow: 7px 5px 7px 0px rgba(0, 0, 0, 0.24);
318
- box-shadow: 7px 5px 7px 0px rgba(0, 0, 0, 0.24);
319
- background-color: #007bff;
320
- width: 75px;
321
- height: 75px;
322
- border-radius: 50%;
323
-
324
- .app-icons-svg {
325
- width: 40px;
326
- height: 40px;
327
- }
328
- }
329
- }
330
- .__media-container.fullscreen {
331
- max-width: 100%;
332
- width: 100%;
333
- height: 100vh;
334
- border-radius: 0px;
335
- }
336
- </style>
1
+ <!--
2
+ @ Description: This component is used to display video element video
3
+ @ What it does: The component create the HTMLMediaElement video tag from data provided by user.
4
+ Once the HTMLMediaElement tag is created, the component save the HTMLMediaElement to store and
5
+ make it available to all other component that will need id
6
+ -->
7
+ <template>
8
+ <section
9
+ v-if="vidData"
10
+ :id="'video_' + id"
11
+ ref="$media-container"
12
+ class="v-media __media-container app-video-player"
13
+ :class="[{ FS: fullScreen }, CCBrowser]"
14
+ aria-label="Video"
15
+ >
16
+ <app-base-error-display
17
+ v-if="hasErr.length"
18
+ :error-group="'component'"
19
+ :error-title="'ERREUR: COMPOSANT DE VIDEO'"
20
+ :errors-list="hasErr"
21
+ />
22
+
23
+ <!------------------video section --------------------------->
24
+
25
+ <template v-else>
26
+ <div class="vid-wrapper">
27
+ <!--Vid-skeleton-->
28
+ <div
29
+ v-if="isLoading || hasSourceLoadingError"
30
+ class="skeleton"
31
+ :class="{ isloading: isLoading, error: hasSourceLoadingError }"
32
+ >
33
+ <p v-if="hasSourceLoadingError">
34
+ Une erreur s'est produite lors du chargement de la vidéo, veuillez
35
+ réessayer
36
+ </p>
37
+ </div>
38
+ <!--End vid-sleleton-->
39
+ <video
40
+ :id="id"
41
+ ref="m-video"
42
+ :poster="vidPoster"
43
+ @loadedmetadata="updateMediaData($event)"
44
+ >
45
+ <source
46
+ v-for="(aSource, index) in vidSources"
47
+ :key="index"
48
+ :src="`${aSource.src}`"
49
+ :type="`video/${aSource.type}`"
50
+ @error="errorHandling($event)"
51
+ />
52
+ <track
53
+ v-for="(subtitle, index) in vidSubtitles"
54
+ :key="`subtitle_${index + 1}`"
55
+ :src="subtitle.src"
56
+ :srclang="subtitle.srclang"
57
+ :label="subtitle.label"
58
+ />
59
+ </video>
60
+ </div>
61
+ <app-comp-play-bar-next
62
+ v-if="$vidElement && !isLoading && !hasSourceLoadingError"
63
+ :ref="`plyr_${id}`"
64
+ :media-to-play="$vidElement"
65
+ @resize-video="resizeVideo"
66
+ />
67
+ </template>
68
+ </section>
69
+ </template>
70
+
71
+ <script>
72
+ import { mapState, mapActions } from 'pinia'
73
+ import { useAppStore } from '../module/stores/appStore'
74
+ import { validateVideoData } from '../shared/validators'
75
+ import AppCompPlayBarNext from './AppCompPlayBarNext.vue'
76
+
77
+ export default {
78
+ components: { AppCompPlayBarNext },
79
+ props: {
80
+ vidData: {
81
+ type: Object,
82
+ required: true,
83
+ validator: (value) => {
84
+ return validateVideoData(value).length === 0
85
+ }
86
+ },
87
+ fullScreen: {
88
+ type: Boolean,
89
+ default: true
90
+ }
91
+ },
92
+
93
+ data() {
94
+ return {
95
+ id: this.vidData.id,
96
+ vidSources: [],
97
+ vidSubtitles: [],
98
+ vidPoster: null,
99
+ vidTranscript: null,
100
+ hasSourceLoadingError: false,
101
+ hasErr: validateVideoData(this.vidData),
102
+ isSet: false,
103
+ playClicked: false,
104
+ vidFocus: false,
105
+ vidElm: null,
106
+ vidElmFocus: false,
107
+ mediaContainer: null
108
+ }
109
+ },
110
+ computed: {
111
+ ...mapState(useAppStore, ['getCurrentBrowser', 'getCurrentPage']),
112
+ //Return true if the video is loading (to show the loading display)
113
+ isLoading() {
114
+ if (!this.isSet && !this.hasSourceLoadingError) return true
115
+ else return false
116
+ },
117
+
118
+ setTimeout() {
119
+ return window.setTimeout
120
+ },
121
+ //Return current browser
122
+ CCBrowser() {
123
+ let browser = this.getCurrentBrowser
124
+
125
+ if (browser === 'Safari') {
126
+ return 'safari'
127
+ } else {
128
+ return 'chrome'
129
+ }
130
+ },
131
+ //Return the videoElement (used in the playbar)
132
+ $vidElement() {
133
+ if (!this.isSet) return null
134
+ const { id, mTranscript, mSubtitles } = this.vidData
135
+ const mElement = this.$refs['m-video']
136
+ return {
137
+ id,
138
+ mTranscript,
139
+ mType: 'video',
140
+ mSubtitles,
141
+ mElement,
142
+ mMediaContainer: this.$refs['$media-container']
143
+ }
144
+ }
145
+ },
146
+
147
+ mounted() {
148
+ this.initVideo()
149
+ },
150
+
151
+ beforeUnmount() {
152
+ this.$bus.$off('hide-playback', this.hideAnimation)
153
+ this.$bus.$off('resize-media', this.resizeVideo)
154
+ },
155
+
156
+ methods: {
157
+ ...mapActions(useAppStore, ['updateCurrentMediaElements']),
158
+ errorHandling(e) {
159
+ this.hasSourceLoadingError = true
160
+ },
161
+ initVideo() {
162
+ const { mSources, mPoster, mSubtitles, mTranscript, id } = this.vidData
163
+ if (id) this.id = id
164
+ if (mSources) this.vidSources = mSources
165
+ if (mPoster) this.vidPoster = mPoster
166
+ if (mSubtitles) this.vidSubtitles = mSubtitles
167
+ if (mTranscript) this.vidTranscript = mTranscript
168
+
169
+ this.$bus.$on('resize-media', this.resizeVideo)
170
+ this.$bus.$on('hide-playback', this.hideAnimation)
171
+ },
172
+
173
+ /**
174
+ * @description update the information for the mediaElement in the store
175
+ * @param {htmlElement} e
176
+ * @fires update-page to AppBaseModule.vue
177
+ */
178
+ updateMediaData(e) {
179
+ //dispatch loading status of for this component
180
+
181
+ this.$bus.$emit('set-comp-status', 'AppCompMediaPlayer', 'loading')
182
+ this.$bus.$emit('update-media-duration')
183
+ //Should Check that the the media Element is unique im Media Liste
184
+ const { mElements } = this.getCurrentPage
185
+
186
+ const hasEntry = mElements.findLastIndex(
187
+ (media) => media.id === e.target.id
188
+ )
189
+
190
+ if (hasEntry !== -1) {
191
+ // Should report Error to Console and Component template about this media
192
+ const errmsg = `Cet élément a le même ID q'un autre media. Vous ne devez pas avoir de médias avec le même ID dans une page.`
193
+
194
+ console.warn(
195
+ `%c WARNING!>>> You cannot use the same ID in your media elements`,
196
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
197
+ )
198
+
199
+ this.$bus.$emit('set-comp-status', 'AppCompMediaPlayer', 'ready')
200
+ return this.hasErr.push(errmsg)
201
+ }
202
+
203
+ this.updateCurrentMediaElements(e.target).then(() => {
204
+ this.isSet = true
205
+ this.$bus.$emit('set-comp-status', 'AppCompMediaPlayer', 'ready')
206
+ })
207
+ },
208
+ /**
209
+ *@description - small animation over the playback button
210
+ * Play a little animation on the svg and then send a play event
211
+ *@emits play-media - To AppComPLayBar
212
+ */
213
+ runPlaybackAnimation() {
214
+ //this.isPlaying = !this.$vidElement.mElement.paused
215
+ // let animation = this.$gsap.fromTo(
216
+ // '.playback-animation',
217
+ // { opacity: 1, scale: 0.8 },
218
+ // {
219
+ // opacity: 0,
220
+ // scale: 1.3,
221
+ // duration: 0.8,
222
+ // ease: 'power2.out'
223
+ // }
224
+ // )
225
+ // animation.play()
226
+ },
227
+
228
+ /**
229
+ * @description initiate play back of media when click on the video Element with animation
230
+ * @emits play-media to AppComplayBar
231
+ *
232
+ */
233
+ /*handlePlayBack(evtType) {
234
+ this.runPlaybackAnimation()
235
+ this.$bus.$emit('play-media', 'KeyK')
236
+ },*/
237
+ /**
238
+ * @description hide the animation when the media is played with click on playbar play button
239
+ * this ensures that animation does not run every time user controls the media via the playbar controls
240
+ */
241
+ hideAnimation(type = null) {
242
+ if (this.playClicked && !type) return
243
+ this.runPlaybackAnimation()
244
+ this.playClicked = true
245
+ },
246
+
247
+ /**
248
+ * @description- Skip directly to the specify containt/region*
249
+ * main content is Node with defined ID
250
+ * @param {String} targetID- Css selector for the target element
251
+ */
252
+
253
+ skipTo(targetID) {
254
+ let skipTo = document.querySelector(`#wrapper-content`) //default definition of main element
255
+
256
+ if (targetID) {
257
+ let targetEl = document.querySelector(`#${targetID}`) // search for node element specified as main
258
+
259
+ if (targetEl) skipTo = targetEl
260
+ }
261
+ let targetTop = skipTo.offsetTop
262
+
263
+ let scrollOpt = {
264
+ top: targetTop - 100,
265
+ left: 0,
266
+ behavior: 'auto' //auto
267
+ }
268
+
269
+ // Allowing accessibility control with keyboard
270
+ skipTo.setAttribute('tabIndex', -1)
271
+ window.scrollTo(scrollOpt)
272
+ skipTo.focus()
273
+ },
274
+
275
+ /**
276
+ * @description -set the size of the video element when transcript is open or closed
277
+ */
278
+
279
+ resizeVideo(size, container) {
280
+ let defaultSize = 100
281
+ if (size == 'sm') defaultSize = 68
282
+ //const videoElement = document.querySelector('.__media-container')
283
+ const videoElement = this.$vidElement.mMediaContainer
284
+ setTimeout(() => {
285
+ videoElement.style.width = `${defaultSize}%`
286
+ }, 100)
287
+ },
288
+
289
+ spaceKeyPreventDefault(evt) {
290
+ let { code } = evt
291
+ if (code == 'Space') {
292
+ evt.preventDefault()
293
+ this.handlePlayBack('spacebar')
294
+ }
295
+ }
296
+ }
297
+ }
298
+ </script>
299
+ <style lang="scss">
300
+ $widthVideo: 100%;
301
+
302
+ .app-video-player {
303
+ display: flex;
304
+ flex-direction: row;
305
+ flex-wrap: wrap;
306
+ position: relative;
307
+ align-items: center;
308
+
309
+ .vid-wrapper {
310
+ width: 100%;
311
+ position: relative;
312
+ overflow: hidden;
313
+
314
+ .playback-button {
315
+ position: absolute;
316
+ top: 0;
317
+ left: 0;
318
+ width: 100%;
319
+ height: 100%;
320
+
321
+ display: flex;
322
+ flex-flow: column wrap;
323
+ justify-content: center;
324
+ align-items: center;
325
+ background-color: transparent;
326
+ }
327
+
328
+ video {
329
+ width: 100%;
330
+ height: auto;
331
+ display: block;
332
+ user-select: none;
333
+ }
334
+ }
335
+ }
336
+
337
+ //Skeleton animation style
338
+ .skeleton {
339
+ height: 100%;
340
+ width: 100%;
341
+ position: absolute;
342
+ z-index: 3;
343
+ &.isloading {
344
+ animation: skeleton-loading 1s linear infinite alternate;
345
+ }
346
+ &.error {
347
+ display: flex;
348
+ justify-content: center;
349
+ align-items: center;
350
+ //colors
351
+ background-color: hsl(200, 20%, 80%);
352
+ }
353
+ &.audio {
354
+ height: 277px;
355
+ max-width: 600px;
356
+ }
357
+ }
358
+
359
+ @keyframes skeleton-loading {
360
+ //colors
361
+ 0% {
362
+ background-color: hsl(200, 20%, 80%);
363
+ }
364
+ 100% {
365
+ background-color: hsl(200, 20%, 95%);
366
+ }
367
+ }
368
+ </style>