refactor: editor-video -> vue component + localization
This commit is contained in:
parent
2aaebb3ce0
commit
87e780bea7
@ -56,6 +56,7 @@ import alertComponent from './components/alert.vue'
|
|||||||
import anchorComponent from './components/anchor.vue'
|
import anchorComponent from './components/anchor.vue'
|
||||||
import colorPickerComponent from './components/color-picker.vue'
|
import colorPickerComponent from './components/color-picker.vue'
|
||||||
import editorCodeblockComponent from './components/editor-codeblock.vue'
|
import editorCodeblockComponent from './components/editor-codeblock.vue'
|
||||||
|
import editorVideoComponent from './components/editor-video.vue'
|
||||||
import loadingSpinnerComponent from './components/loading-spinner.vue'
|
import loadingSpinnerComponent from './components/loading-spinner.vue'
|
||||||
import modalCreatePageComponent from './components/modal-create-page.vue'
|
import modalCreatePageComponent from './components/modal-create-page.vue'
|
||||||
import modalCreateUserComponent from './components/modal-create-user.vue'
|
import modalCreateUserComponent from './components/modal-create-user.vue'
|
||||||
@ -157,6 +158,7 @@ $(() => {
|
|||||||
contentView: contentViewComponent,
|
contentView: contentViewComponent,
|
||||||
editor: editorComponent,
|
editor: editorComponent,
|
||||||
editorCodeblock: editorCodeblockComponent,
|
editorCodeblock: editorCodeblockComponent,
|
||||||
|
editorVideo: editorVideoComponent,
|
||||||
loadingSpinner: loadingSpinnerComponent,
|
loadingSpinner: loadingSpinnerComponent,
|
||||||
modalCreatePage: modalCreatePageComponent,
|
modalCreatePage: modalCreatePageComponent,
|
||||||
modalCreateUser: modalCreateUserComponent,
|
modalCreateUser: modalCreateUserComponent,
|
||||||
|
@ -88,7 +88,7 @@
|
|||||||
this.$store.dispatch('alert', {
|
this.$store.dispatch('alert', {
|
||||||
style: 'red',
|
style: 'red',
|
||||||
icon: 'square-cross',
|
icon: 'square-cross',
|
||||||
msg: 'Error: Unable to load language syntax.'
|
msg: self.$t('editor.codeblockloadingerror')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
@ -110,7 +110,7 @@
|
|||||||
this.$store.dispatch('alert', {
|
this.$store.dispatch('alert', {
|
||||||
style: 'blue',
|
style: 'blue',
|
||||||
icon: 'inbox',
|
icon: 'inbox',
|
||||||
msg: 'Your code block has been inserted.'
|
msg: self.$t('editor.codeblocksuccess')
|
||||||
})
|
})
|
||||||
this.cancel()
|
this.cancel()
|
||||||
}
|
}
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
import $ from 'jquery'
|
|
||||||
import Vue from 'vue'
|
|
||||||
import _ from 'lodash'
|
|
||||||
|
|
||||||
const videoRules = {
|
|
||||||
'youtube': new RegExp(/(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|&v(?:i)?=))([^#&?]*).*/, 'i'),
|
|
||||||
'vimeo': new RegExp(/vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/(?:[^/]*)\/videos\/|album\/(?:\d+)\/video\/|)(\d+)(?:$|\/|\?)/, 'i'),
|
|
||||||
'dailymotion': new RegExp(/(?:dailymotion\.com(?:\/embed)?(?:\/video|\/hub)|dai\.ly)\/([0-9a-z]+)(?:[-_0-9a-zA-Z]+(?:#video=)?([a-z0-9]+)?)?/, 'i')
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = (mde, mdeModalOpenState) => {
|
|
||||||
// Vue Video instance
|
|
||||||
|
|
||||||
let vueVideo = new Vue({
|
|
||||||
el: '#modal-editor-video',
|
|
||||||
data: {
|
|
||||||
link: ''
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
open: (ev) => {
|
|
||||||
$('#modal-editor-video').addClass('is-active')
|
|
||||||
$('#modal-editor-video input').focus()
|
|
||||||
},
|
|
||||||
cancel: (ev) => {
|
|
||||||
mdeModalOpenState = false // eslint-disable-line no-undef
|
|
||||||
$('#modal-editor-video').removeClass('is-active')
|
|
||||||
vueVideo.link = ''
|
|
||||||
},
|
|
||||||
insertVideo: (ev) => {
|
|
||||||
if (mde.codemirror.doc.somethingSelected()) {
|
|
||||||
mde.codemirror.execCommand('singleSelection')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Guess video type
|
|
||||||
|
|
||||||
let videoType = _.findKey(videoRules, (vr) => {
|
|
||||||
return vr.test(vueVideo.link)
|
|
||||||
})
|
|
||||||
if (_.isNil(videoType)) {
|
|
||||||
videoType = 'video'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert video tag
|
|
||||||
|
|
||||||
let videoText = '[video](' + vueVideo.link + '){.' + videoType + '}\n'
|
|
||||||
|
|
||||||
mde.codemirror.doc.replaceSelection(videoText)
|
|
||||||
vueVideo.cancel()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return vueVideo
|
|
||||||
}
|
|
94
client/js/components/editor-video.vue
Normal file
94
client/js/components/editor-video.vue
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<template lang="pug">
|
||||||
|
transition(:duration="400")
|
||||||
|
.modal(v-show='isShown', v-cloak)
|
||||||
|
transition(name='modal-background')
|
||||||
|
.modal-background(v-show='isShown')
|
||||||
|
.modal-container
|
||||||
|
transition(name='modal-content')
|
||||||
|
.modal-content(v-show='isShown')
|
||||||
|
header.is-green
|
||||||
|
span {{ $t('editor.videotitle') }}
|
||||||
|
section
|
||||||
|
label.label
|
||||||
|
p.control.is-fullwidth
|
||||||
|
input.input(type='text', placeholder='https://www.youtube.com/watch?v=xxxxxxxxxxx', v-model='link', ref='editorVideoInput', @keyup.enter='insertVideo', @keyup.esc='cancel')
|
||||||
|
span.help.is-red(v-show='isInvalid') {{ $t('editor.videonotsupported') }}
|
||||||
|
.note {{ $t('editor.videosupportedtitle') }}
|
||||||
|
ul
|
||||||
|
li
|
||||||
|
i.icon-youtube-play
|
||||||
|
span Youtube
|
||||||
|
li
|
||||||
|
i.icon-vimeo
|
||||||
|
span Vimeo
|
||||||
|
li
|
||||||
|
i.icon-film
|
||||||
|
span Dailymotion
|
||||||
|
li
|
||||||
|
i.icon-video
|
||||||
|
span {{ $t('editor.videoanymp4file') }}
|
||||||
|
footer
|
||||||
|
a.button.is-grey.is-outlined(v-on:click='cancel') {{ $t('editor.discard') }}
|
||||||
|
a.button.is-green(v-on:click='insertVideo') {{ $t('editor.videoinsert') }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const videoRules = {
|
||||||
|
'youtube': new RegExp(/(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|&v(?:i)?=))([^#&?]*).*/, 'i'),
|
||||||
|
'vimeo': new RegExp(/vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/(?:[^/]*)\/videos\/|album\/(?:\d+)\/video\/|)(\d+)(?:$|\/|\?)/, 'i'),
|
||||||
|
'dailymotion': new RegExp(/(?:dailymotion\.com(?:\/embed)?(?:\/video|\/hub)|dai\.ly)\/([0-9a-z]+)(?:[-_0-9a-zA-Z]+(?:#video=)?([a-z0-9]+)?)?/, 'i')
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'editor-video',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
link: '',
|
||||||
|
isInvalid: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isShown () {
|
||||||
|
return this.$store.state.editorVideo.shown
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init () {
|
||||||
|
let self = this
|
||||||
|
self.isInvalid = false
|
||||||
|
self._.delay(() => {
|
||||||
|
self.$refs.editorVideoInput.focus()
|
||||||
|
}, 100)
|
||||||
|
},
|
||||||
|
cancel () {
|
||||||
|
this.$store.dispatch('editorVideo/close')
|
||||||
|
},
|
||||||
|
insertVideo () {
|
||||||
|
let self = this
|
||||||
|
|
||||||
|
if (this._.isEmpty(self.link) || self.link.length < 5) {
|
||||||
|
this.isInvalid = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let videoType = this._.findKey(videoRules, (vr) => {
|
||||||
|
return vr.test(self.link)
|
||||||
|
})
|
||||||
|
if (this._.isNil(videoType)) {
|
||||||
|
videoType = 'video'
|
||||||
|
}
|
||||||
|
let videoText = '[video](' + this.link + '){.' + videoType + '}\n'
|
||||||
|
this.$store.dispatch('editor/insert', videoText)
|
||||||
|
this.$store.dispatch('alert', {
|
||||||
|
style: 'blue',
|
||||||
|
icon: 'video',
|
||||||
|
msg: self.$t('editor.videosuccess')
|
||||||
|
})
|
||||||
|
this.cancel()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.$root.$on('editorVideo/init', this.init)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -156,9 +156,7 @@ export default {
|
|||||||
{
|
{
|
||||||
name: 'video',
|
name: 'video',
|
||||||
action: (editor) => {
|
action: (editor) => {
|
||||||
// if (!mdeModalOpenState) {
|
self.$store.dispatch('editorVideo/open')
|
||||||
// vueVideo.open()
|
|
||||||
// }
|
|
||||||
},
|
},
|
||||||
className: 'icon-video-camera2',
|
className: 'icon-video-camera2',
|
||||||
title: 'Insert Video Player'
|
title: 'Insert Video Player'
|
||||||
|
@ -5,6 +5,7 @@ import alert from './modules/alert'
|
|||||||
import anchor from './modules/anchor'
|
import anchor from './modules/anchor'
|
||||||
import editor from './modules/editor'
|
import editor from './modules/editor'
|
||||||
import editorCodeblock from './modules/editor-codeblock'
|
import editorCodeblock from './modules/editor-codeblock'
|
||||||
|
import editorVideo from './modules/editor-video'
|
||||||
import modalCreatePage from './modules/modal-create-page'
|
import modalCreatePage from './modules/modal-create-page'
|
||||||
import modalCreateUser from './modules/modal-create-user'
|
import modalCreateUser from './modules/modal-create-user'
|
||||||
import modalDiscardPage from './modules/modal-discard-page'
|
import modalDiscardPage from './modules/modal-discard-page'
|
||||||
@ -30,6 +31,7 @@ export default new Vuex.Store({
|
|||||||
anchor,
|
anchor,
|
||||||
editor,
|
editor,
|
||||||
editorCodeblock,
|
editorCodeblock,
|
||||||
|
editorVideo,
|
||||||
modalCreatePage,
|
modalCreatePage,
|
||||||
modalCreateUser,
|
modalCreateUser,
|
||||||
modalDiscardPage,
|
modalDiscardPage,
|
||||||
|
19
client/js/store/modules/editor-video.js
Normal file
19
client/js/store/modules/editor-video.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespaced: true,
|
||||||
|
state: {
|
||||||
|
shown: false
|
||||||
|
},
|
||||||
|
getters: {},
|
||||||
|
mutations: {
|
||||||
|
shownChange: (state, shownState) => { state.shown = shownState }
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
open({ commit }) {
|
||||||
|
commit('shownChange', true)
|
||||||
|
wikijs.$emit('editorVideo/init')
|
||||||
|
},
|
||||||
|
close({ commit }) { commit('shownChange', false) }
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,16 @@
|
|||||||
"codeblocktitle": "Insert Code Block",
|
"codeblocktitle": "Insert Code Block",
|
||||||
"codeblockinsert": "Insert Code Block",
|
"codeblockinsert": "Insert Code Block",
|
||||||
"codeblocklanguage": "Language",
|
"codeblocklanguage": "Language",
|
||||||
"codeblockloading": "Loading code syntax for {{name}}"
|
"codeblockloading": "Loading code syntax for {{name}}",
|
||||||
|
"codeblockloadingerror": "Error: Unable to load language syntax.",
|
||||||
|
"codeblocksuccess": "Your code block has been inserted.",
|
||||||
|
"videotitle": "Insert Video",
|
||||||
|
"videolinktitle": "Enter the link to the video to be embedded:",
|
||||||
|
"videoinsert": "Insert Video",
|
||||||
|
"videonotsupported": "This URL is invalid or not supported!",
|
||||||
|
"videosupportedtitle": "The following are supported:",
|
||||||
|
"videoanymp4file": "Any standard MP4 file",
|
||||||
|
"videosuccess": "The video code has been inserted."
|
||||||
},
|
},
|
||||||
"nav": {
|
"nav": {
|
||||||
"home": "Home"
|
"home": "Home"
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
|
|
||||||
.modal#modal-editor-video
|
|
||||||
.modal-background
|
|
||||||
.modal-container
|
|
||||||
.modal-content
|
|
||||||
header.is-green Insert Video Player
|
|
||||||
section
|
|
||||||
label.label Enter the link to the video to be embedded:
|
|
||||||
p.control.is-fullwidth
|
|
||||||
input.input(type='text', placeholder='https://www.youtube.com/watch?v=xxxxxxxxxxx', v-model='link')
|
|
||||||
span.help.is-red.is-hidden This URL is invalid or not supported!
|
|
||||||
.note The following are supported:
|
|
||||||
ul
|
|
||||||
li
|
|
||||||
i.icon-youtube-play
|
|
||||||
span Youtube
|
|
||||||
li
|
|
||||||
i.icon-vimeo
|
|
||||||
span Vimeo
|
|
||||||
li
|
|
||||||
i.icon-film
|
|
||||||
span Dailymotion
|
|
||||||
li
|
|
||||||
i.icon-video
|
|
||||||
span Any standard MP4 file
|
|
||||||
footer
|
|
||||||
a.button.is-grey.is-outlined(v-on:click='cancel') Discard
|
|
||||||
a.button.is-green(v-on:click='insertVideo') Insert Video
|
|
@ -18,5 +18,7 @@ block content
|
|||||||
.editor-area
|
.editor-area
|
||||||
textarea(ref='editorTextArea')= pageData.markdown
|
textarea(ref='editorTextArea')= pageData.markdown
|
||||||
|
|
||||||
|
editor-video
|
||||||
|
editor-codeblock
|
||||||
modal-discard-page(mode='create', current-path=pageData.meta.path)
|
modal-discard-page(mode='create', current-path=pageData.meta.path)
|
||||||
page-loader(text=t('loading.editor'))
|
page-loader(text=t('loading.editor'))
|
||||||
|
@ -18,6 +18,7 @@ block content
|
|||||||
.editor-area
|
.editor-area
|
||||||
textarea(ref='editorTextArea')= pageData.markdown
|
textarea(ref='editorTextArea')= pageData.markdown
|
||||||
|
|
||||||
|
editor-video
|
||||||
editor-codeblock
|
editor-codeblock
|
||||||
modal-discard-page(mode='edit', current-path=pageData.meta.path)
|
modal-discard-page(mode='edit', current-path=pageData.meta.path)
|
||||||
page-loader(text=t('loading.editor'))
|
page-loader(text=t('loading.editor'))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user