fix: make fullscreen mode trigger automatically (#6)

* fix: make fullscreen mode trigger automatically

* Small fix to check whether fullscreen mode is available

* revert: readme

* Bump version

---------

Co-authored-by: peshomir <80340328+peshomir@users.noreply.github.com>
main
Muhammed Kaplan 2024-10-26 21:58:02 +02:00 committed by GitHub
parent 12a4a8e937
commit 14bf32b846
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 317 additions and 205 deletions

View File

@ -1,5 +1,5 @@
const fx_version = '0.6.6.3'; // FX Client Version const fx_version = '0.6.6.4'; // FX Client Version
const fx_update = 'Oct 21'; // FX Client Last Updated const fx_update = 'Oct 26'; // FX Client Last Updated
import settingsManager from './settings.js'; import settingsManager from './settings.js';
import { clanFilter, leaderboardFilter } from "./clanFilters.js"; import { clanFilter, leaderboardFilter } from "./clanFilters.js";

View File

@ -8,18 +8,18 @@ const __fx = window.__fx;
var settings = { var settings = {
//"fontName": "Trebuchet MS", //"fontName": "Trebuchet MS",
//"showBotDonations": false, //"showBotDonations": false,
"displayWinCounter": true, displayWinCounter: true,
"useFullscreenMode": false, useFullscreenMode: false,
"hoveringTooltip": true, hoveringTooltip: true,
//"hideAllLinks": false, //"hideAllLinks": false,
"realisticNames": false, realisticNames: false,
"showPlayerDensity": true, showPlayerDensity: true,
"coloredDensity": true, coloredDensity: true,
"densityDisplayStyle": "percentage", densityDisplayStyle: "percentage",
"highlightClanSpawns": false, highlightClanSpawns: false,
//"customMapFileBtn": true //"customMapFileBtn": true
"customBackgroundUrl": "", customBackgroundUrl: "",
"attackPercentageKeybinds": [], attackPercentageKeybinds: [],
}; };
__fx.settings = settings; __fx.settings = settings;
const discontinuedSettings = ["hideAllLinks", "fontName"]; const discontinuedSettings = ["hideAllLinks", "fontName"];
@ -30,31 +30,76 @@ settingsGearIcon.setAttribute('src', 'assets/geari_white.png');*/
const settingsManager = new (function () { const settingsManager = new (function () {
const settingsStructure = [ const settingsStructure = [
{ for: "displayWinCounter", type: "checkbox", label: "Display win counter", {
note: "The win counter tracks multiplayer solo wins (not in team games)" }, for: "displayWinCounter",
{ type: "button", text: "Reset win counter", action: winCounter.removeWins }, type: "checkbox",
{ for: "useFullscreenMode", type: "checkbox", label: "Use fullscreen mode", label: "Display win counter",
note: "Note: fullscreen mode will trigger after you click anywhere on the page due to browser policy restrictions." }, note: "The win counter tracks multiplayer solo wins (not in team games)",
{ for: "hoveringTooltip", type: "checkbox", label: "Hovering tooltip", },
note: "Display map territory info constantly (on mouse hover) instead of only when right clicking on the map" }, {
type: "button",
text: "Reset win counter",
action: winCounter.removeWins,
},
{
for: "useFullscreenMode",
type: "checkbox",
label: "Use fullscreen mode",
note: "Note: fullscreen mode will trigger after you click anywhere on the page due to browser policy restrictions.",
},
{
for: "hoveringTooltip",
type: "checkbox",
label: "Hovering tooltip",
note: "Display map territory info constantly (on mouse hover) instead of only when right clicking on the map",
},
//{ for: "hideAllLinks", type: "checkbox", label: "Hide Links option also hides app store links" }, //{ for: "hideAllLinks", type: "checkbox", label: "Hide Links option also hides app store links" },
{ for: "realisticNames", type: "checkbox", label: "Realistic Bot Names" }, { for: "realisticNames", type: "checkbox", label: "Realistic Bot Names" },
{ for: "showPlayerDensity", type: "checkbox", label: "Show player density" }, {
{ for: "coloredDensity", type: "checkbox", label: "Colored density", note: "Display the density with a color between red and green depending on the density value" }, for: "showPlayerDensity",
{ for: "densityDisplayStyle", type: "selectMenu", label: "Density value display style:", tooltip: "Controls how the territorial density value should be rendered", options: [ type: "checkbox",
label: "Show player density",
},
{
for: "coloredDensity",
type: "checkbox",
label: "Colored density",
note: "Display the density with a color between red and green depending on the density value",
},
{
for: "densityDisplayStyle",
type: "selectMenu",
label: "Density value display style:",
tooltip: "Controls how the territorial density value should be rendered",
options: [
{ value: "percentage", label: "Percentage" }, { value: "percentage", label: "Percentage" },
{ value: "absoluteQuotient", label: "Value from 0 to 150 (BetterTT style)" } {
]}, value: "absoluteQuotient",
{ for: "highlightClanSpawns", type: "checkbox", label: "Highlight clan spawnpoints", label: "Value from 0 to 150 (BetterTT style)",
note: "Increases the spawnpoint glow size for members of your clan" }, },
{ for: "customBackgroundUrl", type: "textInput", label: "Custom main menu background:", placeholder: "Enter an image URL here", tooltip: "A custom image to be shown as the main menu background instead of the currently selected map." }, ],
KeybindsInput },
{
for: "highlightClanSpawns",
type: "checkbox",
label: "Highlight clan spawnpoints",
note: "Increases the spawnpoint glow size for members of your clan",
},
{
for: "customBackgroundUrl",
type: "textInput",
label: "Custom main menu background:",
placeholder: "Enter an image URL here",
tooltip:
"A custom image to be shown as the main menu background instead of the currently selected map.",
},
KeybindsInput,
]; ];
const settingsContainer = document.querySelector(".settings .scrollable"); const settingsContainer = document.querySelector(".settings .scrollable");
var inputFields = {}; // (includes select menus) var inputFields = {}; // (includes select menus)
var checkboxFields = {}; var checkboxFields = {};
var customElements = []; var customElements = [];
settingsStructure.forEach(item => { settingsStructure.forEach((item) => {
if (typeof item === "function") { if (typeof item === "function") {
const container = document.createElement("div"); const container = document.createElement("div");
customElements.push(new item(container)); customElements.push(new item(container));
@ -63,19 +108,27 @@ const settingsManager = new (function() {
const label = document.createElement("label"); const label = document.createElement("label");
if (item.tooltip) label.title = item.tooltip; if (item.tooltip) label.title = item.tooltip;
const isValueInput = item.type.endsWith("Input"); const isValueInput = item.type.endsWith("Input");
const element = document.createElement(isValueInput || item.type === "checkbox" ? "input" : item.type === "selectMenu" ? "select" : "button"); const element = document.createElement(
isValueInput || item.type === "checkbox"
? "input"
: item.type === "selectMenu"
? "select"
: "button"
);
if (item.type === "textInput") element.type = "text"; if (item.type === "textInput") element.type = "text";
if (item.placeholder) element.placeholder = item.placeholder; if (item.placeholder) element.placeholder = item.placeholder;
if (isValueInput || item.type === "selectMenu") inputFields[item.for] = element; if (isValueInput || item.type === "selectMenu")
inputFields[item.for] = element;
if (item.text) element.innerText = item.text; if (item.text) element.innerText = item.text;
if (item.action) element.addEventListener("click", item.action); if (item.action) element.addEventListener("click", item.action);
if (item.label) label.append(item.label + " "); if (item.label) label.append(item.label + " ");
if (item.note) { if (item.note) {
const note = document.createElement("small"); const note = document.createElement("small");
note.innerText = item.note; note.innerText = item.note;
label.append(document.createElement("br"), note) label.append(document.createElement("br"), note);
} }
if (item.options) item.options.forEach(option => { if (item.options)
item.options.forEach((option) => {
const optionElement = document.createElement("option"); const optionElement = document.createElement("option");
optionElement.setAttribute("value", option.value); optionElement.setAttribute("value", option.value);
optionElement.innerText = option.label; optionElement.innerText = option.label;
@ -93,11 +146,15 @@ const settingsManager = new (function() {
settingsContainer.append(label, document.createElement("br")); settingsContainer.append(label, document.createElement("br"));
}); });
this.save = function () { this.save = function () {
Object.keys(inputFields).forEach(function(key) { settings[key] = inputFields[key].value.trim(); }); Object.keys(inputFields).forEach(function (key) {
Object.keys(checkboxFields).forEach(function(key) { settings[key] = checkboxFields[key].checked; }); settings[key] = inputFields[key].value.trim();
});
Object.keys(checkboxFields).forEach(function (key) {
settings[key] = checkboxFields[key].checked;
});
this.applySettings(); this.applySettings();
WindowManager.closeWindow("settings"); WindowManager.closeWindow("settings");
discontinuedSettings.forEach(settingName => delete settings[settingName]); discontinuedSettings.forEach((settingName) => delete settings[settingName]);
localStorage.setItem("fx_settings", JSON.stringify(settings)); localStorage.setItem("fx_settings", JSON.stringify(settings));
// should probably firgure out a way to do this without reloading - // You can't do it, localstorages REQUIRE you to reload // should probably firgure out a way to do this without reloading - // You can't do it, localstorages REQUIRE you to reload
window.location.reload(); window.location.reload();
@ -113,24 +170,30 @@ const settingsManager = new (function() {
input.removeEventListener("change", handleFileSelect); input.removeEventListener("change", handleFileSelect);
input.value = ""; input.value = "";
if (!selectedFile.name.endsWith(".json")) return alert("Invalid file format"); if (!selectedFile.name.endsWith(".json"))
return alert("Invalid file format");
const fileReader = new FileReader(); const fileReader = new FileReader();
fileReader.onload = function () { fileReader.onload = function () {
let result; let result;
try { try {
result = JSON.parse(fileReader.result); result = JSON.parse(fileReader.result);
if (confirm("Warning: This will override all current settings, click \"OK\" to confirm")) __fx.settings = settings = result; if (
confirm(
'Warning: This will override all current settings, click "OK" to confirm'
)
)
__fx.settings = settings = result;
localStorage.setItem("fx_settings", JSON.stringify(settings)); localStorage.setItem("fx_settings", JSON.stringify(settings));
window.location.reload(); window.location.reload();
} catch (error) { } catch (error) {
alert("Error\n" + error) alert("Error\n" + error);
}
} }
};
fileReader.readAsText(selectedFile); fileReader.readAsText(selectedFile);
} }
this.importFromFile = function () { this.importFromFile = function () {
fileInput.click(); fileInput.click();
fileInput.addEventListener('change', handleFileSelect); fileInput.addEventListener("change", handleFileSelect);
}; };
// https://stackoverflow.com/a/34156339 // https://stackoverflow.com/a/34156339
function saveFile(content, fileName, contentType) { function saveFile(content, fileName, contentType) {
@ -142,45 +205,64 @@ const settingsManager = new (function() {
URL.revokeObjectURL(a.href); URL.revokeObjectURL(a.href);
} }
this.exportToFile = function () { this.exportToFile = function () {
saveFile(JSON.stringify(settings), 'FX_client_settings.json', 'application/json'); saveFile(
JSON.stringify(settings),
"FX_client_settings.json",
"application/json"
);
}; };
this.syncFields = function () { this.syncFields = function () {
Object.keys(inputFields).forEach(function(key) { inputFields[key].value = settings[key]; }); Object.keys(inputFields).forEach(function (key) {
Object.keys(checkboxFields).forEach(function(key) { checkboxFields[key].checked = settings[key]; }); inputFields[key].value = settings[key];
customElements.forEach(element => element.update(settings)); });
Object.keys(checkboxFields).forEach(function (key) {
checkboxFields[key].checked = settings[key];
});
customElements.forEach((element) => element.update(settings));
}; };
this.resetAll = function () { this.resetAll = function () {
if (!confirm("Are you Really SURE you want to RESET ALL SETTINGS back to the default?")) return; if (
!confirm(
"Are you Really SURE you want to RESET ALL SETTINGS back to the default?"
)
)
return;
localStorage.removeItem("fx_settings"); localStorage.removeItem("fx_settings");
window.location.reload(); window.location.reload();
}; };
this.applySettings = function () { this.applySettings = function () {
//setVarByName("bu", "px " + settings.fontName); //setVarByName("bu", "px " + settings.fontName);
if (settings.useFullscreenMode && document.fullscreenEnabled) {
function tryEnterFullscreen() {
if (document.fullscreenElement !== null) return;
document.documentElement.requestFullscreen({ navigationUI: "hide" })
.then(() => { console.log('Fullscreen mode activated'); })
.catch((error) => { console.warn('Could not enter fullscreen mode:', error); });
}
document.addEventListener('mousedown', tryEnterFullscreen, { once: true });
document.addEventListener('click', tryEnterFullscreen, { once: true });
}
if (settings.customBackgroundUrl !== "") { if (settings.customBackgroundUrl !== "") {
document.body.style.backgroundImage = "url(" + settings.customBackgroundUrl + ")"; document.body.style.backgroundImage =
"url(" + settings.customBackgroundUrl + ")";
document.body.style.backgroundSize = "cover"; document.body.style.backgroundSize = "cover";
document.body.style.backgroundPosition = "center"; document.body.style.backgroundPosition = "center";
} }
__fx.makeMainMenuTransparent = settings.customBackgroundUrl !== ""; __fx.makeMainMenuTransparent = settings.customBackgroundUrl !== "";
}; };
if (settings.useFullscreenMode) tryEnterFullscreen();
})();
export function tryEnterFullscreen() {
if (document.fullscreenElement !== null || !document.fullscreenEnabled) return;
document.documentElement
.requestFullscreen({ navigationUI: "hide" })
.then(() => {
console.log("Fullscreen mode activated");
})
.catch((error) => {
console.warn("Could not enter fullscreen mode:", error);
}); });
}
const openCustomBackgroundFilePicker = () => { const openCustomBackgroundFilePicker = () => {
const fileInput = document.getElementById("customBackgroundFileInput"); const fileInput = document.getElementById("customBackgroundFileInput");
fileInput.click(); fileInput.click();
fileInput.addEventListener('change', handleFileSelect); fileInput.addEventListener("change", handleFileSelect);
} };
function handleFileSelect(event) { function handleFileSelect(event) {
const fileInput = event.target; const fileInput = event.target;
const selectedFile = fileInput.files[0]; const selectedFile = fileInput.files[0];
@ -197,13 +279,20 @@ function handleFileSelect(event) {
WindowManager.add({ WindowManager.add({
name: "settings", name: "settings",
element: document.querySelector(".settings"), element: document.querySelector(".settings"),
beforeOpen: function() { settingsManager.syncFields(); } beforeOpen: function () {
settingsManager.syncFields();
},
}); });
if (localStorage.getItem("fx_settings") !== null) { if (localStorage.getItem("fx_settings") !== null) {
__fx.settings = settings = {...settings, ...JSON.parse(localStorage.getItem("fx_settings"))}; __fx.settings = settings = {
...settings,
...JSON.parse(localStorage.getItem("fx_settings")),
};
} }
settingsManager.applySettings(); settingsManager.applySettings();
export default settingsManager; export default settingsManager;
export function getSettings() { return settings; }; export function getSettings() {
return settings;
}

View File

@ -1,9 +1,16 @@
import { getSettings, tryEnterFullscreen } from "./settings.js";
var windows = {}; var windows = {};
const container = document.getElementById("windowContainer"); const container = document.getElementById("windowContainer");
function create(info) { function create(info) {
const window = document.createElement("div"); const window = document.createElement("div");
info.element = window; info.element = window;
window.className = "window" + (info.classes !== undefined ? " " + info.classes : " scrollable selectable"); window.className =
"window" +
(info.classes !== undefined
? " " + info.classes
: " scrollable selectable");
window.style.display = "none"; window.style.display = "none";
container.appendChild(window); container.appendChild(window);
add(info); add(info);
@ -12,29 +19,45 @@ function create(info) {
function add(newWindow) { function add(newWindow) {
windows[newWindow.name] = newWindow; windows[newWindow.name] = newWindow;
windows[newWindow.name].isOpen = false; windows[newWindow.name].isOpen = false;
}; }
function openWindow(windowName, ...args) { function openWindow(windowName, ...args) {
if (windows[windowName].isOpen === true) return; if (windows[windowName].isOpen === true) return;
if (windows[windowName].beforeOpen !== undefined) windows[windowName].beforeOpen(...args); if (windows[windowName].beforeOpen !== undefined)
windows[windowName].beforeOpen(...args);
windows[windowName].isOpen = true; windows[windowName].isOpen = true;
windows[windowName].element.style.display = null; windows[windowName].element.style.display = null;
}; }
function closeWindow(windowName) { function closeWindow(windowName) {
if (windows[windowName].isOpen === false) return; if (windows[windowName].isOpen === false) return;
windows[windowName].isOpen = false; windows[windowName].isOpen = false;
windows[windowName].element.style.display = "none"; windows[windowName].element.style.display = "none";
if (windows[windowName].onClose !== undefined) windows[windowName].onClose(); if (windows[windowName].onClose !== undefined) windows[windowName].onClose();
}; }
function closeAll() { function closeAll() {
Object.values(windows).forEach(function (windowObj) { Object.values(windows).forEach(function (windowObj) {
if (windowObj.closable !== false) closeWindow(windowObj.name); if (windowObj.closable !== false) closeWindow(windowObj.name);
}); });
}; }
document.addEventListener("mousedown", (e) => { document.addEventListener(
"mousedown",
(e) => {
// when clicking outside a window // when clicking outside a window
if (!container.contains(e.target)) closeAll(); if (!container.contains(e.target)) closeAll();
}, { passive: true, capture: true })
document.getElementById("canvasA").addEventListener("touchstart", closeAll, { passive: true });
document.addEventListener("keydown", event => { if (event.key === "Escape") closeAll(); });
export default { create, add, openWindow, closeWindow, closeAll } const isFullScreenEnabled = getSettings().useFullscreenMode;
if (isFullScreenEnabled) {
tryEnterFullscreen();
}
},
{ passive: true, capture: true }
);
document
.getElementById("canvasA")
.addEventListener("touchstart", closeAll, { passive: true });
document.addEventListener("keydown", (event) => {
if (event.key === "Escape") closeAll();
});
export default { create, add, openWindow, closeWindow, closeAll };