2727 accept =" image/*"
2828 aria-hidden =" true"
2929 class =" hidden-visually"
30+ :multiple =" true"
3031 @change =" onImageUploadFilePicked" >
3132 <div v-if =" isRichEditor" ref =" menubar" class =" menubar-icons" >
3233 <template v-for =" (icon , $index ) in allIcons " >
4647 class =" submenu"
4748 :default-icon =" 'icon-image'"
4849 @open =" toggleChildMenu(icon)"
49- @close =" onImageActionClose; toggleChildMenu(icon)" >
50+ @close =" toggleChildMenu(icon)" >
5051 <button slot =" icon"
5152 :class =" { 'icon-image': true, 'loading-small': uploadingImage }"
5253 :title =" icon.label"
6566 @click =" showImagePrompt()" >
6667 {{ t('text', 'Insert from Files') }}
6768 </ActionButton >
68- <ActionButton v-if =" !showImageLinkPrompt"
69- icon =" icon-link"
70- :close-after-click =" false"
71- :disabled =" uploadingImage"
72- @click =" showImageLinkPrompt = true" >
73- {{ t('text', 'Insert from link') }}
74- </ActionButton >
75- <ActionInput v-else
76- icon =" icon-link"
77- :value =" imageLink"
78- @update:value =" onImageLinkUpdateValue"
79- @submit =" onImageLinkSubmit()" >
80- {{ t('text', 'Image link to insert') }}
81- </ActionInput >
8269 </Actions >
8370 <button v-else-if =" icon.class"
8471 v-show =" $index < iconCount"
@@ -137,30 +124,15 @@ import isMobile from './../mixins/isMobile'
137124
138125import Actions from ' @nextcloud/vue/dist/Components/Actions'
139126import ActionButton from ' @nextcloud/vue/dist/Components/ActionButton'
140- import ActionInput from ' @nextcloud/vue/dist/Components/ActionInput'
141127import PopoverMenu from ' @nextcloud/vue/dist/Components/PopoverMenu'
142128import EmojiPicker from ' @nextcloud/vue/dist/Components/EmojiPicker'
143129import ClickOutside from ' vue-click-outside'
144130import { getCurrentUser } from ' @nextcloud/auth'
145- import { showError } from ' @nextcloud/dialogs'
146-
147- const imageMimes = [
148- ' image/png' ,
149- ' image/jpeg' ,
150- ' image/jpg' ,
151- ' image/gif' ,
152- ' image/x-xbitmap' ,
153- ' image/x-ms-bmp' ,
154- ' image/bmp' ,
155- ' image/svg+xml' ,
156- ' image/webp' ,
157- ]
158131
159132export default {
160133 name: ' MenuBar' ,
161134 components: {
162135 ActionButton,
163- ActionInput,
164136 PopoverMenu,
165137 Actions,
166138 EmojiPicker,
@@ -204,6 +176,10 @@ export default {
204176 required: false ,
205177 default: 0 ,
206178 },
179+ uploadingImage: {
180+ type: Boolean ,
181+ default: false ,
182+ },
207183 },
208184 data : () => {
209185 return {
@@ -212,9 +188,6 @@ export default {
212188 forceRecompute: 0 ,
213189 submenuVisibility: {},
214190 lastImagePath: null ,
215- showImageLinkPrompt: false ,
216- uploadingImage: false ,
217- imageLink: ' ' ,
218191 icons: [... menuBarIcons],
219192 }
220193 },
@@ -353,86 +326,24 @@ export default {
353326 this .refocus ()
354327 }
355328 },
356- onImageActionClose () {
357- this .showImageLinkPrompt = false
358- },
359329 onUploadImage () {
360330 this .$refs .imageFileInput .click ()
361331 },
362332 onImageUploadFilePicked (event ) {
363- this .uploadingImage = true
364- const files = event .target .files
365- const image = files[0 ]
366- if (! imageMimes .includes (image .type )) {
367- showError (t (' text' , ' Image format not supported' ))
368- this .uploadingImage = false
369- return
370- }
371-
333+ this .$emit (' image-upload' , event .target .files )
372334 // Clear input to ensure that the change event will be emitted if
373335 // the same file is picked again.
374336 event .target .value = ' '
375-
376- this .syncService .uploadImage (image).then ((response ) => {
377- this .insertAttachmentImage (response .data ? .name , response .data ? .id )
378- }).catch ((error ) => {
379- console .error (error)
380- showError (error? .response ? .data ? .error )
381- }).then (() => {
382- this .uploadingImage = false
383- })
384- },
385- onImageLinkUpdateValue (newImageLink ) {
386- // this avoids the input being reset on each file polling
387- this .imageLink = newImageLink
388- },
389- onImageLinkSubmit () {
390- if (! this .imageLink ) {
391- return
392- }
393- this .uploadingImage = true
394- this .showImageLinkPrompt = false
395- this .$refs .imageActions [0 ].closeMenu ()
396-
397- this .syncService .insertImageLink (this .imageLink ).then ((response ) => {
398- this .insertAttachmentImage (response .data ? .name , response .data ? .id )
399- }).catch ((error ) => {
400- console .error (error)
401- showError (error? .response ? .data ? .error )
402- }).then (() => {
403- this .uploadingImage = false
404- this .imageLink = ' '
405- })
406- },
407- onImagePathSubmit (imagePath ) {
408- this .uploadingImage = true
409- this .$refs .imageActions [0 ].closeMenu ()
410-
411- this .syncService .insertImageFile (imagePath).then ((response ) => {
412- this .insertAttachmentImage (response .data ? .name , response .data ? .id )
413- }).catch ((error ) => {
414- console .error (error)
415- showError (error? .response ? .data ? .error )
416- }).then (() => {
417- this .uploadingImage = false
418- })
419337 },
420338 showImagePrompt () {
421339 const currentUser = getCurrentUser ()
422340 if (! currentUser) {
423341 return
424342 }
425- OC .dialogs .filepicker (t (' text' , ' Insert an image' ), (file ) => {
426- this .onImagePathSubmit (file )
343+ OC .dialogs .filepicker (t (' text' , ' Insert an image' ), (filePath ) => {
344+ this .$emit ( ' image-insert ' , filePath )
427345 }, false , [], true , undefined , this .imagePath )
428346 },
429- insertAttachmentImage (name , fileId ) {
430- const src = ' text://image?imageFileName=' + encodeURIComponent (name)
431- // simply get rid of brackets to make sure link text is valid
432- // as it does not need to be unique and matching the real file name
433- const alt = name .replaceAll (/ [[\] ] / g , ' ' )
434- this .editor .chain ().setImage ({ src, alt }).focus ().run ()
435- },
436347 optimalPathTo (targetFile ) {
437348 const absolutePath = targetFile .split (' /' )
438349 const relativePath = this .relativePathTo (targetFile).split (' /' )
0 commit comments