MediaWiki:Common.js: Difference between revisions

From Kintara
Jump to navigation Jump to search
Add Resources Calculator interactive widget JS
Build calculator UI via JS (wikitext strips form tags)
 
(One intermediate revision by the same user not shown)
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 84: Line 78:


   function buildCalc(root) {
   function buildCalc(root) {
    if (!root || root.dataset.ready) return;
    root.dataset.ready = '1';
     root.className = 'kin-resource-calc';
     root.className = 'kin-resource-calc';
     root.innerHTML =
     root.innerHTML =
Line 110: Line 106:
     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 126: Line 122:
   function init() {
   function init() {
     var root = document.getElementById('kin-resource-calc');
     var root = document.getElementById('kin-resource-calc');
     if (root && !root.dataset.ready) {
     if (!root) return;
       root.dataset.ready = '1';
    var setup = root.querySelector('#kin-rc-setup');
       buildCalc(root);
    if (!setup || setup.tagName !== 'SELECT') {
       root.dataset.ready = '';
       root.textContent = '';
     }
     }
    buildCalc(root);
   }
   }


   if (document.readyState === 'loading') {
   function boot() {
     document.addEventListener('DOMContentLoaded', init);
    init();
    if (window.mw && mw.hook) {
      mw.hook('wikipage.content').add(function ($content) {
        var el = $content[0].querySelector('#kin-resource-calc');
        if (el) {
          el.dataset.ready = '';
          buildCalc(el);
        }
      });
    }
  }
 
  if (window.mw && mw.loader) {
    mw.loader.using('mediawiki.util').then(boot);
  } else if (document.readyState === 'loading') {
     document.addEventListener('DOMContentLoaded', boot);
   } else {
   } else {
     init();
     boot();
   }
   }
})();
})();
/* cache-bust: 2026-06-25b */

Latest revision as of 05:53, 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 buildCalc(root) {
    if (!root || root.dataset.ready) return;
    root.dataset.ready = '1';
    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');
    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() {
    var root = document.getElementById('kin-resource-calc');
    if (!root) return;
    var setup = root.querySelector('#kin-rc-setup');
    if (!setup || setup.tagName !== 'SELECT') {
      root.dataset.ready = '';
      root.textContent = '';
    }
    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) {
          el.dataset.ready = '';
          buildCalc(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-25b */