%PDF- %PDF-
| Direktori : /home/dopla/www/wp-content/plugins/ml-slider/admin/assets/js/app/slideshows/nav/ |
| Current File : /home/dopla/www/wp-content/plugins/ml-slider/admin/assets/js/app/slideshows/nav/Drawer.vue |
<template>
<div class="relative w-full">
<div
ref="drawer-container"
:style="{ 'max-height': drawerHeight }"
class="w-full bg-gray-light transition-all duration-300 ease-in overflow-hidden border-b border-gray-lightest">
<div
v-if="isIE11 && expanded && totalSlideshows > 25"
class="text-center p-2">
{{ __('This feature is not fully supported in Internet Explorer 11 and you may experience slow search result times.', 'ml-slider') }}
</div>
<div
v-if="expanded"
class="relative bg-gray border-b border-gray py-2 text-base text-black text-white w-full">
<div class="container px-6">
<div class="lg:flex items-center justify-between -mx-2">
<div class="flex lg:w-1/2 px-2 mb-2 lg:mb-0">
<div class="mr-2 rtl:mr-0 rtl:ml-2">
<select
v-model="sortType"
class="text-black bg-gray-lightest block focus:bg-white h-full leading-normal m-0 rounded shadow-none"
@change="sort()">
<option value="sortByTitle">{{ __('Sort by title', 'ml-slider') }}</option>
<option value="">{{ __('Sort by modified date', 'ml-slider') }}</option>
</select>
</div>
<div class="flex-grow relative">
<input
:placeholder="__('Filter slideshows\u200E', 'ml-slider')"
v-model="searchTerm"
data-lpignore="true"
type="text"
class="appearance-none text-black bg-gray-lightest block focus:bg-white h-full leading-normal m-0 placeholder-gray-darker rounded shadow-none transition-all duration-300 ease-in w-full"/>
<div
@click="searchTerm = ''"
:class="{ invisible: !searchTerm.length }"
class="absolute inset-y-0 right-0 rtl:right-auto rtl:left-0 pr-2 rtl:pl-2 rtl:pr-0 flex items-center text-gray-dark">
<svg class="w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</div>
</div>
</div>
<div class="lg:w-1/2 px-2">
<div class="flex items-center justify-between -mx-2">
<p
v-if="sorting"
class="m-0 text-center">
<svg class="inline w-5 ms-spin text-gray-darker" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
</svg>
{{ __('Searching...', 'ml-slider') }}
</p>
<p
v-else
class="m-0 p-2 text-center">{{ summaryText }}</p>
<div class="p-2 flex">
<!-- If they have local storage then the data is already there -->
<div
v-if="fetchingAllSlideshows"
class="flex items-center">
<svg
class="w-4 ms-spin mr-1 rtl:mr-0 rtl:ml-1"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
</svg>
<p
v-if="slideshows.length < totalSlideshows"
class="m-0">{{ loadingSlideshowsText() }}</p>
<p
v-else
class="m-0">{{ __('Updating...', 'ml-slider') }}</p>
</div>
<div v-else>
<button
v-if="slideshows.length < totalSlideshows"
@click.prevent="fetchAllSlideshows()"
:class="{ 'underline': !fetchingAllSlideshows }"
class="bg-gray-lighter leading-none m-0 outline-none px-2 py-1 rounded shadow no-underline text-xs">
{{ __('Load all', 'ml-slider') }}
</button>
<button
v-else
@click.prevent="clearCache(event)"
class="bg-gray-lighter leading-none m-0 outline-none px-2 py-1 rounded-lg shadow no-underline text-xs">
{{ __('Clear cache', 'ml-slider') }}
</button>
</div>
<div
v-if="!fetchingAllSlideshows"
class="tipsy-tooltip-bottom inline-flex ml-1 rtl:ml-0 rtl:mr-1"
:title="slideshows.length < totalSlideshows ?
sprintf(__('Load remaining %s slideshows', 'ml-slider'), totalSlideshows - slideshows.length) :
__('Press to clear the slideshow cache from your web browser', 'ml-slider')"
:original-title="slideshows.length < totalSlideshows ?
sprintf(__('Load remaining %s slideshows', 'ml-slider'), totalSlideshows - slideshows.length) :
__('Press to clear the slideshow cache from your web browser', 'ml-slider')">
<svg class="w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<template v-if="slideshowsFiltered.length || currentSlideshow">
<div class="relative">
<button
@click.prevent="toggleDrawer();searchTerm = ''"
:class="{ invisible: !expanded }"
class="absolute flex items-center mr-4 mt-5 right-0 rtl:left-0 rtl:ml-4 rtl:mr-0 rtl:right-auto top-0 text-gray-dark hover:text-black">
<svg class="w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
<ul
class="flex -mx-2 overflow-auto"
:class="{
'flex-nowrap p-4': !expanded,
'flex-wrap justify-lcenter p-10': expanded
}"
style="-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;"
role="navigation"
aria-label="Recent slideshows">
<li
:class="{
'md:w-1/2 lg:w-1/3 xl:w-1/4 3xl:w-1/5': expanded
}"
class="w-full px-4 my-2 max-w-md"
style="min-width:400px">
<span
:class="{ 'whitespace-normal': expanded }"
class="block -mx-2 rounded bg-white shadow">
<slideshow-meta :slideshow="currentSlideshow" :include-images="false"/>
</span>
</li>
<li
:key="slideshow.id"
:class="{
'md:w-1/2 lg:w-1/3 xl:w-1/4 3xl:w-1/5': expanded
}"
class="w-full px-4 my-2 max-w-md"
style="min-width:400px"
v-for="slideshow in slideshowsFiltered">
<span
:class="{ 'whitespace-normal': expanded }"
class="block -mx-2 rounded bg-white shadow">
<slideshow-meta :slideshow="slideshow" :include-images="false"/>
</span>
</li>
<li v-if="!expanded" style="min-width:4rem;"></li>
</ul>
</div>
</template>
<template v-else>
<span class="flex items-center font-normal block container text-xl my-4 h-24">
{{ searchTerm.length ? __('No slideshows found', 'ml-slider') : __('Loading slideshows...', 'ml-slider') }}
</span>
</template>
</div>
<div class="container mx-auto flex px-6">
<button
@click.prevent="toggleDrawer();searchTerm = ''"
:class="{
'bg-gray-light border-gray-light': opened,
'bg-gray-lighter pt-1 border-transparent': !opened
}"
class="block relative transition-all duration-300 ease-in text-xs text-gray-dark px-4 -mt-px border border-t-0 hover:bg-gray-light focus:bg-gray-light rounded-b shadow-none outline-none"
>
<template v-if="!opened">
{{ __('Browse slideshows', 'ml-slider') }}
</template>
<svg v-else class="w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
<button
@click.prevent="expanded = !expanded;searchTerm = ''"
v-if="opened && slideshowsFiltered.length > 4"
:title=" expanded ? __('Collapse', 'ml-slider') : __('Press to expand', 'ml-slider')"
class="block relative transition-all duration-300 ease-in text-xs text-gray-dark px-4 -mt-px border border-t-0 bg-gray-lighter hover:bg-gray-light rounded-b shadow-none outline-none border-gray-light tipsy-tooltip-bottom-toolbar"
>
<svg class="w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 9l4-4 4 4m0 6l-4 4-4-4" />
</svg>
</button>
</div>
</div>
</template>
<script>
import hotkeys from 'hotkeys-js';
import { EventManager, Helpers as _ } from '../../utils'
import FuzzySearch from 'fuzzy-search/dist/FuzzySearch';
import Settings from '../../api/Settings'
import SlideshowMeta from '../SlideshowMeta'
import { mapState, mapGetters } from 'vuex'
import slideshows from '../../store/modules/slideshows';
export default {
components: {
'slideshow-meta': SlideshowMeta
},
props: {
open: {
type: Boolean,
default: false
}
},
data() {
return {
opened: this.open,
expanded: false,
slideshowsFiltered: [],
sortType: '',
searchTerm: '',
slideshowCountdown: 0,
sorting: false
}
},
watch: {
slideshows: {
immediate: true,
handler: function(slideshows) {
this.searcher = slideshows.length ? new FuzzySearch(slideshows, ['title'], { sort: false }) : null
this.sort()
}
},
searchTerm() {
this.sorting = true
_.debounce(() => { this.sort() }, 1500)()
},
opened() {
// If we are closing the drawer, remove the expanded state
if (!this.opened) {
this.$refs['drawer-container'].style.maxHeight = '12rem'
this.expanded = false
}
this.saveNavPosition()
},
expanded() {
this.$refs['drawer-container'].style.maxHeight = 'none'
},
slideshowsFiltered() {
this.slideshowCountdown = this.totalSlideshows - this.slideshowsFiltered.length
}
},
computed: {
drawerHeight() {
return this.opened ? '12rem' : '0'
},
summaryText() {
if (!this.slideshowsFiltered.length || !this.slideshows.length) return ''
let count = this.slideshowsFiltered.length + 1 // Plus the current slideshow
if (this.slideshows.length == this.totalSlideshows) {
const message = count == 1 ?
this.__('1 slideshow', 'ml-slider') :
this.__('Viewing %s out of %s slideshows', 'ml-slider')
return this.sprintf(message, count, this.totalSlideshows)
}
const message = count == 1 ?
this.__('1 slideshow','ml-slider') :
this.__('Viewing %s out of %s slideshows (%s loaded)', 'ml-slider')
return this.sprintf(message, count, this.totalSlideshows, this.slideshows.length)
},
...mapState({
slideshows: state => state.slideshows.all,
fetchingAllSlideshows: state => state.slideshows.fetchingAll,
totalSlideshows: state => state.slideshows.totalSlideshows
}),
...mapGetters({
currentSlideshow: 'slideshows/getCurrent'
})
},
created() {
// Accept a prop to remeber the state
this.opened = this.open
// Let the draw be opened closed elsewhere if needed
EventManager.$on('metaslider/open-drawer', () => {
this.opened = true
})
EventManager.$on('metaslider/close-drawer', () => {
this.opened = false
})
// Run the filter again if the title changes
EventManager.$on('metaslider/title-saved', () => {
this.sort()
})
},
mounted() {
},
methods: {
toggleDrawer() {
this.opened = !this.opened
},
saveNavPosition: _.debounce(function() {
// Let users save the state of the nav position
Settings.saveUserSetting('metaslider_nav_drawer_opened', this.opened)
}, 3000),
sort() {
// If there is a search term then use that first before sorting
let s = this.searchTerm.trim().length ? this.searcher.search(this.searchTerm.replace(/\s/g,'')) : [...this.slideshows]
// Remove current slideshow which is handled elsewhere
if (this.currentSlideshow) {
s = s.filter(slideshow => slideshow.id != this.currentSlideshow.id)
}
this.slideshowsFiltered = s.sort(this[this.sortType])
this.sorting = false
},
sortByTitle(a, b) {
let one = a.title.toUpperCase()
let two = b.title.toUpperCase()
if (one < two) return -1
if (one > two) return 1
return 0
},
clearCache() {
window.localStorage.removeItem('metaslider-vuex-' + this.siteId)
window.location.reload(true)
},
fetchAllSlideshows() {
// Keep a counter for a slightly better UX experience
this.slideshowCountdown = this.totalSlideshows - this.slideshowsFiltered.length
const countdown = () => {
this.slideshowCountdown = this.slideshowCountdown - 1
// lag randomly
while(Math.random() > 0.0000001) {}
if (this.slideshowCountdown > 0) requestAnimationFrame(countdown)
}
requestAnimationFrame(countdown)
this.notifyInfo(
'metaslider-loading-all-slideshows',
this.sprintf(this.__('Indexing %s slideshows into local storage...', 'ml-slider'), this.totalSlideshows))
this.$store.dispatch('slideshows/getAllSlideshows').then(() => {
this.notifySuccess('metaslider/all-slideshows-loaded', this.__('All Slideshows loaded', 'ml-slider'), true)
})
},
loadingSlideshowsText() {
if (this.totalSlideshows < 200) return this.__('Fetching slideshows...', 'ml-slider')
if (this.slideshowCountdown <= 0) return this.__('Finished', 'ml-slider')
return sprintf(this.__('Indexing slideshows... %s remaining', 'ml-slider'), this.slideshowCountdown)
},
}
}
</script>