@enso-ui/how-to 4.0.12 → 4.0.16

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enso-ui/how-to",
3
- "version": "4.0.12",
3
+ "version": "4.0.16",
4
4
  "description": "Basic how-to package",
5
5
  "main": "src/bulma/pages/howTo/Index.vue",
6
6
  "scripts": {
@@ -28,12 +28,11 @@
28
28
  "@enso-ui/transitions": "^2.0",
29
29
  "@fortawesome/fontawesome-svg-core": "^1.2.2",
30
30
  "@fortawesome/free-regular-svg-icons": "^5.2.0",
31
- "@fortawesome/free-solid-svg-icons": "^5.2.0",
31
+ "@fortawesome/free-solid-svg-icons": "^5.11.2",
32
32
  "@fortawesome/vue-fontawesome": "3.0.0-5",
33
- "v-tooltip": "4.0.0-beta.2",
33
+ "v-tooltip": "^4.0.0-beta.2",
34
34
  "video.js": "^7.0",
35
- "vue": "^3.0",
36
- "vue-video-player": "^5.0"
35
+ "vue": "^3.0"
37
36
  },
38
37
  "devDependencies": {
39
38
  "@vue/cli-plugin-babel": "5.0.0-beta.6",
@@ -72,7 +72,7 @@
72
72
  <div class="columns is-multiline">
73
73
  <div class="column is-half"
74
74
  v-for="(vid, index) in filteredVideos"
75
- :key="index">
75
+ :key="vid.id">
76
76
  <how-to-video class="is-rounded raises-on-hover"
77
77
  :video="vid"
78
78
  :tags="tags"
@@ -199,9 +199,11 @@ export default {
199
199
 
200
200
  directives: { focus },
201
201
 
202
- components: { Fa, Fade, HowToVideo, Uploader, },
202
+ components: {
203
+ Fa, Fade, HowToVideo, Uploader,
204
+ },
203
205
 
204
- inject: ['canAccess', 'errorHandler', 'i18n', 'route', 'toastr'],
206
+ inject: ['canAccess', 'errorHandler', 'http', 'i18n', 'route', 'toastr'],
205
207
 
206
208
  data: () => ({
207
209
  videos: [],
@@ -236,7 +238,7 @@ export default {
236
238
  ? this.videos
237
239
  : this.videos.filter(({ tagList }) => tagList
238
240
  .filter(
239
- (tagId) => this.selectedTags.findIndex(({ id }) => tagId === id) !== -1,
241
+ tagId => this.selectedTags.findIndex(({ id }) => tagId === id) !== -1,
240
242
  ).length === this.selectedTags.length);
241
243
  },
242
244
  filteredTags() {
@@ -265,12 +267,12 @@ export default {
265
267
 
266
268
  methods: {
267
269
  getVideos() {
268
- axios.get(this.route('howTo.videos.index'))
270
+ this.http.get(this.route('howTo.videos.index'))
269
271
  .then(({ data }) => (this.videos = data))
270
272
  .catch(this.errorHandler);
271
273
  },
272
274
  getTags() {
273
- axios.get(this.route('howTo.tags.index'))
275
+ this.http.get(this.route('howTo.tags.index'))
274
276
  .then(({ data }) => (this.tags = data))
275
277
  .catch(this.errorHandler);
276
278
  },
@@ -295,7 +297,7 @@ export default {
295
297
  this.deselectTags();
296
298
  },
297
299
  deselectTags() {
298
- this.tags.map((tag) => {
300
+ this.tags.map(tag => {
299
301
  tag.selected = false;
300
302
  return tag;
301
303
  });
@@ -305,26 +307,26 @@ export default {
305
307
  return;
306
308
  }
307
309
 
308
- axios.post(this.route('howTo.tags.store'), { name: this.query })
310
+ this.http.post(this.route('howTo.tags.store'), { name: this.query })
309
311
  .then(({ data }) => {
310
312
  this.tags.push(data);
311
313
  this.query = '';
312
314
  }).catch(this.errorHandler);
313
315
  },
314
316
  updateTag() {
315
- axios.patch(this.route('howTo.tags.update', this.selectedTag.id), {
317
+ this.http.patch(this.route('howTo.tags.update', this.selectedTag.id), {
316
318
  name: this.selectedTag.name,
317
319
  }).catch(this.errorHandler);
318
320
  },
319
321
  deleteTag(tagId) {
320
- axios.delete(this.route('howTo.tags.destroy', tagId))
322
+ this.http.delete(this.route('howTo.tags.destroy', tagId))
321
323
  .then(() => {
322
324
  const index = this.tags.findIndex(({ id }) => id === tagId);
323
325
  this.tags.splice(index, 1);
324
326
  }).catch(this.errorHandler);
325
327
  },
326
328
  update() {
327
- axios.patch(this.route('howTo.videos.update', this.video.id), this.video)
329
+ this.http.patch(this.route('howTo.videos.update', this.video.id), this.video)
328
330
  .then(({ data }) => {
329
331
  this.toastr.success(data.message);
330
332
  this.reset();
@@ -35,21 +35,20 @@
35
35
  </card-control>
36
36
  <card-control v-if="canAccess('howTo.videos.update')">
37
37
  <span class="icon"
38
- @click="tagging = !tagging; $emit(tagging ? 'start-tagging' : 'stop-tagging')">
38
+ @click="tagging = !tagging;
39
+ $emit(tagging ? 'start-tagging' : 'stop-tagging')">
39
40
  <fa :icon="tagging ? 'check' : 'tags'"/>
40
41
  </span>
41
42
  </card-control>
42
43
  <card-control v-if="canAccess('howTo.posters.destroy') && video.poster">
43
- <confirmation @confirm="destroyPoster"
44
- v-tooltip="i18n('Remove poster')">
44
+ <confirmation @confirm="destroyPoster">
45
45
  <span class="icon is-small">
46
46
  <fa :icon="['far', 'trash-alt']"/>
47
47
  </span>
48
48
  </confirmation>
49
49
  </card-control>
50
50
  <card-control v-else-if="canAccess('howTo.videos.destroy')">
51
- <confirmation @confirm="destroyVideo"
52
- v-tooltip="i18n('Delete video')">
51
+ <confirmation @confirm="destroyVideo">
53
52
  <span class="icon is-small">
54
53
  <fa :icon="['far', 'trash-alt']"/>
55
54
  </span>
@@ -96,14 +95,13 @@ import { FontAwesomeIcon as Fa } from '@fortawesome/vue-fontawesome';
96
95
  import { library } from '@fortawesome/fontawesome-svg-core';
97
96
  import { faInfo, faTags, faInfoCircle } from '@fortawesome/free-solid-svg-icons';
98
97
  import { faTrashAlt, faEdit, faImage } from '@fortawesome/free-regular-svg-icons';
99
- import { videoPlayer } from 'vue-video-player';
100
- import 'vue-video-player/src/custom-theme.css';
101
98
  import {
102
99
  Card, CardHeader, CardCollapse, CardControl, CardContent,
103
100
  CardFooter, CardFooterItem,
104
101
  } from '@enso-ui/card/bulma';
105
102
  import Confirmation from '@enso-ui/confirmation/bulma';
106
103
  import { Uploader } from '@enso-ui/uploader';
104
+ import VideoPlayer from './VideoPlayer.vue';
107
105
  import 'video.js/dist/video-js.css';
108
106
 
109
107
  library.add([faTrashAlt, faInfo, faTags, faEdit, faImage, faInfoCircle]);
@@ -124,10 +122,10 @@ export default {
124
122
  CardContent,
125
123
  Fa,
126
124
  Uploader,
127
- videoPlayer,
125
+ VideoPlayer,
128
126
  },
129
127
 
130
- inject: ['canAccess', 'errorHandler', 'i18n', 'route', 'toastr'],
128
+ inject: ['canAccess', 'errorHandler', 'http', 'i18n', 'route', 'toastr'],
131
129
 
132
130
  props: {
133
131
  video: {
@@ -140,7 +138,7 @@ export default {
140
138
  },
141
139
  },
142
140
 
143
- emits: ['delete', 'edit', 'start-tagging', 'stop-tagging'],
141
+ emits: ['delete', 'edit', 'start-tagging', 'stop-tagging'],
144
142
 
145
143
  data: () => ({
146
144
  tagging: false,
@@ -169,21 +167,21 @@ export default {
169
167
  };
170
168
  },
171
169
  destroyPoster() {
172
- axios.delete(this.route('howTo.posters.destroy', this.video.poster.id))
170
+ this.http.delete(this.route('howTo.posters.destroy', this.video.poster.id))
173
171
  .then(({ data }) => {
174
172
  this.toastr.success(data.message);
175
173
  this.video.poster = null;
176
174
  }).catch(this.errorHandler);
177
175
  },
178
176
  destroyVideo() {
179
- axios.delete(this.route('howTo.videos.destroy', this.video.id))
177
+ this.http.delete(this.route('howTo.videos.destroy', this.video.id))
180
178
  .then(({ data }) => {
181
179
  this.toastr.success(data.message);
182
180
  this.$emit('delete');
183
181
  }).catch(this.errorHandler);
184
182
  },
185
183
  removeTag(tag) {
186
- const index = this.video.tagList.findIndex((id) => id === tag.id);
184
+ const index = this.video.tagList.findIndex(id => id === tag.id);
187
185
  this.video.tagList.splice(index, 1);
188
186
  },
189
187
  },
@@ -0,0 +1,224 @@
1
+ <template>
2
+ <div class="video-player" v-if="reseted">
3
+ <video class="video-js" ref="video">
4
+ <track v-for="crtTrack in trackList"
5
+ :key="crtTrack.src"
6
+ :kind="crtTrack.kind"
7
+ :label="crtTrack.label"
8
+ :src="crtTrack.src"
9
+ :srcLang="crtTrack.srcLang"
10
+ :default="crtTrack.default">
11
+ </video>
12
+ </div>
13
+ </template>
14
+
15
+ <script>
16
+ // lib
17
+ import _videojs from 'video.js';
18
+
19
+ const videojs = window.videojs || _videojs;
20
+
21
+ // as of videojs 6.6.0
22
+ const DEFAULT_EVENTS = [
23
+ 'loadeddata',
24
+ 'canplay',
25
+ 'canplaythrough',
26
+ 'play',
27
+ 'pause',
28
+ 'waiting',
29
+ 'playing',
30
+ 'ended',
31
+ 'error',
32
+ ];
33
+
34
+ // export
35
+ export default {
36
+ name: 'VideoPlayer',
37
+
38
+ props: {
39
+ start: {
40
+ type: Number,
41
+ default: 0,
42
+ },
43
+ crossOrigin: {
44
+ type: String,
45
+ default: '',
46
+ },
47
+ playsinline: {
48
+ type: Boolean,
49
+ default: false,
50
+ },
51
+ customEventName: {
52
+ type: String,
53
+ default: 'statechanged',
54
+ },
55
+ options: {
56
+ type: Object,
57
+ required: true,
58
+ },
59
+ events: {
60
+ type: Array,
61
+ default: () => [],
62
+ },
63
+ globalOptions: {
64
+ type: Object,
65
+ default: () => ({
66
+ // autoplay: false,
67
+ controls: true,
68
+ // preload: 'auto',
69
+ // fluid: false,
70
+ // muted: false,
71
+ controlBar: {
72
+ remainingTimeDisplay: false,
73
+ playToggle: {},
74
+ progressControl: {},
75
+ fullscreenToggle: {},
76
+ volumeMenuButton: {
77
+ inline: false,
78
+ vertical: true,
79
+ },
80
+ },
81
+ techOrder: ['html5'],
82
+ plugins: {},
83
+ }),
84
+ },
85
+ globalEvents: {
86
+ type: Array,
87
+ default: () => [],
88
+ },
89
+ trackList: {
90
+ type: Array,
91
+ default: () => [],
92
+ },
93
+ },
94
+
95
+ emits: ['ready'],
96
+
97
+ data() {
98
+ return {
99
+ player: null,
100
+ reseted: true,
101
+ };
102
+ },
103
+
104
+ watch: {
105
+ options: {
106
+ deep: true,
107
+ handler(options) {
108
+ this.dispose(() => {
109
+ if (options && options.sources && options.sources.length) {
110
+ this.initialize();
111
+ }
112
+ });
113
+ },
114
+ },
115
+ },
116
+
117
+ mounted() {
118
+ if (!this.player) {
119
+ this.initialize();
120
+ }
121
+ },
122
+
123
+ beforeUnmount() {
124
+ if (this.player) {
125
+ this.dispose();
126
+ }
127
+ },
128
+
129
+ methods: {
130
+ initialize() {
131
+ // videojs options
132
+ const videoOptions = { ...this.globalOptions, ...this.options };
133
+
134
+ // ios fullscreen
135
+ if (this.playsinline) {
136
+ this.$refs.video.setAttribute('playsinline', this.playsinline);
137
+ this.$refs.video.setAttribute('webkit-playsinline', this.playsinline);
138
+ this.$refs.video.setAttribute('x5-playsinline', this.playsinline);
139
+ this.$refs.video.setAttribute('x5-video-player-type', 'h5');
140
+ this.$refs.video.setAttribute('x5-video-player-fullscreen', false);
141
+ }
142
+
143
+ // cross origin
144
+ if (this.crossOrigin !== '') {
145
+ this.$refs.video.crossOrigin = this.crossOrigin;
146
+ this.$refs.video.setAttribute('crossOrigin', this.crossOrigin);
147
+ }
148
+
149
+ // emit event
150
+ const emitPlayerState = (event, value) => {
151
+ if (event) {
152
+ this.$emit(event, this.player);
153
+ }
154
+ if (value) {
155
+ this.$emit(this.customEventName, { [event]: value });
156
+ }
157
+ };
158
+
159
+ // avoid error "VIDEOJS: ERROR: Unable to find plugin: __ob__"
160
+ if (videoOptions.plugins) {
161
+ delete videoOptions.plugins.__ob__;
162
+ }
163
+
164
+ // videoOptions
165
+ // console.log('videoOptions', videoOptions)
166
+
167
+ // player
168
+ const self = this;
169
+ this.player = videojs(this.$refs.video, videoOptions, function () {
170
+ // events
171
+ const events = DEFAULT_EVENTS.concat(self.events).concat(self.globalEvents);
172
+
173
+ // watch events
174
+ const onEdEvents = {};
175
+ for (let i = 0; i < events.length; i++) {
176
+ if (typeof events[i] === 'string' && onEdEvents[events[i]] === undefined) {
177
+ (event => {
178
+ onEdEvents[event] = null;
179
+ this.on(event, () => {
180
+ emitPlayerState(event, true);
181
+ });
182
+ })(events[i]);
183
+ }
184
+ }
185
+
186
+ // watch timeupdate
187
+ this.on('timeupdate', function () {
188
+ emitPlayerState('timeupdate', this.currentTime());
189
+ });
190
+
191
+ // player readied
192
+ self.$emit('ready', this);
193
+ });
194
+ },
195
+ dispose(callback) {
196
+ if (this.player && this.player.dispose) {
197
+ if (this.player.techName_ !== 'Flash') {
198
+ this.player.pause && this.player.pause();
199
+ }
200
+ this.player.dispose();
201
+ this.player = null;
202
+ this.$nextTick(() => {
203
+ this.reseted = false;
204
+ this.$nextTick(() => {
205
+ this.reseted = true;
206
+ this.$nextTick(() => {
207
+ callback && callback();
208
+ });
209
+ });
210
+ });
211
+ }
212
+ },
213
+ },
214
+ };
215
+ </script>
216
+
217
+ <style>
218
+ .vjs-custom-skin > .video-js .vjs-big-play-button {
219
+ top: 50%;
220
+ left: 50%;
221
+ margin-left: -1.5em;
222
+ margin-top: -1em
223
+ }
224
+ </style>