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