Skip to content

fix: Fix controller focus not being acquired on screen entry#1634

Open
VinceBT wants to merge 4 commits into
utkarshdalal:masterfrom
VinceBT:feature/initial-focus
Open

fix: Fix controller focus not being acquired on screen entry#1634
VinceBT wants to merge 4 commits into
utkarshdalal:masterfrom
VinceBT:feature/initial-focus

Conversation

@VinceBT

@VinceBT VinceBT commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Description

On most screens, opening them with a controller left nothing focused, so the first D-pad/A press did nothing — you had to press once "into the void" before anything reacted.

This adds a small reusable Modifier.requestInitialFocus() helper and uses it to focus a sensible first element on entry:

  • Settings → the back button
  • Login → the username field
  • Recommended game → the primary action button
  • Library → the content list, once it has loaded
  • Downloads → the portrait tab row (landscape already did this via the sidebar)

The helper retries focus a few times because the node isn't always laid out on the first frame.

Recording

Type of Change

  • Bug fix
  • Performance / stability improvement
  • Compatibility improvements
  • Other (requires prior approval)

Checklist

  • If I have access to #code-changes, I have discussed this change there and it has been green-lighted. If I do not have access, I have still provided clear context in this PR. If I skip both, I accept that this change may face delays in review, may not be reviewed at all, or may be closed.
  • This change aligns with the current project scope (core functionality, stability, or performance). If not, it has been explicitly approved beforehand.
  • I have attached a recording of the change.
  • I have read and agree to the contribution guidelines in CONTRIBUTING.md.

Summary by cubic

Fixes missing controller focus on screen entry so the first D‑pad/A press works immediately. Adds a reusable Modifier.requestInitialFocus() that requests focus after layout and retries until it succeeds.

  • Bug Fixes
    • Added Modifier.requestInitialFocus() (attaches FocusRequester; retries until requestFocus() returns true; effect keyed on requester/enabled).
    • Settings: Back button gets initial focus.
    • Login: Username and 2FA fields auto-focus with retry.
    • Library: One‑shot content list focus after load; game detail Play button auto‑focus on entry and when switching games (retry).
    • Recommended Game: Primary action button auto-focus.
    • Downloads: Auto-focus the portrait tab row; sidebar/tab focus now retry until success.

Written for commit 96c5de7. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Improved initial keyboard/controller focus across key screens, including Downloads tabs/sections, Library content, Login (username + 2FA), Settings (back button), Recommended Game (Buy), and Library play button after switching games.
    • Added a reusable “request initial focus” helper for consistent, timed focus behavior.
  • Bug Fixes
    • Enhanced focus reliability with bounded retries and brief delays, ensuring focus is applied when UI elements appear.
    • Reduced mis-focus by gating initial focus until relevant views are ready and inactive overlays/search/detail states aren’t blocking input.

@VinceBT VinceBT requested a review from utkarshdalal as a code owner June 28, 2026 20:22
@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a reusable Modifier.requestInitialFocus extension and applies bounded focus-request retries across downloads, library, recommended game, login, two-factor authentication, and settings screens.

Changes

Initial Focus Navigation

Layer / File(s) Summary
requestInitialFocus Modifier extension
app/src/main/java/app/gamenative/ui/util/FocusModifiers.kt
Adds a modifier that attaches a FocusRequester and retries initial focus requests up to five times when enabled.
Downloads tab focus behavior
app/src/main/java/app/gamenative/ui/screen/downloads/DownloadsScreen.kt
Updates sidebar focus success handling and adds per-section tab requesters with bounded retries for the selected tab.
Library content and play-button focus
app/src/main/java/app/gamenative/ui/screen/library/LibraryScreen.kt, app/src/main/java/app/gamenative/ui/screen/library/LibraryAppScreen.kt
Focuses the first library item once when content becomes available and retries play-button focus when the displayed game changes.
Screen-specific initial focus wiring
app/src/main/java/app/gamenative/ui/screen/library/RecommendedGameScreen.kt, app/src/main/java/app/gamenative/ui/screen/login/UserLoginScreen.kt, app/src/main/java/app/gamenative/ui/screen/login/TwoFactorAuthScreen.kt, app/src/main/java/app/gamenative/ui/screen/settings/SettingsScreen.kt
Adds initial focus for the recommended-game Buy button, username field, two-factor field, and settings Back button, with retry handling where applicable.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: utkarshdalal

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise and accurately summarizes the main change: fixing controller focus on screen entry.
Description check ✅ Passed All required sections are present and the change is clearly described, though the recording is still a TODO.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
app/src/main/java/app/gamenative/ui/screen/library/LibraryScreen.kt (1)

586-600: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consolidate this with the existing tab bootstrap effect.

This adds a third entry-focus path, but the LaunchedEffect(state.currentTab) above still runs on first composition, so loaded tabs can queue two initial requestContentFocusOrDefer(0) calls at the same time. If this guard is meant to prevent focus fights, it also needs to gate the existing tab bootstrap.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/main/java/app/gamenative/ui/screen/library/LibraryScreen.kt` around
lines 586 - 600, The initial content-focus guard in LibraryScreen adds a third
focus path, but the existing LaunchedEffect(state.currentTab) bootstrap still
issues its own first-load requestContentFocusOrDefer(0) call. Consolidate the
startup focus logic so both the current-tab bootstrap and the new content-loaded
effect share the same one-shot guard (for example via didInitialContentFocus)
and only one initial focus request can be queued.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/src/main/java/app/gamenative/ui/screen/login/UserLoginScreen.kt`:
- Around line 619-623: The username auto-focus on entry is being attempted only
once and `runCatching` can silently fail before the field is attached, leaving
the login screen unfocused. Update the `LaunchedEffect(Unit)` block in
`UserLoginScreen` to use the existing
`requestInitialFocus(usernameFocusRequester)` helper, or copy its retry behavior
here, so focus keeps retrying until `usernameFocusRequester` can actually attach
and receive focus.

In `@app/src/main/java/app/gamenative/ui/util/FocusModifiers.kt`:
- Line 21: The LaunchedEffect in FocusModifiers.kt is only keyed by enabled, so
a new FocusRequester instance will not retrigger the initial focus request when
the requester changes. Update the effect keys in the focus modifier logic
(LaunchedEffect in the FocusRequester-related composable) to include the
requester instance alongside enabled, so the effect restarts whenever a
different FocusRequester is supplied.

---

Nitpick comments:
In `@app/src/main/java/app/gamenative/ui/screen/library/LibraryScreen.kt`:
- Around line 586-600: The initial content-focus guard in LibraryScreen adds a
third focus path, but the existing LaunchedEffect(state.currentTab) bootstrap
still issues its own first-load requestContentFocusOrDefer(0) call. Consolidate
the startup focus logic so both the current-tab bootstrap and the new
content-loaded effect share the same one-shot guard (for example via
didInitialContentFocus) and only one initial focus request can be queued.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 74e41970-7c84-44ee-9763-4426317236c3

📥 Commits

Reviewing files that changed from the base of the PR and between 82fc5b2 and 6e3259d.

📒 Files selected for processing (6)
  • app/src/main/java/app/gamenative/ui/screen/downloads/DownloadsScreen.kt
  • app/src/main/java/app/gamenative/ui/screen/library/LibraryScreen.kt
  • app/src/main/java/app/gamenative/ui/screen/library/RecommendedGameScreen.kt
  • app/src/main/java/app/gamenative/ui/screen/login/UserLoginScreen.kt
  • app/src/main/java/app/gamenative/ui/screen/settings/SettingsScreen.kt
  • app/src/main/java/app/gamenative/ui/util/FocusModifiers.kt

Comment thread app/src/main/java/app/gamenative/ui/screen/login/UserLoginScreen.kt
Comment thread app/src/main/java/app/gamenative/ui/util/FocusModifiers.kt Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 6 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="app/src/main/java/app/gamenative/ui/screen/downloads/DownloadsScreen.kt">

<violation number="1" location="app/src/main/java/app/gamenative/ui/screen/downloads/DownloadsScreen.kt:370">
P2: New portrait tab focus handling duplicates the reusable `Modifier.requestInitialFocus()` helper introduced by this PR. `DownloadsTabRow` hand-rolls the same `remember` + `FocusRequester` map + retrying `LaunchedEffect` pattern instead of delegating to the shared helper, creating inconsistent retry parameters and multiple places to update if the focus logic changes.</violation>

<violation number="2" location="app/src/main/java/app/gamenative/ui/screen/downloads/DownloadsScreen.kt:434">
P1: Initial-focus retry loop ignores `requestFocus()` return value. `FocusRequester.requestFocus()` returns `Boolean` (`true` on success, `false` if cancelled); a `false` result is not an exception. When focus is denied but no exception is thrown, this code still sets `requestedInitialFocus = true` and exits, so retries are skipped and focus may never actually be acquired.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread app/src/main/java/app/gamenative/ui/screen/downloads/DownloadsScreen.kt Outdated
Comment thread app/src/main/java/app/gamenative/ui/util/FocusModifiers.kt Outdated
Comment thread app/src/main/java/app/gamenative/ui/screen/login/UserLoginScreen.kt Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
app/src/main/java/app/gamenative/ui/screen/login/UserLoginScreen.kt (1)

619-629: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace the inline retry loop with requestInitialFocus.

This now duplicates the shared retry contract in FocusModifiers.kt, so the login screen can drift from the other screens the next time that helper changes. It’s simpler to move the behavior onto the username field’s modifier and delete this LaunchedEffect.

Suggested change
-    // Focus the username field on entry so the first controller/D-pad press is not wasted.
-    // Retry: the field may not be attached on the first frame.
-    LaunchedEffect(Unit) {
-        repeat(5) {
-            try {
-                usernameFocusRequester.requestFocus()
-                return@LaunchedEffect
-            } catch (_: IllegalStateException) {
-                delay(32)
-            }
-        }
-    }
...
             NoExtractOutlinedTextField(
                 value = username,
                 onValueChange = onUsername,
                 singleLine = true,
                 label = { Text(stringResource(R.string.login_username_hint)) },
                 modifier = Modifier
                     .fillMaxWidth()
-                    .focusRequester(usernameFocusRequester)
+                    .requestInitialFocus(usernameFocusRequester)
                     .dpadFocusEscape(
                         focusManager = focusManager,
                         keyboardController = keyboardController,
                         onDown = { passwordFocusRequester.requestFocus() },
                     ),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/main/java/app/gamenative/ui/screen/login/UserLoginScreen.kt` around
lines 619 - 629, The username auto-focus logic in UserLoginScreen should use the
shared requestInitialFocus helper instead of the local LaunchedEffect retry
loop. Move the initial focus behavior onto the username field’s modifier via
requestInitialFocus from FocusModifiers.kt, and remove the duplicated
repeat/delay retry block so the login screen stays aligned with the other
screens.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@app/src/main/java/app/gamenative/ui/screen/login/UserLoginScreen.kt`:
- Around line 619-629: The username auto-focus logic in UserLoginScreen should
use the shared requestInitialFocus helper instead of the local LaunchedEffect
retry loop. Move the initial focus behavior onto the username field’s modifier
via requestInitialFocus from FocusModifiers.kt, and remove the duplicated
repeat/delay retry block so the login screen stays aligned with the other
screens.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: df4a2110-7506-432c-a508-f3a6680ad206

📥 Commits

Reviewing files that changed from the base of the PR and between 6e3259d and 0cf1c46.

📒 Files selected for processing (2)
  • app/src/main/java/app/gamenative/ui/screen/login/UserLoginScreen.kt
  • app/src/main/java/app/gamenative/ui/util/FocusModifiers.kt
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/src/main/java/app/gamenative/ui/util/FocusModifiers.kt

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 2 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread app/src/main/java/app/gamenative/ui/util/FocusModifiers.kt
Comment thread app/src/main/java/app/gamenative/ui/screen/login/UserLoginScreen.kt Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
app/src/main/java/app/gamenative/ui/screen/downloads/DownloadsScreen.kt (1)

349-355: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Narrow the swallowed exception to the focus-layout case.

These loops currently catch every Exception, while the shared focus helper only masks IllegalStateException. Keeping the catch broad here can hide unrelated runtime failures and silently fall back to the unfocused state.

Suggested change
-            } catch (_: Exception) {
+            } catch (_: IllegalStateException) {
             }

Also applies to: 434-440

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/main/java/app/gamenative/ui/screen/downloads/DownloadsScreen.kt`
around lines 349 - 355, The focus request loop in DownloadsScreen is catching
every Exception, which is broader than the shared focus helper behavior and can
hide unrelated failures. Narrow the catch in the LaunchedEffect focus attempt
around focusRequester.requestFocus() to only the focus-layout case (matching the
helper’s IllegalStateException handling), and apply the same fix to the other
identical block referenced by the review.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@app/src/main/java/app/gamenative/ui/screen/downloads/DownloadsScreen.kt`:
- Around line 349-355: The focus request loop in DownloadsScreen is catching
every Exception, which is broader than the shared focus helper behavior and can
hide unrelated failures. Narrow the catch in the LaunchedEffect focus attempt
around focusRequester.requestFocus() to only the focus-layout case (matching the
helper’s IllegalStateException handling), and apply the same fix to the other
identical block referenced by the review.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 09cc39d7-2a09-42a3-a0d2-333455dfc81c

📥 Commits

Reviewing files that changed from the base of the PR and between 0cf1c46 and 8277361.

📒 Files selected for processing (3)
  • app/src/main/java/app/gamenative/ui/screen/downloads/DownloadsScreen.kt
  • app/src/main/java/app/gamenative/ui/screen/login/UserLoginScreen.kt
  • app/src/main/java/app/gamenative/ui/util/FocusModifiers.kt
🚧 Files skipped from review as they are similar to previous changes (2)
  • app/src/main/java/app/gamenative/ui/util/FocusModifiers.kt
  • app/src/main/java/app/gamenative/ui/screen/login/UserLoginScreen.kt

@phobos665 phobos665 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@utkarshdalal quite interested in this one.

Basically allow for easier controller focus on certain screens.

The big one is rgarding the FocusModifiers, but seems pretty interesting to me.

@utkarshdalal

Copy link
Copy Markdown
Owner

@VinceBT - could you please add a recording after merging latest master?

@utkarshdalal utkarshdalal reopened this Jul 7, 2026
@utkarshdalal

Copy link
Copy Markdown
Owner

Sorry I closed it by mistake - please provide a recording after merging in latest master

@VinceBT VinceBT force-pushed the feature/initial-focus branch from 8277361 to b5a875f Compare July 7, 2026 21:47
@utkarshdalal

Copy link
Copy Markdown
Owner

@VinceBT - can you provide a recording please

@VinceBT VinceBT changed the title Fix controller focus not being acquired on screen entry fix: Fix controller focus not being acquired on screen entry Jul 12, 2026
VinceBT added 4 commits July 12, 2026 21:58
On most screens nothing was focused on entry, so the first D-pad/controller
press was consumed just to seed focus ('press A in the void'). Add a reusable
Modifier.requestInitialFocus(focusRequester, enabled) helper that attaches the
requester and requests focus once the node is laid out (with retry), and apply
it on:
 - SettingsScreen: the back button
 - UserLoginScreen: the username field
 - RecommendedGameScreen: the primary action button
 - LibraryScreen: content focus once the list loads (one-shot, reusing the
   existing requestContentFocusOrDefer with the same overlay guards)
 - DownloadsScreen: the portrait tab row (the landscape sidebar already did this)
@VinceBT VinceBT force-pushed the feature/initial-focus branch from b5a875f to 96c5de7 Compare July 12, 2026 20:00

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
app/src/main/java/app/gamenative/ui/screen/login/TwoFactorAuthScreen.kt (1)

134-142: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace inlined retry with requestInitialFocus helper.

The retry loop here duplicates Modifier.requestInitialFocus from FocusModifiers.kt. Since focusRequester is already applied via .focusRequester(focusRequester) on line 156, you can replace both the LaunchedEffect block and that modifier call with a single requestInitialFocus(focusRequester) on the text field modifier, consistent with RecommendedGameScreen.kt.

♻️ Proposed refactor
     val focusRequester = remember { FocusRequester() }
     val keyboardController = LocalSoftwareKeyboardController.current

-    LaunchedEffect(Unit) {
-        // Node may not be placed on the first frame; retry until requestFocus() takes.
-        repeat(5) {
-            try {
-                if (focusRequester.requestFocus()) return@LaunchedEffect
-            } catch (_: IllegalStateException) {
-            }
-            delay(32)
-        }
-    }

     Column(modifier = Modifier.fillMaxWidth()) {

And on the text field modifier:

         NoExtractOutlinedTextField(
             modifier = Modifier
                 .fillMaxWidth()
-                .focusRequester(focusRequester)
+                .requestInitialFocus(focusRequester)
                 .dpadFocusEscape(

This also removes the need for the kotlinx.coroutines.delay import.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/main/java/app/gamenative/ui/screen/login/TwoFactorAuthScreen.kt`
around lines 134 - 142, Replace the inline LaunchedEffect retry loop in
TwoFactorAuthScreen with the existing requestInitialFocus(focusRequester)
modifier on the text field, removing the separate focusRequester modifier call.
Remove the now-unused kotlinx.coroutines.delay import, while preserving the text
field’s initial-focus behavior consistent with RecommendedGameScreen.
app/src/main/java/app/gamenative/ui/screen/library/LibraryAppScreen.kt (1)

598-607: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Focus retry loop is correct but duplicates requestInitialFocus helper logic.

The retry pattern here (5 attempts, IllegalStateException catch, delay(32)) is identical to the Modifier.requestInitialFocus helper introduced in FocusModifiers.kt. However, since playButtonFocusRequester is passed as a parameter to PrimaryActionButton rather than applied via a modifier chain, requestInitialFocus can't be used directly without refactoring PrimaryActionButton to accept a modifier.

Consider extracting just the retry portion into a reusable suspend helper (e.g., suspend fun FocusRequester.requestFocusWithRetry()) that both requestInitialFocus and this call site can share, eliminating the duplicated loop body.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/main/java/app/gamenative/ui/screen/library/LibraryAppScreen.kt`
around lines 598 - 607, Extract the shared five-attempt focus retry behavior
from the LaunchedEffect block and Modifier.requestInitialFocus into a suspend
FocusRequester helper, such as requestFocusWithRetry(), preserving the
IllegalStateException handling and 32ms delay. Update both callers to use the
helper, including the playButtonFocusRequester flow, while keeping the existing
focus-triggering behavior unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@app/src/main/java/app/gamenative/ui/screen/library/LibraryAppScreen.kt`:
- Around line 598-607: Extract the shared five-attempt focus retry behavior from
the LaunchedEffect block and Modifier.requestInitialFocus into a suspend
FocusRequester helper, such as requestFocusWithRetry(), preserving the
IllegalStateException handling and 32ms delay. Update both callers to use the
helper, including the playButtonFocusRequester flow, while keeping the existing
focus-triggering behavior unchanged.

In `@app/src/main/java/app/gamenative/ui/screen/login/TwoFactorAuthScreen.kt`:
- Around line 134-142: Replace the inline LaunchedEffect retry loop in
TwoFactorAuthScreen with the existing requestInitialFocus(focusRequester)
modifier on the text field, removing the separate focusRequester modifier call.
Remove the now-unused kotlinx.coroutines.delay import, while preserving the text
field’s initial-focus behavior consistent with RecommendedGameScreen.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 29d80392-ade3-4844-ae15-2dc8c38fcc85

📥 Commits

Reviewing files that changed from the base of the PR and between b5a875f and 96c5de7.

📒 Files selected for processing (8)
  • app/src/main/java/app/gamenative/ui/screen/downloads/DownloadsScreen.kt
  • app/src/main/java/app/gamenative/ui/screen/library/LibraryAppScreen.kt
  • app/src/main/java/app/gamenative/ui/screen/library/LibraryScreen.kt
  • app/src/main/java/app/gamenative/ui/screen/library/RecommendedGameScreen.kt
  • app/src/main/java/app/gamenative/ui/screen/login/TwoFactorAuthScreen.kt
  • app/src/main/java/app/gamenative/ui/screen/login/UserLoginScreen.kt
  • app/src/main/java/app/gamenative/ui/screen/settings/SettingsScreen.kt
  • app/src/main/java/app/gamenative/ui/util/FocusModifiers.kt
🚧 Files skipped from review as they are similar to previous changes (5)
  • app/src/main/java/app/gamenative/ui/screen/login/UserLoginScreen.kt
  • app/src/main/java/app/gamenative/ui/screen/downloads/DownloadsScreen.kt
  • app/src/main/java/app/gamenative/ui/util/FocusModifiers.kt
  • app/src/main/java/app/gamenative/ui/screen/settings/SettingsScreen.kt
  • app/src/main/java/app/gamenative/ui/screen/library/LibraryScreen.kt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants