From fbec743e5f21af2aeec1d71c2126271d23f1f82d Mon Sep 17 00:00:00 2001 From: choiminyeong Date: Sat, 29 Aug 2026 22:58:05 +0900 Subject: [PATCH] =?UTF-8?q?TASK-043:=20fix=20empty=20=EC=A6=90=EA=B2=A8?= =?UTF-8?q?=EC=B0=BE=EA=B8=B0=20offering=20=EB=A1=9C=EA=B7=B8=EC=95=84?= =?UTF-8?q?=EC=9B=83=20instead=20of=20a=20way=20back?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The FAVORITES-mode empty state ("nothing starred yet") shared its MessageState call with the ALL-mode empty state ("account has zero repositories"), inheriting a hardcoded 로그아웃 action that only made sense for the latter. Gives FAVORITES-mode its own action: "전체 저장소 보기", wired to the same onShowAllRepositories the tab row already uses. Live bug report: "현재 화면 즐겨찾기가 안되어있는데 로그아웃할거냐는 버튼이 왜 있지?" Live-verified the fix on-device. Co-Authored-By: Claude Sonnet 5 --- .../repositories/RepositoryListScreen.kt | 32 ++++++--- .../main/res/values/strings_repositories.xml | 1 + docs/development-log.md | 29 ++++++++ .../043-favorites-empty-state-wrong-action.md | 72 +++++++++++++++++++ 4 files changed, 124 insertions(+), 10 deletions(-) create mode 100644 tasks/043-favorites-empty-state-wrong-action.md diff --git a/app/src/main/java/com/ubisam/ubgitea/feature/repositories/RepositoryListScreen.kt b/app/src/main/java/com/ubisam/ubgitea/feature/repositories/RepositoryListScreen.kt index 7a862fa..4b91bc5 100644 --- a/app/src/main/java/com/ubisam/ubgitea/feature/repositories/RepositoryListScreen.kt +++ b/app/src/main/java/com/ubisam/ubgitea/feature/repositories/RepositoryListScreen.kt @@ -100,16 +100,28 @@ fun RepositoryListScreen( .modeSwipeGesture(state.mode, onShowAllRepositories, onShowFavorites), ) { ModeTabs(state.mode, onShowAllRepositories, onShowFavorites) - MessageState( - if (state.mode == RepositoryListMode.FAVORITES) { - stringResource(R.string.repositories_favorites_empty) - } else { - stringResource(R.string.repositories_empty_account, state.accountName) - }, - stringResource(R.string.repositories_logout), - onLogout, - Modifier.weight(1f), - ) + // FAVORITES-mode empty doesn't mean the account has nothing to show -- it means + // nothing is starred *yet*, while 전체 저장소 (the other tab, right above this + // message) is very likely non-empty. The only sensible primary action here is + // "go look at 전체 저장소 and star something", never 로그아웃 -- offering logout as + // if this were a dead end was a copy-paste leftover from the ALL-mode branch below, + // where the account genuinely has zero repositories and logout is the only thing + // left to do. + if (state.mode == RepositoryListMode.FAVORITES) { + MessageState( + stringResource(R.string.repositories_favorites_empty), + stringResource(R.string.repositories_favorites_empty_action), + onShowAllRepositories, + Modifier.weight(1f), + ) + } else { + MessageState( + stringResource(R.string.repositories_empty_account, state.accountName), + stringResource(R.string.repositories_logout), + onLogout, + Modifier.weight(1f), + ) + } } is RepositoryListUiState.Error -> { val needsLogin = state.type == RepositoryListError.AUTHENTICATION_EXPIRED || diff --git a/app/src/main/res/values/strings_repositories.xml b/app/src/main/res/values/strings_repositories.xml index 603de48..a516e2d 100644 --- a/app/src/main/res/values/strings_repositories.xml +++ b/app/src/main/res/values/strings_repositories.xml @@ -41,6 +41,7 @@ 전체 저장소 즐겨찾기 즐겨찾기한 저장소가 없습니다. + 전체 저장소 보기 즐겨찾기 즐겨찾기 해제 즐겨찾기됨 diff --git a/docs/development-log.md b/docs/development-log.md index 374d604..e04153b 100644 --- a/docs/development-log.md +++ b/docs/development-log.md @@ -938,3 +938,32 @@ This is the append-only implementation and handoff record shared by Codex and Cl - Next recommended task: no further design-review gaps are currently queued; awaiting the next live bug report or explicit direction from the human product owner. - Next owner: Claude. + +## 2026-08-29 (continued) — TASK-043: empty 즐겨찾기 offered 로그아웃 instead of a way back + +- Agent and role: Claude, direct continuation of the same live session. Live bug report mid-turn: + "현재 화면 즐겨찾기가 안되어있는데 로그아웃할거냐는 버튼이 왜 있지?" — reproduced immediately via + screenshot of the actual device screen. +- Commit/diff: on `claude/task-015-notifications`; `feature/repositories/RepositoryListScreen.kt`'s + `RepositoryListUiState.Empty` branch split into two `MessageState` calls; + `strings_repositories.xml` gained `repositories_favorites_empty_action`; + `tasks/043-favorites-empty-state-wrong-action.md`. +- Root cause: the FAVORITES-mode ("nothing starred yet") and ALL-mode ("account has zero + repositories") empty states shared one `MessageState` call with a single hardcoded action — + `onLogout`/"로그아웃" — that only made sense for the ALL-mode dead-end case. FAVORITES-mode + inherited it as an unrelated leftover instead of getting its own action. +- How it was fixed: FAVORITES-mode now gets its own `MessageState` call using + `onShowAllRepositories` (already passed into this composable, and already what the tab row above it + calls) with a new "전체 저장소 보기" label; ALL-mode is unchanged. +- Files changed: `feature/repositories/RepositoryListScreen.kt`, `strings_repositories.xml`, + `tasks/043-favorites-empty-state-wrong-action.md`. +- Checks and results: `./gradlew compileDebugKotlin compileDebugUnitTestKotlin testDebugUnitTest assembleDebug lintDebug` + BUILD SUCCESSFUL, all existing tests passing unmodified, 0 lint errors. +- Live verification: installed over wireless `adb`. 즐겨찾기 tab, empty, now shows "전체 저장소 보기" + instead of "로그아웃"; tapping it switches to 전체 저장소 and shows the full list — screenshots at + each step. +- Review findings and resolutions: None from a separate review pass. +- Known limitations: None outstanding for this task. +- Next recommended task: no further design-review gaps currently queued; continuing to watch for live + bug reports and awaiting further direction from the human product owner. +- Next owner: Claude, continuing per the standing direction. diff --git a/tasks/043-favorites-empty-state-wrong-action.md b/tasks/043-favorites-empty-state-wrong-action.md new file mode 100644 index 0000000..ebe0583 --- /dev/null +++ b/tasks/043-favorites-empty-state-wrong-action.md @@ -0,0 +1,72 @@ +# TASK-043: Empty 즐겨찾기 tab offered 로그아웃 instead of a way back to 전체 저장소 + +Status: implemented; all required checks pass; live-confirmed on the human product owner's device +Owner: Claude +Reviewer: Codex + +## Outcome + +Live bug report: "현재 화면 즐겨찾기가 안되어있는데 로그아웃할거냐는 버튼이 왜 있지?" (the current +screen has nothing favorited, so why is there a button asking whether to log out?). Confirmed on +screen: the 즐겨찾기 tab, with zero starred repositories, showed "즐겨찾기한 저장소가 없습니다." and +directly below it a green primary button labeled "로그아웃" — logging out was presented as the answer +to "you have nothing starred," which makes no sense and is a jarring, semi-destructive-looking action +to put in front of a user who just wants to go star something. + +Root cause: `RepositoryListScreen`'s `RepositoryListUiState.Empty` branch renders both of its two very +different cases — "즐겨찾기 has nothing starred yet" (fixable by visiting the other tab, right above +this message) and "the account itself has zero repositories" (a genuine dead end where logout really +is the only remaining action) — through the same `MessageState` call, which requires exactly one +mandatory action/label pair. The FAVORITES-mode branch reused `onLogout`/"로그아웃" from the ALL-mode +branch below it instead of getting its own action wired up. + +## Scope + +- Included: `feature/repositories/RepositoryListScreen.kt`'s `RepositoryListUiState.Empty` branch — + split into two calls to `MessageState`, one per mode. FAVORITES-mode now uses + `onShowAllRepositories` (already in scope at this call site) with a new + `repositories_favorites_empty_action` ("전체 저장소 보기") label instead of `onLogout`/"로그아웃". + ALL-mode (genuinely zero repositories on the account) is unchanged. +- Excluded: `MessageState` itself (still single-action by design; not worth generalizing for one call + site). `RepositoryListViewModel` — this is a pure presentation fix, the `Empty` state's `mode` field + it reads already existed. + +## Acceptance criteria + +- [x] 즐겨찾기 tab with zero starred repositories shows a button that reads "전체 저장소 보기", not + "로그아웃". +- [x] Tapping it switches to the 전체 저장소 tab (reuses the same `onShowAllRepositories` the tab row + itself already calls). +- [x] The genuinely-empty-account case (전체 저장소 tab, zero repositories at all) is unchanged and + still offers 로그아웃. +- [x] Build, unit tests, and lint pass. +- [x] Live-confirmed on the human product owner's device: emptied 즐겨찾기 (repository had been + unstarred since the last check), confirmed the button now reads "전체 저장소 보기", tapped it, + confirmed it switches to 전체 저장소 and shows the full repository list. + +## Required checks + +```text +./gradlew compileDebugKotlin compileDebugUnitTestKotlin testDebugUnitTest assembleDebug lintDebug +``` + +## Evidence + +- `feature/repositories/RepositoryListScreen.kt`: `RepositoryListUiState.Empty` branch now has two + `MessageState` calls (FAVORITES vs. everything else) instead of one shared call with a hardcoded + logout action. +- `strings_repositories.xml`: new `repositories_favorites_empty_action` = "전체 저장소 보기". +- `./gradlew compileDebugKotlin compileDebugUnitTestKotlin testDebugUnitTest assembleDebug lintDebug`: + BUILD SUCCESSFUL, all unit tests passing unmodified (no test exercised this exact button label), 0 + lint errors. +- Live device: installed over wireless `adb`. 즐겨찾기 tab (currently empty — a previously-starred + repository had been unstarred since TASK-041's verification) showed "전체 저장소 보기" (screenshot); + tapped it and confirmed it lands on 전체 저장소 with the full list visible (screenshot). + +## Known limitations + +None outstanding for this task. + +## Review findings + +None yet — pending Codex/human review.