197 lines
5.8 KiB
JavaScript
197 lines
5.8 KiB
JavaScript
/* ==========================================================================
|
|
Transfer Broadcast Graphics - Controller
|
|
Data: data/transfers.json (generated from assets/transfers-list.csv)
|
|
========================================================================== */
|
|
|
|
(function () {
|
|
"use strict";
|
|
|
|
var REVEAL_TIME = 5000; // 5 seconds in State 1, then -> compact
|
|
var AUTOPLAY_MS = 8000; // auto-advance interval
|
|
|
|
var transfers = [];
|
|
var currentIndex = 0;
|
|
var compactTimer = null;
|
|
var autoplayTimer = null;
|
|
var isHidden = true;
|
|
var autoplayOn = false;
|
|
var skipReveal = false; // if true, jump straight to compact (on reload restore)
|
|
|
|
var container, card, opCounter;
|
|
|
|
function $(id) { return document.getElementById(id); }
|
|
|
|
// --------------------------------------------------------------------
|
|
async function init() {
|
|
container = $("graphicsContainer");
|
|
card = $("transferCard");
|
|
opCounter = $("currentTransfer");
|
|
|
|
try {
|
|
var res = await fetch("data/transfers.json");
|
|
var data = await res.json();
|
|
transfers = data.transfers;
|
|
} catch (e) {
|
|
console.error("Failed to load transfers.json", e);
|
|
opCounter.textContent = "DATA ERROR";
|
|
return;
|
|
}
|
|
|
|
var saved = sessionStorage.getItem("transferIndex");
|
|
if (saved !== null) {
|
|
var idx = parseInt(saved, 10);
|
|
if (!isNaN(idx) && idx >= 0 && idx < transfers.length) {
|
|
currentIndex = idx;
|
|
skipReveal = true;
|
|
showTransfer(currentIndex);
|
|
}
|
|
}
|
|
|
|
updateCounter();
|
|
setupKeys();
|
|
console.log("Loaded " + transfers.length + " transfers. Press \u2192 or Enter to start.");
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
function showTransfer(index) {
|
|
if (!transfers.length) return;
|
|
var t = transfers[index];
|
|
if (!t) return;
|
|
|
|
container.classList.remove("compact");
|
|
|
|
// photo
|
|
$("playerPhoto").src = t.photo;
|
|
|
|
// text
|
|
$("playerName").textContent = t.playerName;
|
|
$("teamName").textContent = t.team.name;
|
|
$("teamLogo").src = t.team.logo;
|
|
|
|
// price / status
|
|
var badge = $("priceBadge");
|
|
var priceValue = $("priceValue");
|
|
var priceLabel = $("priceLabel");
|
|
|
|
badge.classList.remove("free-agent", "loan");
|
|
|
|
if (t.status === "free-agent") {
|
|
badge.classList.add("free-agent");
|
|
priceLabel.textContent = "СТАТУС";
|
|
priceValue.textContent = t.price;
|
|
} else if (t.status === "loan") {
|
|
badge.classList.add("loan");
|
|
priceLabel.textContent = "СТАТУС";
|
|
priceValue.textContent = t.price;
|
|
} else {
|
|
priceLabel.textContent = "СУММА";
|
|
priceValue.textContent = t.price;
|
|
}
|
|
|
|
// team colour vars
|
|
card.style.setProperty("--team-color", t.team.color);
|
|
card.style.setProperty("--team-accent", t.team.accent);
|
|
|
|
// show
|
|
container.classList.remove("hidden");
|
|
container.classList.add("visible");
|
|
isHidden = false;
|
|
|
|
if (skipReveal) {
|
|
skipReveal = false;
|
|
container.classList.add("compact");
|
|
card.classList.remove("reveal");
|
|
} else {
|
|
container.classList.remove("compact");
|
|
card.classList.remove("reveal");
|
|
void card.offsetWidth;
|
|
card.classList.add("reveal");
|
|
|
|
clearTimeout(compactTimer);
|
|
compactTimer = setTimeout(function () {
|
|
card.classList.remove("reveal");
|
|
container.classList.add("compact");
|
|
}, REVEAL_TIME);
|
|
}
|
|
|
|
sessionStorage.setItem("transferIndex", String(index));
|
|
updateCounter();
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
function next() {
|
|
if (isHidden) { showTransfer(currentIndex); return; }
|
|
currentIndex = (currentIndex + 1) % transfers.length;
|
|
showTransfer(currentIndex);
|
|
}
|
|
function prev() {
|
|
if (isHidden) { showTransfer(currentIndex); return; }
|
|
currentIndex = (currentIndex - 1 + transfers.length) % transfers.length;
|
|
showTransfer(currentIndex);
|
|
}
|
|
function replay() { showTransfer(currentIndex); }
|
|
|
|
function toggleHide() {
|
|
if (isHidden) {
|
|
isHidden = false;
|
|
replay();
|
|
} else {
|
|
isHidden = true;
|
|
container.classList.add("hidden");
|
|
container.classList.remove("visible");
|
|
clearTimeout(compactTimer);
|
|
}
|
|
}
|
|
|
|
function toggleAutoplay() {
|
|
autoplayOn = !autoplayOn;
|
|
if (autoplayOn) {
|
|
console.log("Autoplay ON");
|
|
if (isHidden) replay();
|
|
autoplayTimer = setInterval(next, AUTOPLAY_MS);
|
|
} else {
|
|
console.log("Autoplay OFF");
|
|
clearInterval(autoplayTimer);
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
function updateCounter() {
|
|
if (transfers.length && opCounter)
|
|
opCounter.textContent = (currentIndex + 1) + " / " + transfers.length;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
function setupKeys() {
|
|
document.addEventListener("keydown", function (e) {
|
|
switch (e.key) {
|
|
case "ArrowRight":
|
|
case "Enter":
|
|
e.preventDefault(); next(); break;
|
|
case "ArrowLeft":
|
|
case "Backspace":
|
|
e.preventDefault(); prev(); break;
|
|
case "r": case "R": replay(); break;
|
|
case "h": case "H": toggleHide(); break;
|
|
case "a": case "A": toggleAutoplay(); break;
|
|
}
|
|
});
|
|
}
|
|
|
|
// Expose for CasparCG / OBS / external control
|
|
window.transferGraphics = {
|
|
next: next,
|
|
prev: prev,
|
|
replay: replay,
|
|
hide: function () { if (!isHidden) toggleHide(); },
|
|
show: function () { if (isHidden) toggleHide(); },
|
|
showAt: function (i) { currentIndex = i; showTransfer(i); },
|
|
autoplay: toggleAutoplay,
|
|
};
|
|
|
|
// GO
|
|
if (document.readyState === "loading")
|
|
document.addEventListener("DOMContentLoaded", init);
|
|
else
|
|
init();
|
|
})(); |