MediaWiki:Common.js: Difference between revisions

From Kintara
Jump to navigation Jump to search
Add Plausible Analytics for site traffic tracking
Build calculator UI via JS (wikitext strips form tags)
 
(3 intermediate revisions by the same user not shown)
Line 43: Line 43:
});
});


/* Plausible Analytics — pageviews for kintara.wiki (dashboard: https://plausible.io) */
/* Plausible Analytics — privacy-friendly pageviews for kintara.wiki */
(function () {
(function () {
   if (document.querySelector('script[data-domain="kintara.wiki"]')) return;
   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');
   var s = document.createElement('script');
   s.defer = true;
   s.async = true;
  s.dataset.domain = 'kintara.wiki';
   s.src = 'https://plausible.io/js/pa-QBNr94JQzRuLvqXz02DEQ.js';
   s.src = 'https://plausible.io/js/script.js';
  s.onload = function () { plausible.init(); };
   document.head.appendChild(s);
   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 */

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 */