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

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 (90) hide show
  1. package/.editorconfig +33 -33
  2. package/.eslintignore +29 -29
  3. package/.eslintrc.cjs +81 -81
  4. package/CHANGELOG +13 -0
  5. package/README.md +71 -71
  6. package/bk.scss +117 -117
  7. package/package.json +8 -8
  8. package/src/$locales/en.json +145 -143
  9. package/src/$locales/fr.json +107 -105
  10. package/src/assets/data/onboardingMessages.json +47 -47
  11. package/src/components/AppBase.vue +1150 -1054
  12. package/src/components/AppBaseButton.test.js +22 -0
  13. package/src/components/AppBaseButton.vue +93 -87
  14. package/src/components/AppBaseErrorDisplay.vue +438 -438
  15. package/src/components/AppBaseFlipCard.vue +84 -84
  16. package/src/components/AppBaseModule.vue +1657 -1673
  17. package/src/components/AppBasePage.vue +742 -779
  18. package/src/components/AppBasePopover.vue +41 -41
  19. package/src/components/AppCompAudio.vue +265 -234
  20. package/src/components/AppCompBranchButtons.vue +556 -552
  21. package/src/components/AppCompButtonProgress.vue +121 -126
  22. package/src/components/AppCompCarousel.vue +328 -298
  23. package/src/components/AppCompInputCheckBoxNext.vue +200 -195
  24. package/src/components/AppCompInputDropdownNext.vue +201 -159
  25. package/src/components/AppCompInputRadioNext.vue +152 -152
  26. package/src/components/AppCompInputTextNext.vue +125 -106
  27. package/src/components/AppCompInputTextTableNext.vue +142 -141
  28. package/src/components/AppCompInputTextToFillDropdownNext.vue +238 -230
  29. package/src/components/AppCompInputTextToFillNext.vue +171 -171
  30. package/src/components/AppCompJauge.vue +74 -74
  31. package/src/components/AppCompMenu.vue +25 -10
  32. package/src/components/AppCompMenuItem.vue +228 -228
  33. package/src/components/AppCompNavigation.vue +972 -960
  34. package/src/components/AppCompNoteCall.vue +159 -133
  35. package/src/components/AppCompNoteCredit.vue +490 -292
  36. package/src/components/AppCompPlayBar.vue +1217 -1218
  37. package/src/components/AppCompPlayBarNext.vue +2060 -2052
  38. package/src/components/AppCompPlayBarProgress.vue +82 -82
  39. package/src/components/AppCompPopUpNext.vue +500 -503
  40. package/src/components/AppCompQuizNext.vue +2908 -2904
  41. package/src/components/AppCompQuizRecall.vue +298 -276
  42. package/src/components/AppCompSVGNext.vue +347 -347
  43. package/src/components/AppCompSettingsMenu.vue +172 -172
  44. package/src/components/AppCompTableOfContent.vue +386 -387
  45. package/src/components/AppCompTranscript.vue +24 -24
  46. package/src/components/AppCompVideoPlayer.vue +368 -368
  47. package/src/components/BaseModule.vue +55 -72
  48. package/src/components/tests__/AppBaseButton.spec.js +53 -0
  49. package/src/composables/useQuiz.js +206 -206
  50. package/src/externalComps/ModuleView.vue +22 -22
  51. package/src/externalComps/SummaryView.vue +91 -91
  52. package/src/main.js +272 -272
  53. package/src/mixins/$mediaMixins.js +819 -819
  54. package/src/mixins/timerMixin.js +155 -155
  55. package/src/module/stores/appStore.js +954 -893
  56. package/src/module/xapi/ADL.js +380 -376
  57. package/src/module/xapi/Crypto/Hasher.js +241 -241
  58. package/src/module/xapi/Crypto/WordArray.js +278 -278
  59. package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +103 -103
  60. package/src/module/xapi/Crypto/algorithms/C_algo.js +315 -315
  61. package/src/module/xapi/Crypto/algorithms/HMAC.js +9 -9
  62. package/src/module/xapi/Crypto/algorithms/SHA1.js +9 -9
  63. package/src/module/xapi/Crypto/encoders/Base.js +105 -105
  64. package/src/module/xapi/Crypto/encoders/Base64.js +99 -99
  65. package/src/module/xapi/Crypto/encoders/Hex.js +61 -61
  66. package/src/module/xapi/Crypto/encoders/Latin1.js +61 -61
  67. package/src/module/xapi/Crypto/encoders/Utf8.js +45 -45
  68. package/src/module/xapi/Statement/agent.js +55 -55
  69. package/src/module/xapi/Statement/index.js +259 -259
  70. package/src/module/xapi/Statement/statement.js +253 -253
  71. package/src/module/xapi/launch.js +157 -157
  72. package/src/module/xapi/utils.js +167 -167
  73. package/src/module/xapi/verbs.js +294 -294
  74. package/src/module/xapi/wrapper.js +1963 -1963
  75. package/src/module/xapi/xapiStatement.js +444 -444
  76. package/src/plugins/bus.js +8 -8
  77. package/src/plugins/gsap.js +14 -14
  78. package/src/plugins/helper.js +355 -308
  79. package/src/plugins/i18n.js +44 -44
  80. package/src/plugins/idb.js +227 -219
  81. package/src/plugins/save.js +37 -37
  82. package/src/plugins/scorm.js +287 -287
  83. package/src/plugins/xapi.js +11 -11
  84. package/src/public/index.html +33 -33
  85. package/src/router/index.js +48 -43
  86. package/src/router/routes.js +312 -312
  87. package/src/shared/generalfuncs.js +210 -210
  88. package/src/shared/validators.js +926 -1069
  89. package/vitest.config.js +19 -0
  90. package/vite.config.js +0 -27
@@ -1,368 +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
- <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>
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>