User:Rummskartoffel/talk page usage.js

Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/*
	On Special:Contributions and user (talk) pages, displays information about
	the user's most recent edits to talk namespaces.
*/

mw.loader.using(["mediawiki.util", "mediawiki.api"], function() {
  /* ==== DEFINITIONS ==== */
  function getLatestNamespaceEdit(api, username, namespace) {
    return api
      .get({
        action: "query",
        format: "json",
        list: "usercontribs",
        formatversion: "2",
        uclimit: 1,
        ucuser: username,
        ucnamespace: namespace,
      })
      .then(function(response) {
        return {
          namespace: namespace,
          edit: response.query.usercontribs[0],
        };
      });
  }

  function createResultList() {
    const div = document.createElement("div");
    div.id = "rummskartoffel-talk-page-usage";
    div.classList.add("hlist");
    div.style.fontSize = "92%";
    div.innerText = "Latest edits in namespaces: ";
    const dl = document.createElement("dl");
    dl.style.display = "inline";
    div.appendChild(dl);

    return div;
  }

  function formatTimeInterval(timestamp) {
    const interval_milliseconds = new Date(timestamp).getTime() - Date.now();
    const formatter = new Intl.RelativeTimeFormat(
      mw.config.get("wgUserLanguage"), {
        numeric: "auto",
      }
    );
    const day_milliseconds = 1000 * 60 * 60 * 24;
    const week_milliseconds = day_milliseconds * 7;
    const month_milliseconds = day_milliseconds * 30;
    const year_milliseconds = day_milliseconds * 356;

    if (interval_milliseconds < week_milliseconds)
      return formatter.format(
        Math.round(interval_milliseconds / day_milliseconds),
        "day"
      );
    else if (interval_milliseconds < month_milliseconds)
      return formatter.format(
        Math.round(interval_milliseconds / week_milliseconds),
        "week"
      );
    else if (interval_milliseconds < year_milliseconds)
      return formatter.format(
        Math.round(interval_milliseconds / month_milliseconds),
        "month"
      );
    else
      return formatter.format(
        Math.round(interval_milliseconds / year_milliseconds),
        "year"
      );
  }

  function createNamespaceResultListEntry(namespace, username, edit) {
    const dt = document.createElement("dt");
    const dt_a = document.createElement("a");
    dt.style.fontWeight = 400;
    dt_a.innerText = mw.config.get("wgFormattedNamespaces")[namespace];
    dt_a.href = mw.util.getUrl("Special:Contributions", {
      target: username,
      namespace,
    });
    if (!edit) dt_a.classList.add("new");
    dt.appendChild(dt_a);

    const dd = document.createElement("dd");
    if (edit) {
      const dd_a = document.createElement("a");
      dd_a.innerText = formatTimeInterval(edit.timestamp);
      dd_a.href = mw.util.getUrl("", {
        diff: edit.revid,
      });
      dd.appendChild(dd_a);
    } else dd.innerText = "no edits";

    return [dt, document.createTextNode(" "), dd];
  }

  /* ==== MAIN ==== */
  const is_user = !!mw.config.get("wgRelevantUserName"),
		is_contributions = mw.config.get("wgCanonicalSpecialPageName") === "Contributions",
		is_user_namespace = [2, 3].indexOf(mw.config.get("wgNamespaceNumber")) !== -1;
  if (!is_user || !(is_contributions || is_user_namespace)) {
    return;
  }
  
  mw.loader.load("/wiki/Template:Hlist/styles.css?action=raw&ctype=text/css", "text/css");

  const api = new mw.Api();
  const username = mw.config.get("wgRelevantUserName");
  const requests = [1, 3, 4, 5, 119].map(namespace =>
    getLatestNamespaceEdit(api, username, namespace)
  );
  const result_list = createResultList();
  Promise.all(requests)
    .then(results =>
      results.map(result =>
        result_list.firstElementChild.append(
          ...createNamespaceResultListEntry(
            result.namespace,
            username,
            result.edit
          )
        )
      )
    )
    .then(() => {
      const site_sub = document.getElementById("siteSub");
      if (site_sub) site_sub.after(result_list);
      else document.getElementById("bodyContent").prepend(result_list);
    });
});