refactor: editor-video -> vue component + localization
This commit is contained in:
		| @@ -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')) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user