webframe/public/app.js

169 lines
No EOL
5.5 KiB
JavaScript

new Vue({
el: "#app",
data: {
files: [],
index: 0,
interval: null,
carouselTimeout: 20000,
carouselActive: true,
videoSrc: null,
isDownloading: false,
controlsTimeout: null,
menuVisible: false,
},
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;
},
subscribeForNewData: function () {
const ws = new WebSocket(`ws://${window.location.host}/watchdog`);
ws.onmessage = (event) => {
if (event.data) {
const data = JSON.parse(event.data);
if (data.code === 201) {
console.log('NEW IMAGE/S'); // TODO toast
this.loadData();
}
}
}
},
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);
localStorage.setItem('wf-carouselTimeout', 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.top .btn.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.top .btn.right', 'fadeOutRight'),
this.animateCSS('.floatBar.bottom .btn', 'fadeOutDown')
]).then(data => {
document.querySelector('.controls').style.display = "none"
});
}
},
toggleMenu: function () {
this.menuVisible = !this.menuVisible;
if (document.querySelector('.fullScreenMenu').style.display === "none") {
document.querySelector('.fullScreenMenu').style.display = "";
this.animateCSS('.fullScreenMenu', 'rotateIn');
} else {
Promise.all([
this.animateCSS('.fullScreenMenu', 'rotateOut'),
]).then(data => {
document.querySelector('.fullScreenMenu').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);
})
},
interfaceClick: function (time = 5000) {
clearTimeout(this.controlsTimeout)
this.controlsTimeout = setTimeout(() => this.toggleControls(), time);
},
moveToBlacklist: function (file) {
const index = this.files.findIndex(f => f.filename === file.filename);
this.files.splice(index, 1);
// TODO add file to blacklist
}
},
mounted() {
this.loadData().then(data => {
this.subscribeForNewData();
setTimeout(() => {
this.animateCSS('.floatBtn.left', 'fadeInLeft');
this.animateCSS('.floatBtn.right', 'fadeInRight');
this.animateCSS('.floatBar.top .btn.right', 'fadeInRight');
this.animateCSS('.floatBar.bottom .btn', 'fadeInUp');
this.controlsTimeout = setTimeout(() => this.toggleControls(), 2500);
}, 0);
});
if (Number(localStorage.getItem('wf-carouselTimeout'))) {
this.carouselTimeout = Number(localStorage.getItem('wf-carouselTimeout'));
this.startCarousel();
}
}
})