/* ========================================================================== 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(); })();