MediaWiki:Common.js: Difference between revisions

From Kintara
Jump to navigation Jump to search
Add Resources Calculator interactive widget JS
Fix Resources Calculator JS init + cache bust
Line 58: Line 58:
   document.head.appendChild(s);
   document.head.appendChild(s);
})();
})();
/* Resources Calculator — interactive widget on Category:Resources Calculator */
/* Resources Calculator — interactive widget on Category:Resources Calculator */
(function () {
(function () {
  'use strict';
   var RATES = {
   var RATES = {
     wood_1: { label: 'Wood · Lvl 1 Axe', min: 60, max: 96, unit: 'Wood' },
     wood_1: { label: 'Wood · Lvl 1 Axe', min: 60, max: 96, unit: 'Wood' },
Line 68: Line 68:
     fish_1: { label: 'Fish · Fishing Rod', min: 2, max: 4, unit: 'Fish' },
     fish_1: { label: 'Fish · Fishing Rod', min: 2, max: 4, unit: 'Fish' },
   };
   };
  function fmtNum(n) {
    if (n >= 1000000) return (n / 1000000).toFixed(2).replace(/\.?0+$/, '') + 'M';
    if (n >= 1000) return (n / 1000).toFixed(1).replace(/\.0$/, '') + 'k';
    return String(Math.round(n * 10) / 10);
  }


   function fmtDuration(minutes) {
   function fmtDuration(minutes) {
Line 83: Line 77:
   }
   }


   function buildCalc(root) {
   function wireCalc(root) {
    if (!root || root.dataset.ready) return;
    root.dataset.ready = '1';
     root.className = 'kin-resource-calc';
     root.className = 'kin-resource-calc';
    root.innerHTML =
      '<div class="kin-rc-card">' +
        '<div class="kin-rc-head">Gathering time estimator</div>' +
        '<p class="kin-rc-note">Uses midpoint rate: (min + max) ÷ 2 per minute. Does not include travel between nodes or competition.</p>' +
        '<div class="kin-rc-fields">' +
          '<label class="kin-rc-field"><span>Setup</span><select id="kin-rc-setup"></select></label>' +
          '<label class="kin-rc-field"><span>Target amount</span><input id="kin-rc-target" type="number" min="1" step="1" value="1000" /></label>' +
        '</div>' +
        '<div class="kin-rc-results">' +
          '<div class="kin-rc-stat"><span class="kin-rc-stat-label">Rate range</span><strong id="kin-rc-rate">—</strong></div>' +
          '<div class="kin-rc-stat"><span class="kin-rc-stat-label">Midpoint rate</span><strong id="kin-rc-mid">—</strong></div>' +
          '<div class="kin-rc-stat kin-rc-stat--highlight"><span class="kin-rc-stat-label">Estimated time</span><strong id="kin-rc-time">—</strong></div>' +
        '</div>' +
      '</div>';


     var setup = root.querySelector('#kin-rc-setup');
     var setup = root.querySelector('#kin-rc-setup');
     Object.keys(RATES).forEach(function (key) {
     if (!setup) return;
      var opt = document.createElement('option');
 
      opt.value = key;
    if (!setup.options.length) {
      opt.textContent = RATES[key].label;
      Object.keys(RATES).forEach(function (key) {
      setup.appendChild(opt);
        var opt = document.createElement('option');
    });
        opt.value = key;
        opt.textContent = RATES[key].label;
        setup.appendChild(opt);
      });
    }


     function update() {
     function update() {
       var cfg = RATES[setup.value];
       var cfg = RATES[setup.value];
       var target = parseFloat(root.querySelector('#kin-rc-target').value);
       var target = parseFloat(root.querySelector('#kin-rc-target').value, 10);
       var mid = (cfg.min + cfg.max) / 2;
       var mid = (cfg.min + cfg.max) / 2;
       root.querySelector('#kin-rc-rate').textContent = cfg.min + '–' + cfg.max + ' / min';
       root.querySelector('#kin-rc-rate').textContent = cfg.min + '–' + cfg.max + ' / min';
Line 125: Line 111:


   function init() {
   function init() {
     var root = document.getElementById('kin-resource-calc');
     wireCalc(document.getElementById('kin-resource-calc'));
     if (root && !root.dataset.ready) {
  }
       root.dataset.ready = '1';
 
       buildCalc(root);
  function boot() {
    init();
     if (window.mw && mw.hook) {
       mw.hook('wikipage.content').add(function ($content) {
        var el = $content[0].querySelector('#kin-resource-calc');
        if (el) wireCalc(el);
       });
     }
     }
   }
   }


   if (document.readyState === 'loading') {
   if (window.mw && mw.loader) {
     document.addEventListener('DOMContentLoaded', init);
    mw.loader.using('mediawiki.util').then(boot);
  } else if (document.readyState === 'loading') {
     document.addEventListener('DOMContentLoaded', boot);
   } else {
   } else {
     init();
     boot();
   }
   }
})();
})();
/* cache-bust: 2026-06-25 */

Revision as of 05:48, 25 June 2026

/* Kintara dashboard sky — drifting geo clouds (matches kintara.com leaderboard backdrop) */
(function () {
  function injectKinSky() {
    if (document.getElementById('kin-sky-backdrop')) return;
    var el = document.createElement('div');
    el.id = 'kin-sky-backdrop';
    el.setAttribute('aria-hidden', 'true');
    el.innerHTML =
      '<div class="kin-sky-clouds">' +
      '<div class="kin-geo-puff kin-geo-puff--1"><span class="kin-geo-block kin-geo-block--a"></span><span class="kin-geo-block kin-geo-block--b"></span><span class="kin-geo-block kin-geo-block--c"></span></div>' +
      '<div class="kin-geo-puff kin-geo-puff--2"><span class="kin-geo-block kin-geo-block--a"></span><span class="kin-geo-block kin-geo-block--b"></span><span class="kin-geo-block kin-geo-block--c"></span><span class="kin-geo-block kin-geo-block--d"></span></div>' +
      '<div class="kin-geo-puff kin-geo-puff--3"><span class="kin-geo-block kin-geo-block--a"></span><span class="kin-geo-block kin-geo-block--b"></span><span class="kin-geo-block kin-geo-block--c"></span></div>' +
      '<div class="kin-geo-puff kin-geo-puff--4"><span class="kin-geo-block kin-geo-block--a"></span><span class="kin-geo-block kin-geo-block--b"></span><span class="kin-geo-block kin-geo-block--c"></span><span class="kin-geo-block kin-geo-block--d"></span></div>' +
      '<div class="kin-geo-puff kin-geo-puff--5"><span class="kin-geo-block kin-geo-block--a"></span><span class="kin-geo-block kin-geo-block--b"></span><span class="kin-geo-block kin-geo-block--c"></span></div>' +
      '<div class="kin-geo-puff kin-geo-puff--6"><span class="kin-geo-block kin-geo-block--a"></span><span class="kin-geo-block kin-geo-block--b"></span><span class="kin-geo-block kin-geo-block--c"></span><span class="kin-geo-block kin-geo-block--d"></span></div>' +
      '</div>';
    document.body.insertBefore(el, document.body.firstChild);
  }
  if (document.body) injectKinSky();
  else document.addEventListener('DOMContentLoaded', injectKinSky);
})();

mw.loader.using('mediawiki.util').then(function () {
  if (mw.config.get('wgPageName') === 'Main_Page') {
    document.querySelectorAll(
      '.kin-promo.discord .pbody a, .kin-promo.xbox .pbody a'
    ).forEach(function (link) {
      link.setAttribute('target', '_blank');
      link.setAttribute('rel', 'nofollow noopener noreferrer');
    });
  }

  var tabs = document.querySelector('#p-namespaces ul');
  if (tabs && !document.getElementById('ca-kintara-play')) {
    var playTab = document.createElement('li');
    playTab.id = 'ca-kintara-play';
    playTab.className = 'mw-list-item';
    playTab.innerHTML =
      '<a href="https://kintara.com/" target="_blank" rel="nofollow noopener noreferrer"><span>Play Now</span></a>';

    tabs.appendChild(playTab);
  }
});

/* Plausible Analytics — privacy-friendly pageviews for kintara.wiki */
(function () {
  if (document.querySelector('script[src*="pa-QBNr94JQzRuLvqXz02DEQ.js"]')) return;
  window.plausible = window.plausible || function () {
    (plausible.q = plausible.q || []).push(arguments);
  };
  plausible.init = plausible.init || function (i) {
    plausible.o = i || {};
  };
  var s = document.createElement('script');
  s.async = true;
  s.src = 'https://plausible.io/js/pa-QBNr94JQzRuLvqXz02DEQ.js';
  s.onload = function () { plausible.init(); };
  document.head.appendChild(s);
})();
/* Resources Calculator — interactive widget on Category:Resources Calculator */
(function () {
  'use strict';
  var RATES = {
    wood_1: { label: 'Wood · Lvl 1 Axe', min: 60, max: 96, unit: 'Wood' },
    wood_2: { label: 'Wood · Lvl 2 Axe', min: 120, max: 192, unit: 'Wood' },
    mine_1: { label: 'Stone/Coal/Metal · Lvl 1 Pickaxe', min: 84, max: 120, unit: 'resources' },
    mine_2: { label: 'Stone/Coal/Metal · Lvl 2 Pickaxe', min: 168, max: 240, unit: 'resources' },
    fish_1: { label: 'Fish · Fishing Rod', min: 2, max: 4, unit: 'Fish' },
  };

  function fmtDuration(minutes) {
    if (!isFinite(minutes) || minutes <= 0) return '—';
    if (minutes < 60) return Math.round(minutes * 10) / 10 + ' minutes';
    var h = minutes / 60;
    if (h < 24) return Math.round(h * 10) / 10 + ' hours';
    return Math.round((h / 24) * 10) / 10 + ' days';
  }

  function wireCalc(root) {
    if (!root || root.dataset.ready) return;
    root.dataset.ready = '1';
    root.className = 'kin-resource-calc';

    var setup = root.querySelector('#kin-rc-setup');
    if (!setup) return;

    if (!setup.options.length) {
      Object.keys(RATES).forEach(function (key) {
        var opt = document.createElement('option');
        opt.value = key;
        opt.textContent = RATES[key].label;
        setup.appendChild(opt);
      });
    }

    function update() {
      var cfg = RATES[setup.value];
      var target = parseFloat(root.querySelector('#kin-rc-target').value, 10);
      var mid = (cfg.min + cfg.max) / 2;
      root.querySelector('#kin-rc-rate').textContent = cfg.min + '–' + cfg.max + ' / min';
      root.querySelector('#kin-rc-mid').textContent = mid + ' ' + cfg.unit + ' / min';
      root.querySelector('#kin-rc-time').textContent = (!target || target <= 0)
        ? 'Enter a target amount'
        : fmtDuration(target / mid);
    }

    setup.addEventListener('change', update);
    root.querySelector('#kin-rc-target').addEventListener('input', update);
    update();
  }

  function init() {
    wireCalc(document.getElementById('kin-resource-calc'));
  }

  function boot() {
    init();
    if (window.mw && mw.hook) {
      mw.hook('wikipage.content').add(function ($content) {
        var el = $content[0].querySelector('#kin-resource-calc');
        if (el) wireCalc(el);
      });
    }
  }

  if (window.mw && mw.loader) {
    mw.loader.using('mediawiki.util').then(boot);
  } else if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', boot);
  } else {
    boot();
  }
})();
/* cache-bust: 2026-06-25 */