Skip to content

implement UI models and immutable collections#335

Merged
rainxchzed merged 7 commits intomainfrom
stabiliity-impr
Mar 18, 2026
Merged

implement UI models and immutable collections#335
rainxchzed merged 7 commits intomainfrom
stabiliity-impr

Conversation

@rainxchzed
Copy link
Member

@rainxchzed rainxchzed commented Mar 18, 2026

Summary by CodeRabbit

  • New Features

    • Added APK package validation during app updates to prevent installation of incompatible packages.
  • Bug Fixes

    • Improved update failure handling with enhanced error detection and user-facing messages.
  • Localization

    • Added multilingual error messages for update failures and package validation mismatches across 13 languages.
  • Refactor

    • Optimized navigation by using repository IDs instead of full objects.
    • Improved internal data handling with immutable collection support.

…anguages

- Add `update_failed` string resource to the default `strings.xml`.
- Provide localized translations for Arabic, Bengali, Chinese (Simplified), French, Hindi, Italian, Japanese, Korean, Polish, Russian, Spanish, and Turkish.
- Implement `Ui` model counterparts for `InstalledApp`, `DeviceApp`, `GithubAsset`, `GithubUser`, and `GithubRepoInfo` to decouple the presentation layer from the domain layer.
- Add mapper functions (`toUi`, `toDomain`) for all new UI models.
- Update `AppsState`, `AppsAction`, and `AppsViewModel` to use the new UI models instead of domain models.
- Integrate `kotlinx.collections.immutable` (e.g., `ImmutableList`, `persistentListOf`) across the presentation layer to improve performance and ensure state stability.
- Refactor `UpdateState` from a sealed interface to a sealed class.
- Clean up `AppsRoot` by removing unused imports and streamlining event handling for app linking and importing.
- Improve `AppsViewModel` logic for filtering and sorting apps, ensuring the results are returned as immutable lists.
- Create `GithubDeviceStartUi` and a corresponding mapper to decouple domain models from the presentation layer.
- Update `AuthenticationViewModel`, `AuthenticationAction`, and `AuthLoginState` to use `GithubDeviceStartUi` instead of the domain `GithubDeviceStart`.
- Refactor `AuthLoginState` from a sealed interface to a sealed class.
- Clean up resource imports in `AuthenticationRoot` and update the preview data to use the new UI model.
- Replace the standard Material3 `Button` with the custom `GithubStoreButton` component.
- Update imports to include `GithubStoreButton` and remove the unused `androidx.compose.material3.Button` import.
…d home features

- Introduce `GithubRepoSummaryUi`, `GithubUserUi`, and `DiscoveryRepositoryUi` to separate domain models from the presentation layer.
- Refactor `SearchState` and `HomeState` to use `ImmutableList` and `persistentListOf` for better performance and stability.
- Add UI-specific enums (`ProgrammingLanguageUi`, `SearchPlatformUi`, `SortByUi`, `SortOrderUi`) and corresponding mappers to handle UI-to-domain transformations.
- Update `RepositoryCard` and other UI components to consume the new UI models.
- Refactor navigation to pass repository IDs instead of full summary objects.
- Move `ParsedGithubLink` and `GithubUrlParser` into the search presentation model package.
- Add `kotlinx.collections.immutable` dependency to core and search presentation modules.
- Update `HomeState` to use `ImmutableList` instead of `List` for `repos` and `installedApps` to improve stability and performance in Compose.
- Refactor `HomeViewModel` to use `persistentListOf()` for initial states and `toImmutableList()` when updating repository lists.
- Ensure all repository list transformations (filtering, mapping, and pagination) return immutable collections.
- Add validation logic to `DetailsViewModel` to ensure the downloaded APK package name matches the installed application before proceeding with an update.
- Enhance `AutoUpdateWorker` to perform package name verification, throwing an exception and skipping the update if a mismatch is detected.
- Introduce new localized string resources for "Package mismatch" and "Signing key mismatch" errors across multiple languages (Arabic, Bengali, Chinese, English, French, Hindi, Italian, Japanese, Korean, Polish, Russian, Spanish, Turkish).
- Update error handling UI to display specific mismatch messages and block invalid updates.
@rainxchzed rainxchzed merged commit 42f8b5a into main Mar 18, 2026
1 check was pending
@rainxchzed rainxchzed deleted the stabiliity-impr branch March 18, 2026 07:00
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 18, 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: 1ff2d343-68a9-4b24-ad97-71a941422f20

📥 Commits

Reviewing files that changed from the base of the PR and between 0ffe3fb and 6bef2aa.

📒 Files selected for processing (73)
  • composeApp/build.gradle.kts
  • composeApp/src/commonMain/kotlin/zed/rainxch/githubstore/app/navigation/AppNavigation.kt
  • core/data/src/androidMain/kotlin/zed/rainxch/core/data/services/AutoUpdateWorker.kt
  • core/presentation/build.gradle.kts
  • 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
  • core/presentation/src/commonMain/composeResources/values/strings.xml
  • core/presentation/src/commonMain/kotlin/zed/rainxch/core/presentation/components/RepositoryCard.kt
  • core/presentation/src/commonMain/kotlin/zed/rainxch/core/presentation/model/DiscoveryRepositoryUi.kt
  • core/presentation/src/commonMain/kotlin/zed/rainxch/core/presentation/model/GithubRepoSummaryUi.kt
  • core/presentation/src/commonMain/kotlin/zed/rainxch/core/presentation/model/GithubUserUi.kt
  • core/presentation/src/commonMain/kotlin/zed/rainxch/core/presentation/utils/GithubRepoSummaryMappers.kt
  • core/presentation/src/commonMain/kotlin/zed/rainxch/core/presentation/utils/GithubUserMappers.kt
  • feature/apps/presentation/build.gradle.kts
  • feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/AppsAction.kt
  • feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/AppsEvent.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/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/components/LinkAppBottomSheet.kt
  • feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/mappers/DeviceAppMapper.kt
  • feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/mappers/GithubAssetMapper.kt
  • feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/mappers/GithubRepoInfoMapper.kt
  • feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/mappers/InstalledAppMapper.kt
  • feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/model/AppItem.kt
  • feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/model/DeviceAppUi.kt
  • feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/model/GithubAssetUi.kt
  • feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/model/GithubRepoInfoUi.kt
  • feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/model/GithubUserUi.kt
  • feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/model/InstalledAppUi.kt
  • feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/model/UpdateState.kt
  • feature/auth/presentation/src/commonMain/kotlin/zed/rainxch/auth/presentation/AuthenticationAction.kt
  • feature/auth/presentation/src/commonMain/kotlin/zed/rainxch/auth/presentation/AuthenticationRoot.kt
  • feature/auth/presentation/src/commonMain/kotlin/zed/rainxch/auth/presentation/AuthenticationViewModel.kt
  • feature/auth/presentation/src/commonMain/kotlin/zed/rainxch/auth/presentation/mapper/GithubDeviceStartMapper.kt
  • feature/auth/presentation/src/commonMain/kotlin/zed/rainxch/auth/presentation/model/AuthLoginState.kt
  • feature/auth/presentation/src/commonMain/kotlin/zed/rainxch/auth/presentation/model/GithubDeviceStartUi.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt
  • feature/home/presentation/src/commonMain/kotlin/zed/rainxch/home/presentation/HomeAction.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/search/presentation/build.gradle.kts
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/SearchAction.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
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/components/LanguageFilterBottomSheet.kt
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/components/SortByBottomSheet.kt
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/mappers/PlatformLanguageMappers.kt
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/mappers/SearchPlatformMappers.kt
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/mappers/SortByMappers.kt
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/mappers/SortOrderMapper.kt
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/model/ParsedGithubLink.kt
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/model/ProgrammingLanguageUi.kt
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/model/SearchPlatformUi.kt
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/model/SortByUi.kt
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/model/SortOrderUi.kt
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/utils/GithubUrlParser.kt
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/utils/ProgrammingLanguageMapper.kt
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/utils/SortByMapper.kt
  • feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/utils/SortOrderMapper.kt
  • feature/starred/presentation/src/commonMain/kotlin/zed/rainxch/starred/presentation/StarredReposRoot.kt

Walkthrough

This PR introduces a presentation layer abstraction by creating UI model variants of domain models and migrating state management to use immutable collections. Additionally, it adds APK package-name validation, converts sealed interfaces to sealed classes, updates navigation to pass repository IDs, and adds localized error messages across 15 languages.

Changes

Cohort / File(s) Summary
Dependency Updates
composeApp/build.gradle.kts, core/presentation/build.gradle.kts, feature/apps/presentation/build.gradle.kts, feature/search/presentation/build.gradle.kts
Added kotlinx.collections.immutable dependency to support immutable list usage; removed empty source set blocks.
UI Model Definitions (Core)
core/presentation/src/commonMain/kotlin/zed/rainxch/core/presentation/model/{DiscoveryRepositoryUi, GithubRepoSummaryUi, GithubUserUi}.kt
Introduced new UI-facing data classes replacing domain models for discovery and repository summaries.
UI Model Mappers (Core)
core/presentation/src/commonMain/kotlin/zed/rainxch/core/presentation/utils/{GithubRepoSummaryMappers, GithubUserMappers}.kt
Added extension functions to convert domain models to UI model variants.
UI Model Definitions (Apps)
feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/model/{InstalledAppUi, DeviceAppUi, GithubAssetUi, GithubRepoInfoUi, GithubUserUi}.kt
Introduced new UI model classes for installed/device apps, assets, and repository info.
UI Model Mappers (Apps)
feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/mappers/{InstalledAppMapper, DeviceAppMapper, GithubAssetMapper, GithubRepoInfoMapper}.kt
Added bidirectional mapping functions between domain and UI models.
State & ViewModel Updates (Apps)
feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/{AppsState, AppsViewModel, AppsAction}.kt
Migrated state to use ImmutableList and UI model types; updated action payloads accordingly.
UI Model Definitions (Auth)
feature/auth/presentation/src/commonMain/kotlin/zed/rainxch/auth/presentation/model/{GithubDeviceStartUi}.kt
Introduced new UI model for device-based OAuth flow.
UI Model Mappers (Auth)
feature/auth/presentation/src/commonMain/kotlin/zed/rainxch/auth/presentation/mapper/GithubDeviceStartMapper.kt
Added mapping from domain to UI model for device authentication.
Sealed Type Conversions (Auth)
feature/auth/presentation/src/commonMain/kotlin/zed/rainxch/auth/presentation/model/AuthLoginState.kt
Converted sealed interface to sealed class; renamed DevicePrompt.start to use GithubDeviceStartUi.
State & ViewModel Updates (Auth)
feature/auth/presentation/src/commonMain/kotlin/zed/rainxch/auth/presentation/{AuthenticationRoot, AuthenticationViewModel, AuthenticationAction}.kt
Updated to use GithubDeviceStartUi; refactored ViewModel with UI model conversions.
UI Model Definitions (Search)
feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/model/{ProgrammingLanguageUi, SearchPlatformUi, SortByUi, SortOrderUi, ParsedGithubLink}.kt
Introduced UI enum variants and link parsing model.
UI Model Mappers (Search)
feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/mappers/{PlatformLanguageMappers, SearchPlatformMappers, SortByMappers, SortOrderMapper}.kt
Added conversion functions between domain and UI enum models.
State & ViewModel Updates (Search)
feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/{SearchState, SearchViewModel, SearchAction}.kt
Migrated to immutable lists and UI model types; updated action payloads and component parameters.
Component & Utility Updates (Search)
feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/components/{LanguageFilterBottomSheet, SortByBottomSheet}.kt, feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/utils/{ProgrammingLanguageMapper, SortByMapper, SortOrderMapper, GithubUrlParser}.kt
Updated to use UI model types; converted URL parser return type to immutable list.
Navigation & Component Updates
composeApp/src/commonMain/kotlin/zed/rainxch/githubstore/app/navigation/AppNavigation.kt, core/presentation/src/commonMain/kotlin/zed/rainxch/core/presentation/components/RepositoryCard.kt, feature/home/presentation/src/commonMain/kotlin/zed/rainxch/home/presentation/{HomeRoot, HomeState, HomeViewModel, HomeAction}.kt
Changed navigation to accept repoId: Long; updated RepositoryCard parameter names; migrated state to immutable lists and UI models.
Sealed Type Conversion (Apps)
feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/model/UpdateState.kt
Converted sealed interface to sealed class with constructor calls.
APK Validation
core/data/src/androidMain/kotlin/zed/rainxch/core/data/services/AutoUpdateWorker.kt, feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt
Added package-name mismatch validation before APK processing; logs error and blocks update on mismatch.
Localized Error Messages
core/presentation/src/commonMain/composeResources/values{,\-ar,\-bn,\-es,\-fr,\-hi,\-it,\-ja,\-ko,\-pl,\-ru,\-tr,\-zh\-rCN}/strings*.xml
Added three new localized strings (update_failed, update_package_mismatch, update_signing_key_mismatch) across 15 language variants.
UI Root & Event Updates
feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/{AppsRoot, AppsEvent}.kt
Refactored event handling; removed ExportReady event; updated resource imports and Snackbar logic.
Misc Component Updates
feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/components/LinkAppBottomSheet.kt, feature/starred/presentation/src/commonMain/kotlin/zed/rainxch/starred/presentation/StarredReposRoot.kt
Updated to use UI model types; replaced standard Button with GithubStoreButton.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Poem

🐰 With models dressed in UI attire,
And lists made immutable, ever higher,
Domain and view now dance apart—
Each layer plays its proper part!
Mappings flow like streams so clean,
A cleaner arch than e'er been seen. ✨

✨ 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 stabiliity-impr
📝 Coding Plan
  • Generate coding plan for human review comments

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

Tip

CodeRabbit can suggest fixes for GitHub Check annotations.

Configure the reviews.tools.github-checks setting to adjust the time to wait for GitHub Checks to complete.

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