From f65f6200ec7343d2b27aca9dc16982e33ffcd389 Mon Sep 17 00:00:00 2001 From: zortos293 <65777760+zortos293@users.noreply.github.com> Date: Thu, 16 Apr 2026 19:21:56 +0000 Subject: [PATCH 1/2] Add confirmation dialog to logout handler to prevent accidental sign-outs --- opennow-stable/src/renderer/src/App.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/opennow-stable/src/renderer/src/App.tsx b/opennow-stable/src/renderer/src/App.tsx index 582e3b29..c0a517b5 100644 --- a/opennow-stable/src/renderer/src/App.tsx +++ b/opennow-stable/src/renderer/src/App.tsx @@ -2399,6 +2399,10 @@ export function App(): JSX.Element { // Logout handler const handleLogout = useCallback(async () => { + if (!window.confirm("Are you sure you want to log out?")) { + return; + } + await window.openNow.logout(); setAuthSession(null); setGames([]); From 1f619225e73b15601fa87b18ab0b854c2ce3f62d Mon Sep 17 00:00:00 2001 From: zortos293 <65777760+zortos293@users.noreply.github.com> Date: Thu, 16 Apr 2026 19:28:01 +0000 Subject: [PATCH 2/2] Replace browser logout confirm with styled modal --- opennow-stable/src/renderer/src/App.tsx | 84 ++++++++++- opennow-stable/src/renderer/src/styles.css | 159 +++++++++++++++++++++ 2 files changed, 237 insertions(+), 6 deletions(-) diff --git a/opennow-stable/src/renderer/src/App.tsx b/opennow-stable/src/renderer/src/App.tsx index c0a517b5..0c34bd8e 100644 --- a/opennow-stable/src/renderer/src/App.tsx +++ b/opennow-stable/src/renderer/src/App.tsx @@ -1,5 +1,6 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import type { CSSProperties, JSX } from "react"; +import { createPortal } from "react-dom"; import type { ActiveSessionInfo, @@ -877,6 +878,7 @@ export function App(): JSX.Element { const [navbarActiveSession, setNavbarActiveSession] = useState(null); const [isResumingNavbarSession, setIsResumingNavbarSession] = useState(false); const [isTerminatingNavbarSession, setIsTerminatingNavbarSession] = useState(false); + const [logoutConfirmOpen, setLogoutConfirmOpen] = useState(false); const [launchError, setLaunchError] = useState(null); const [queueModalGame, setQueueModalGame] = useState(null); const [queueModalData, setQueueModalData] = useState(null); @@ -2397,12 +2399,8 @@ export function App(): JSX.Element { } }, [applyCatalogBrowseResult, applyVariantSelections, loadSubscriptionInfo, providerIdpId, catalogFilterKey, catalogSelectedSortId]); - // Logout handler - const handleLogout = useCallback(async () => { - if (!window.confirm("Are you sure you want to log out?")) { - return; - } - + const confirmLogout = useCallback(async () => { + setLogoutConfirmOpen(false); await window.openNow.logout(); setAuthSession(null); setGames([]); @@ -2423,6 +2421,11 @@ export function App(): JSX.Element { setSelectedGameId(""); }, [resetLaunchRuntime]); + // Logout handler + const handleLogout = useCallback(() => { + setLogoutConfirmOpen(true); + }, []); + // Load games handler const loadGames = useCallback(async (targetSource: GameSource) => { setIsLoadingGames(true); @@ -2917,6 +2920,74 @@ export function App(): JSX.Element { setQueueModalData(null); }, []); + useEffect(() => { + if (!logoutConfirmOpen) return; + + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key === "Escape") { + setLogoutConfirmOpen(false); + } + if (event.key === "Enter") { + event.preventDefault(); + void confirmLogout(); + } + }; + + window.addEventListener("keydown", handleKeyDown); + const previousOverflow = document.body.style.overflow; + document.body.style.overflow = "hidden"; + + return () => { + window.removeEventListener("keydown", handleKeyDown); + document.body.style.overflow = previousOverflow; + }; + }, [confirmLogout, logoutConfirmOpen]); + + const logoutConfirmModal = logoutConfirmOpen && typeof document !== "undefined" + ? createPortal( +
+ + +
+
+ Enter confirm ยท Esc cancel +
+ + , + document.body, + ) + : null; + const handleResumeFromNavbar = useCallback(async () => { if ( !selectedProvider @@ -3789,6 +3860,7 @@ export function App(): JSX.Element { )} + {logoutConfirmModal} {queueModalGame && streamStatus === "idle" && (