125 lines
No EOL
3.8 KiB
JavaScript
125 lines
No EOL
3.8 KiB
JavaScript
new Vue({
|
|
el: "#app",
|
|
data: {
|
|
files: [],
|
|
index: 0,
|
|
interval: null,
|
|
carouselTimeout: 20000,
|
|
carouselActive: true,
|
|
videoSrc: null,
|
|
isDownloading: false,
|
|
controlsTimeout: null,
|
|
},
|
|
methods: {
|
|
next: function () {
|
|
if (this.index + 1 < this.files.length) {
|
|
this.index++;
|
|
} else {
|
|
this.index = 0;
|
|
}
|
|
this.refreshVideoSrc();
|
|
},
|
|
nextClick: function () {
|
|
this.next();
|
|
this.startCarousel();
|
|
},
|
|
prev: function () {
|
|
if (this.index - 1 >= 0) {
|
|
this.index--;
|
|
} else {
|
|
this.index = this.files.length - 1;
|
|
}
|
|
this.refreshVideoSrc();
|
|
},
|
|
prevClick: function () {
|
|
this.next();
|
|
this.startCarousel();
|
|
},
|
|
loadData: function () {
|
|
this.isDownloading = true;
|
|
const prom = fetch('api/files').then(response => response.json());
|
|
prom.then(
|
|
data => {
|
|
this.files = data.resource || [];
|
|
this.startCarousel();
|
|
this.refreshVideoSrc();
|
|
this.isDownloading = false;
|
|
setTimeout(() => this.loadData(), (this.files.length*this.carouselTimeout)+1000);
|
|
}
|
|
);
|
|
return prom;
|
|
},
|
|
refreshVideoSrc: function () {
|
|
// force video src reload
|
|
this.videoSrc = null;
|
|
setTimeout(() => {
|
|
if (this.files[this.index].mime.includes('video')) {
|
|
this.videoSrc = '/files/'+this.files[this.index].basename;
|
|
}
|
|
}, 100);
|
|
},
|
|
startCarousel: function (time = this.carouselTimeout) {
|
|
this.carouselActive = true;
|
|
clearInterval(this.interval);
|
|
this.interval = setInterval(this.next, time);
|
|
},
|
|
stopCarousel: function () {
|
|
this.carouselActive = false;
|
|
clearInterval(this.interval);
|
|
},
|
|
toggleCarousel: function () {
|
|
if (this.carouselActive) {
|
|
this.stopCarousel();
|
|
} else {
|
|
this.startCarousel();
|
|
}
|
|
},
|
|
toggleControls: function () {
|
|
clearTimeout(this.controlsTimeout)
|
|
if (document.querySelector('.controls').style.display === "none") {
|
|
document.querySelector('.controls').style.display = "";
|
|
this.animateCSS('.floatBtn.left', 'fadeInLeft');
|
|
this.animateCSS('.floatBtn.right', 'fadeInRight');
|
|
this.animateCSS('.floatBar.bottom .btn', 'fadeInUp');
|
|
this.controlsTimeout = setTimeout(() => this.toggleControls(), 15000);
|
|
} else {
|
|
Promise.all([
|
|
this.animateCSS('.floatBtn.left', 'fadeOutLeft'),
|
|
this.animateCSS('.floatBtn.right', 'fadeOutRight'),
|
|
this.animateCSS('.floatBar.bottom .btn', 'fadeOutDown')
|
|
]).then(data => {
|
|
document.querySelector('.controls').style.display = "none"
|
|
});
|
|
}
|
|
},
|
|
animateCSS: function (element, animation, prefix = 'animate__') {
|
|
// We create a Promise and return it
|
|
return new Promise((resolve, reject) => {
|
|
const animationName = `${prefix}${animation}`;
|
|
const node = document.querySelector(element);
|
|
|
|
node.classList.add(`${prefix}animated`, animationName);
|
|
|
|
// When the animation ends, we clean the classes and resolve the Promise
|
|
function handleAnimationEnd() {
|
|
node.classList.remove(`${prefix}animated`, animationName);
|
|
node.removeEventListener('animationend', handleAnimationEnd);
|
|
|
|
resolve('Animation ended');
|
|
}
|
|
|
|
node.addEventListener('animationend', handleAnimationEnd);
|
|
})
|
|
}
|
|
},
|
|
mounted() {
|
|
this.loadData().then(data => {
|
|
setTimeout(() => {
|
|
this.animateCSS('.floatBtn.left', 'fadeInLeft');
|
|
this.animateCSS('.floatBtn.right', 'fadeInRight');
|
|
this.animateCSS('.floatBar.bottom .btn', 'fadeInUp');
|
|
this.controlsTimeout = setTimeout(() => this.toggleControls(), 2500);
|
|
}, 0);
|
|
});
|
|
}
|
|
}) |