Geoguessr Better Menu

Adds a menu bar to Geoguessr's new UI

  1. // ==UserScript==
  2. // @name Geoguessr Better Menu
  3. // @namespace https://gf.qytechs.cn/en/users/997484-aimee4737
  4. // @version 2.7
  5. // @description Adds a menu bar to Geoguessr's new UI
  6. // @author aimee
  7. // @match https://www.geoguessr.com/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=geoguessr.com
  9. // @run-at document-start
  10. // @grant none
  11. // @license MIT
  12. // @require https://update.gf.qytechs.cn/scripts/460322/1246943/Geoguessr%20Styles%20Scan.js
  13. // ==/UserScript==
  14.  
  15. // ======================================== DO NOT EDIT OUTSIDE THIS SECTION UNLESS YOU KNOW WHAT YOU ARE DOING ========================================
  16.  
  17. // menu items (can customise following the same structure as the others)
  18. // const [variable name] = `<a href="[link]"> [name to show in menu] </a>`
  19. const singleplayer = `<a href="/singleplayer"> Singleplayer </a>`
  20. const multiplayer = `<a href="/multiplayer"> Multiplayer </a>`
  21. const party = `<a href="/play-with-friends"> Party </a>`
  22. const quiz = `<a href="/quiz"> Quiz </a>`
  23. const ongoing_games = `<a href="/me/current"> Ongoing Games </a>`
  24. const activities = `<a href="/me/activities"> Activities </a>`
  25. const my_maps = `<a href="/me/maps"> My Maps </a>`
  26. const liked_maps = `<a href="/me/likes"> Liked Maps </a>`
  27. const new_party = `<a href="/party"> Party </a>`
  28. const profile = `<a href="/me/profile"> Profile </a>`
  29. const badges = `<a href="/me/badges"> Badges </a>`
  30. const account = `<a href="/me/settings"> Account </a>`
  31. const shop = `<a href="/shop"> Shop </a>`
  32. const community = `<a href="/community"> Community </a>`
  33. const explorer = `<a href="/explorer"> Explorer </a>`
  34. const daily_challenge = `<a href="/daily-challenges"> Daily Challenge </a>`
  35. const streaks = `<a href="/streaks"> Streaks </a>`
  36.  
  37. // items to show in menu (can customise list using variable names defined above)
  38. const items = [liked_maps, ongoing_games, multiplayer, shop]
  39.  
  40. // ======================================================================================================================================================
  41.  
  42. async function setup(items) {
  43. await scanStyles();
  44.  
  45. const start = `<div class="` + cn("slanted-wrapper_root__") + ` ` + cn("slanted-wrapper_variantGrayTransparent__") + `">
  46. <div class="` + cn("slanted-wrapper_start__") + ` ` + cn("slanted-wrapper_right__") + `"></div>
  47. <div class="` + cn("page-label_labelWrapper__") + `">
  48. <div style="--fs:var(--font-size-12);--lh:var(--line-height-12)" class="` + cn("label_label__") + `">`
  49.  
  50. const end = `</div></div><div class="` + cn("slanted-wrapper_end__") + ` ` + cn("slanted-wrapper_right__") + `"></div></div>`
  51. let html = ""
  52. for (let item of items) {
  53. html = html + start + item + end
  54. }
  55.  
  56. return html
  57. }
  58.  
  59. const refresh = () => {
  60.  
  61. // only refreshes if not loading
  62. if (document.querySelector("[class^='page-loading_loading__']")) return;
  63.  
  64. // if header exists
  65. if (document.querySelector("[class^='header_header__']")) {
  66. const header = document.querySelector("[class^='header_header__']")
  67.  
  68. // hides promos
  69. if (document.querySelector("[class^='header_promoDealButtonWrapper__']")) {
  70. document.querySelector("[class^='header_promoDealButtonWrapper__']").style.display = "none"
  71. }
  72.  
  73. // hides existing page labels
  74. if (document.querySelectorAll("[class^='header_pageLabel__']").length > 1) {
  75. document.querySelectorAll("[class^='header_pageLabel__']")[1].style.display = "none"
  76. }
  77.  
  78. // adds new page labels
  79. if (!document.querySelector("[class^='newItems']")) {
  80.  
  81. let menu = document.createElement("div")
  82. menu.classList.add(cn("header_pageLabel__"))
  83. menu.style.display = "flex"
  84. header.childNodes[1].before(menu)
  85.  
  86. // creates new div from html
  87. const newItems = document.createElement("div")
  88. newItems.className = "newItems"
  89. setup(items).then(function(result) { newItems.innerHTML = result })
  90. newItems.style.display = "flex"
  91.  
  92. // prepends new div
  93. menu.prepend(newItems)
  94. }
  95.  
  96. header.style.display = "grid"
  97. header.style.gridAutoFlow = "column"
  98.  
  99. // highlights active menu item
  100. if (document.querySelector(".newItems")) {
  101. let url = window.location.href
  102. const newItems = document.querySelector(".newItems")
  103. for (let i = 0; i < newItems.childNodes.length; i++) {
  104. let link = newItems.childNodes[i].querySelector("a")
  105. link.style.color = "white"
  106. newItems.childNodes[i].classList.remove(cn("slanted-wrapper_variantWhite__"))
  107. newItems.childNodes[i].classList.add(cn("slanted-wrapper_variantGrayTransparent__"))
  108. if (link.href == url) {
  109. link.style.color = "#1a1a2e"
  110. newItems.childNodes[i].classList.remove(cn("slanted-wrapper_variantGrayTransparent__"))
  111. newItems.childNodes[i].classList.add(cn("slanted-wrapper_variantWhite__"))
  112. }
  113. }
  114. }
  115. }
  116.  
  117. if (document.querySelector("[class^='footer_footer__']")) {
  118. document.querySelector("[class^='footer_footer__']").style.display = "none"
  119. }
  120.  
  121. if (document.querySelector("[class^='signed-in-start-page_avatar__']")) {
  122. document.querySelector("[class^='signed-in-start-page_avatar__']").style.display = "none"
  123. }
  124.  
  125. if (document.querySelector("[class^='signed-in-start-page_playDailyReminder__']")) {
  126. document.querySelector("[class^='signed-in-start-page_playDailyReminder__']").style.display = "none"
  127. }
  128. }
  129.  
  130. let observer = new MutationObserver((mutations) => {
  131. refresh();
  132. });
  133.  
  134. observer.observe(document.body, {
  135. characterDataOldValue: false,
  136. subtree: true,
  137. childList: true,
  138. characterData: false
  139. });

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址