MediaWiki:Common.js: Difference between revisions

Update Discord injection to be simple button
Switched to use CSS class for passing arguments
 
(7 intermediate revisions by the same user not shown)
Line 1: Line 1:
/**
$(document).ready(function() {
* Winds of Valen Wiki — Common JS
    $('#ca-nstab-main a').text('Article');
*/
    $('#ca-history a').text('History');
    $('#ca-view a').text('Read');
});
// Skill Calculator logic to be embedded in MediaWiki:Common.js
mw.hook('wikipage.content').add(function($content) {
    // Only run if the page contains a calculator container
    const calcContainer = $content.find('#wiki-skill-calc')[0];
    if (!calcContainer) return;
    if (calcContainer.dataset.initialized) return;
    calcContainer.dataset.initialized = 'true';


/* 1. Force light color scheme immediately (before paint) */
    const skillClass = Array.from(calcContainer.classList).find(c => c.startsWith('skill-'));
(function () {
    if (!skillClass) {
    document.documentElement.style.colorScheme = 'light';
        calcContainer.innerHTML = "<p style='color:red;'>Error: No skill class found on container.</p>";
}());
        return;
    }
    const currentSkill = skillClass.replace('skill-', ''); // e.g., "Mining"


/* 2. Fix Vector 2022 sidebar: switch pinned-disabled → pinned-enabled */
    // Raw XP Table (Level 1 to 99)
(function () {
     const xpTable = [
     var h = document.documentElement;
         0, 0, 74, 160, 258, 371, 500, 649, 820, 1016, 1241, 1500, 1797, 2139, 2531, 2982, 3500, 4095, 4778, 5563, 6464, 7500, 8690, 10056, 11626, 13429, 15500, 17879, 20612, 23751, 27358, 31500, 36258, 41724, 48003, 55215, 63500, 73017, 83949, 96506, 110930, 127500, 146533, 168397, 193512, 222361, 255500, 293567, 337294, 387523, 445222, 511500, 587634, 675088, 775547, 890944, 1023500, 1175767, 1350676, 1551594, 1782388, 2047500, 2352034, 2701852, 3103688, 3565275, 4095500, 4704568, 5404204, 6207875, 7131050, 8191500, 9409637, 10808909, 12416250, 14262600, 16383500, 18819774, 21618318, 24833000, 28525701, 32767500, 37640048, 43237135, 49666500, 57051902, 65535500, 75280595, 86474770, 99333501, 114104303, 131071500, 150561691, 172950041, 198667502, 228209107, 262143500, 301123982, 345900582, 397335504
    h.className = h.className
    ];
         .replace('vector-feature-main-menu-pinned-disabled', 'vector-feature-main-menu-pinned-enabled');
}());


/* 3. Load Cinzel + Inter fonts */
    // Data compiled from the scraped files
(function () {
    const skillData = {
    if (!document.getElementById('wov-fonts')) {
        "Mining": [
         var l = document.createElement('link');
            { "name": "Copper Ore", "reqLevel": 1, "xp": 15 },
         l.id = 'wov-fonts';
            { "name": "Tin Ore", "reqLevel": 1, "xp": 15 },
         l.rel = 'stylesheet';
            { "name": "Iron Ore", "reqLevel": 10, "xp": 30 },
         l.href = 'https://fonts.googleapis.com/css2?family=Cinzel:wght@700&family=PT+Serif:ital,wght@0,400;0,700;1,400&family=Inter:wght@400;600&display=swap';
            { "name": "Coal Ore", "reqLevel": 20, "xp": 80 },
         document.head.appendChild(l);
            { "name": "Mithril Ore", "reqLevel": 30, "xp": 150 },
            { "name": "Gold Ore", "reqLevel": 40, "xp": 350 },
            { "name": "Essence Geode", "reqLevel": 50, "xp": 550 }
         ],
         "Fishing": [
            { "name": "Minnow", "reqLevel": 1, "xp": 8 },
            { "name": "Common Trout", "reqLevel": 5, "xp": 75 },
            { "name": "Perch", "reqLevel": 10, "xp": 225 },
            { "name": "Bass", "reqLevel": 20, "xp": 200 },
            { "name": "Blue Gill", "reqLevel": 30, "xp": 75 },
            { "name": "Elder Trout", "reqLevel": 40, "xp": 500 },
            { "name": "Carp", "reqLevel": 50, "xp": 1250 }
         ],
         "PotionMaking": [
            { "name": "Weak Health Potion", "reqLevel": 1, "xp": 25 },
            { "name": "Health Potion", "reqLevel": 10, "xp": 100 },
            { "name": "Attack Potion", "reqLevel": 25, "xp": 1500 },
            { "name": "Fishing Potion", "reqLevel": 30, "xp": 2000 },
            { "name": "Mining Potion", "reqLevel": 30, "xp": 2000 },
            { "name": "Shield Potion", "reqLevel": 40, "xp": 3500 },
            { "name": "Strong Health Potion", "reqLevel": 50, "xp": 5000 },
            { "name": "Strong Shield Potion", "reqLevel": 60, "xp": 8000 }
        ]
    };
 
    const actions = skillData[currentSkill];
    if (!actions) {
         calcContainer.innerHTML = "<p style='color:red;'>Calculator data not found for " + currentSkill + ".</p>";
        return;
     }
     }
}());


document.addEventListener('DOMContentLoaded', function () {
    // Convert level to XP
    function levelToXP(level) {
        if (level < 1) return xpTable[1];
        if (level > 99) return xpTable[99];
        return xpTable[level];
    }


     /* 4. Move main menu from hamburger dropdown into pinned sidebar slot */
     function calculateActions(currentXP, targetXP) {
    var pinned  = document.getElementById('vector-main-menu-pinned-container');
        const xpNeeded = targetXP - currentXP;
    var unpinned = document.getElementById('vector-main-menu-unpinned-container');
        if (xpNeeded <= 0) return [];
    if (pinned && unpinned && unpinned.children.length > 0 && pinned.children.length === 0) {
         return actions.map(action => {
         while (unpinned.firstChild) {
             const amount = Math.ceil(xpNeeded / action.xp);
             pinned.appendChild(unpinned.firstChild);
            return { ...action, amount, xpNeeded };
         }
         }).sort((a, b) => a.reqLevel - b.reqLevel);
     }
     }


     /* 5. Hide hamburger button since sidebar is now always visible */
     function renderCalculator() {
    var ham = document.getElementById('vector-main-menu-dropdown');
        const currentLvl = parseInt(document.getElementById('calc-current-lvl').value) || 1;
    if (ham) ham.style.display = 'none';
        const targetLvl = parseInt(document.getElementById('calc-target-lvl').value) || (currentLvl + 1);


    /* 6. Inject Logo banner + Discord button at top of sidebar */
        const currentXP = levelToXP(currentLvl);
    var sidebarEl = pinned || document.getElementById('vector-main-menu');
         const targetXP = levelToXP(targetLvl);
    if (sidebarEl) {
         const xpNeeded = targetXP - currentXP;
         var logoImg = document.querySelector('#p-logo img, #p-logo .mw-logo-icon');
         var logoSrc = logoImg ? logoImg.src : '';


         /* Logo Banner */
         let html = `
        var logoDiv = document.createElement('div');
            <div class="calc-results-header">
        logoDiv.className = 'wov-sidebar-logo';
                <h3>XP Required: <span>${xpNeeded.toLocaleString()}</span></h3>
        logoDiv.innerHTML =
                <p>From Level ${currentLvl} (${currentXP.toLocaleString()} XP) to Level ${targetLvl} (${targetXP.toLocaleString()} XP)</p>
            '<a href="/wiki/Main_Page">' +
             </div>
            (logoSrc ? '<img src="' + logoSrc + '" alt="Winds of Valen Wiki" />' : '') +
            <table class="wikitable calc-table">
             '<div class="wov-sidebar-logo-title">Winds of Valen</div>' +
                <tr><th>Action</th><th>Level Req.</th><th>XP/Action</th><th>Total Actions</th></tr>
            '<div class="wov-sidebar-logo-sub">Wiki</div>' +
         `;
            '</a>';
         sidebarEl.insertBefore(logoDiv, sidebarEl.firstChild);


         /* Simple HTML Discord Button */
         if (xpNeeded <= 0) {
         var discordDiv = document.createElement('div');
            html += `<tr><td colspan="4" style="text-align:center;">You have already reached the target level!</td></tr>`;
        discordDiv.style.padding = "10px";
         } else {
        discordDiv.innerHTML = '<a href="https://discord.gg/xxzDqg9xWc" class="wov-discord-btn-link" target="_blank" rel="noopener">Chat on Discord</a>';
            const results = calculateActions(currentXP, targetXP);
         sidebarEl.insertBefore(discordDiv, sidebarEl.children[1]);
            results.forEach(res => {
                const available = currentLvl >= res.reqLevel;
                const rowClass = available ? '' : 'calc-unavailable';
                const opacity = available ? '1' : '0.5';
                html += `
                    <tr class="${rowClass}" style="opacity: ${opacity}">
                        <td><strong>${res.name}</strong></td>
                        <td>${res.reqLevel}</td>
                        <td>${res.xp}</td>
                        <td><strong>${res.amount.toLocaleString()}</strong></td>
                    </tr>
                `;
            });
        }
        html += `</table>`;
         document.getElementById('calc-results').innerHTML = html;
     }
     }


     /* 7. Hide "Main Page" h1 on the Main Page only */
     // Inject CSS
     if (mw && mw.config && mw.config.get('wgPageName') === 'Main_Page') {
     const style = document.createElement('style');
         var h1 = document.getElementById('firstHeading');
    style.innerHTML = `
         if (h1) h1.style.display = 'none';
        .calc-wrapper {
         var mh = document.querySelector('.mw-first-heading');
            background: #1a1b26;
         if (mh) mh.style.display = 'none';
            color: #a9b1d6;
     }
            padding: 20px;
            border-radius: 8px;
            border: 1px solid #414868;
            max-width: 600px;
            margin: 20px 0;
            font-family: 'Inter', sans-serif;
            box-shadow: 0 10px 25px rgba(0,0,0,0.5);
        }
        .calc-wrapper h2 {
            margin-top: 0;
            color: #7aa2f7;
            border-bottom: 2px solid #24283b;
            padding-bottom: 10px;
        }
        .calc-inputs {
            display: flex;
            gap: 20px;
            margin-bottom: 20px;
        }
        .calc-input-group {
            display: flex;
            flex-direction: column;
            gap: 5px;
        }
        .calc-input-group label {
            font-size: 12px;
            text-transform: uppercase;
            font-weight: bold;
            color: #565f89;
        }
        .calc-input-group input {
            background: #24283b;
            border: 1px solid #414868;
            color: #c0caf5;
            padding: 10px;
            border-radius: 4px;
            width: 100px;
            font-size: 16px;
            font-weight: bold;
        }
         .calc-input-group input:focus {
            outline: none;
            border-color: #7aa2f7;
         }
        .calc-results-header h3 {
            color: #bb9af7;
            margin: 0 0 5px 0;
        }
        .calc-table {
            width: 100%;
            background: transparent !important;
            border: none !important;
            border-collapse: collapse;
         }
        .calc-table th {
            background: #24283b !important;
            color: #7dcfff !important;
            border: none !important;
            text-align: left;
            padding: 10px;
        }
        .calc-table td {
            border: none !important;
            border-bottom: 1px solid #24283b !important;
            padding: 10px;
            color: #c0caf5;
         }
        .calc-unavailable td {
            color: #565f89;
        }
        .calc-btn {
            margin-top: 19px;
            background: #7aa2f7;
            color: #1a1b26;
            border: none;
            padding: 10px 20px;
            border-radius: 4px;
            font-weight: bold;
            cursor: pointer;
            transition: all 0.2s ease;
        }
        .calc-btn:hover {
            background: #8caaee;
        }
    `;
    document.head.appendChild(style);
 
    // Initial Layout Setup
     calcContainer.innerHTML = `
        <div class="calc-wrapper">
            <h2>${currentSkill} Calculator</h2>
            <div class="calc-inputs">
                <div class="calc-input-group">
                    <label>Current Level</label>
                    <input type="number" id="calc-current-lvl" value="1" min="1" max="99">
                </div>
                <div class="calc-input-group">
                    <label>Target Level</label>
                    <input type="number" id="calc-target-lvl" value="10" min="2" max="99">
                </div>
                <button class="calc-btn" id="calc-refresh-btn">Calculate</button>
            </div>
            <div id="calc-results"></div>
        </div>
    `;


    /* 8. Make .wov-popular-btn spans behave as full-block links */
     document.getElementById('calc-current-lvl').addEventListener('change', renderCalculator);
     document.querySelectorAll('.wov-popular-grid a').forEach(function (a) {
    document.getElementById('calc-target-lvl').addEventListener('change', renderCalculator);
        a.style.display = 'block';
    document.getElementById('calc-refresh-btn').addEventListener('click', renderCalculator);
        a.style.textDecoration = 'none';
        var span = a.querySelector('.wov-popular-btn');
        if (span) {
            span.style.display = 'block';
        }
    });


    // Render initially
    renderCalculator();
});
});