Add quit confirmation to main menu
Implement a quit confirmation dialog that appears when the QUIT button is selected on the main menu. The dialog displays 'EXIT GAME?' with YES/NO options. YES sends a coAction quit request to the plugin, which hides the overlay, disconnects any active server session, and sets RE::Main::quitGame to exit the game. NO returns to the main menu. Includes full keyboard (arrow keys, Enter, Escape), gamepad (dpad, A/B buttons), and mouse support. Default selection is NO.
This commit is contained in:
@@ -165,10 +165,13 @@
|
||||
var menu = document.getElementById("menu");
|
||||
var settingsPanel = document.getElementById("settingsPanel");
|
||||
var browserPanel = document.getElementById("browserPanel");
|
||||
var quitConfirmPanel = document.getElementById("quitConfirmPanel");
|
||||
var quitConfirmOptions = document.getElementById("quitConfirmOptions");
|
||||
var mainPromptBar = document.getElementById("mainPromptBar");
|
||||
var settingsPromptBar = document.getElementById("settingsPromptBar");
|
||||
|
||||
if (!menu || !settingsPanel || !browserPanel || !window.CO_Settings || !window.CO_Browser) {
|
||||
if (!menu || !settingsPanel || !browserPanel || !quitConfirmPanel || !quitConfirmOptions ||
|
||||
!window.CO_Settings || !window.CO_Browser) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -176,12 +179,17 @@
|
||||
var browserController = null;
|
||||
|
||||
var items = Array.prototype.slice.call(menu.querySelectorAll(".menu-item"));
|
||||
var quitConfirmItems = Array.prototype.slice.call(
|
||||
quitConfirmOptions.querySelectorAll(".quit-confirm__option")
|
||||
);
|
||||
var MULTIPLAYER_INDEX = 0;
|
||||
var SETTINGS_INDEX = 2;
|
||||
var QUIT_INDEX = 4;
|
||||
|
||||
// viewMode: "menu" | "settings" | "browser"
|
||||
// viewMode: "menu" | "settings" | "browser" | "quitConfirm"
|
||||
var viewMode = "menu";
|
||||
var selectedIndex = -1;
|
||||
var quitConfirmSelectedIndex = 0;
|
||||
var PANEL_TRANSITION_MS = 220;
|
||||
var settingsHideFallbackId = 0;
|
||||
var settingsHideOnTransitionEnd = null;
|
||||
@@ -243,11 +251,11 @@
|
||||
enterSettingsMode();
|
||||
} else if (action === "multiplayer") {
|
||||
enterBrowserMode();
|
||||
} else if (action === "quit") {
|
||||
enterQuitConfirmMode();
|
||||
} else {
|
||||
window.CommonwealthOnlineUI.onOpenView(action);
|
||||
if (action !== "quit") {
|
||||
setSelected(-1);
|
||||
}
|
||||
setSelected(-1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,6 +271,11 @@
|
||||
return;
|
||||
}
|
||||
exitBrowserMode();
|
||||
} else if (viewMode === "quitConfirm") {
|
||||
if (index === QUIT_INDEX) {
|
||||
return;
|
||||
}
|
||||
exitQuitConfirmMode();
|
||||
}
|
||||
if (item.classList.contains("is-disabled")) {
|
||||
return;
|
||||
@@ -472,6 +485,129 @@
|
||||
exitBrowserMode(true);
|
||||
};
|
||||
|
||||
function setQuitConfirmSelected(index) {
|
||||
if (index >= quitConfirmItems.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
quitConfirmSelectedIndex = index < 0 ? 0 : index;
|
||||
|
||||
quitConfirmItems.forEach(function (item, i) {
|
||||
var isSelected = i === quitConfirmSelectedIndex;
|
||||
item.classList.toggle("is-selected", isSelected);
|
||||
item.setAttribute("aria-selected", isSelected ? "true" : "false");
|
||||
item.tabIndex = isSelected ? 0 : -1;
|
||||
});
|
||||
}
|
||||
|
||||
function moveQuitConfirmSelection(delta) {
|
||||
var next = quitConfirmSelectedIndex + delta;
|
||||
if (next < 0) {
|
||||
next = quitConfirmItems.length - 1;
|
||||
} else if (next >= quitConfirmItems.length) {
|
||||
next = 0;
|
||||
}
|
||||
setQuitConfirmSelected(next);
|
||||
}
|
||||
|
||||
function showQuitConfirmPanelAnimated() {
|
||||
if (mainScreen) {
|
||||
mainScreen.classList.add("is-quit-confirm-mode");
|
||||
}
|
||||
quitConfirmPanel.hidden = false;
|
||||
quitConfirmPanel.classList.remove("is-open");
|
||||
void quitConfirmPanel.offsetWidth;
|
||||
quitConfirmPanel.classList.add("is-open");
|
||||
}
|
||||
|
||||
function hideQuitConfirmPanelAnimated(done) {
|
||||
if (quitConfirmPanel.hidden) {
|
||||
if (done) {
|
||||
done();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
quitConfirmPanel.classList.remove("is-open");
|
||||
|
||||
window.setTimeout(function finishHide() {
|
||||
if (viewMode === "quitConfirm" || quitConfirmPanel.classList.contains("is-open")) {
|
||||
if (done) {
|
||||
done();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (mainScreen) {
|
||||
mainScreen.classList.remove("is-quit-confirm-mode");
|
||||
}
|
||||
quitConfirmPanel.hidden = true;
|
||||
if (done) {
|
||||
done();
|
||||
}
|
||||
}, PANEL_TRANSITION_MS + 80);
|
||||
}
|
||||
|
||||
function enterQuitConfirmMode() {
|
||||
if (viewMode === "quitConfirm") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (viewMode === "settings") {
|
||||
exitSettingsMode();
|
||||
} else if (viewMode === "browser") {
|
||||
exitBrowserMode();
|
||||
}
|
||||
|
||||
viewMode = "quitConfirm";
|
||||
console.log("[CO Main Menu] Entering quit confirmation");
|
||||
|
||||
setSelected(QUIT_INDEX);
|
||||
setQuitConfirmSelected(1);
|
||||
showQuitConfirmPanelAnimated();
|
||||
}
|
||||
|
||||
function exitQuitConfirmMode() {
|
||||
if (viewMode !== "quitConfirm") {
|
||||
return;
|
||||
}
|
||||
|
||||
viewMode = "menu";
|
||||
console.log("[CO Main Menu] Exiting quit confirmation");
|
||||
|
||||
hideQuitConfirmPanelAnimated(function () {
|
||||
if (viewMode === "menu") {
|
||||
setSelected(QUIT_INDEX);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function confirmQuit() {
|
||||
console.log("[CO Main Menu] Quit confirmed");
|
||||
sendCoAction({ action: "quit" });
|
||||
}
|
||||
|
||||
function activateQuitConfirmSelected() {
|
||||
var item = quitConfirmItems[quitConfirmSelectedIndex];
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
var choice = item.getAttribute("data-choice");
|
||||
if (choice === "yes") {
|
||||
confirmQuit();
|
||||
return;
|
||||
}
|
||||
|
||||
exitQuitConfirmMode();
|
||||
}
|
||||
|
||||
quitConfirmItems.forEach(function (item, index) {
|
||||
item.addEventListener("click", function () {
|
||||
setQuitConfirmSelected(index);
|
||||
activateQuitConfirmSelected();
|
||||
});
|
||||
});
|
||||
|
||||
window.onMainMenuShown = function () {
|
||||
if (mainScreen) {
|
||||
mainScreen.classList.remove("is-session-loading");
|
||||
@@ -489,11 +625,14 @@
|
||||
settingsController.hide();
|
||||
settingsPanel.classList.remove("is-open");
|
||||
settingsPanel.hidden = true;
|
||||
} else if (viewMode === "quitConfirm") {
|
||||
quitConfirmPanel.classList.remove("is-open");
|
||||
quitConfirmPanel.hidden = true;
|
||||
}
|
||||
|
||||
viewMode = "menu";
|
||||
if (mainScreen) {
|
||||
mainScreen.classList.remove("is-browser-mode", "is-settings-mode");
|
||||
mainScreen.classList.remove("is-browser-mode", "is-settings-mode", "is-quit-confirm-mode");
|
||||
mainScreen.classList.add("is-session-loading");
|
||||
}
|
||||
if (mainPromptBar) {
|
||||
@@ -580,6 +719,30 @@
|
||||
|
||||
// ── Keyboard navigation ────────────────────────────────────────
|
||||
|
||||
function handleQuitConfirmKeydown(event) {
|
||||
switch (event.key) {
|
||||
case "ArrowUp":
|
||||
event.preventDefault();
|
||||
moveQuitConfirmSelection(-1);
|
||||
break;
|
||||
case "ArrowDown":
|
||||
event.preventDefault();
|
||||
moveQuitConfirmSelection(1);
|
||||
break;
|
||||
case "Enter":
|
||||
case " ":
|
||||
event.preventDefault();
|
||||
activateQuitConfirmSelected();
|
||||
break;
|
||||
case "Escape":
|
||||
event.preventDefault();
|
||||
exitQuitConfirmMode();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function handleMenuKeydown(event) {
|
||||
switch (event.key) {
|
||||
case "ArrowUp":
|
||||
@@ -614,6 +777,10 @@
|
||||
browserController.handleKeydown(event);
|
||||
return;
|
||||
}
|
||||
if (viewMode === "quitConfirm") {
|
||||
handleQuitConfirmKeydown(event);
|
||||
return;
|
||||
}
|
||||
handleMenuKeydown(event);
|
||||
});
|
||||
|
||||
@@ -626,6 +793,23 @@
|
||||
if (viewMode === "settings") {
|
||||
return;
|
||||
}
|
||||
if (viewMode === "quitConfirm") {
|
||||
switch (button) {
|
||||
case "dpad_up":
|
||||
moveQuitConfirmSelection(-1);
|
||||
break;
|
||||
case "dpad_down":
|
||||
moveQuitConfirmSelection(1);
|
||||
break;
|
||||
case "a":
|
||||
activateQuitConfirmSelected();
|
||||
break;
|
||||
case "b":
|
||||
exitQuitConfirmMode();
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
switch (button) {
|
||||
case "dpad_up":
|
||||
moveSelection(-1);
|
||||
|
||||
Reference in New Issue
Block a user