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_update = 'Oct 21'; // FX Client Last Updated
const fx_version = '0.6.6.4'; // FX Client Version
const fx_update = 'Oct 26'; // FX Client Last Updated
import settingsManager from './settings.js';
import { clanFilter, leaderboardFilter } from "./clanFilters.js";
@ -29,4 +29,4 @@ __fx.clanFilter = clanFilter;
__fx.wins = winCounter;
__fx.customLobby = customLobby;
console.log('Successfully loaded FX Client');
console.log('Successfully loaded FX Client');

View File

@ -6,204 +6,293 @@ window.__fx = window.__fx || {};
const __fx = window.__fx;
var settings = {
//"fontName": "Trebuchet MS",
//"showBotDonations": false,
"displayWinCounter": true,
"useFullscreenMode": false,
"hoveringTooltip": true,
//"hideAllLinks": false,
"realisticNames": false,
"showPlayerDensity": true,
"coloredDensity": true,
"densityDisplayStyle": "percentage",
"highlightClanSpawns": false,
//"customMapFileBtn": true
"customBackgroundUrl": "",
"attackPercentageKeybinds": [],
//"fontName": "Trebuchet MS",
//"showBotDonations": false,
displayWinCounter: true,
useFullscreenMode: false,
hoveringTooltip: true,
//"hideAllLinks": false,
realisticNames: false,
showPlayerDensity: true,
coloredDensity: true,
densityDisplayStyle: "percentage",
highlightClanSpawns: false,
//"customMapFileBtn": true
customBackgroundUrl: "",
attackPercentageKeybinds: [],
};
__fx.settings = settings;
const discontinuedSettings = [ "hideAllLinks", "fontName" ];
const discontinuedSettings = ["hideAllLinks", "fontName"];
__fx.makeMainMenuTransparent = false;
/*var settingsGearIcon = document.createElement('img');
settingsGearIcon.setAttribute('src', 'assets/geari_white.png');*/
const settingsManager = new (function() {
const settingsStructure = [
{ for: "displayWinCounter", type: "checkbox", label: "Display win counter",
note: "The win counter tracks multiplayer solo wins (not in team games)" },
{ 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: "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: "densityDisplayStyle", type: "selectMenu", label: "Density value display style:", tooltip: "Controls how the territorial density value should be rendered", options: [
{ value: "percentage", label: "Percentage" },
{ value: "absoluteQuotient", label: "Value from 0 to 150 (BetterTT style)" }
]},
{ 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");
var inputFields = {}; // (includes select menus)
var checkboxFields = {};
var customElements = [];
settingsStructure.forEach(item => {
if (typeof item === "function") {
const container = document.createElement("div");
customElements.push(new item(container));
return settingsContainer.append(container);
}
const label = document.createElement("label");
if (item.tooltip) label.title = item.tooltip;
const isValueInput = item.type.endsWith("Input");
const element = document.createElement(isValueInput || item.type === "checkbox" ? "input" : item.type === "selectMenu" ? "select" : "button");
if (item.type === "textInput") element.type = "text";
if (item.placeholder) element.placeholder = item.placeholder;
if (isValueInput || item.type === "selectMenu") inputFields[item.for] = element;
if (item.text) element.innerText = item.text;
if (item.action) element.addEventListener("click", item.action);
if (item.label) label.append(item.label + " ");
if (item.note) {
const note = document.createElement("small");
note.innerText = item.note;
label.append(document.createElement("br"), note)
}
if (item.options) item.options.forEach(option => {
const optionElement = document.createElement("option");
optionElement.setAttribute("value", option.value);
optionElement.innerText = option.label;
element.append(optionElement);
});
label.append(element);
if (item.type === "checkbox") {
element.type = "checkbox";
const checkmark = document.createElement("span");
checkmark.className = "checkmark";
label.className = "checkbox";
label.append(checkmark);
checkboxFields[item.for] = element;
} else label.append(document.createElement("br"));
settingsContainer.append(label, document.createElement("br"));
const settingsManager = new (function () {
const settingsStructure = [
{
for: "displayWinCounter",
type: "checkbox",
label: "Display win counter",
note: "The win counter tracks multiplayer solo wins (not in team games)",
},
{
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: "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: "densityDisplayStyle",
type: "selectMenu",
label: "Density value display style:",
tooltip: "Controls how the territorial density value should be rendered",
options: [
{ value: "percentage", label: "Percentage" },
{
value: "absoluteQuotient",
label: "Value from 0 to 150 (BetterTT style)",
},
],
},
{
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");
var inputFields = {}; // (includes select menus)
var checkboxFields = {};
var customElements = [];
settingsStructure.forEach((item) => {
if (typeof item === "function") {
const container = document.createElement("div");
customElements.push(new item(container));
return settingsContainer.append(container);
}
const label = document.createElement("label");
if (item.tooltip) label.title = item.tooltip;
const isValueInput = item.type.endsWith("Input");
const element = document.createElement(
isValueInput || item.type === "checkbox"
? "input"
: item.type === "selectMenu"
? "select"
: "button"
);
if (item.type === "textInput") element.type = "text";
if (item.placeholder) element.placeholder = item.placeholder;
if (isValueInput || item.type === "selectMenu")
inputFields[item.for] = element;
if (item.text) element.innerText = item.text;
if (item.action) element.addEventListener("click", item.action);
if (item.label) label.append(item.label + " ");
if (item.note) {
const note = document.createElement("small");
note.innerText = item.note;
label.append(document.createElement("br"), note);
}
if (item.options)
item.options.forEach((option) => {
const optionElement = document.createElement("option");
optionElement.setAttribute("value", option.value);
optionElement.innerText = option.label;
element.append(optionElement);
});
label.append(element);
if (item.type === "checkbox") {
element.type = "checkbox";
const checkmark = document.createElement("span");
checkmark.className = "checkmark";
label.className = "checkbox";
label.append(checkmark);
checkboxFields[item.for] = element;
} else label.append(document.createElement("br"));
settingsContainer.append(label, document.createElement("br"));
});
this.save = function () {
Object.keys(inputFields).forEach(function (key) {
settings[key] = inputFields[key].value.trim();
});
this.save = function() {
Object.keys(inputFields).forEach(function(key) { settings[key] = inputFields[key].value.trim(); });
Object.keys(checkboxFields).forEach(function(key) { settings[key] = checkboxFields[key].checked; });
this.applySettings();
WindowManager.closeWindow("settings");
discontinuedSettings.forEach(settingName => delete settings[settingName]);
Object.keys(checkboxFields).forEach(function (key) {
settings[key] = checkboxFields[key].checked;
});
this.applySettings();
WindowManager.closeWindow("settings");
discontinuedSettings.forEach((settingName) => delete settings[settingName]);
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
window.location.reload();
};
const fileInput = document.createElement("input");
fileInput.type = "file";
function handleFileSelect(event) {
const input = event.target;
/** @type {File} */
const selectedFile = input.files[0];
if (!selectedFile) return;
input.removeEventListener("change", handleFileSelect);
input.value = "";
if (!selectedFile.name.endsWith(".json"))
return alert("Invalid file format");
const fileReader = new FileReader();
fileReader.onload = function () {
let result;
try {
result = JSON.parse(fileReader.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));
// should probably firgure out a way to do this without reloading - // You can't do it, localstorages REQUIRE you to reload
window.location.reload();
} catch (error) {
alert("Error\n" + error);
}
};
fileReader.readAsText(selectedFile);
}
this.importFromFile = function () {
fileInput.click();
fileInput.addEventListener("change", handleFileSelect);
};
// https://stackoverflow.com/a/34156339
function saveFile(content, fileName, contentType) {
var a = document.createElement("a");
var file = new Blob([content], { type: contentType });
a.href = URL.createObjectURL(file);
a.download = fileName;
a.click();
URL.revokeObjectURL(a.href);
}
this.exportToFile = function () {
saveFile(
JSON.stringify(settings),
"FX_client_settings.json",
"application/json"
);
};
const fileInput = document.createElement("input");
fileInput.type = "file";
function handleFileSelect(event) {
const input = event.target;
/** @type {File} */
const selectedFile = input.files[0];
if (!selectedFile) return;
this.syncFields = function () {
Object.keys(inputFields).forEach(function (key) {
inputFields[key].value = settings[key];
});
Object.keys(checkboxFields).forEach(function (key) {
checkboxFields[key].checked = settings[key];
});
customElements.forEach((element) => element.update(settings));
};
this.resetAll = function () {
if (
!confirm(
"Are you Really SURE you want to RESET ALL SETTINGS back to the default?"
)
)
return;
localStorage.removeItem("fx_settings");
window.location.reload();
};
this.applySettings = function () {
//setVarByName("bu", "px " + settings.fontName);
input.removeEventListener("change", handleFileSelect);
input.value = "";
if (!selectedFile.name.endsWith(".json")) return alert("Invalid file format");
const fileReader = new FileReader();
fileReader.onload = function() {
let result;
try {
result = JSON.parse(fileReader.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));
window.location.reload();
} catch (error) {
alert("Error\n" + error)
}
}
fileReader.readAsText(selectedFile);
if (settings.customBackgroundUrl !== "") {
document.body.style.backgroundImage =
"url(" + settings.customBackgroundUrl + ")";
document.body.style.backgroundSize = "cover";
document.body.style.backgroundPosition = "center";
}
this.importFromFile = function() {
fileInput.click();
fileInput.addEventListener('change', handleFileSelect);
};
// https://stackoverflow.com/a/34156339
function saveFile(content, fileName, contentType) {
var a = document.createElement("a");
var file = new Blob([content], {type: contentType});
a.href = URL.createObjectURL(file);
a.download = fileName;
a.click();
URL.revokeObjectURL(a.href);
}
this.exportToFile = function() {
saveFile(JSON.stringify(settings), 'FX_client_settings.json', 'application/json');
};
__fx.makeMainMenuTransparent = settings.customBackgroundUrl !== "";
};
this.syncFields = function() {
Object.keys(inputFields).forEach(function(key) { inputFields[key].value = settings[key]; });
Object.keys(checkboxFields).forEach(function(key) { checkboxFields[key].checked = settings[key]; });
customElements.forEach(element => element.update(settings));
};
this.resetAll = function() {
if (!confirm("Are you Really SURE you want to RESET ALL SETTINGS back to the default?")) return;
localStorage.removeItem("fx_settings");
window.location.reload();
};
this.applySettings = function() {
//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 !== "") {
document.body.style.backgroundImage = "url(" + settings.customBackgroundUrl + ")";
document.body.style.backgroundSize = "cover";
document.body.style.backgroundPosition = "center";
}
__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 fileInput = document.getElementById("customBackgroundFileInput");
fileInput.click();
fileInput.addEventListener('change', handleFileSelect);
}
const fileInput = document.getElementById("customBackgroundFileInput");
fileInput.click();
fileInput.addEventListener("change", handleFileSelect);
};
function handleFileSelect(event) {
const fileInput = event.target;
const selectedFile = fileInput.files[0];
console.log(fileInput.files);
console.log(fileInput.files[0]);
if (selectedFile) {
const fileUrl = URL.createObjectURL(selectedFile);
console.log("File URL:", fileUrl);
fileInput.value = "";
fileInput.removeEventListener("change", handleFileSelect);
}
const fileInput = event.target;
const selectedFile = fileInput.files[0];
console.log(fileInput.files);
console.log(fileInput.files[0]);
if (selectedFile) {
const fileUrl = URL.createObjectURL(selectedFile);
console.log("File URL:", fileUrl);
fileInput.value = "";
fileInput.removeEventListener("change", handleFileSelect);
}
}
WindowManager.add({
name: "settings",
element: document.querySelector(".settings"),
beforeOpen: function() { settingsManager.syncFields(); }
name: "settings",
element: document.querySelector(".settings"),
beforeOpen: function () {
settingsManager.syncFields();
},
});
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();
export default settingsManager;
export function getSettings() { return settings; };
export function getSettings() {
return settings;
}

View File

@ -1,40 +1,63 @@
import { getSettings, tryEnterFullscreen } from "./settings.js";
var windows = {};
const container = document.getElementById("windowContainer");
function create(info) {
const window = document.createElement("div");
info.element = window;
window.className = "window" + (info.classes !== undefined ? " " + info.classes : " scrollable selectable");
window.style.display = "none";
container.appendChild(window);
add(info);
return window;
const window = document.createElement("div");
info.element = window;
window.className =
"window" +
(info.classes !== undefined
? " " + info.classes
: " scrollable selectable");
window.style.display = "none";
container.appendChild(window);
add(info);
return window;
}
function add(newWindow) {
windows[newWindow.name] = newWindow;
windows[newWindow.name].isOpen = false;
};
windows[newWindow.name] = newWindow;
windows[newWindow.name].isOpen = false;
}
function openWindow(windowName, ...args) {
if (windows[windowName].isOpen === true) return;
if (windows[windowName].beforeOpen !== undefined) windows[windowName].beforeOpen(...args);
windows[windowName].isOpen = true;
windows[windowName].element.style.display = null;
};
if (windows[windowName].isOpen === true) return;
if (windows[windowName].beforeOpen !== undefined)
windows[windowName].beforeOpen(...args);
windows[windowName].isOpen = true;
windows[windowName].element.style.display = null;
}
function closeWindow(windowName) {
if (windows[windowName].isOpen === false) return;
windows[windowName].isOpen = false;
windows[windowName].element.style.display = "none";
if (windows[windowName].onClose !== undefined) windows[windowName].onClose();
};
if (windows[windowName].isOpen === false) return;
windows[windowName].isOpen = false;
windows[windowName].element.style.display = "none";
if (windows[windowName].onClose !== undefined) windows[windowName].onClose();
}
function closeAll() {
Object.values(windows).forEach(function (windowObj) {
if (windowObj.closable !== false) closeWindow(windowObj.name);
});
};
document.addEventListener("mousedown", (e) => {
Object.values(windows).forEach(function (windowObj) {
if (windowObj.closable !== false) closeWindow(windowObj.name);
});
}
document.addEventListener(
"mousedown",
(e) => {
// when clicking outside a window
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 };