%PDF- %PDF-
| Direktori : /home/dopla/www/wp-content/plugins/ml-slider/admin/assets/js/app/slideshows/ |
| Current File : /home/dopla/www/wp-content/plugins/ml-slider/admin/assets/js/app/slideshows/Slideshow.vue |
<script>
import { Axios, Slideshow, Settings } from '../api'
import { AnalyticsNotice } from '../notices'
import { EventManager } from '../utils'
import QS from 'qs'
import Swal from 'sweetalert2'
import { mapGetters, mapState } from 'vuex'
import { MainTour } from '../tour'
export default {
props: {
id: {
type: [Number],
default: null
},
settings: {
type: [Object, Boolean],
default: false
},
tourStatus: {
type: [String, Boolean],
default: false
},
showOptIn: {
type: [String, Boolean],
default: false
},
},
data() {
return {
allowedElements: ['metaslider-ui', 'updraft-ad-container', 'metaslider-admin-notice'],
titleChanged: ''
}
},
computed: {
...mapGetters({
current: 'slideshows/getCurrent'
}),
...mapState({
locked: state => state.slideshows.locked
}),
},
created() {
window.metaslider_slider_id = this.id // used in admin.js
this.$store.commit('slideshows/setCurrent', this.id)
this.$store.dispatch('slideshows/getSingleSlideshow', this.id)
this.$store.dispatch('slideshows/getRecentSlideshows')
},
mounted() {
// Show only the allowed elements on our page (keeps rogue notices from showing)
document.querySelectorAll('#wpbody-content > *').forEach(element => {
let identifiers = element.className.split(' ').concat(element.id)
if (identifiers && this.allowedElements.filter(elm => identifiers.indexOf(elm) > -1).length) {
element.style.display = 'block'
}
})
EventManager.$on('metaslider/save', () => {
this.save()
})
EventManager.$on('metaslider/preview', data => {
let slideshowId = data && data.hasOwnProperty('slideshowId') ? data.slideshowId : this.current.id
let themeId = data && data.hasOwnProperty('themeId') ? data.themeId : this.current.theme.folder
this.save().then(() => {
this.preview(slideshowId, themeId)
})
})
EventManager.$on(['metaslider/creating-slides', 'metaslider/updating-slide'], () => {
this.$store.commit('slideshows/setLocked', true)
})
EventManager.$on([
'metaslider/slides-created', 'metaslider/slide-create-failed',
'metaslider/slide-updated', 'metaslider/slide-update-failed'
], () => {
this.$store.commit('slideshows/setLocked', false)
})
EventManager.$on('metaslider/duplicate', () => {
this.save().then(() => {
this.notifyInfo('metaslider/duplicate-pre', this.__('Duplicating...', 'ml-slider'), true)
this.duplicate()
})
})
// Listen for a successful save and enable buttons
EventManager.$on(['metaslider/save-success', 'metaslider/save-error'], () => {
this.$store.commit('slideshows/setLocked', false)
})
// Listen to start the tour (only if there's an id and it hasnt been seen)
EventManager.$on('metaslider/start-tour', () => {
!this.tourStatus && this.id && this.startTour()
})
if (!this.showOptIn) {
EventManager.$emit('metaslider/start-tour')
}
if (this.showOptIn) {
EventManager.$emit('metaslider/open-utility-modal', AnalyticsNotice)
}
window.addEventListener('load', () => {
setTimeout(() => {
this.notifyInfo('metaslider/app-loaded', this.__('MetaSlider dashboard loaded', 'ml-slider'))
}, 1500)
})
this.titleChanged = this.current.title
},
methods: {
async save() {
if (this.locked) return
this.$store.commit('slideshows/setLocked', true)
this.notifyInfo('metaslider/saving', this.__('Saving...', 'ml-slider'))
// TODO: this is temporary until there is a slide component
this.orderSlides()
let data = window.jQuery('#ms-form-settings').serializeArray()
await this.saveSettings(data).then(() => {
// Todo: refactor out slides logic
let slides = this.prepareSlideData(data)
slides.length > 20 && this.notifyInfo(
'metaslider/saving-more-notice',
this.sprintf(this.__('Saving %s slides. This may take a few moments.', 'ml-slider'), slides.length),
true
)
this.showSlideSaveNotification = false
setTimeout(() => { this.showSlideSaveNotification = true }, 4000)
return this.saveSlides(slides).then(() => {
// TODO: refactor out with psuedocode below
this.cropSlidesTheOldWay()
this.notifySuccess('metaslider/save-success', this.__('Slideshow saved', 'ml-slider'), true)
}).catch(error => {
// If the input vars are too low, reload the page with the error message
if (error.response.data.data && error.response.data.data.current_input_vars || error.response.data.includes('max_input_vars')) {
window.location.replace(this.metasliderPage + '&id=' + this.current.id + '&input_vars_error=true')
}
throw error
})
}).catch(error => {
this.notifyError('metaslider/save-error', error.response, true)
})
// TODO: refactor like this in a future branch
// let touchedSlides = getTouchedSlides()
// Only update slides that need it
// touchedSlides.forEach(element => {
// Save
// Crop
// })
// Look into only cropping if not already cropping, or better yet, to kill the initial cropping process
},
preview(slideshowId, themeId) {
EventManager.$emit('metaslider/open-preview', {
slideshowId: slideshowId,
themeId: themeId
})
},
async duplicate(slideshowId, themeId) {
Slideshow.duplicate().then(response => {
this.notifySuccess('metaslider/duplicate-success', this.__('Duplicated successfully. Reloading...', 'ml-slider'), true)
setTimeout(() => {
localStorage.removeItem('metaslider-vuex-' + this.siteId)
window.location.replace(this.metasliderPage + '&id=' + response.data.data)
}, 1500)
}).catch(error => {
this.notifyError('metaslider/duplicate-error', error, true)
})
},
startTour() {
EventManager.tourEnabled = true
// Slight timeout to avoid any funky layouts like poopy.life
setTimeout(() => {
MainTour.start()
}, 750)
// Set an event to handle cancelling the tour
MainTour.on('cancel', () => { this.cancelTour() })
},
saveSettings(data) {
let settings = data.filter(input => 'title' === input.name || input.name.startsWith('settings'))
return Settings.save(settings).then(() => {
this.notifySuccess('metaslider/save-setting-success', this.__('Settings saved', 'ml-slider'))
})
},
prepareSlideData(data) {
let slides = data.filter(input => input.name.startsWith('attachment'))
let allSlides = []
let currentSlide = ''
slides.forEach(slide => {
// Grab the id from a string like "attachment[2069][]"
let thisSlide = slide.name.match(/attachment\[([\s\S]*?)\]/)[1]
currentSlide = (currentSlide != thisSlide) ? thisSlide : currentSlide
if ('undefined' === typeof allSlides[currentSlide]) {
allSlides[currentSlide] = []
}
allSlides[currentSlide].push(slide)
})
return allSlides.filter(val => val) // re-index
},
saveSlides(slides) {
return new Promise((resolve, reject) => {
// Pro users have a sigificant amoutn of extra input variables because of scheduling
let chunks = this.proUser ? 20 : 50
Slideshow.save(slides, chunks).then(response => {
if (Array.isArray(response) && response.length) {
// Only notify the user every 4 seconds
if (this.showSlideSaveNotification && response.length >= 10) {
this.notifyInfo(
'metaslider/saving-more',
this.sprintf(
this.__('Still working... %s slides remaining...', 'ml-slider'),
Math.floor(response.length / 10) * 10
),
true
)
this.showSlideSaveNotification = false
setTimeout(() => { this.showSlideSaveNotification = true }, 4000)
}
// if there are slides that need to be processed call the function again with the remaining data
resolve(this.saveSlides(response))
} else { resolve(response) }
}).catch(error => { reject(error) })
})
},
orderSlides() {
document.querySelectorAll('#metaslider-slides-list .slide input.menu_order').forEach((element, index) => {
element.value = index
})
},
cropSlidesTheOldWay() {
window.jQuery.when(window.jQuery('.metaslider table#metaslider-slides-list').trigger('resizeSlides')).done(function() {
let $ = window.jQuery
$('button[data-thumb]').each(function() {
let $this = $(this)
$('button[data-editor_id=' + $this.attr('data-editor_id') + ']')
.attr('data-thumb', $this.attr('data-thumb'))
.attr('data-width', $this.attr('data-width'))
.attr('data-height', $this.attr('data-height'))
})
})
},
cancelTour() {
EventManager.tourEnabled = false
MainTour.setPosition()
.then(() => {
this.notifySuccess('metaslider/tour-cancelled', this.__('Tour cancelled successfully', 'ml-slider'), false)
})
.catch(() => {
this.notifySuccess('metaslider/tour-cancelled-failed', this.__('Tour cancelled unsuccessfully', 'ml-slider'), false)
})
},
deleteSlideshow() {
Swal.queue([{
icon: 'warning',
iconHtml: '<div class="dashicons dashicons-warning" style="transform: scale(3.5);"></div>',
title: this.__('Are you sure?', 'ml-slider'),
text: this.__('You will not be able to undo this.', 'ml-slider'),
confirmButtonText: this.__('Delete', 'ml-slider'),
showCancelButton: true,
confirmButtonColor: '#e82323',
focusCancel: true,
showLoaderOnConfirm: true,
allowOutsideClick: () => !Swal.isLoading(),
preConfirm: () => {
// TODO: Refactor to use api object
return Axios.post('slideshow/delete', QS.stringify({
action: 'ms_delete_slideshow',
slideshow_id: this.current.id
})).then(response => {
console.log('MetaSlider:', response.data.data)
// Set the next slideshow to show. If false, just reload the page.
this.nextSlideshow = Number.isInteger(response.data.data.message) ? response.data.data.message : false
}).catch(error => {
let errorMessage = this.getErrorMessage(error.response)
this.notifyError('metaslider/delete-error', error)
Swal.insertQueueStep({
icon: 'error',
title: this.__('Something went wrong', 'ml-slider'),
confirmButtonText: this.__('OK', 'ml-slider'),
text: errorMessage
})
})
}
}]).then(result => {
localStorage.removeItem('metaslider-vuex-' + this.siteId)
if (!result.dismiss) {
// use replace becasue the resource is deleted
this.nextSlideshow && window.location.replace(this.metasliderPage + '&id=' + this.nextSlideshow)
// If no next slideshow then just reload the current page
this.nextSlideshow || window.location.reload(true)
}
})
}
}
}
</script>
<style lang="scss">
@import '../assets/styles/main.scss';
</style>