dreifachpunkt. / GeoGuessr Profile Activities

// ==UserScript==
// @name GeoGuessr Profile Activities
// @namespace    dreifachpunkt.
// @author dreifachpunkt.
// @description Displays the activities of friends in their GeoGuessr profile. Website might lag shortly when entering a users profile.
// @version 0.0.1
// @include https://www.geoguessr.com/*
// @run-at document-start
// @license MIT
// @updateURL https://openuserjs.org/meta/dreifachpunkt./GeoGuessr_Profile_Activities.meta.js
// ==/UserScript==

/*jshint esversion: 6 */

// ---------------------------------------------------------------------------------------
// If you encounter any bugs or errors, please contact me on discord: dreifachpunkt.#9954
// ---------------------------------------------------------------------------------------

const timeStrOptions = {
  hour: "numeric",
  minute: "numeric",
};
const dateStrOptions = {
  month: "numeric",
  day: "numeric",
};

var oldHref = document.location.href;

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

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

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

  observer.observe(bodyList, config);
};

function showActivities() {
  if (!location.pathname.includes("/user/")) {
    return false;
  }

  var data;

  var xmlhttp = new XMLHttpRequest();
  xmlhttp.open(
    "GET",
    "https://www.geoguessr.com/api/v3/social/feed/" +
    location.pathname.substring(6) +
    "?count=100",
    false
  );
  xmlhttp.send();
  if (xmlhttp.status === 200) {
    data = JSON.parse(xmlhttp.responseText);
  }
  else {
    //alert("An error occured, while getting user's activities.");
    return false;
  }

  var style =
    "a.customhref {\n" +
    "    color: white;\n" +
    "}\n" +
    "table.custom-table {\n" +
    "    border: 1px solid #e2e2e2;\n" +
    "    width: 50%;\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" +
    "    color: black;\n" +
    "    background-color: #FCFAF9;\n" +
    "    opacity: 0.9;\n" +
    "}\n" +
    "\n" +
    "table.custom-table td:nth-child(3) {\n" +
    "    max-width: 500px;\n" +
    "    word-break: break-word;\n" +
    "    text-align: center;\n" +
    "}\n" +
    "\n" +
    "table.custom-table td:nth-child(2) {\n" +
    "    text-align: center;\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" +
    "    text-align: center;\n" +
    "}\n" +
    "\n";

  var nicestyle = document.createElement("style");
  nicestyle.innerHTML = style;
  var activitiesTable = document.createElement("table");
  activitiesTable.setAttribute("class", "custom-table center");
  activitiesTable.setAttribute("style", "margin-bottom: 15px");
  activitiesTable.innerHTML =
    "<tr><th>Date</th><th>Activity Type</th><th>Map / User</th><th>Score</th></tr>";

  data.forEach((el) => {
    var date = Date.parse(el.dateTime);

    var trueDate = new Date(date);

    var tableRow =
      "<tr><td>" +
      trueDate.toLocaleDateString(undefined, dateStrOptions) +
      " at " +
      trueDate.toLocaleTimeString(undefined, timeStrOptions) +
      "</td>";
    switch (el.activityType) {
      case 1: //become friends
        tableRow +=
          '<td>friends</td><td><a class="customhref" href="https://www.geoguessr.com/user/' +
          el.payload.user.id +
          '">' +
          el.payload.user.nick +
          "</a></td>";
        break;
      case 2:
        tableRow += "<td>UNKNOWN TYPE</td><td></td><td></td>";
        break;
      case 3: //play game
        tableRow +=
          '<td>game</td><td><a class="customhref" href="https://www.geoguessr.com/maps/' +
          el.payload.map.slug +
          '">' +
          el.payload.map.name +
          '</a></td><td><a class="customhref" href="https://www.geoguessr.com/results/' +
          el.payload.map.gameToken +
          '">' +
          el.payload.map.score +
          "</a></td>";
        break;
      case 4: //create map
        tableRow +=
          '<td>map creation</td><td><a class="customhref" href="https://www.geoguessr.com/maps/' +
          el.payload.map.slug +
          '">' +
          el.payload.map.name +
          "</a></td>";
        break;
      case 5:
        tableRow += "<td>UNKNOWN TYPE</td><td></td><td></td>";
        break;
      case 6: //like map
        tableRow +=
          '<td>like</td><td><a class="customhref" href="https://www.geoguessr.com/maps/' +
          el.payload.map.slug +
          '">' +
          el.payload.map.name +
          "</a></td>";
        break;
      case 7:
        tableRow += "<td>UNKNOWN TYPE</td><td></td><td></td>";
        break;
      case 8: //play challenge
        tableRow +=
          '<td>challenge</td><td><a class="customhref" href="https://www.geoguessr.com/maps/' +
          el.payload.map.slug +
          '">' +
          el.payload.map.name +
          '</a></td><td><a class="customhref" href="https://www.geoguessr.com/results/' +
          el.payload.challenge.token +
          '">' +
          el.payload.challenge.score +
          "</a></td>";
        break;
      case 9:
        tableRow += "<td>UNKNOWN TYPE</td><td></td><td></td>";
        break;
      case 10:
        tableRow += "<td>UNKNOWN TYPE</td><td></td><td></td>";
        break;
      case 11:
        tableRow += "<td>UNKNOWN TYPE</td><td></td><td></td>";
        break;
      case 12: //unlock achievement
        tableRow += "<td>achievement</td><td>" + el.payload.name + "</td>";
        break;
      case 13:
        tableRow += "<td>UNKNOWN TYPE</td><td></td><td></td>";
        break;
      case 14:
        tableRow += "<td>UNKNOWN TYPE</td><td></td><td></td>";
        break;
      case 15:
        tableRow += "<td>UNKNOWN TYPE</td><td></td><td></td>";
        break;
      case 16:
        tableRow += "<td>UNKNOWN TYPE</td><td></td><td></td>";
        break;
      case 17: //play streak game
        tableRow +=
          '<td>streak</td><td></td><td><a class="customhref" href="https://www.geoguessr.com/results/' +
          el.payload.streak.gameToken +
          '">' +
          el.payload.streak.streak +
          "</a></td>";
    }
    activitiesTable.innerHTML += tableRow + "</tr>";
  });

  document.getElementsByTagName("main")[0].appendChild(nicestyle);
  document.getElementsByTagName("main")[0].appendChild(activitiesTable);
}