toggleFavorite's ALL-list success branch updated favoriteAction to Starred but never touched starsCount, so a row kept showing its pre-star count even after the server had actually accepted it. Now increments starsCount by 1 in the same update. Also guards against a repeat tap on an already-Starred row (the ALL list can't tell a repo's already-starred state on load, so the star stays tappable) double-incrementing the displayed count. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
89 lines
4.9 KiB
Markdown
89 lines
4.9 KiB
Markdown
# TASK-034: Star count doesn't increment after a successful favorite
|
|
|
|
Status: implemented; all required checks pass; live-installed, awaiting the human product owner's confirmation
|
|
Owner: Claude
|
|
Reviewer: Codex
|
|
|
|
## Outcome
|
|
|
|
Following TASK-033's OAuth scope fix, the human product owner confirmed starring itself now works
|
|
("별표 눌러서 즐겨찾기는 되는데") but reported the displayed star count doesn't go up
|
|
("카운팅은 안올라가네"). `toggleFavorite`'s ALL-list success branch updated only `favoriteAction`
|
|
(to `Starred`) and never touched `starsCount`, so a row kept showing whatever count the last full
|
|
list load had returned, even after a star that the server had actually accepted. Fixed by
|
|
incrementing the row's `starsCount` in the same state update that marks it `Starred`. While fixing
|
|
this, found and closed a related gap: a repeat tap on an already-`Starred` row (the ALL list has no
|
|
way to know a repository's already-starred state on initial load, so the star stays tappable) would
|
|
have re-called `star()` and double-incremented the client-displayed count each time — now a no-op.
|
|
|
|
## Scope
|
|
|
|
- Included: `feature/repositories/RepositoryListViewModel.kt` (`toggleFavorite` only), matching
|
|
test additions in `RepositoryListViewModelTest.kt`.
|
|
- Excluded: No change to the FAVORITES-list unstar path (removing the row entirely already made
|
|
its count irrelevant, no bug there). No change to how the initial list load populates
|
|
`starsCount` (that already came from Gitea's own response, unaffected). No attempt to fetch the
|
|
server's authoritative post-star count instead of incrementing client-side (see Design notes).
|
|
|
|
## Design notes
|
|
|
|
- **Optimistic +1, not a re-fetch**: Gitea's star endpoint (`PUT`, 204 No Content) doesn't return
|
|
the new count, so getting the authoritative number back would mean a second network call
|
|
(re-fetching the repository) purely to update one number — not worth it for a value the app
|
|
already knows how to derive from something it just confirmed itself (the star succeeded, so the
|
|
count is exactly one higher than what was last displayed).
|
|
- **The repeat-tap guard closes a real double-count bug, not just a hypothetical one**: because the
|
|
ALL list can't determine a repository's already-starred state on load (an existing, accepted
|
|
limitation from TASK-018/TASK-030), a `Starred` row's star icon stays enabled and tappable —
|
|
nothing before this fix stopped a second tap from calling `star()` again and incrementing the
|
|
displayed count a second time for a repository the user only starred once. The guard checks the
|
|
row's own `favoriteAction` before doing anything, so it also saves a redundant network call, not
|
|
just a redundant `+1`.
|
|
|
|
## Acceptance criteria
|
|
|
|
- [x] Starring a repository from the ALL list increments its displayed star count by exactly 1.
|
|
- [x] Tapping an already-`Starred` row again does not call `star()` a second time and does not
|
|
change the displayed count further.
|
|
- [x] Unstarring from the FAVORITES list is unaffected (row removal, no count to update).
|
|
- [x] Build, unit tests, and lint pass.
|
|
- [ ] Live confirmation from the human product owner that the count now visibly increments on tap —
|
|
installed on the device but not yet re-tested in this exact session.
|
|
|
|
## Required checks
|
|
|
|
```text
|
|
./gradlew compileDebugKotlin compileDebugUnitTestKotlin
|
|
./gradlew testDebugUnitTest
|
|
./gradlew assembleDebug lintDebug
|
|
```
|
|
|
|
## Evidence
|
|
|
|
- `RepositoryListViewModel.kt`: `toggleFavorite`'s ALL-list success branch now updates
|
|
`starsCount = it.starsCount + 1` alongside `favoriteAction = Starred`; new early-return guard
|
|
when the row's `favoriteAction` is already `Starred`.
|
|
- `RepositoryListViewModelTest.kt`: `repo()` test helper gained a `starsCount` parameter; two new
|
|
tests — starring increments the displayed count by 1; a repeat tap after a successful star is a
|
|
no-op (no second `star()` call, count stays at 1).
|
|
- `./gradlew compileDebugKotlin compileDebugUnitTestKotlin`: BUILD SUCCESSFUL.
|
|
- `./gradlew testDebugUnitTest`: BUILD SUCCESSFUL, all unit tests passing (including the two new
|
|
ones above).
|
|
- `./gradlew assembleDebug lintDebug`: BUILD SUCCESSFUL, 0 lint errors.
|
|
- Installed on the human product owner's device over wireless `adb` (`adb install -r`, streamed
|
|
install succeeded); not yet re-tested live in this exact session.
|
|
|
|
## Known limitations
|
|
|
|
- Still optimistic, not authoritative: if Gitea's real count differs from this app's local
|
|
increment for any reason (e.g. another client starred the same repo around the same time), the
|
|
displayed number stays off until the next full list reload. Considered an acceptable tradeoff
|
|
given the alternative (a second network call per star) for a rarely-contended personal count.
|
|
- The underlying "can't tell if already starred on initial load" limitation (TASK-018/TASK-030)
|
|
is unchanged — this task only stops it from causing a *visible count* bug, it doesn't resolve the
|
|
limitation itself.
|
|
|
|
## Review findings
|
|
|
|
None yet — pending Codex/human review.
|