feat: skip-this-version per app (#542)#559
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (17)
✅ Files skipped from review due to trivial changes (8)
🚧 Files skipped from review as they are similar to previous changes (9)
WalkthroughThis PR implements a per-app “skip this version” feature: DB migration (15→16) adds ChangesSkip Release Version Feature
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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: 6
🧹 Nitpick comments (1)
feature/tweaks/presentation/src/commonMain/kotlin/zed/rainxch/tweaks/presentation/skipped/SkippedUpdatesEvent.kt (1)
5-5: ⚡ Quick winPrefer typed/localized failure events over raw
Stringmessages.
Failure(val message: String)can leak non-localized or backend/exception text directly into snackbar UI. Consider using a UI-text wrapper or resource-backed error key at this boundary.As per coding guidelines, "Localize all user-facing strings using the 13-language localization system provided by
core/presentation".🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@feature/tweaks/presentation/src/commonMain/kotlin/zed/rainxch/tweaks/presentation/skipped/SkippedUpdatesEvent.kt` at line 5, The Failure event on SkippedUpdatesEvent currently exposes raw String text via Failure(val message: String); change it to carry a localization-safe type (e.g., Failure(val message: UiText) or a ResourceKey/LocalizedString sealed value) and update all places that construct Failure to convert backend/exception text into localized UI messages (map exceptions to resource keys or create user-facing messages via core/presentation localization helpers). Ensure consumers (snackbar renderer) read the new localized type instead of treating it as a raw String and add any small adapter helpers where Failure is created to keep error-to-resource mapping centralized.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@core/presentation/src/commonMain/composeResources/files/whatsnew/it/17.json`:
- Line 11: Replace the mixed-language phrase in the localized string "Salta un
aggiornamento specifico — scarta una notifica di update se è un falso positivo;
verrai avvisato di nuovo quando uscirà una versione più recente." by using fully
Italian wording: change "notifica di update" to "notifica di aggiornamento" so
the string reads with consistent Italian phrasing.
In `@core/presentation/src/commonMain/composeResources/values-tr/strings-tr.xml`:
- Line 1107: The Turkish label for the "unskip" action is ambiguous; update the
string resource named apps_skip_version_unskip (and the other equivalent key
mentioned around line 1118) to a clear reversal phrase such as "Atlamayı kaldır"
or "Yoksaymayı kaldır" so the action reads explicitly as "Undo skip" rather than
"Skip."
In
`@feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/AppsRoot.kt`:
- Around line 1172-1179: The DropdownMenuItem for skipping a version is only
shown when app.isUpdateAvailable && !app.latestVersion.isNullOrBlank(), but the
click path uses latestVersion ?: latestVersionName; update the visibility check
to mirror that fallback by using the combined value (latestVersion ?:
latestVersionName) and ensure it is not null or blank before rendering the
DropdownMenuItem (references: app.isUpdateAvailable, app.latestVersion,
app.latestVersionName, DropdownMenuItem, showRowOverflow, onSkipVersionClick).
In
`@feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/AppsViewModel.kt`:
- Around line 615-621: The skipReleaseTag function currently saves the
skippedReleaseTag but doesn't refresh the app's update state; after calling
installedAppsRepository.setSkippedReleaseTag(packageName, trimmed) and sending
the success event (_events.send(AppsEvent.ShowSuccess(...))), invoke
checkForUpdates(packageName) (from the same AppsViewModel) inside the
viewModelScope.launch so the UI/update state is re-evaluated immediately and the
"update available" prompt is dismissed.
- Around line 639-641: The catch block in AppsViewModel (where it logs "Failed
to unskip release for $packageName" and sends the skip-version error event) uses
the wrong UI message; update the _events.send call to use a dedicated unskip
error key (e.g. Res.string.apps_unskip_version_error) and ensure the
logger.error stays descriptive, and if the string resource
apps_unskip_version_error doesn't exist add the localized key to resources; keep
the logger message as-is but swap the ShowError argument to the unskip-specific
message.
In
`@feature/tweaks/presentation/src/commonMain/kotlin/zed/rainxch/tweaks/presentation/skipped/SkippedUpdatesRoot.kt`:
- Around line 93-97: The back IconButton currently has its Icon set with
contentDescription = null making it inaccessible; update the Icon (or
IconButton) in SkippedUpdatesRoot (the IconButton that uses
Icons.AutoMirrored.Filled.ArrowBack and onNavigateBack) to provide a meaningful
content description (e.g., a localized "Back" label via stringResource) so
screen readers can announce the action, ensuring the description is not null and
matches the navigation purpose.
---
Nitpick comments:
In
`@feature/tweaks/presentation/src/commonMain/kotlin/zed/rainxch/tweaks/presentation/skipped/SkippedUpdatesEvent.kt`:
- Line 5: The Failure event on SkippedUpdatesEvent currently exposes raw String
text via Failure(val message: String); change it to carry a localization-safe
type (e.g., Failure(val message: UiText) or a ResourceKey/LocalizedString sealed
value) and update all places that construct Failure to convert backend/exception
text into localized UI messages (map exceptions to resource keys or create
user-facing messages via core/presentation localization helpers). Ensure
consumers (snackbar renderer) read the new localized type instead of treating it
as a raw String and add any small adapter helpers where Failure is created to
keep error-to-resource mapping centralized.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: fb008874-e970-4a0e-8656-4d037e5b210f
📒 Files selected for processing (52)
composeApp/src/commonMain/kotlin/zed/rainxch/githubstore/app/di/ViewModelsModule.ktcomposeApp/src/commonMain/kotlin/zed/rainxch/githubstore/app/navigation/AppNavigation.ktcomposeApp/src/commonMain/kotlin/zed/rainxch/githubstore/app/navigation/GithubStoreGraph.ktcore/data/src/androidMain/kotlin/zed/rainxch/core/data/local/db/initDatabase.ktcore/data/src/androidMain/kotlin/zed/rainxch/core/data/local/db/migrations/MIGRATION_15_16.ktcore/data/src/commonMain/kotlin/zed/rainxch/core/data/local/db/AppDatabase.ktcore/data/src/commonMain/kotlin/zed/rainxch/core/data/local/db/dao/InstalledAppDao.ktcore/data/src/commonMain/kotlin/zed/rainxch/core/data/local/db/entities/InstalledAppEntity.ktcore/data/src/commonMain/kotlin/zed/rainxch/core/data/mappers/InstalledAppsMappers.ktcore/data/src/commonMain/kotlin/zed/rainxch/core/data/repository/InstalledAppsRepositoryImpl.ktcore/domain/src/commonMain/kotlin/zed/rainxch/core/domain/model/InstalledApp.ktcore/domain/src/commonMain/kotlin/zed/rainxch/core/domain/repository/InstalledAppsRepository.ktcore/presentation/src/commonMain/composeResources/files/whatsnew/17.jsoncore/presentation/src/commonMain/composeResources/files/whatsnew/ar/17.jsoncore/presentation/src/commonMain/composeResources/files/whatsnew/bn/17.jsoncore/presentation/src/commonMain/composeResources/files/whatsnew/es/17.jsoncore/presentation/src/commonMain/composeResources/files/whatsnew/fr/17.jsoncore/presentation/src/commonMain/composeResources/files/whatsnew/hi/17.jsoncore/presentation/src/commonMain/composeResources/files/whatsnew/it/17.jsoncore/presentation/src/commonMain/composeResources/files/whatsnew/ja/17.jsoncore/presentation/src/commonMain/composeResources/files/whatsnew/ko/17.jsoncore/presentation/src/commonMain/composeResources/files/whatsnew/pl/17.jsoncore/presentation/src/commonMain/composeResources/files/whatsnew/ru/17.jsoncore/presentation/src/commonMain/composeResources/files/whatsnew/tr/17.jsoncore/presentation/src/commonMain/composeResources/files/whatsnew/zh-CN/17.jsoncore/presentation/src/commonMain/composeResources/values-ar/strings-ar.xmlcore/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-ko/strings-ko.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.xmlfeature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/AppsAction.ktfeature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/AppsRoot.ktfeature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/AppsViewModel.ktfeature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/components/CompactAppRow.ktfeature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/mappers/InstalledAppMapper.ktfeature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/model/InstalledAppUi.ktfeature/tweaks/presentation/src/commonMain/kotlin/zed/rainxch/tweaks/presentation/TweaksAction.ktfeature/tweaks/presentation/src/commonMain/kotlin/zed/rainxch/tweaks/presentation/TweaksRoot.ktfeature/tweaks/presentation/src/commonMain/kotlin/zed/rainxch/tweaks/presentation/components/sections/Installation.ktfeature/tweaks/presentation/src/commonMain/kotlin/zed/rainxch/tweaks/presentation/skipped/SkippedUpdatesAction.ktfeature/tweaks/presentation/src/commonMain/kotlin/zed/rainxch/tweaks/presentation/skipped/SkippedUpdatesEvent.ktfeature/tweaks/presentation/src/commonMain/kotlin/zed/rainxch/tweaks/presentation/skipped/SkippedUpdatesRoot.ktfeature/tweaks/presentation/src/commonMain/kotlin/zed/rainxch/tweaks/presentation/skipped/SkippedUpdatesState.ktfeature/tweaks/presentation/src/commonMain/kotlin/zed/rainxch/tweaks/presentation/skipped/SkippedUpdatesViewModel.kt
- it/17.json: fix mixed-language phrase (notifica di update -> di aggiornamento). - tr strings: clarify ambiguous "Atlama" (=Skip) -> "Atlamayı kaldır" (=Undo skip) on apps_skip_version_unskip and skipped_updates_unskip_action. - AppsRoot DropdownMenuItem visibility now mirrors click handler fallback (latestVersion ?: latestVersionName). - AppsViewModel.skipReleaseTag re-runs checkForUpdates after success so the row drops the update prompt immediately. - AppsViewModel.unskipReleaseTag catch now reports apps_unskip_version_error instead of the skip key. - SkippedUpdatesRoot back IconButton announces stringResource(navigate_back) for screen readers. - New apps_unskip_version_error string added in all 13 locales.
Summary
Closes #542. Lets users dismiss false-positive update prompts (pixiv-viewer-app, LuckyTool, WAuxiliary, Nagram cases) by skipping a specific upstream release tag. The skip is sticky on the row, persists across launches, and auto-clears the moment a strictly newer release lands so users don't have to manage skips manually for future bumps.
skippedReleaseTagoninstalled_apps(MIGRATION_15_16, version 16)InstalledAppsRepositoryImpl.checkForUpdates: when the matched tag equals the skipped tag, forceisUpdateAvailable = false; when the matched tag is strictly newer than the skipped tag, clear the skip and let normal logic compute. UsesVersionMath.isExactSameVersionfor the equality check so a re-tag with build metadata doesn't get auto-unskipped.Skip this version(when an update is being prompted) orDon't skip(when a skip is already stored), with a snackbar confirmation.SkippedUpdatesScreenlists every app with a non-null skipped tag and lets the user unskip per-row.The underlying tag-vs-manifest mismatch is not fixed here (would require sniffing every release asset's APK metadata — too invasive). Skip-this-version is the user-side hammer; the per-app bugs from #542 stay open for separate investigation.
Test plan
Skip this version→ tap → badge clears, snackbar fires, row moves to "Up to date" sectionDon't skip→ tap → re-runs update check, badge re-appears if upstream is still aheadSkipped updateslists the skipped row, unskip from there also re-runs the update checkSummary by CodeRabbit