Skip to content

feat: use game hero image as booting splash background#1128

Open
xXJSONDeruloXx wants to merge 106 commits into
utkarshdalal:masterfrom
xXJSONDeruloXx:feat/hero-bg-booting-splash
Open

feat: use game hero image as booting splash background#1128
xXJSONDeruloXx wants to merge 106 commits into
utkarshdalal:masterfrom
xXJSONDeruloXx:feat/hero-bg-booting-splash

Conversation

@xXJSONDeruloXx
Copy link
Copy Markdown
Contributor

@xXJSONDeruloXx xXJSONDeruloXx commented Apr 7, 2026

Description

add game art from hero or equivalent when game is booting, with drop shadow blur and darkening to make text more legible. more closely mirrors steam bpm experience and personalizes per game.

https://discord.com/channels/1378308569287622737/1489699856774729839

Recording

Screen.Recording.2026-04-07.at.10.37.22.AM.mov

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.
  • I have attached a recording of the change.
  • I have read and agree to the contribution guidelines in CONTRIBUTING.md.

Summary by cubic

Use each game's hero image as the booting splash background to personalize launch and improve text readability. Adds blur, vignettes, and a dark overlay; resolves hero art across stores and local custom games.

  • New Features
    • BootingSplash accepts heroImageUrl and renders a blurred, full-bleed background with vertical/horizontal vignettes and a darker scrim; adds drop shadows to status/tip text and removes background particles.
    • On launch, MainViewModel picks hero art with fallbacks (Steam hero→header, GOG background→image, Epic portrait→cover→square, Amazon hero→art, local steamgriddb_hero*); wired via MainState.bootingSplashHeroImageUrl and passed through PluviaMain.

Written for commit c9c19e4. Summary will update on new commits.

Summary by CodeRabbit

  • New Features

    • Booting splash now shows a per-game hero image (remote or local) as the splash background, resolved with store- and app-specific fallbacks.
  • Style

    • Background replaced with a scaled, blurred hero image plus dark vignette overlays (replacing the previous particle backdrop).
    • Status and tip text now include drop shadows for improved readability.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 7, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8b2ea662-c56c-4244-aa33-67d1cc05890d

📥 Commits

Reviewing files that changed from the base of the PR and between 67b9e04 and c9c19e4.

📒 Files selected for processing (3)
  • app/src/main/java/app/gamenative/ui/PluviaMain.kt
  • app/src/main/java/app/gamenative/ui/components/BootingSplash.kt
  • app/src/main/java/app/gamenative/ui/model/MainViewModel.kt
🚧 Files skipped from review as they are similar to previous changes (3)
  • app/src/main/java/app/gamenative/ui/PluviaMain.kt
  • app/src/main/java/app/gamenative/ui/model/MainViewModel.kt
  • app/src/main/java/app/gamenative/ui/components/BootingSplash.kt

📝 Walkthrough

Walkthrough

Supplies a boot-splash hero image URL through MainState/MainViewModel and passes it into BootingSplash; BootingSplash renders a remote/local hero backdrop (with scale/blur, darkening and vignette overlays, and text drop shadows) when the URL is present and removes the prior particle canvas background.

Changes

Boot splash feature (state, VM resolution, UI rendering)

Layer / File(s) Summary
State plumbing
app/src/main/java/app/gamenative/ui/data/MainState.kt, app/src/main/java/app/gamenative/ui/PluviaMain.kt
Added bootingSplashHeroImageUrl: String = "" to MainState; PluviaMain now passes state.bootingSplashHeroImageUrl into BootingSplash.heroImageUrl.
Hero URL resolution in ViewModel
app/src/main/java/app/gamenative/ui/model/MainViewModel.kt
Added setBootingSplashHeroImageUrl(url: String) and extended launchApp() to resolve a hero image URL by source: Steam/GOG/EPIC/AMAZON fields with fallbacks, or scanning local custom-game folder for a matching steamgriddb_hero* image; writes resolved URL to state before showing the splash.
BootingSplash UI & rendering
app/src/main/java/app/gamenative/ui/components/BootingSplash.kt
Added heroImageUrl: String = "" parameter. When non-empty, replaces particle/gradient backdrop with a full-screen Coil-loaded hero image (scale/graphicsLayer + blur) and overlays a darkening layer plus vertical/horizontal vignette gradients; status and tip texts gain a black drop shadow. Removed AmbientParticles particle background and related phase animation.

Sequence Diagram(s)

sequenceDiagram
    participant VM as MainViewModel
    participant Services as Remote Services
    participant Scanner as CustomGameScanner
    participant State as MainState
    participant UI as BootingSplash

    VM->>VM: launchApp(context, appId)
    VM->>VM: parse gameSource & gameId

    alt remote source (Steam/GOG/EPIC/AMAZON)
        VM->>Services: request artwork fields / pick fallback URL
        Services-->>VM: hero image URL or empty
    else custom game
        VM->>Scanner: find first local hero image file
        Scanner-->>VM: file Uri string or empty
    end

    VM->>State: setBootingSplashHeroImageUrl(url)
    VM->>State: setShowBootingSplash(true)
    State-->>UI: expose heroImageUrl

    alt heroImageUrl non-empty
        UI->>UI: load image via Coil, apply scale & blur
        UI->>UI: render overlays (darken, vertical/horizontal vignettes) and text shadows
    else heroImageUrl empty
        UI->>UI: render standard animated splash (particles/gradient)
    end

    UI-->>UI: display splash with progress/other animations
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • utkarshdalal
  • phobos665
  • DanielJVoxSmart

Poem

🐰 I hopped through folders, cloud and crate,
I found a hero, strong and great.
I blurred the edges, dimmed the light,
So boot feels cozy, soft, and bright.
Hooray — the splash now greets the sight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Title check ✅ Passed The pull request title accurately summarizes the main change: adding game hero images as the booting splash background, which is the primary feature across all modified files.
Description check ✅ Passed The pull request description is mostly complete with clear context about the changes, a recording link, and all checklist items marked as complete. The auto-generated summary by cubic provides detailed technical information.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

Copy link
Copy Markdown

@DanielJVoxSmart DanielJVoxSmart left a comment

Choose a reason for hiding this comment

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

.

Copy link
Copy Markdown
Contributor

@phobos665 phobos665 left a comment

Choose a reason for hiding this comment

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

Based on the video and code, this looks like a massive improvement in both style and legibility.

@xXJSONDeruloXx xXJSONDeruloXx marked this pull request as ready for review April 8, 2026 23:43
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
app/src/main/java/app/gamenative/ui/model/MainViewModel.kt (1)

458-491: Consider moving I/O operations off the main thread.

The hero URL resolution runs on the main dispatcher. While most service lookups are likely cached in memory, the custom game path involves folder.listFiles() which is a filesystem I/O operation. Consider wrapping the custom game branch (or the entire resolution block) in withContext(Dispatchers.IO) to avoid potential UI jank.

♻️ Optional: Move resolution to IO dispatcher
 viewModelScope.launch {
     // Resolve hero image URL for the booting splash background
     val gameSource = ContainerUtils.extractGameSourceFromContainerId(appId)
     val gameId = ContainerUtils.extractGameIdFromContainerId(appId)
-    val heroUrl = when (gameSource) {
+    val heroUrl = withContext(Dispatchers.IO) {
+        when (gameSource) {
             // ... existing cases ...
+        }
+    }
     setBootingSplashHeroImageUrl(heroUrl)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/java/app/gamenative/ui/model/MainViewModel.kt` around lines 458
- 491, The hero URL resolution in MainViewModel does filesystem I/O on the main
dispatcher (notably CustomGameScanner.getFolderPathFromAppId and
folder.listFiles()), so move the custom-game branch (or the whole resolution
block) into a withContext(Dispatchers.IO) block to perform folder.listFiles()
off the main thread; update the coroutine context where heroUrl is computed to
call withContext(Dispatchers.IO) and keep the UI-thread-safe return values
(strings/URIs) to be used back on the main dispatcher.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/src/main/java/app/gamenative/ui/model/MainViewModel.kt`:
- Around line 478-490: The current custom-game hero lookup in the
GameSource.CUSTOM_GAME branch uses startsWith("steamgriddb_grid_hero") and thus
incorrectly selects grid images; update the filter in the heroFile selection
(the lambda used when assigning heroFile) to match files starting with
"steamgriddb_hero" and explicitly exclude any names containing "grid_" (i.e.,
startsWith("steamgriddb_hero", ignoreCase = true) &&
!file.name.contains("grid_", ignoreCase = true)) while keeping the existing
extension checks; this change should be made near
CustomGameScanner.getFolderPathFromAppId usage where heroFile is determined.

---

Nitpick comments:
In `@app/src/main/java/app/gamenative/ui/model/MainViewModel.kt`:
- Around line 458-491: The hero URL resolution in MainViewModel does filesystem
I/O on the main dispatcher (notably CustomGameScanner.getFolderPathFromAppId and
folder.listFiles()), so move the custom-game branch (or the whole resolution
block) into a withContext(Dispatchers.IO) block to perform folder.listFiles()
off the main thread; update the coroutine context where heroUrl is computed to
call withContext(Dispatchers.IO) and keep the UI-thread-safe return values
(strings/URIs) to be used back on the main dispatcher.
🪄 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: 30d481cd-96a4-4940-8449-eb940a2e8962

📥 Commits

Reviewing files that changed from the base of the PR and between 8f95184 and 0fa26c9.

📒 Files selected for processing (4)
  • app/src/main/java/app/gamenative/ui/PluviaMain.kt
  • app/src/main/java/app/gamenative/ui/components/BootingSplash.kt
  • app/src/main/java/app/gamenative/ui/data/MainState.kt
  • app/src/main/java/app/gamenative/ui/model/MainViewModel.kt

Comment thread app/src/main/java/app/gamenative/ui/model/MainViewModel.kt
Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

2 issues found across 4 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/components/BootingSplash.kt">

<violation number="1" location="app/src/main/java/app/gamenative/ui/components/BootingSplash.kt:158">
P2: Newly added hardcoded overlay/vignette/shadow colors bypass centralized theme resources, reducing theming consistency and maintainability.</violation>
</file>

<file name="app/src/main/java/app/gamenative/ui/model/MainViewModel.kt">

<violation number="1" location="app/src/main/java/app/gamenative/ui/model/MainViewModel.kt:482">
P2: Synchronous directory scan (`File.listFiles`) runs inside `viewModelScope.launch` on the main dispatcher, which can block UI/ANR for large custom-game folders. Offload this filesystem scan to `Dispatchers.IO` or a helper that limits/streams results.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread app/src/main/java/app/gamenative/ui/components/BootingSplash.kt
Comment thread app/src/main/java/app/gamenative/ui/model/MainViewModel.kt
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Utkarsh Dalal and others added 17 commits April 28, 2026 06:14
…w submitting feedback for non-steam, non-custom games
…nstalled (utkarshdalal#1138)

Co-authored-by: Utkarsh Dalal <utkarsh.dalal@toptal.com>
Co-authored-by: Utkarsh Dalal <utkarsh.dalal@toptal.com>
…path if it's a different store (utkarshdalal#1141)

Co-authored-by: Utkarsh Dalal <utkarsh.dalal@toptal.com>
* fix: prevent carousel touch loss during pagination by removing touch-conflicting draggable modifier

* fix: address bot review feedback on carousel mouse input handler

* fix: add drag slop to carousel mouse drag to prevent accidental scrolls on click
* Download support files for gen 2

* Added tests to verify downloading support and game files for gen 1 and 2
…arshdalal#1166)

* fix: include shared redistributables when resolving steam depots

Merges depot IDs from the shared license (ID 0) with app-specific depots to ensure common redistributables and dependencies are correctly identified and downloaded along with game-specific files.

* Update app/src/main/java/app/gamenative/service/SteamService.kt

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
…tkarshdalal#1142)

* do less caching for god of war download

* bump js version 1.8.0.1-18-SNAPSHOT, update CaseInsensitiveFileSystem to implement BaseCaseInsensitiveFileSystem

* only remove the file from cache inside removeFileCache

* fix: nested segment cache + pre-populated listings in CaseInsensitiveFileSystem

* update resolveAndCache only cache directory and skip file

* add log option to CaseInsensitiveFileSystem, handle deleteRecursively properly

* coderabbitai comments

---------

Co-authored-by: Utkarsh Dalal <utkarsh.dalal@toptal.com>
Co-authored-by: Jeremy Bernstein <jeremy.d.bernstein@googlemail.com>
* Reorder sidebar: Storage Manager first, Downloads second; fix header title on Downloads tab

* Default selected tab to Storage Manager

* Add downloads_section_title translations for all 13 locales

* fix: swap Settings before Downloads in System sidebar
Co-authored-by: Phobos665 <5970062+phobos665@users.noreply.github.com>
…hdalal#1133)

* feat: update wine-mono version to 11.0.0 in installer scripts

* fix: bump_version in ImageFsInstaller.java,
will trigger extraction for all existing containers that are on Mono 9.0.0 and install 11.0.0.
joshuatam and others added 23 commits April 28, 2026 06:15
…hdalal#1277)

* refactor: Improve GOGDownloadManager download efficiency

1. Adopt Flow queuing concept from JavaSteam
2. add DownloadSpeedConfig to be used later for other store enhancement
3. update kotlinx-coroutines-core version to match JavaSteam version using
4. Update NetworkUtils httpForParallelDownloads for timeout and http protocol config

* ai comments

* add retry logic when same pendingChunks appear 10 times in a row
…utkarshdalal#1269)

* Reapply "fix/feat: extract XAudio DLLs from DirectX redistributables (utkarshdalal#1184)" (utkarshdalal#1266)

This reverts commit 93793fa.

* fix: extract XAudio DLLs using native cabarc instead of 7-Zip binding

Replaces the 7-Zip JBinding library with a Wine-based batch script that uses the native cabarc utility to extract DirectX DLLs. This removes the dependency on JitPack and the external 7-Zip library while maintaining the fix for Proton 10.

* ai comments

* ai comments

* ai comments, refactor to XAudioUtils

* guard batchCommand with BATCH_SUCCESS_CHECK

* move guard code location after all extraction

* remove useless comment

* add splash text when extracting dlls
…karshdalal#1260)

- Add AppID 1468810 (Tale of Immortal) to `forceStandardAppIds` to ensure workshop items are handled via the standard ISteamUGC path.
Moved Touchscreen Mode toggle from Edit Container > Controller section to the in-game sidebar, right below the existing Edit On-screen Controller line. Added gear icon for gesture settings that appears when touchscreen mode is active.
…ome games (utkarshdalal#1212)

* fix: late release single tap in touchscreen mode to fix clicking in some games

* fix: immediately release click before a new single tap

* clear delayedPress state after execution

* flush pending single tap release on handleTsDown
…alal#1297)

Danganronpa 2 stores saves in WinMyDocuments/My Games/Danganronpa2/ via
a Windows rootoverride, but GameNative was placing downloaded cloud saves
in the game install directory instead, so the game never found them.

Two bugs fixed:

1. KeyValueUtils: treat PICS path '/' as empty (same as '.')
   A lone forward-slash means 'root of this path type' with no subdir.
   Keeping the literal '/' caused uploadPath='/' which put a trailing
   slash on the cloudPrefixToLocalPath map key ('%GameInstall%/') while
   the lookup trimmed it ('%GameInstall%'), causing a miss. With the fix,
   uploadPath='' and path='My Games/Danganronpa2' (no trailing slash).
   Also bumps CURRENT_UFS_PARSE_VERSION 2->3 to force cache refresh.

2. SteamAutoCloud getFullFilePath: consult cloudPrefixToLocalPath when
   Steam embeds the placeholder in the filename (prefix=[],
   filename='%GameInstall%savedata.vfs'). The previous early-return
   hardcoded the destination as the game install dir, bypassing all
   rootoverride remapping. Now checks cloudPrefixToLocalPath['%GameInstall%']
   first so the file lands in WinMyDocuments/My Games/Danganronpa2/.

Also adds .trimEnd('/') to cloudKey construction in cloudPrefixToLocalPath
so map keys are always slash-free (matching the existing lookup behaviour).

Tests added:
- KeyValueUtilsTest: danganronpa2SlashPathWithWindowsRootOverrideIsNormalizedToEmpty
- SteamAutoCloudTest: downloadWithEmbeddedGameInstallPrefixUsesRootoverrideLocalPath
- keyvalues/Danganronpa 2 Goodbye Despair.txt: PICS reference documentation
…dalal#1267)

* feat: move Disable Mouse Input to in-game Quick Menu overlay

Removes the Disable Mouse Input toggle from the container settings
Controller tab and adds it to the in-game Quick Menu, where it can
be toggled during gameplay without leaving the game. State is
persisted to the container config on toggle.

* fix: address code review feedback

- Remove unconditional setCursorVisible call; cursor state is managed
  by existing pointer-availability logic and should not be overridden
  when a physical mouse may be present
- Key isDisableMouseInput state to container.id to prevent stale state
  if container changes

* fix: restore cursor visibility on mouse input toggle

Show cursor when re-enabling mouse input (unless touchscreen mode is
also active), hide it when disabling. Required for touch-as-mouse
users who have no physical pointer device.

* fix: use mouse icon and pink accent for Disable Mouse quick menu item
utkarshdalal#1310)

* Stop overwriting wine prefix when switching between containers of different variants/archs, only extract xaudio dlls once

* do reinstall of mono and preinstallsteps on wine version change (not arch), fixed bugs with wincomponents, audio driver, and startup selection being overwritten on wine version change

---------

Co-authored-by: Utkarsh Dalal <utkarsh.dalal@toptal.com>
Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

4 issues found across 202 files (changes from recent commits).

Note: This PR contains a large number of files. cubic only reviews up to 75 files per PR, so some files may not have been reviewed. cubic prioritises the most important files to review.

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/gamefixes/IniFileFix.kt">

<violation number="1" location="app/src/main/java/app/gamenative/gamefixes/IniFileFix.kt:13">
P2: Regex replacement uses raw value, so `$`/`\` in INI defaults are interpreted as group refs/escapes and can corrupt or fail updates</violation>
</file>

<file name="CONTRIBUTING.md">

<violation number="1" location="CONTRIBUTING.md:27">
P2: Process section mandates pre-PR discussion/approval while Quick Start treats it as optional, creating conflicting contribution requirements.</violation>
</file>

<file name="app/src/main/java/app/gamenative/ui/util/ContainerConfigTransfer.kt">

<violation number="1" location="app/src/main/java/app/gamenative/ui/util/ContainerConfigTransfer.kt:108">
P2: Detached background coroutine returns false before import completes, breaking importConfig result/cancellation contract</violation>
</file>

<file name="app/src/main/java/app/gamenative/PluviaApp.kt">

<violation number="1" location="app/src/main/java/app/gamenative/PluviaApp.kt:231">
P2: `shutdownEnvironment()` does not clear the companion `xServerView`, so the new shared teardown path can retain a static Android view and its context, risking leaks/stale state despite being described as a full teardown.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

private fun updateIniValue(content: String, key: String, value: String): String {
val regex = Regex("(?im)^(${Regex.escape(key)}\\s*=\\s*).*$")
return if (regex.containsMatchIn(content)) {
content.replace(regex, "$1$value")
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 28, 2026

Choose a reason for hiding this comment

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

P2: Regex replacement uses raw value, so $/\ in INI defaults are interpreted as group refs/escapes and can corrupt or fail updates

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At app/src/main/java/app/gamenative/gamefixes/IniFileFix.kt, line 13:

<comment>Regex replacement uses raw value, so `$`/`\` in INI defaults are interpreted as group refs/escapes and can corrupt or fail updates</comment>

<file context>
@@ -0,0 +1,66 @@
+private fun updateIniValue(content: String, key: String, value: String): String {
+    val regex = Regex("(?im)^(${Regex.escape(key)}\\s*=\\s*).*$")
+    return if (regex.containsMatchIn(content)) {
+        content.replace(regex, "$1$value")
+    } else {
+        val suffix = if (content.endsWith("\n") || content.isEmpty()) "" else System.lineSeparator()
</file context>
Fix with Cubic

Comment thread CONTRIBUTING.md

## Process

Before opening a PR:
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 28, 2026

Choose a reason for hiding this comment

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

P2: Process section mandates pre-PR discussion/approval while Quick Start treats it as optional, creating conflicting contribution requirements.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At CONTRIBUTING.md, line 27:

<comment>Process section mandates pre-PR discussion/approval while Quick Start treats it as optional, creating conflicting contribution requirements.</comment>

<file context>
@@ -9,6 +9,32 @@ Thanks for your interest in contributing. We welcome pull requests, bug reports,
+
+## Process
+
+Before opening a PR:
+1. Discuss the change in #code-changes
+2. Wait for it to be acknowledged/approved
</file context>
Fix with Cubic

if (missingComponents.isNotEmpty()) {
BaseAppScreen.showMissingComponentsDialog(appId, missingComponents) {
// "apply anyway" — re-parse with defaults, install manifest entries, apply
CoroutineScope(Dispatchers.IO).launch {
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 28, 2026

Choose a reason for hiding this comment

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

P2: Detached background coroutine returns false before import completes, breaking importConfig result/cancellation contract

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At app/src/main/java/app/gamenative/ui/util/ContainerConfigTransfer.kt, line 108:

<comment>Detached background coroutine returns false before import completes, breaking importConfig result/cancellation contract</comment>

<file context>
@@ -97,10 +100,55 @@ object ContainerConfigTransfer {
+                if (missingComponents.isNotEmpty()) {
+                    BaseAppScreen.showMissingComponentsDialog(appId, missingComponents) {
+                        // "apply anyway" — re-parse with defaults, install manifest entries, apply
+                        CoroutineScope(Dispatchers.IO).launch {
+                            try {
+                                val forced = BestConfigService.parseConfigToContainerData(
</file context>
Fix with Cubic

runCatching { env?.stopEnvironmentComponents() }
.onFailure { Timber.e(it, "shutdownEnvironment: stopEnvironmentComponents") }

xEnvironment = null
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 28, 2026

Choose a reason for hiding this comment

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

P2: shutdownEnvironment() does not clear the companion xServerView, so the new shared teardown path can retain a static Android view and its context, risking leaks/stale state despite being described as a full teardown.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At app/src/main/java/app/gamenative/PluviaApp.kt, line 231:

<comment>`shutdownEnvironment()` does not clear the companion `xServerView`, so the new shared teardown path can retain a static Android view and its context, risking leaks/stale state despite being described as a full teardown.</comment>

<file context>
@@ -200,6 +210,33 @@ class PluviaApp : SplitCompatApplication() {
+            runCatching { env?.stopEnvironmentComponents() }
+                .onFailure { Timber.e(it, "shutdownEnvironment: stopEnvironmentComponents") }
+
+            xEnvironment = null
+            inputControlsView = null
+            inputControlsManager = null
</file context>
Suggested change
xEnvironment = null
xEnvironment = null
xServerView = null
Fix with Cubic

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/src/main/java/app/gamenative/ui/model/MainViewModel.kt`:
- Around line 458-482: The hero URL resolution in launchApp is doing blocking IO
and service lookups on the Main dispatcher (calls like
CustomGameScanner.getFolderPathFromAppId, File.listFiles(),
SteamService.getAppInfoOf, GOGService.getGOGGameOf, EpicService.getEpicGameOf,
AmazonService.getAmazonGameByAppId), which delays setShowBootingSplash(true);
move the entire hero-resolution block into withContext(Dispatchers.IO) so it
runs off the main thread, return the resolved heroUrl back to the caller thread,
and keep UI state calls (e.g., setShowBootingSplash(true)) on the Main
dispatcher; ensure you only access UI/state from the Main dispatcher after the
IO work completes.
🪄 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: 2eecf4e7-6aec-4c61-8b78-f94b55be8a50

📥 Commits

Reviewing files that changed from the base of the PR and between e6b8ed5 and 67b9e04.

📒 Files selected for processing (2)
  • app/src/main/java/app/gamenative/ui/PluviaMain.kt
  • app/src/main/java/app/gamenative/ui/model/MainViewModel.kt

Comment thread app/src/main/java/app/gamenative/ui/model/MainViewModel.kt
@utkarshdalal
Copy link
Copy Markdown
Owner

image Regression for games that don't have a hero image - just shows a black background. We should preserve the current behaviour.

@utkarshdalal
Copy link
Copy Markdown
Owner

utkarshdalal commented May 17, 2026

image image

We should use a grayscale or much less saturated image here. Looks fine for Rivals of Aether but not for the few games I've tried - not enough contrast with the GameNative text and loading bar.

@xXJSONDeruloXx
Copy link
Copy Markdown
Contributor Author

I disagree, I think these look great, greyscale would be a bummer

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.