Skip to content

feat: add oss/playstore flavors and feature flags#1007

Open
xXJSONDeruloXx wants to merge 2 commits into
utkarshdalal:masterfrom
xXJSONDeruloXx:feat/playstore-build-flavors-custom-games
Open

feat: add oss/playstore flavors and feature flags#1007
xXJSONDeruloXx wants to merge 2 commits into
utkarshdalal:masterfrom
xXJSONDeruloXx:feat/playstore-build-flavors-custom-games

Conversation

@xXJSONDeruloXx
Copy link
Copy Markdown
Contributor

@xXJSONDeruloXx xXJSONDeruloXx commented Mar 24, 2026

Starting groundwork to feat flag between playstore focused releases vs "oss" which would be releases in GitHub.

First and most obvious thing we want to flag I think is hiding custom games creation, and accessing of them. so here we have one new bool for ENABLE_CUSTOM_GAMES where if false:

  • remove the LOCAL tab when disabled
  • prevent switching into hidden tabs
  • hide add-game actions/buttons
  • sanitize state so Play Store builds don’t land in invalid UI state
image (yes, tabs not centered but thats out of scope for this one, will address in a ui centered PR. removal of local just made it more obvious lol)

Summary by CodeRabbit

  • New Features
    • New distribution variants allow builds with custom-games enabled or disabled; UI adapts (add button, tab visibility, counts, navigation) when custom games are off.
  • Bug Fixes
    • Tab navigation and selection now handle unavailable tabs and sanitize current tab to a valid choice.
  • Chores
    • CI test step updated to run the variant-specific unit tests.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 24, 2026

📝 Walkthrough

Walkthrough

Adds a new product-flavor dimension (distribution) with oss and playstore, exposes build-time BuildConfig.ENABLE_CUSTOM_GAMES, and gates enum/tab availability, ViewModel logic, and UI flows to enable/disable custom-games and sanitize available tabs.

Changes

Cohort / File(s) Summary
Build configuration
app/build.gradle.kts, ubuntufs/build.gradle.kts, .github/workflows/pluvia-pr-check.yml
Added distribution flavor dimension with oss (ENABLE_CUSTOM_GAMES=true) and playstore (ENABLE_CUSTOM_GAMES=false). CI test task updated to run :app:testOssDebugUnitTest.
Tab enum & navigation
app/src/main/java/app/gamenative/ui/enums/LibraryTab.kt
Added availableTabs() and sanitize(); next()/previous() now accept an availableTabs list and cycle within available tabs rather than all enum entries.
Library view model
app/src/main/java/app/gamenative/ui/model/LibraryViewModel.kt
Introduced customGamesEnabled from BuildConfig; gated toggles, folder additions, scanning/filtering, and badge counts; sanitize tab storage and navigation.
Library UI & components
app/src/main/java/app/gamenative/ui/screen/library/LibraryScreen.kt, app/src/main/java/app/gamenative/ui/screen/library/components/LibraryTabBar.kt
UI now respects ENABLE_CUSTOM_GAMES: disables add-custom-game actions, conditionally renders Add button, auto-switches from LOCAL when disabled, and derives tab lists from availableTabs().

Sequence Diagram(s)

sequenceDiagram
  participant User as User
  participant UI as LibraryScreen / TabBar
  participant VM as LibraryViewModel
  participant Enum as LibraryTab

  User->>UI: select tab / press Add Custom Game
  UI->>UI: check BuildConfig.ENABLE_CUSTOM_GAMES
  alt ENABLE_CUSTOM_GAMES = false
    UI-->>User: no-op or switch to ALL
    UI->>VM: setTab(LibraryTab.sanitize(selected))
    VM->>Enum: LibraryTab.availableTabs()
    Enum-->>VM: available list (LOCAL excluded)
    VM-->>UI: updated state (custom-game flows disabled)
  else ENABLE_CUSTOM_GAMES = true
    UI->>VM: open folder picker / set LOCAL
    VM->>Enum: LibraryTab.availableTabs()
    Enum-->>VM: available list (LOCAL included)
    VM-->>UI: allow custom-game actions
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • phobos665

Poem

🐰✨ I hopped through flavors, OSS and store,
I hid the LOCAL when custom-games are no more.
Tabs now sanitize and bounce to the right,
I nudge the UI gently—soft moonlit night. 🎮

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description is partially complete. It clearly explains the feature flag purpose and implementation, but lacks sections required by the template (Type of Change, Recording, and Checklist items). Complete the PR description by selecting a Type of Change checkbox, including a recording/GIF, and confirming all checklist items per the repository template.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: adding distribution flavors (oss/playstore) and introducing a feature flag (ENABLE_CUSTOM_GAMES) for conditional behavior.
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
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.

No issues found across 6 files

@xXJSONDeruloXx xXJSONDeruloXx changed the title feat: add oss/playstore flavors for custom games feat: add oss/playstore flavors and feature flags Mar 24, 2026
@updeshxp
Copy link
Copy Markdown

Any reason why custom games feature is required to be Disabled for playstore?

@utkarshdalal
Copy link
Copy Markdown
Owner

can we keep this one as draft for now?

@xXJSONDeruloXx xXJSONDeruloXx marked this pull request as draft March 27, 2026 10:29
@xXJSONDeruloXx xXJSONDeruloXx force-pushed the feat/playstore-build-flavors-custom-games branch from 91aadb8 to 377828b Compare April 9, 2026 12:51
@xXJSONDeruloXx xXJSONDeruloXx marked this pull request as ready for review April 13, 2026 00:18
@xXJSONDeruloXx
Copy link
Copy Markdown
Contributor Author

@utkarshdalal bringing out of draft as 0.9.0 release is up, as discussed I think we should get this in as groundwork toward play store release and unblock feature works

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.

No issues found across 7 files

@xXJSONDeruloXx xXJSONDeruloXx force-pushed the feat/playstore-build-flavors-custom-games branch from d74058b to 67deef7 Compare April 28, 2026 14:00
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.

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

435-438: Consider reusing LibraryTab.sanitize() for tab correction.

Line 437 hardcodes LibraryTab.ALL. Using LibraryTab.sanitize(state.currentTab) here would keep policy centralized if valid fallback behavior ever changes.

Suggested patch
LaunchedEffect(customGamesEnabled, state.currentTab) {
-    if (!customGamesEnabled && state.currentTab == LibraryTab.LOCAL) {
-        onTabChanged(LibraryTab.ALL)
-    }
+    if (!customGamesEnabled) {
+        val sanitizedTab = LibraryTab.sanitize(state.currentTab)
+        if (sanitizedTab != state.currentTab) {
+            onTabChanged(sanitizedTab)
+        }
+    }
}
🤖 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/screen/library/LibraryScreen.kt` around
lines 435 - 438, The LaunchedEffect block that currently forces a hardcoded
fallback to LibraryTab.ALL should instead call
LibraryTab.sanitize(state.currentTab) and pass that result to onTabChanged so
fallback logic is centralized; update the LaunchedEffect in LibraryScreen (the
block referencing customGamesEnabled and state.currentTab) to compute val
corrected = LibraryTab.sanitize(state.currentTab) and call
onTabChanged(corrected) rather than onTabChanged(LibraryTab.ALL).
app/src/main/java/app/gamenative/ui/enums/LibraryTab.kt (1)

82-93: Add a defensive empty-list guard in tab navigation helpers.

Line 85 and Line 92 assume availableTabs is non-empty. If a caller passes emptyList(), this can crash (% 0 or invalid index). A small guard makes these helpers resilient.

Suggested patch
fun LibraryTab.next(availableTabs: List<LibraryTab> = LibraryTab.availableTabs()): LibraryTab {
+    if (availableTabs.isEmpty()) return ALL
     val currentIndex = availableTabs.indexOf(this)
     if (currentIndex == -1) return ALL
     val nextIndex = (currentIndex + 1) % availableTabs.size
     return availableTabs[nextIndex]
 }

 fun LibraryTab.previous(availableTabs: List<LibraryTab> = LibraryTab.availableTabs()): LibraryTab {
+    if (availableTabs.isEmpty()) return ALL
     val currentIndex = availableTabs.indexOf(this)
     if (currentIndex == -1) return ALL
     val prevIndex = if (currentIndex == 0) availableTabs.size - 1 else currentIndex - 1
     return availableTabs[prevIndex]
 }
🤖 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/enums/LibraryTab.kt` around lines 82 -
93, The next and previous helpers (LibraryTab.next and LibraryTab.previous)
assume availableTabs is non-empty and can crash on emptyList() (mod by zero or
invalid index); add a defensive guard at the start of both functions that
returns a safe default (e.g., LibraryTab.ALL) when availableTabs.isEmpty() to
avoid division by zero/invalid indexing, then continue with the existing logic
for non-empty lists.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@app/src/main/java/app/gamenative/ui/enums/LibraryTab.kt`:
- Around line 82-93: The next and previous helpers (LibraryTab.next and
LibraryTab.previous) assume availableTabs is non-empty and can crash on
emptyList() (mod by zero or invalid index); add a defensive guard at the start
of both functions that returns a safe default (e.g., LibraryTab.ALL) when
availableTabs.isEmpty() to avoid division by zero/invalid indexing, then
continue with the existing logic for non-empty lists.

In `@app/src/main/java/app/gamenative/ui/screen/library/LibraryScreen.kt`:
- Around line 435-438: The LaunchedEffect block that currently forces a
hardcoded fallback to LibraryTab.ALL should instead call
LibraryTab.sanitize(state.currentTab) and pass that result to onTabChanged so
fallback logic is centralized; update the LaunchedEffect in LibraryScreen (the
block referencing customGamesEnabled and state.currentTab) to compute val
corrected = LibraryTab.sanitize(state.currentTab) and call
onTabChanged(corrected) rather than onTabChanged(LibraryTab.ALL).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 74e42258-2484-4618-ad56-783efcbb7ce1

📥 Commits

Reviewing files that changed from the base of the PR and between d74058b and 67deef7.

📒 Files selected for processing (7)
  • .github/workflows/pluvia-pr-check.yml
  • app/build.gradle.kts
  • app/src/main/java/app/gamenative/ui/enums/LibraryTab.kt
  • app/src/main/java/app/gamenative/ui/model/LibraryViewModel.kt
  • app/src/main/java/app/gamenative/ui/screen/library/LibraryScreen.kt
  • app/src/main/java/app/gamenative/ui/screen/library/components/LibraryTabBar.kt
  • ubuntufs/build.gradle.kts
✅ Files skipped from review due to trivial changes (2)
  • .github/workflows/pluvia-pr-check.yml
  • app/src/main/java/app/gamenative/ui/screen/library/components/LibraryTabBar.kt
🚧 Files skipped from review as they are similar to previous changes (3)
  • ubuntufs/build.gradle.kts
  • app/build.gradle.kts
  • app/src/main/java/app/gamenative/ui/model/LibraryViewModel.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