Seterra (by GeoGuessr) Fullscreen Mode

Adds a fullscreen mode button to Seterra

  1. // ==UserScript==
  2. // @name Seterra (by GeoGuessr) Fullscreen Mode
  3. // @name:de Seterra Vollbildmodus
  4. // @name:fr Mode plein écran Seterra
  5. // @name:it Modalità schermo intero Seterra
  6. // @name:ja Seterra フルスクリーンモード
  7. // @name:nl Seterra Volledig Scherm Modus
  8. // @name:tr Seterra Tam Ekran Modu
  9. // @name:es Modo de pantalla completa de Seterra
  10. // @name:pt Modo de tela cheia Seterra
  11. // @name:sv Seterra Helskärmsläge
  12. // @name:pl Tryb pełnoekranowy Seterra
  13. // @namespace http://tampermonkey.net/
  14. // @version 1.2
  15. // @description Adds a fullscreen mode button to Seterra
  16. // @description:de Fügt eine Vollbildmodus-Schaltfläche zu Seterra hinzu
  17. // @description:fr Ajoute un bouton de mode plein écran à Seterra
  18. // @description:it Aggiunge un pulsante per la modalità a schermo intero in Seterra
  19. // @description:ja Seterraにフルスクリーンモードボタンを追加します
  20. // @description:nl Voegt een volledig scherm knop toe aan Seterra
  21. // @description:tr Seterra'ya tam ekran modu düğmesi ekler
  22. // @description:es Agrega un botón de modo de pantalla completa a Seterra
  23. // @description:pt Adiciona um botão de modo de tela cheia ao Seterra
  24. // @description:sv Lägger till en helskärmsläge-knapp till Seterra
  25. // @description:pl Dodaje przycisk trybu pełnoekranowego do Seterra
  26. // @author TWolf01
  27. // @license MIT
  28. // @match https://www.geoguessr.com/vgp/*
  29. // @match https://www.geoguessr.com/*/vgp/*
  30. // @icon https://www.geoguessr.com/favicon.ico
  31. // @run-at document-end
  32. // @grant none
  33. // ==/UserScript==
  34.  
  35. (function() {
  36. 'use strict';
  37.  
  38. const GAME_MAP_SELECTOR = "[class^='game-area_mapWrapper__']";
  39. const FOOTER_BUTTONS_SELECTOR = "[class^='game-footer_buttons__']";
  40. const FULLSCREEN_STYLE_CLASS = "custom-fullscreen-style";
  41. const FULLSCREEN_BUTTON_CLASS = "custom-fullscreen-button";
  42.  
  43. const languageCode = document.documentElement.lang || navigator.language || "en";
  44.  
  45. const translations = {
  46. de: "Vollbild",
  47. fr: "Plein écran",
  48. it: "Schermo intero",
  49. ja: "全画面",
  50. nl: "Volledig scherm",
  51. tr: "Tam ekran",
  52. es: "Pantalla completa",
  53. pt: "ecrã inteiro",
  54. sv: "Helskärm",
  55. pl: "Pełny ekran"
  56. };
  57.  
  58. const fullscreenText = translations[languageCode] || "Fullscreen";
  59.  
  60. function updateStyle(stylesheet, selectors, padding) {
  61. const content = `${selectors} { padding-left: ${padding}px; padding-right: ${padding}px; }`;
  62. if (stylesheet) {
  63. if (!stylesheet.textContent.includes(`padding-left: ${padding}px`)) stylesheet.textContent = content;
  64. } else {
  65. const style = document.createElement('style');
  66. style.className = FULLSCREEN_STYLE_CLASS;
  67. style.textContent = content;
  68. document.head.appendChild(style);
  69. }
  70. }
  71.  
  72. function createFullscreenStyles(gameMap) {
  73. const heightRatio = (window.screen.height - gameMap.clientHeight) / gameMap.clientHeight;
  74. const padding = (window.screen.width - (gameMap.clientWidth * (1 + heightRatio))) / 2;
  75.  
  76. if (padding > 5 && padding < 100000) {
  77. const selectors = `
  78. :fullscreen,
  79. :fullscreen div[class^='game-header_wrapper'],
  80. :fullscreen div[class^='corner-image_wrapper'],
  81. :fullscreen div[class^='game-area_mapWrapper']`;
  82. updateStyle(document.head.querySelector(`style.${FULLSCREEN_STYLE_CLASS}`), selectors, padding);
  83. }
  84. }
  85.  
  86. function createFullscreenButton(footerContainer, gameMap) {
  87. if (footerContainer.querySelector(`.${FULLSCREEN_BUTTON_CLASS}`)) return;
  88.  
  89. const button = document.createElement("button");
  90. button.textContent = fullscreenText;
  91. button.className = FULLSCREEN_BUTTON_CLASS;
  92. Object.assign(button.style, {
  93. padding: "10px", backgroundColor: "blue", color: "white",
  94. border: "none", borderRadius: "5px", cursor: "pointer",
  95. });
  96.  
  97. button.addEventListener("click", () => {
  98. gameMap.requestFullscreen?.() || gameMap.webkitRequestFullscreen?.() || gameMap.msRequestFullscreen?.();
  99. });
  100.  
  101. footerContainer.appendChild(button);
  102. }
  103.  
  104. function initializeFullscreenButton() {
  105. const gameMap = document.querySelector(GAME_MAP_SELECTOR);
  106. const footerButtons = document.querySelector(FOOTER_BUTTONS_SELECTOR);
  107. if (gameMap && footerButtons) {
  108. createFullscreenStyles(gameMap);
  109. createFullscreenButton(footerButtons, gameMap);
  110. }
  111. }
  112.  
  113. new MutationObserver(initializeFullscreenButton).observe(document.body, { childList: true, subtree: true });
  114. initializeFullscreenButton();
  115. })();