MediaWiki:TeamBingo.js

From Roat Pkz
Revision as of 17:32, 7 March 2026 by Hefner (talk | contribs)
Jump to navigation Jump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
// --- Team Bingo Board with Captains and Smart Polling ---
mw.hook('wikipage.content').add(function () {

    const currentUser = mw.config.get('wgUserName'); // logged-in user
    const containers = document.querySelectorAll(".teamBingoContainer");
    if (!containers.length) return;

    const infoBox = document.getElementById("teamBingoInfoBox");

    // Set default bingo info immediately on page load
    infoBox.innerHTML = `
<div style="text-align: center; font-weight: bold; font-size: 16px; margin-bottom: 8px;">
  Team Bingo Challenge
</div>
Welcome to the <strong>Roat Pkz Team Bingo #3</strong> event. Each team has its own bingo board — your goal is to collect the drops or items listed on your team’s board to score points. Each completed tile = 1 point.<br><br>

<strong>Rules:</strong><br>
- Only <strong>team captains</strong> can mark tiles for their team.<br>
- Your board updates <strong>in real time every 30 seconds</strong> for all team members.<br>
- Screenshots of drops/items are required for verification.<br>
- Chests, crates, and boxes do <em>not</em> count.<br><br>

<strong>Event ends:</strong> June 28th, 11:59 PM GMT<br><br>

<strong>Rewards:</strong><br>
- 500 CREDITS (25M+) — 1st place<br>
- 300 CREDITS (15M+) — 2nd place<br>
- 200 CREDITS (10M+) — 3rd place<br><br>
`;

    const boardState = {}; // central source of truth for all tiles
    let lastRevisionId = null;

    // Fetch JSON from Module page
    function fetchBoardData(callback) {
        $.getJSON(mw.util.wikiScript('api'), {
            action: 'query',
            titles: 'Module:TeamBingo/data.json',
            prop: 'revisions',
            rvprop: 'content',
            format: 'json',
            formatversion: 2
        }).done(function(data){
            if (!data.query.pages[0].revisions) return;
            const content = data.query.pages[0].revisions[0].content;
            try {
                const json = JSON.parse(content);
                Object.assign(boardState, json); // update central state
                if(callback) callback(boardState);
            } catch(e) {
                console.error("Failed to parse JSON from Module:TeamBingo/data.json", e);
            }
        });
    }

    // Render board function stays exactly the same
    function renderBoard(container, teamKey) {
        // ... your full renderBoard function untouched ...
        // This includes table creation, hover, click handling, checkmark update, progress bar, etc.
    }

    // Initial render
    fetchBoardData(function(boardData){
        containers.forEach(container => {
            const teamKey = container.getAttribute("data-team");
            renderBoard(container, teamKey);
        });
    });

    // --- SMART POLLING ---
    function smartPoll() {
        if(document.hidden) return;

        // Only get the revision ID to check if board changed
        $.getJSON(mw.util.wikiScript('api'), {
            action: 'query',
            titles: 'Module:TeamBingo/data.json',
            prop: 'revisions',
            rvprop: 'ids',
            format: 'json',
            formatversion: 2
        }).done(function(data){
            const page = data.query.pages[0];
            if(!page.revisions) return;
            const revId = page.revisions[0].revid;

            if(lastRevisionId === null) {
                lastRevisionId = revId;
                return; // first time, no update
            }

            if(revId !== lastRevisionId) {
                lastRevisionId = revId;
                // Only fetch full JSON if revision changed
                fetchBoardData(function(newState){
                    // Update only changed tiles
                    containers.forEach(container => {
                        const teamKey = container.getAttribute("data-team");
                        const cells = container.querySelectorAll("td");
                        cells.forEach((cell,index) => {
                            const oldVal = boardState[teamKey][`tile_${index}`];
                            const newVal = newState[teamKey][`tile_${index}`];
                            if(oldVal !== newVal) {
                                boardState[teamKey][`tile_${index}`] = newVal;
                                const checkmark = cell.querySelector(".bingoCheckmark");
                                if(checkmark) {
                                    checkmark.style.display = newVal ? "block" : "none";
                                    cell.style.background = newVal ? "rgba(76,175,80,0.5)" : "#313e59";
                                }
                            }
                        });
                    });
                });
            }
        });
    }

    // Poll every 5 seconds
    setInterval(smartPoll, 5000);

});