kommu / GeoGuessr Last Maps Played

// ==UserScript==
// @name GeoGuessr Last Maps Played
// @namespace kommu
// @description Display your last maps played on the front pages
// @version 0.0.1
// @match https://www.geoguessr.com/*
// @run-at document-start
// @license MIT
// ==/UserScript==

/*jshint esversion: 6 */

let oldHref = document.location.href;
window.addEventListener("load", (event) => {
  lastMapsBehavior();

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

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

  observer.observe(bodyList, config);
});

const isJson = (string) => {
  try {
    JSON.parse(string);
  } catch (e) {
    return false;
  }
  return true;
}

const parseJsonResponse = (response, maps) => {
  for (let index in response) {
    let response_element = response[index];
    if (!response_element.hasOwnProperty('payload')) {
      continue;
    }

    if (!response_element.hasOwnProperty('type')) {
      continue;
    }

    if (response_element.type === 1 || response_element.type === 2 || response_element.type === 5) {
      if (isJson(response_element.payload)) {
        let payload = JSON.parse(response_element.payload);
        if (payload.hasOwnProperty('mapName')) {
          maps[payload.mapSlug] = payload.mapName;
        }
        else if (payload.hasOwnProperty('mapname')) {
          maps[payload.mapSlug] = payload.mapname;
        }
      }
      else {
        if (response_element.payload.hasOwnProperty('mapName')) {
          maps[response_element.payload.mapSlug] = response_element.payload.mapName;
        }
        else if (response_element.payload.hasOwnProperty('mapname')) {
          maps[response_element.payload.mapSlug] = response_element.payload.mapname;
        }
      }
      continue;
    }

    if (response_element.type === 7) {
      let payload = JSON.parse(response_element.payload);
      parseJsonResponse(payload, maps);
    }
  }
}

const getMaps = (callback) => {
  fetch("https://www.geoguessr.com/api/v4/feed/private?count=25", {method: 'GET', async: true, contentType: 'json'})
    .then((response) => response.json())
    .then((response) => {
      if (response.hasOwnProperty('entries')) {
        const maps = {};
        parseJsonResponse(response.entries, maps);
        callback(maps);
      }
    })
    .catch(function (err) {
      // nothing.
    });
}

const lastMapsBehavior = () => {
  if (location.pathname !== '/' && location.pathname !== '/classic') {
    return false;
  }

  let style_general = document.createElement("style");
  document.head.appendChild(style_general);
  style_general.sheet.insertRule("#scrip_last_maps a {\n" +
    "    background: #1a1a1a;\n" +
    "    color: #c9c9c9;\n" +
    "    padding: 5px 10px;\n" +
    "    display: inline-block;\n" +
    "    border-radius: 6px;\n" +
    "    margin: 5px;\n" +
    "    text-decoration: none;\n" +
    "    transition-duration: 0.2s;\n" +
    "}");
  style_general.sheet.insertRule("#scrip_last_maps a:hover {\n" +
    "    transform: scale(1.1);\n\n" +
    "    color: white;\n" +
    "}");
  style_general.sheet.insertRule("#scrip_last_maps {\n" +
    "    margin-bottom: 20px;\n" +
    "    text-align: center;\n\n" +
    "}");

  let div_parent = document.createElement('div');
  div_parent.id = "scrip_last_maps";
  let elements = document.querySelector("[class^=container_content]");
  elements.prepend(div_parent);

  getMaps(async function (maps) {
    if (Object.values(maps).length === 0) {
      return;
    }

    let html = '<div>';
    for (let map_slug in maps) {
      let map = maps[map_slug];
      html += '<a href="https://www.geoguessr.com/maps/' + map_slug + '">' + map + '</a>';
    }
    html += '</div>';
    div_parent.innerHTML = html;
  });
}