Geoguessr Better Menu

Adds a menu bar to Geoguessr's new UI

当前为 2023-06-10 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Geoguessr Better Menu
// @namespace    https://greasyfork.org/en/users/997484-aimee4737
// @version      2.1
// @description  Adds a menu bar to Geoguessr's new UI
// @author       aimee
// @match        https://www.geoguessr.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=geoguessr.com
// @run-at       document-start
// @grant        none
// @license      MIT
// ==/UserScript==

// ======================================== DO NOT EDIT OUTSIDE THIS SECTION UNLESS YOU KNOW WHAT YOU ARE DOING ========================================

// menu items (can customise following the same structure as the others)
// const [variable name] = `<a href="[link]"> [name to show in menu] </a>`
const singleplayer = `<a href="/singleplayer"> Singleplayer </a>`
const multiplayer = `<a href="/multiplayer"> Multiplayer </a>`
const party = `<a href="/play-with-friends"> Party </a>`
const quiz = `<a href="/quiz"> Quiz </a>`
const ongoingGames = `<a href="/me/current"> Ongoing Games </a>`
const activities = `<a href="/me/activities"> Activities </a>`
const myMaps = `<a href="/me/maps"> My Maps </a>`
const likedMaps = `<a href="/me/likes"> Liked Maps </a>`
const newParty = `<a href=/party"> Party </a>`
const profile = `<a href=/me/profile"> Profile </a>`
const badges = `<a href=/me/badges"> Badges </a>`
const account = `<a href=/me/settings"> Account </a>`

// items to show in menu (can customise list using variable names defined above)
const items = [singleplayer, multiplayer, party, ongoingGames, activities, likedMaps]

// ======================================================================================================================================================

const start = `<div class="slanted-wrapper_root__2eaEs slanted-wrapper_variantGrayTransparent__aufaF">
               <div class="slanted-wrapper_start__Kl7rv slanted-wrapper_right__G0JWR"></div>
               <div class="page-label_labelWrapper__o1vpe">
               <div class="label_sizeXSmall__mFnrR">`

const end = `</div></div><div class="slanted-wrapper_end__cD1Qu slanted-wrapper_right__G0JWR"></div></div>`

let html = ""

for (let item of items) {
    html = html + start + item + end
}

const refresh = () => {
    // only refreshes if not loading
    if (document.querySelector("[class^='page-loading_loading__']")) return;

    // if header exists
    if (document.querySelector("[class^='header_header__']")) {
        const header = document.querySelector("[class^='header_header__']")

        // gets right section of header and hides avatar deals (div without any classes)
        const right = header.querySelector("[class^='header_context__']")
        for (let child of right.childNodes) {
            if (child.nodeName == "DIV" && child.classList.length == 0) {
                console.log(child)
                child.style.display = "none"
            }
        }

        // gets menu (middle) section of header (div without any classes)
        let menu
        for (let section of header.childNodes) {
            if (section.classList.length == 0) {
                menu = section
                menu.style.display = "flex"
                break
            }
        }
        // hides old menu items
        for (let child of menu.childNodes) {
            if (!child.classList.contains("newItems")) {
                child.style.display = "none"
            }
        }
        // adds better menu items
        if (document.querySelector(".newItems") === null) {
            // creates new div from html
            const newItems = document.createElement("div")
            newItems.className = "newItems"
            newItems.innerHTML = html
            newItems.style.display = "flex"
            // prepends new div
            menu.prepend(newItems)
        }
    }

    // highlights active menu item
    if (document.querySelector(".newItems")) {
        let url = window.location.href
        const newItems = document.querySelector(".newItems")
        for (let i = 0; i < newItems.childNodes.length; i++) {
            let link = newItems.childNodes[i].querySelector("a")
            link.style.color = "white"
            newItems.childNodes[i].classList.remove("slanted-wrapper_variantWhite__VKHvw")
            newItems.childNodes[i].classList.add("slanted-wrapper_variantGrayTransparent__aufaF")
            if (link.href == url) {
                link.style.color = ""
                newItems.childNodes[i].classList.remove("slanted-wrapper_variantGrayTransparent__aufaF")
                newItems.childNodes[i].classList.add("slanted-wrapper_variantWhite__VKHvw")
            }
       }
    }

    // hides maprunner on home
    if (document.querySelector("[class^='maprunner-start-page_content__']")) {
        document.querySelector("[class^='maprunner-start-page_content__']").style.display = "none"
    }
    if (document.querySelector("[class^='maprunner-start-page_progress__']")) {
        document.querySelector("[class^='maprunner-start-page_progress__']").style.display = "none"
    }
    if (document.querySelector("[class^='maprunner-signed-in-start-page_gradientPlate__']")) {
        document.querySelector("[class^='maprunner-signed-in-start-page_gradientPlate__']").style.display = "none"
    }
    if (document.querySelector("[class^='maprunner-signed-in-start-page_avatar__']")) {
        document.querySelector("[class^='maprunner-signed-in-start-page_avatar__']").style.display = "none"
    }

    // hides footer on home
    if (document.querySelector("[class^='footer_footer__']")) {
        document.querySelector("[class^='footer_footer__']").style.display = "none"
    }

    // hides secondary menu on home
    if (document.querySelector("[class^='secondary-menu_menu__']") && !document.querySelector("[class^='pop-out-main-menu_wrapper__']")) {
        document.querySelector("[class^='secondary-menu_menu__']").style.display = "none"
    }

    // hides ongoing games on home
    if (document.querySelectorAll("[class^='primary-menu_wrapper__']")) {
        const primaryMenu = document.querySelector("[class^='primary-menu_wrapper__']")
        for (let child of primaryMenu.childNodes) {
            if (child.childNodes.length > 1) {
                child.style.display = "none"
            }
        }
    }
}

let observer = new MutationObserver((mutations) => {
    refresh();
});

observer.observe(document.body, {
  characterDataOldValue: false,
  subtree: true,
  childList: true,
  characterData: false
});