Skip to content

feat: implement "Liquid Glass" toggle and rename theme repository#343

Merged
rainxchzed merged 3 commits intomainfrom
togglable-liquid
Mar 20, 2026
Merged

feat: implement "Liquid Glass" toggle and rename theme repository#343
rainxchzed merged 3 commits intomainfrom
togglable-liquid

Conversation

@rainxchzed
Copy link
Member

@rainxchzed rainxchzed commented Mar 20, 2026

  • Rename ThemesRepository to TweaksRepository to reflect its expanded scope of managing various app behaviors and settings.
  • Implement a new "Liquid Glass Effect" setting in the Appearance section, allowing users to toggle the smooth glass-like UI effects.
  • Update ProfileViewModel, HomeViewModel, SearchViewModel, AppsViewModel, and DetailsViewModel to observe and react to the isLiquidGlassEnabled state.
  • Conditionally apply Modifier.liquefiable and liquid frost backgrounds across multiple UI components (TopBars, BottomNavigation, FilterChips, and content sections) based on the user's preference.
  • Refactor dependency injection and repository usages to support the new TweaksRepository interface.
  • Add localized strings for the Liquid Glass option title and description.
  • Adjust layout and padding in the Profile screen settings sections.

Summary by CodeRabbit

  • New Features

    • Added "Liquid Glass Effect" toggle in Appearance settings to enable a smooth glass-like visual treatment across the app.
    • Liquid Glass setting now controls UI effects globally (top bars, cards, lists, navigation, install screens).
  • Improvements

    • Liquid Glass visuals are now conditionally applied for better performance and consistency.
    • Settings layout updated for clearer organization.
  • Localization

    • New localized strings for the Liquid Glass option added in multiple languages.

- Rename `ThemesRepository` to `TweaksRepository` to reflect its expanded scope of managing various app behaviors and settings.
- Implement a new "Liquid Glass Effect" setting in the Appearance section, allowing users to toggle the smooth glass-like UI effects.
- Update `ProfileViewModel`, `HomeViewModel`, `SearchViewModel`, `AppsViewModel`, and `DetailsViewModel` to observe and react to the `isLiquidGlassEnabled` state.
- Conditionally apply `Modifier.liquefiable` and liquid frost backgrounds across multiple UI components (TopBars, BottomNavigation, FilterChips, and content sections) based on the user's preference.
- Refactor dependency injection and repository usages to support the new `TweaksRepository` interface.
- Add localized strings for the Liquid Glass option title and description.
- Adjust layout and padding in the Profile screen settings sections.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 20, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a151baa7-bb46-47b8-8c2e-e841f19ca1e0

📥 Commits

Reviewing files that changed from the base of the PR and between 0a0c289 and 6e24d9d.

📒 Files selected for processing (13)
  • core/presentation/src/commonMain/composeResources/values-ar/strings-ar.xml
  • core/presentation/src/commonMain/composeResources/values-bn/strings-bn.xml
  • core/presentation/src/commonMain/composeResources/values-es/strings-es.xml
  • core/presentation/src/commonMain/composeResources/values-fr/strings-fr.xml
  • core/presentation/src/commonMain/composeResources/values-hi/strings-hi.xml
  • core/presentation/src/commonMain/composeResources/values-it/strings-it.xml
  • core/presentation/src/commonMain/composeResources/values-ja/strings-ja.xml
  • core/presentation/src/commonMain/composeResources/values-ko/strings-ko.xml
  • core/presentation/src/commonMain/composeResources/values-pl/strings-pl.xml
  • core/presentation/src/commonMain/composeResources/values-ru/strings-ru.xml
  • core/presentation/src/commonMain/composeResources/values-tr/strings-tr.xml
  • core/presentation/src/commonMain/composeResources/values-zh-rCN/strings-zh-rCN.xml
  • feature/home/presentation/src/commonMain/kotlin/zed/rainxch/home/presentation/HomeState.kt

Walkthrough

Renames ThemesRepositoryTweaksRepository and adds persistent get/setLiquidGlassEnabled() preference. Threads new isLiquidGlassEnabled flag through DI, view models, states, navigation, and many composables to conditionally enable/disable the liquid‑glass UI effects; also updates DI and Android workers to use TweaksRepository.

Changes

Cohort / File(s) Summary
Domain & Impl
core/domain/.../TweaksRepository.kt, core/data/.../Tweak*s*RepositoryImpl.kt
Renamed interface/type from ThemesRepositoryTweaksRepository; added getLiquidGlassEnabled(): Flow<Boolean> and setLiquidGlassEnabled(Boolean); impl adds LIQUID_GLASS_ENABLED_KEY and persists/reads the preference.
DI & Modules
core/data/.../di/SharedModule.kt, composeApp/.../app/di/SharedModules.kt, core/data/.../di/PlatformModule.android.kt
Swapped DI bindings/wiring to provide TweaksRepository where ThemesRepository was used; minor formatting changes in platform module.
App Root & Navigation
composeApp/src/commonMain/.../Main.kt, .../AppNavigation.kt, .../BottomNavigation.kt, composeApp/src/androidMain/.../GithubStoreApp.kt
Main threads state.isLiquidGlassEnabled into AppNavigationBottomNavigation; BottomNavigation now gates liquid shader on the flag and availability. GithubStoreApp resolves TweaksRepository for update interval scheduling.
ViewModels & State (core + features)
composeApp/.../MainViewModel.kt, feature viewmodels: AppsViewModel.kt, DetailsViewModel.kt, HomeViewModel.kt, ProfileViewModel.kt, SearchViewModel.kt
Replaced ThemesRepository injections with TweaksRepository; each VM observes getLiquidGlassEnabled() and updates its state (isLiquidGlassEnabled). ProfileViewModel adds set handler and startup wiring changes.
State Models
composeApp/.../MainState.kt, feature states: AppsState.kt, DetailsState.kt, HomeState.kt, ProfileState.kt, SearchState.kt
Added isLiquidGlassEnabled: Boolean to multiple screen state data classes (default true).
UI / Composables (widespread)
many files under feature/*/presentation/... (Details sections, SmartInstallButton, AppsRoot, HomeRoot, SearchRoot, ProfileRoot, HomeFilterChips, BottomNavigation, etc.)
Propagated isLiquidGlassEnabled into composable signatures where needed and replaced unconditional Modifier.liquefiable(...) usages with conditional .then(if (isLiquidGlassEnabled) Modifier.liquefiable(...) else Modifier) or useLiquid gating. Added Appearance toggle and profile action.
Android workers & services
core/data/src/androidMain/.../AutoUpdateWorker.kt, UpdateCheckWorker.kt, shizuku/ShizukuInstallerWrapper.kt
Swapped injected ThemesRepositoryTweaksRepository and read auto-update / installer / includePreReleases prefs from TweaksRepository.
Apps / Installed repos
feature/apps/data/.../AppsRepositoryImpl.kt, core/data/.../repository/InstalledAppsRepositoryImpl.kt
Constructor deps switched to TweaksRepository; use getIncludePreReleases() from tweaks when choosing releases.
Strings / Localization
core/presentation/src/commonMain/composeResources/values*/strings-*.xml
Added liquid_glass_option_title and liquid_glass_option_description to core presentation resources and localized variants.

Sequence Diagram

sequenceDiagram
    participant User
    participant ProfileUI as Profile UI
    participant ProfileVM as ProfileViewModel
    participant TweaksRepo as TweaksRepository
    participant DataStore as DataStore
    participant OtherVMs as Other ViewModels

    User->>ProfileUI: Toggle "Liquid Glass" setting
    ProfileUI->>ProfileVM: dispatch OnLiquidGlassEnabledChange(enabled)
    ProfileVM->>TweaksRepo: setLiquidGlassEnabled(enabled)
    TweaksRepo->>DataStore: persist LIQUID_GLASS_ENABLED_KEY
    DataStore-->>TweaksRepo: write ack

    Note right of TweaksRepo: TweaksRepo exposes Flow<Boolean>
    TweaksRepo-->>OtherVMs: emit new value via getLiquidGlassEnabled()
    OtherVMs->>OtherVMs: update _state.isLiquidGlassEnabled
    OtherVMs-->>UI: new states emitted
    UI->>UI: recomposition applies or removes Modifier.liquefiable()
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 A toggle I hoard in my burrow so deep,
Flip liquid glass on — watch the UI leap!
From repo to view the soft shimmer streams,
I nibble on bytes and dream glowing dreams. ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 1.28% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the two main changes: renaming the repository and implementing a liquid glass toggle feature.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch togglable-liquid

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.

…uages

- Add localized strings for "Liquid Glass" effect title and description.
- Provide translations for Bengali, Hindi, Italian, Spanish, Arabic, French, Polish, Russian, Japanese, Korean, Turkish, and Chinese (Simplified).
- Include descriptions for enhancing the interface with a smooth glass-like appearance.
Copy link
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 (4)
feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/Header.kt (2)

107-108: Redundant liquidState declaration.

liquidState is already declared at line 48 within the same LazyListScope.header function scope. The second declaration at line 108 shadows the first unnecessarily. While this doesn't cause a bug (both resolve to the same CompositionLocal value), it adds visual noise.

♻️ Remove redundant declaration
     item {
-        val liquidState = LocalTopbarLiquidState.current
-
         Box(
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/Header.kt`
around lines 107 - 108, Remove the redundant declaration of liquidState inside
the LazyListScope.header item: there is already a val liquidState =
LocalTopbarLiquidState.current earlier in the same function (around line 48), so
delete the second declaration at the item block to avoid shadowing; keep using
the existing liquidState reference throughout the item and ensure no other local
variable with the same name is introduced inside LazyListScope.header.

155-162: Consider extracting a conditional liquefiable modifier helper to reduce repetition.

The same Modifier.then(if (state.isLiquidGlassEnabled) Modifier.liquefiable(liquidState) else Modifier) pattern is repeated four times in this file. A small helper extension would improve readability.

♻️ Optional: Extract helper extension
`@Composable`
private fun Modifier.conditionalLiquefiable(
    enabled: Boolean,
    liquidState: LiquidState
): Modifier = if (enabled) this.liquefiable(liquidState) else this

Then use as:

modifier = Modifier.conditionalLiquefiable(state.isLiquidGlassEnabled, liquidState)

Also applies to: 192-199, 229-236

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/Header.kt`
around lines 155 - 162, Extract a small Modifier extension to encapsulate the
repeated pattern instead of repeating Modifier.then(if
(state.isLiquidGlassEnabled) Modifier.liquefiable(liquidState) else Modifier) in
Header.kt; add a private helper extension (e.g., conditionalLiquefiable) that
takes enabled: Boolean and liquidState: LiquidState and returns either
this.liquefiable(liquidState) when enabled or this otherwise, then replace the
four occurrences with
Modifier.conditionalLiquefiable(state.isLiquidGlassEnabled, liquidState) to
improve readability and remove duplication.
feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/Stats.kt (1)

37-73: Consider extracting the conditional liquefiable modifier pattern.

The same conditional modifier logic is repeated three times. This could be extracted to a small extension function for better maintainability:

private fun Modifier.conditionalLiquefiable(
    enabled: Boolean,
    liquidState: LiquidState
): Modifier = if (enabled) liquefiable(liquidState) else this

This pattern appears across multiple files in this PR, so a shared utility in the core presentation module would reduce duplication.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/Stats.kt`
around lines 37 - 73, Extract the repeated conditional Modifier logic into a
single extension function (e.g., Modifier.conditionalLiquefiable(enabled:
Boolean, liquidState: LiquidState)) that returns if (enabled)
this.liquefiable(liquidState) else this, add it to a shared presentation
utilities file, and replace the repeated .then(if (isLiquidGlassEnabled)
Modifier.liquefiable(liquidState) else Modifier) occurrences in StatItem usages
(and other files) with
.then(Modifier.conditionalLiquefiable(isLiquidGlassEnabled, liquidState)) to
remove duplication while keeping behavior identical.
feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/WhatsNew.kt (1)

83-90: Consider extracting the conditional liquefiable modifier into an extension function.

The same conditional pattern is repeated 4 times in this file (and likely elsewhere in the PR). An extension function would improve readability and reduce duplication.

♻️ Suggested extension function
// In a shared utility file
fun Modifier.liquefiableIf(
    enabled: Boolean,
    liquidState: LiquidState,
): Modifier = if (enabled) this.liquefiable(liquidState) else this

Then usage becomes:

-Modifier.then(
-    if (isLiquidGlassEnabled) {
-        Modifier.liquefiable(liquidState)
-    } else {
-        Modifier
-    },
-),
+Modifier.liquefiableIf(isLiquidGlassEnabled, liquidState),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/WhatsNew.kt`
around lines 83 - 90, Extract the repeated conditional Modifier.liquefiable(...)
pattern into an extension function (e.g., fun Modifier.liquefiableIf(enabled:
Boolean, liquidState: LiquidState): Modifier) and replace each occurrence that
checks isLiquidGlassEnabled and applies Modifier.liquefiable(liquidState) with a
call to .liquefiableIf(isLiquidGlassEnabled, liquidState); update references in
WhatsNew.kt where isLiquidGlassEnabled and liquidState are used to call the new
extension to remove duplication and improve readability.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@feature/home/presentation/src/commonMain/kotlin/zed/rainxch/home/presentation/HomeState.kt`:
- Line 22: The HomeState default for isLiquidGlassEnabled is currently false
causing a visual mismatch on first render; update the HomeState data class
(symbol: HomeState and property isLiquidGlassEnabled) to initialize
isLiquidGlassEnabled to true so it matches other screens' defaults and avoids
the brief UI inconsistency until the preferences flow updates state.

---

Nitpick comments:
In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/Header.kt`:
- Around line 107-108: Remove the redundant declaration of liquidState inside
the LazyListScope.header item: there is already a val liquidState =
LocalTopbarLiquidState.current earlier in the same function (around line 48), so
delete the second declaration at the item block to avoid shadowing; keep using
the existing liquidState reference throughout the item and ensure no other local
variable with the same name is introduced inside LazyListScope.header.
- Around line 155-162: Extract a small Modifier extension to encapsulate the
repeated pattern instead of repeating Modifier.then(if
(state.isLiquidGlassEnabled) Modifier.liquefiable(liquidState) else Modifier) in
Header.kt; add a private helper extension (e.g., conditionalLiquefiable) that
takes enabled: Boolean and liquidState: LiquidState and returns either
this.liquefiable(liquidState) when enabled or this otherwise, then replace the
four occurrences with
Modifier.conditionalLiquefiable(state.isLiquidGlassEnabled, liquidState) to
improve readability and remove duplication.

In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/Stats.kt`:
- Around line 37-73: Extract the repeated conditional Modifier logic into a
single extension function (e.g., Modifier.conditionalLiquefiable(enabled:
Boolean, liquidState: LiquidState)) that returns if (enabled)
this.liquefiable(liquidState) else this, add it to a shared presentation
utilities file, and replace the repeated .then(if (isLiquidGlassEnabled)
Modifier.liquefiable(liquidState) else Modifier) occurrences in StatItem usages
(and other files) with
.then(Modifier.conditionalLiquefiable(isLiquidGlassEnabled, liquidState)) to
remove duplication while keeping behavior identical.

In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/WhatsNew.kt`:
- Around line 83-90: Extract the repeated conditional Modifier.liquefiable(...)
pattern into an extension function (e.g., fun Modifier.liquefiableIf(enabled:
Boolean, liquidState: LiquidState): Modifier) and replace each occurrence that
checks isLiquidGlassEnabled and applies Modifier.liquefiable(liquidState) with a
call to .liquefiableIf(isLiquidGlassEnabled, liquidState); update references in
WhatsNew.kt where isLiquidGlassEnabled and liquidState are used to call the new
extension to remove duplication and improve readability.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bf82d675-1574-4a6c-9672-38d656564322

📥 Commits

Reviewing files that changed from the base of the PR and between 402f3cf and 0a0c289.

📒 Files selected for processing (44)
  • composeApp/src/androidMain/kotlin/zed/rainxch/githubstore/app/GithubStoreApp.kt
  • composeApp/src/commonMain/kotlin/zed/rainxch/githubstore/Main.kt
  • composeApp/src/commonMain/kotlin/zed/rainxch/githubstore/MainState.kt
  • composeApp/src/commonMain/kotlin/zed/rainxch/githubstore/MainViewModel.kt
  • composeApp/src/commonMain/kotlin/zed/rainxch/githubstore/app/di/SharedModules.kt
  • composeApp/src/commonMain/kotlin/zed/rainxch/githubstore/app/navigation/AppNavigation.kt
  • composeApp/src/commonMain/kotlin/zed/rainxch/githubstore/app/navigation/BottomNavigation.kt
  • core/data/src/androidMain/kotlin/zed/rainxch/core/data/di/PlatformModule.android.kt
  • core/data/src/androidMain/kotlin/zed/rainxch/core/data/services/AutoUpdateWorker.kt
  • core/data/src/androidMain/kotlin/zed/rainxch/core/data/services/UpdateCheckWorker.kt
  • core/data/src/androidMain/kotlin/zed/rainxch/core/data/services/shizuku/ShizukuInstallerWrapper.kt
  • core/data/src/commonMain/kotlin/zed/rainxch/core/data/di/SharedModule.kt
  • core/data/src/commonMain/kotlin/zed/rainxch/core/data/repository/InstalledAppsRepositoryImpl.kt
  • core/data/src/commonMain/kotlin/zed/rainxch/core/data/repository/TweaksRepositoryImpl.kt
  • core/domain/src/commonMain/kotlin/zed/rainxch/core/domain/repository/TweaksRepository.kt
  • core/presentation/src/commonMain/composeResources/values/strings.xml
  • feature/apps/data/src/commonMain/kotlin/zed/rainxch/apps/data/di/SharedModule.kt
  • feature/apps/data/src/commonMain/kotlin/zed/rainxch/apps/data/repository/AppsRepositoryImpl.kt
  • feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/AppsRoot.kt
  • feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/AppsState.kt
  • feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/AppsViewModel.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsRoot.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsState.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/SmartInstallButton.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/About.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/Header.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/Logs.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/Owner.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/Stats.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/components/sections/WhatsNew.kt
  • feature/home/presentation/src/commonMain/kotlin/zed/rainxch/home/presentation/HomeRoot.kt
  • feature/home/presentation/src/commonMain/kotlin/zed/rainxch/home/presentation/HomeState.kt
  • feature/home/presentation/src/commonMain/kotlin/zed/rainxch/home/presentation/HomeViewModel.kt
  • feature/home/presentation/src/commonMain/kotlin/zed/rainxch/home/presentation/components/HomeFilterChips.kt
  • feature/profile/presentation/src/commonMain/kotlin/zed/rainxch/profile/presentation/ProfileAction.kt
  • feature/profile/presentation/src/commonMain/kotlin/zed/rainxch/profile/presentation/ProfileRoot.kt
  • feature/profile/presentation/src/commonMain/kotlin/zed/rainxch/profile/presentation/ProfileState.kt
  • feature/profile/presentation/src/commonMain/kotlin/zed/rainxch/profile/presentation/ProfileViewModel.kt
  • feature/profile/presentation/src/commonMain/kotlin/zed/rainxch/profile/presentation/components/sections/Appearance.kt
  • feature/profile/presentation/src/commonMain/kotlin/zed/rainxch/profile/presentation/components/sections/SettingsSection.kt
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/SearchRoot.kt
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/SearchState.kt
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/SearchViewModel.kt

- Update the default value of `isLiquidGlassEnabled` to `true` in `HomeState`.
@rainxchzed rainxchzed merged commit 533ce50 into main Mar 20, 2026
@rainxchzed rainxchzed deleted the togglable-liquid branch March 20, 2026 18:38
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.

1 participant