Conversation
This commit updates the Android application icons across various densities and introduces a dedicated monochrome resource for adaptive icons to improve compatibility with themed icons. - **chore(android)**: Updated `ic_launcher` and `ic_launcher_round` webp assets for hdpi, mdpi, xhdpi, xxhdpi, and xxxhdpi densities. - **chore(android)**: Updated `ic_launcher-playstore.png` asset. - **chore(android)**: Modified `ic_launcher.xml` and `ic_launcher_round.xml` to use `@drawable/ic_launcher_monochrome` for the monochrome layer.
…ages This commit introduces a sharing feature to the repository details screen, allowing users to share app links. It also cleans up the codebase by removing the experimental `trackExistingApp` logic and reorganizing desktop utility classes. - **feat(details)**: Added `OnShareClick` action and integrated `ShareManager` to generate and share repository links. - **feat(core)**: Introduced `ShareManager` interface in the domain layer with platform-specific implementations: `AndroidShareManager` (using `Intent.ACTION_SEND`) and `DesktopShareManager` (copying to clipboard). - **refactor(details)**: Removed the unused and complex `trackExistingApp` method and `TrackExistingApp` action from `DetailsViewModel`. - **refactor(core)**: Moved desktop utility classes (`DesktopAppLauncher`, `DesktopBrowserHelper`, `DesktopClipboardHelper`) from `services` to the `utils` package for consistency across platforms. - **ui(details)**: Added a share icon button to the top app bar in `DetailsRoot`. - **chore**: Updated DI modules for Android and JVM to include the new `ShareManager` and reflect package moves.
|
Caution Review failedThe pull request is closed. ℹ️ Recent review infoConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (12)
WalkthroughAdds a cross-platform sharing feature: new common ShareManager interface, Android and JVM implementations, DI bindings, UI action wiring and ViewModel handling for sharing, many localized strings, and a reusable ExpressiveCard component; also adjusts launcher monochrome drawable references. Changes
Sequence DiagramsequenceDiagram
actor User
participant UI as DetailsRoot / RepoCard (UI)
participant VM as ViewModel (Details/Home/Search)
participant SM as ShareManager (interface)
participant P as PlatformImpl (Android / Desktop)
User->>UI: Click Share button
UI->>VM: Dispatch OnShareClick(repo)
VM->>VM: Build repo URL
VM->>SM: shareText(repo URL)
SM->>P: platform-specific shareText()
alt Android
P->>P: Create ACTION_SEND intent
P->>P: Start chooser activity (FLAG_ACTIVITY_NEW_TASK)
P-->>User: Share dialog shown
else Desktop
P->>P: Copy text to system clipboard
P-->>User: Clipboard updated
end
P-->>VM: success / exception
alt exception
VM-->>UI: Emit failure message (failed_to_share_link)
else not Android (success)
VM-->>UI: Emit info message (link_copied_to_clipboard)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
core/data/src/jvmMain/kotlin/zed/rainxch/core/data/utils/DesktopShareManager.kt (1)
7-12: Prefer reusingClipboardHelperto avoid duplicated clipboard integration.
DesktopShareManagercurrently re-implements clipboard logic that already exists inDesktopClipboardHelper. Delegate toClipboardHelperto keep one platform clipboard path.♻️ Suggested refactor
import zed.rainxch.core.domain.utils.ShareManager -import java.awt.Toolkit -import java.awt.datatransfer.StringSelection +import zed.rainxch.core.domain.utils.ClipboardHelper -class DesktopShareManager : ShareManager { +class DesktopShareManager( + private val clipboardHelper: ClipboardHelper +) : ShareManager { override fun shareText(text: String) { - val clipboard = Toolkit.getDefaultToolkit().systemClipboard - val selection = StringSelection(text) - clipboard.setContents(selection, null) + clipboardHelper.copy(label = "share", text = text) } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@core/data/src/jvmMain/kotlin/zed/rainxch/core/data/utils/DesktopShareManager.kt` around lines 7 - 12, DesktopShareManager.shareText currently re-implements clipboard logic using Toolkit; replace that logic by delegating to the existing DesktopClipboardHelper (or the platform ClipboardHelper API) instead of manually using Toolkit/StringSelection—update DesktopShareManager.shareText to call the DesktopClipboardHelper clipboard method (e.g., its public set/copy method) and remove the direct Toolkit/StringSelection usage so there is a single shared clipboard integration point.
🤖 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/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsRoot.kt`:
- Around line 371-374: The Icon currently sets contentDescription = null which
makes the Share action inaccessible; update the Icon at Icons.Default.Share
inside DetailsRoot (the Share action) to provide a meaningful, localized
contentDescription (e.g., use stringResource(R.string.share) or a passed-in
descriptive label) so assistive tech can announce it; ensure you import and use
androidx.compose.ui.res.stringResource (or accept a label parameter) and replace
contentDescription = null with that localized string.
In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt`:
- Around line 457-458: Replace the hardcoded message "Link copied to clipboard"
in the Platform != Platform.ANDROID branch with a localized string obtained from
the app's i18n/string provider (e.g., call the project's
StringProvider/Resources method to fetch the "link_copied" key) and pass that
localized value to _events.send(DetailsEvent.OnMessage(...)) inside
DetailsViewModel so the displayed text is localized.
- Around line 452-456: In the DetailsAction.OnShareClick handler, the call to
shareManager.shareText(...) can throw and is currently unguarded; wrap the
shareManager.shareText call inside a try/catch within the existing
viewModelScope.launch in DetailsViewModel so exceptions are caught, then handle
failures by logging the error and updating the view model (e.g., set an error
state on _state or emit a one-time UiEvent) so the UI can show a failure
message; reference DetailsAction.OnShareClick, viewModelScope.launch,
shareManager.shareText, and _state when making the change.
---
Nitpick comments:
In
`@core/data/src/jvmMain/kotlin/zed/rainxch/core/data/utils/DesktopShareManager.kt`:
- Around line 7-12: DesktopShareManager.shareText currently re-implements
clipboard logic using Toolkit; replace that logic by delegating to the existing
DesktopClipboardHelper (or the platform ClipboardHelper API) instead of manually
using Toolkit/StringSelection—update DesktopShareManager.shareText to call the
DesktopClipboardHelper clipboard method (e.g., its public set/copy method) and
remove the direct Toolkit/StringSelection usage so there is a single shared
clipboard integration point.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
composeApp/src/androidMain/ic_launcher-playstore.pngis excluded by!**/*.png
📒 Files selected for processing (23)
composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xmlcomposeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xmlcomposeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.webpcomposeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.webpcomposeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.webpcomposeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.webpcomposeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.webpcomposeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.webpcomposeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.webpcomposeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.webpcomposeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.webpcomposeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.webpcore/data/src/androidMain/kotlin/zed/rainxch/core/data/di/PlatformModule.android.ktcore/data/src/androidMain/kotlin/zed/rainxch/core/data/utils/AndroidShareManager.ktcore/data/src/jvmMain/kotlin/zed/rainxch/core/data/di/PlatformModule.jvm.ktcore/data/src/jvmMain/kotlin/zed/rainxch/core/data/utils/DesktopAppLauncher.ktcore/data/src/jvmMain/kotlin/zed/rainxch/core/data/utils/DesktopBrowserHelper.ktcore/data/src/jvmMain/kotlin/zed/rainxch/core/data/utils/DesktopClipboardHelper.ktcore/data/src/jvmMain/kotlin/zed/rainxch/core/data/utils/DesktopShareManager.ktcore/domain/src/commonMain/kotlin/zed/rainxch/core/domain/utils/ShareManager.ktfeature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsAction.ktfeature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsRoot.ktfeature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt
...e/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsRoot.kt
Show resolved
Hide resolved
...ails/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt
Show resolved
Hide resolved
...ails/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt
Outdated
Show resolved
Hide resolved
…onents This commit moves the `ExpressiveCard` component from the `dev-profile` feature to the `core` presentation module to allow for consistent styling and reuse across different features. It also updates the component to support optional click handling. - **refactor(core)**: Relocated `ExpressiveCard` to `zed.rainxch.core.presentation.components` and added an `onClick` parameter. - **refactor(apps)**: Removed local `ExpressiveCard` implementation in `AppsRoot.kt` in favor of the core component. - **refactor(profile)**: Removed local `ExpressiveCard` implementation in `Appearance.kt` and updated imports. - **refactor(dev-profile)**: Deleted redundant `ExpressiveCard.kt` and updated `StatsRow.kt`, `DeveloperRepoItem.kt`, and `ProfileInfoCard.kt` to use the core component. - **refactor(core)**: Updated `RepositoryCard` to use `ExpressiveCard` instead of a standard `Card`, ensuring UI consistency.
This commit enhances the repository sharing logic by adding error handling, localizing UI strings, and improving accessibility. - **fix(details)**: Added error handling to the share action in `DetailsViewModel` with logging and user feedback on failure. - **refactor(details)**: Localized "Link copied to clipboard" and share failure messages using string resources. - **ui(details)**: Added a content description to the share icon in `DetailsRoot` for better accessibility.
This commit adds new string resources to support repository sharing functionality across multiple languages. The new strings include "Share repository", "Failed to share link", and "Link copied to clipboard". - **i18n**: Added sharing-related strings to `strings.xml` (default) and localized versions for Turkish, Spanish, Chinese (Simplified), French, Hindi, Italian, Japanese, Korean, Polish, Bengali, and Russian.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/AppsRoot.kt (1)
378-383:⚠️ Potential issue | 🟠 MajorAvoid no-op clickable semantics on the card surface.
At Line 378,
ExpressiveCardis used withoutonClick. If the shared implementation always uses clickableElevatedCard(onClick = ...), this creates a clickable card with a no-op action. Prefer wiringonClick = onRepoClickand removing the innerModifier.clickableto keep semantics correct.💡 Suggested local fix
- ExpressiveCard(modifier = modifier) { + ExpressiveCard( + modifier = modifier, + onClick = onRepoClick + ) { Column( modifier = Modifier .clip(RoundedCornerShape(32.dp)) - .clickable { onRepoClick() } .padding(16.dp) ) {#!/bin/bash set -euo pipefail # Verify shared ExpressiveCard behavior and impacted call sites. # Expected: # 1) If ExpressiveCard always calls clickable ElevatedCard(onClick = ...), calls without onClick are problematic. # 2) List all Kotlin call sites where ExpressiveCard omits onClick. echo "== ExpressiveCard implementation ==" fd 'ExpressiveCard.kt' -t f | while read -r f; do echo "-- $f --" sed -n '1,140p' "$f" done echo echo "== ExpressiveCard call sites without explicit onClick argument ==" python - <<'PY' import pathlib, re for p in pathlib.Path('.').rglob('*.kt'): text = p.read_text(encoding='utf-8', errors='ignore') for m in re.finditer(r'ExpressiveCard\s*\((.*?)\)\s*\{', text, re.S): args = m.group(1) if 'onClick' not in args: line = text.count('\n', 0, m.start()) + 1 print(f"{p}:{line}") PY🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/AppsRoot.kt` around lines 378 - 383, ExpressiveCard is creating a clickable surface with a no-op because the shared implementation uses ElevatedCard(onClick=...) while this call passes no onClick and instead uses Modifier.clickable; change the call to pass the click handler into ExpressiveCard (use ExpressiveCard(onClick = onRepoClick, modifier = modifier) { ... }) and remove the inner Modifier.clickable to avoid redundant/no-op semantics; update the block referencing onRepoClick and remove Modifier.clickable to rely on the card's onClick behavior (verify ElevatedCard/ExpressiveCard signature supports onClick).
🧹 Nitpick comments (1)
core/presentation/src/commonMain/composeResources/values-tr/strings-tr.xml (1)
424-427: Minor terminology inconsistency: "Depo" vs "Repo"The new string uses "Depoyu" (Turkish word) while existing strings like
open_repositoryat line 142 use "Repoyu" (borrowed English term). For consistency, consider aligning with the existing convention:- <string name="share_repository">Depoyu paylaş</string> + <string name="share_repository">Repoyu paylaş</string>The other two translations look good.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@core/presentation/src/commonMain/composeResources/values-tr/strings-tr.xml` around lines 424 - 427, The string "share_repository" uses "Depoyu" which is inconsistent with other strings like "open_repository" that use the borrowed term "Repoyu"; update the value of share_repository from "Depoyu paylaş" to "Repoyu paylaş" (and similarly check any neighboring strings such as failed_to_share_link and link_copied_to_clipboard for consistent use of "Repo/Repoyu" if needed) so all repository-related strings use the same terminology.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@core/presentation/src/commonMain/kotlin/zed/rainxch/core/presentation/components/ExpressiveCard.kt`:
- Around line 23-25: ExpressiveCard currently always uses the clickable
ElevatedCard overload by passing onClick, causing ripple feedback when onClick
is null; update the composable to branch on the onClick parameter and call the
non-clickable ElevatedCard overload when onClick == null, and the clickable
ElevatedCard overload when onClick != null (refer to ExpressiveCard and its
onClick param), preserving all other modifiers, colors, elevation, and content
parameters so only the overload choice changes.
---
Outside diff comments:
In
`@feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/AppsRoot.kt`:
- Around line 378-383: ExpressiveCard is creating a clickable surface with a
no-op because the shared implementation uses ElevatedCard(onClick=...) while
this call passes no onClick and instead uses Modifier.clickable; change the call
to pass the click handler into ExpressiveCard (use ExpressiveCard(onClick =
onRepoClick, modifier = modifier) { ... }) and remove the inner
Modifier.clickable to avoid redundant/no-op semantics; update the block
referencing onRepoClick and remove Modifier.clickable to rely on the card's
onClick behavior (verify ElevatedCard/ExpressiveCard signature supports
onClick).
---
Nitpick comments:
In `@core/presentation/src/commonMain/composeResources/values-tr/strings-tr.xml`:
- Around line 424-427: The string "share_repository" uses "Depoyu" which is
inconsistent with other strings like "open_repository" that use the borrowed
term "Repoyu"; update the value of share_repository from "Depoyu paylaş" to
"Repoyu paylaş" (and similarly check any neighboring strings such as
failed_to_share_link and link_copied_to_clipboard for consistent use of
"Repo/Repoyu" if needed) so all repository-related strings use the same
terminology.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (21)
core/presentation/src/commonMain/composeResources/values-bn/strings-bn.xmlcore/presentation/src/commonMain/composeResources/values-es/strings-es.xmlcore/presentation/src/commonMain/composeResources/values-fr/strings-fr.xmlcore/presentation/src/commonMain/composeResources/values-hi/strings-hi.xmlcore/presentation/src/commonMain/composeResources/values-it/strings-it.xmlcore/presentation/src/commonMain/composeResources/values-ja/strings-ja.xmlcore/presentation/src/commonMain/composeResources/values-kr/strings-kr.xmlcore/presentation/src/commonMain/composeResources/values-pl/strings-pl.xmlcore/presentation/src/commonMain/composeResources/values-ru/strings-ru.xmlcore/presentation/src/commonMain/composeResources/values-tr/strings-tr.xmlcore/presentation/src/commonMain/composeResources/values-zh-rCN/strings-zh-rCN.xmlcore/presentation/src/commonMain/composeResources/values/strings.xmlcore/presentation/src/commonMain/kotlin/zed/rainxch/core/presentation/components/ExpressiveCard.ktcore/presentation/src/commonMain/kotlin/zed/rainxch/core/presentation/components/RepositoryCard.ktfeature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/AppsRoot.ktfeature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsRoot.ktfeature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.ktfeature/dev-profile/presentation/src/commonMain/kotlin/zed/rainxch/devprofile/presentation/components/DeveloperRepoItem.ktfeature/dev-profile/presentation/src/commonMain/kotlin/zed/rainxch/devprofile/presentation/components/ProfileInfoCard.ktfeature/dev-profile/presentation/src/commonMain/kotlin/zed/rainxch/devprofile/presentation/components/StatsRow.ktfeature/profile/presentation/src/commonMain/kotlin/zed/rainxch/profile/presentation/components/sections/Appearance.kt
✅ Files skipped from review due to trivial changes (1)
- core/presentation/src/commonMain/composeResources/values/strings.xml
🚧 Files skipped from review as they are similar to previous changes (1)
- feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsRoot.kt
...resentation/src/commonMain/kotlin/zed/rainxch/core/presentation/components/ExpressiveCard.kt
Outdated
Show resolved
Hide resolved
This commit introduces a sharing feature to repository cards, allowing users to share repository links directly from the home and search screens. It also integrates snackbar notifications to provide feedback on sharing actions. - **feat(ui)**: Added a share button to `RepositoryCard` with a new `onShareClick` callback. - **feat(home)**: Integrated `ShareManager` into `HomeViewModel` and added `OnShareClick` action to handle repository link generation and sharing. - **feat(search)**: Integrated `ShareManager` into `SearchViewModel` and added `OnShareClick` action to handle repository link generation and sharing. - **feat(presentation)**: Added `SnackbarHost` to `HomeScreen` and `SearchScreen` to display success/error messages during sharing. - **feat(presentation)**: Introduced `SearchEvent` and updated `HomeEvent` to include `OnMessage` for triggering snackbar notifications from ViewModels. - **refactor(ui)**: Adjusted `SnackbarHost` positioning in `Scaffold` to account for bottom navigation height. - **fix(presentation)**: Improved sharing logic to provide a "link copied" message on non-Android platforms when a link is shared.
This commit refactors the click handling logic for repository items by moving the `clickable` interaction from the inner content containers to the `ExpressiveCard` component itself. This ensures a more consistent ripple effect and simplifies the internal layout structure. - **refactor(core)**: Updated `ExpressiveCard` to conditionally support an `onClick` parameter, leveraging `ElevatedCard` overloads for better accessibility and interaction handling. - **refactor(apps)**: Moved repo click logic from the inner `Column` to the `ExpressiveCard` in `AppsRoot.kt`. - **refactor(dev-profile)**: Moved repo click logic from the inner `Column` to the `ExpressiveCard` in `DeveloperRepoItem.kt`.
Summary by CodeRabbit
New Features
Removed Features
Localization
Chores / Style