refactor: editor-video -> vue component + localization

pull/119/head
NGPixel 8 years ago
parent 2aaebb3ce0
commit 87e780bea7

@ -56,6 +56,7 @@ import alertComponent from './components/alert.vue'
import anchorComponent from './components/anchor.vue'
import colorPickerComponent from './components/color-picker.vue'
import editorCodeblockComponent from './components/editor-codeblock.vue'
import editorVideoComponent from './components/editor-video.vue'
import loadingSpinnerComponent from './components/loading-spinner.vue'
import modalCreatePageComponent from './components/modal-create-page.vue'
import modalCreateUserComponent from './components/modal-create-user.vue'
@ -157,6 +158,7 @@ $(() => {
contentView: contentViewComponent,
editor: editorComponent,
editorCodeblock: editorCodeblockComponent,
editorVideo: editorVideoComponent,
loadingSpinner: loadingSpinnerComponent,
modalCreatePage: modalCreatePageComponent,
modalCreateUser: modalCreateUserComponent,

@ -88,7 +88,7 @@
this.$store.dispatch('alert', {
style: 'red',
icon: 'square-cross',
msg: 'Error: Unable to load language syntax.'
msg: self.$t('editor.codeblockloadingerror')
})
}
}).catch(err => {
@ -110,7 +110,7 @@
this.$store.dispatch('alert', {
style: 'blue',
icon: 'inbox',
msg: 'Your code block has been inserted.'
msg: self.$t('editor.codeblocksuccess')
})
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
}

@ -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',
action: (editor) => {
// if (!mdeModalOpenState) {
// vueVideo.open()
// }
self.$store.dispatch('editorVideo/open')
},
className: 'icon-video-camera2',
title: 'Insert Video Player'

@ -5,6 +5,7 @@ import alert from './modules/alert'
import anchor from './modules/anchor'
import editor from './modules/editor'
import editorCodeblock from './modules/editor-codeblock'
import editorVideo from './modules/editor-video'
import modalCreatePage from './modules/modal-create-page'
import modalCreateUser from './modules/modal-create-user'
import modalDiscardPage from './modules/modal-discard-page'
@ -30,6 +31,7 @@ export default new Vuex.Store({
anchor,
editor,
editorCodeblock,
editorVideo,
modalCreatePage,
modalCreateUser,
modalDiscardPage,

@ -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",
"codeblockinsert": "Insert Code Block",
"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": {
"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
textarea(ref='editorTextArea')= pageData.markdown
editor-video
editor-codeblock
modal-discard-page(mode='create', current-path=pageData.meta.path)
page-loader(text=t('loading.editor'))

@ -18,6 +18,7 @@ block content
.editor-area
textarea(ref='editorTextArea')= pageData.markdown
editor-video
editor-codeblock
modal-discard-page(mode='edit', current-path=pageData.meta.path)
page-loader(text=t('loading.editor'))

Loading…
Cancel
Save