fix(settings): harden RomM sign-in and consolidate the connection/SteamGridDB UX#1565
Merged
Conversation
…surface errors in the modal The RomM sign-in modal now gates the Sign in button until the selected mode's required fields are complete, runs the sign-in to completion inside the modal, and only closes on success — a failed sign-in stays open and shows the returned message inline instead of at the bottom of the page. - ConnectModal switches from ConfirmModal to ModalRoot with a custom Sign in / Cancel footer so closing is controlled. Submit is async: it awaits the parent handler, closes on success, and on failure (or a thrown error) sets an inline error and stays open. A stale error clears when any field is edited or the mode is switched. - Enter on the username field advances focus to the password field rather than submitting; Enter on the password/token field submits only when the mode's fields are complete; the pairing boxes submit on Enter only once all eight are filled, routed through the async submit. - SettingsPage's connect handlers return their result to the modal and only touch the bottom status line on success; the invalid-URL and error paths return a failure for the modal to display.
…ic server error RomM 5.0 answers the token-carrying /api/heartbeat version probe with a 500 (a malformed token) or a 403 (a token-shaped but invalid/revoked one) rather than a clean 401, so a bad pasted token surfaced as the misleading generic "Server error (500)" message. On a probe failure in establish_user_token, restore the auth state and run a reachability re-probe: when the server is reachable, the pasted token is at fault, so return a token-rejected auth failure; otherwise keep the real server error.
…osing on empty Enter, and clarify the credentials error TextInputModal now gates OK on a non-empty (trimmed) value via bOKDisabled and only runs the confirm/close on Enter when the value is non-empty, so an empty or whitespace-only field can no longer be confirmed with R2/Enter on the Deck. The ConnectModal token field is wrapped in a Focusable (the structure proven not to close the modal on an incomplete field) and all three keydown handlers consume Enter with preventDefault/stopPropagation before deciding to submit, advance, or no-op, so R2/OSK-Enter on the empty token field no longer closes the modal. The credentials 403 message now names both possible causes — wrong username/password and an account without token-creation permission — because RomM returns 403 indistinguishably for both.
…ndant test buttons Sign-in already validates inline in the modal and the QAM connection row probes the server on open, so the two manual "test" buttons in Connection Settings were redundant. - Remove the "Test Connection" button from ConnectionSection (the QAM row probes automatically; the test_connection callable stays for that probe). - Remove the SteamGridDB "Verify Key" button and the section's status line. - Enter the SteamGridDB key through a dedicated SgdbApiKeyModal that verifies the key against SteamGridDB before saving it — an invalid key is rejected inline and the modal stays open, so no unchecked key is ever persisted. - Surface the specific reason on a failed QAM connection probe (Sign-in rejected / Server unreachable / No server URL / Not signed in) instead of a bare "Not connected".
danielcopper
force-pushed
the
feature/1564-login-hardening
branch
from
July 22, 2026 21:17
ce9bff8 to
3d1a044
Compare
danielcopper
enabled auto-merge (squash)
July 22, 2026 21:27
danielcopper
disabled auto-merge
July 22, 2026 21:39
…st the sign-in gate Pull the ModalRoot -> body -> title -> error line -> footer scaffolding shared by ConnectModal and SgdbApiKeyModal into a single ValidatingModalShell, which now owns the modal-body, title, error, and footer style constants that were duplicated in both modals. Each modal renders its own field content as the shell's children and passes its title, error, error test id, submit label, submit-disabled gate, and submit handler. Replace ConnectModal's nested-ternary canSubmit with a plain if/else helper, keeping the untrimmed-password semantics.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Hardens the RomM sign-in flow and consolidates the connection / SteamGridDB settings UX after on-device testing.
Sign-in (RomM):
SteamGridDB key: validated inline in its own modal — the entered key is tested against SteamGridDB before it is saved; a rejected key keeps the modal open with the reason, and only a valid key is persisted.
Fewer redundant buttons: removed the settings-page Test Connection and Verify Key buttons — the QAM Connection row already probes on open, and both modals now validate inline.
Clearer QAM status: the Connection row surfaces the specific reason on failure (Not signed in / Sign-in rejected / Server unreachable / No server URL) instead of a bare "Not connected".
All settings text inputs (RomM URL, SteamGridDB key, default save slot) now require a non-empty value.
Needs on-device verification in Game Mode — the on-screen-keyboard Enter/R2 dispatch and gamepad focus traversal can't be exercised by the unit tests.
Closes #1564