kommu / GeoGuessr Maps Enhanced

// ==UserScript==
// @name GeoGuessr Maps Enhanced
// @namespace   kommu
// @description Display all your maps in a simple table.
// @version 0.0.1
// @include https://www.geoguessr.com/*
// @run-at document-start
// @license MIT
// ==/UserScript==

/*jshint esversion: 6 */

var oldHref = document.location.href;

window.onload = (event) => {
  mapsBehavior();

  var bodyList = document.querySelector("body"),
    observer = new MutationObserver(function (mutations) {
      mutations.forEach(function (mutation) {
        if (oldHref != document.location.href) {
          oldHref = document.location.href;
          mapsBehavior();
        }
      });
    });

  var config = {
    childList: true,
    subtree: true
  };

  observer.observe(bodyList, config);
};

function mapsBehavior() {
  if (!location.pathname.startsWith("/me/maps") || location.pathname.endsWith("#")) {
    return false;
  }

  var style = "table.custom-table {\n" +
    "    border: 1px solid #e2e2e2;\n" +
    "    width: 100%;\n" +
    "    border-collapse: collapse;\n" +
    "    margin-bottom: 40px;\n" +
    "        font-size: 12px;\n" +
    "}\n" +
    "\n" +
    "table.custom-table td, table.custom-table th {\n" +
    "    padding: 5px 10px;\n" +
    "    border: 1px solid #e2e2e2;\n" +
    "}\n" +
    "\n" +
    "table.custom-table th {\n" +
    "    text-transform: uppercase;\n" +
    "    font-size: 10px;\n" +
    "}\n" +
    "\n" +
    "table.custom-table td:nth-child(3) {\n" +
    "    font-size: 10px;\n" +
    "    width: 300px!important;\n" +
    "    max-width: 500px;\n" +
    "}\n" +
    "\n" +
    "table.custom-table td:nth-child(1),\n" +
    "table.custom-table td:nth-child(4),\n" +
    "table.custom-table td:nth-child(5),\n" +
    "table.custom-table td:nth-child(6),\n" +
    "table.custom-table td:nth-child(7) {\n" +
    "    text-align: center;\n" +
    "}";
  var table = "<style>" + style + "</style><table class=\"custom-table\"><tr><th>published</th><th>Name</th><th>Description</th><th>Nb coordinates</th><th>Likes</th><th>Nb games</th><th>Actions</th></tr>";
  var current = null;
  var page = 0;
  while (current === null || current % 100 === 0) {
    if (current === null) {
      current = 0;
    }
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("GET", 'https://www.geoguessr.com/api/v3/profiles/maps?page=' + page + '&count=100', false);
    xmlhttp.send();
    if (xmlhttp.status === 200) {
      var data = JSON.parse(xmlhttp.responseText);
      current = current + data.length;
      page++;
      table += getHtml(data);
    }
    else {
      alert('An error occured, while getting maps.');
      return false;
    }
  }

  table += "</table>";
  var div = document.createElement('div');
  div.innerHTML = table;
  var elements = document.getElementsByClassName('container__content');
  elements[0].parentNode.insertBefore(div, elements[0]);
}

function getHtml(data) {
  var output = '';
  for (let obj in data) {
    var map = data[obj];
    output += '<tr>' +
      '<td>' + ((map.published) ? '✅' : '') + '</td>' +
      '<td>' + map.name + '</td>' +
      '<td style="width: 200px">' + map.description + '</td>' +
      '<td>' + map.coordinateCount + '</td>' +
      '<td>' + map.likes + '</td>' +
      '<td>' + map.numFinishedGames + '</td>' +
      '<td>' +
      '<a target="_blank" class="button button--small button--secondary" href="/map-maker/' + map.id + '"><span class="button__animation"></span><span class="button__label">Edit</span></a>' +
      '&nbsp;&nbsp;&nbsp;&nbsp;<a target="_blank" class="button button--small button--primary" href="/maps/' + map.id + '"><span class="button__animation"></span><span class="button__label">Open</span></a>' +
      '</td>' +
      '</tr>';
  }
  return output;
}