fix(home): 라이브 전체 항목을 항상 표시한다
This commit is contained in:
@@ -1225,6 +1225,134 @@ git diff --check
|
||||
- 2026-07-31: 사용자 인터뷰에서 모든 `모두 팔로우` 동작에 확인 절차를 적용하되 현재 구현은 `최근 응원이 많은 크리에이터` 섹션만 대상으로 하는 B안을 확정했다. 기존 `HomeMainFragment`의 직접 API 호출 경로와 `V2ModalDialog`의 취소·확인·중복 클릭 방지 계약을 확인해 Phase 17을 작성했다. 이번 요청 범위에 따라 production·test·resource 구현은 시작하지 않았으며 모든 구현 및 Gate 체크박스는 미완료로 유지한다.
|
||||
- 2026-07-31: Phase 17 구현으로 `HomeMainFragment`의 응원 크리에이터 모두 팔로우 callback을 기존 즉시 `followCreators()` 호출에서 `V2ModalDialog` 확인창 표시로 변경했다. 확인 버튼에서만 기존 `homeRecommendationViewModel.followCreators(SECTION_KEY_CHEER_CREATORS, creatorIds)`를 호출하고, 취소 버튼은 기존 `R.string.cancel`과 `V2ModalDialog` 기본 닫기 동작을 재사용한다. 한국어·영어·일본어 `home_recommendation_follow_all_confirm_title`, `home_recommendation_follow_all_confirm_description`, `home_recommendation_follow_all_confirm_button` resource를 추가했다.
|
||||
|
||||
## Phase 18: 현재 진행 중인 라이브 `전체` 항목 상시 표시
|
||||
|
||||
**Phase 결과:** 메인 홈 추천 탭의 현재 진행 중인 라이브가 1개 이상이면 최대 20개의 라이브 뒤에 `전체` 항목이 항상 표시되고, 0개이면 기존처럼 라이브 섹션이 숨겨진다.
|
||||
|
||||
**선행 조건:** `prd.md`의 `2026-07-31 변경: 현재 진행 중인 라이브 전체 항목 상시 표시` 승인, 기존 `HomeLiveAdapter`의 20개 상한·`MoreViewHolder` 디자인·`HomeOnAirLiveActivity` 이동 계약 유지.
|
||||
|
||||
**Phase 완료 조건:** `P18-T1`과 `P18-GATE` 완료, Task 검증 기록과 `Verification Log`에 실제 결과 누적.
|
||||
|
||||
### 구현 항목
|
||||
|
||||
#### Task 18.1: 라이브가 1개 이상이면 `전체` 항목 추가
|
||||
|
||||
**Goal 실행 `P18-T1`:** `HomeLiveAdapter`가 빈 목록에는 항목을 만들지 않고, 라이브가 1개 이상이면 라이브 개수와 관계없이 마지막에 기존 `전체` 항목을 추가한다.
|
||||
|
||||
- **시작 조건:** Phase 18 선행 조건 충족.
|
||||
- **완료 증거:** RED/GREEN 체크박스 완료, 0개·1개·20개·21개 이상 경계 자동 검증, focused 회귀·compile·lint·diff 결과 누적.
|
||||
- **범위 밖:** 라이브 최대 표시 개수 변경, `전체` 항목 디자인·문구·클릭 목적지·로그인 가드 변경, 라이브 item 입장 흐름, 추천/전체 라이브 API 계약, 신규 abstraction·dependency 추가.
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/ui/HomeLiveAdapter.kt`
|
||||
- Test: `app/src/test/java/kr/co/vividnext/sodalive/v2/main/home/HomeMainFragmentLayoutTest.kt`
|
||||
- Modify: `docs/20260601_메인_홈_추천_UI와_API_연동/plan-task.md`
|
||||
|
||||
**Interfaces:**
|
||||
|
||||
- Consumes: `HomeLiveAdapter.submitItems(items: List<HomeRecommendationLiveUiModel>)`, `MAX_VISIBLE_LIVE_COUNT = 20`, 기존 `MoreViewHolder`와 `setOnMoreClick(listener: (() -> Unit)?)`.
|
||||
- Produces: `showAllItem: Boolean` 내부 상태와 `0개 -> itemCount 0`, `1~20개 -> lives + 전체`, `21개 이상 -> live 20개 + 전체` adapter 계약.
|
||||
|
||||
- [x] **RED:** `HomeMainFragmentLayoutTest`에 아래 경계 테스트를 추가한다.
|
||||
|
||||
```kotlin
|
||||
@Test
|
||||
fun `홈 라이브 어댑터는 라이브가 있으면 전체 항목을 추가한다`() {
|
||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||
val parent = RecyclerView(context)
|
||||
parent.layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
|
||||
val adapter = HomeLiveAdapter()
|
||||
|
||||
adapter.submitItems(emptyList())
|
||||
assertEquals(0, adapter.itemCount)
|
||||
|
||||
adapter.submitItems(listOf(liveItem(1L)))
|
||||
assertEquals(2, adapter.itemCount)
|
||||
val viewHolder = adapter.onCreateViewHolder(parent, adapter.getItemViewType(1))
|
||||
assertEquals(
|
||||
context.getString(R.string.screen_home_theme_all),
|
||||
(viewHolder.itemView as TextView).text.toString()
|
||||
)
|
||||
|
||||
adapter.submitItems((1L..20L).map(::liveItem))
|
||||
assertEquals(21, adapter.itemCount)
|
||||
}
|
||||
```
|
||||
|
||||
- [x] **RED 확인:** 아래 focused test를 실행해 기존 `hasMore = items.size > MAX_VISIBLE_LIVE_COUNT` 조건에서는 라이브 1개의 `itemCount`가 `1`이라 `assertEquals(2, adapter.itemCount)`에서 의도대로 실패하는지 확인한다.
|
||||
|
||||
```bash
|
||||
./gradlew :app:testDebugUnitTest \
|
||||
--tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest"
|
||||
```
|
||||
|
||||
- [x] **GREEN:** `HomeLiveAdapter`의 `hasMore` 이름과 조건만 아래처럼 최소 수정한다.
|
||||
|
||||
```kotlin
|
||||
private var showAllItem: Boolean = false
|
||||
|
||||
fun submitItems(items: List<HomeRecommendationLiveUiModel>) {
|
||||
this.items = items.take(MAX_VISIBLE_LIVE_COUNT)
|
||||
showAllItem = items.isNotEmpty()
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = items.size + if (showAllItem) 1 else 0
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return if (showAllItem && position == itemCount - 1) VIEW_TYPE_MORE else VIEW_TYPE_LIVE
|
||||
}
|
||||
```
|
||||
|
||||
- [x] **GREEN 확인:** RED 확인과 같은 focused test를 다시 실행해 신규 0개·1개 계약과 기존 21개 표시·22개 입력 cap 테스트가 모두 성공하는지 확인한다.
|
||||
- [x] **REFACTOR:** 새 abstraction 없이 변수명과 조건 변경만 유지하고 아래 직접 영향 회귀와 품질 검증 결과를 Task 검증 기록 및 `Verification Log`에 누적한다. 공용 계약·API·Fragment 흐름을 변경하지 않는 단일 adapter 분기는 `HomeMainFragmentLayoutTest`의 0개·1개·20개·21개·22개 경계로 직접 검증하고, 최종 branch 완료 검증에서 전체 unit test도 실행한다.
|
||||
|
||||
```bash
|
||||
./gradlew :app:testDebugUnitTest \
|
||||
--tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest"
|
||||
./gradlew :app:compileDebugKotlin
|
||||
./gradlew :app:ktlintCheck
|
||||
git diff --check
|
||||
```
|
||||
|
||||
검증 기록:
|
||||
|
||||
- 2026-07-31: 구현 전 baseline `HomeMainFragmentLayoutTest` 73개가 성공했다. 신규 `홈 라이브 어댑터는 라이브가 있으면 전체 항목을 추가한다` 테스트를 추가한 RED 실행은 총 74개 중 신규 1개만 `expected:<2> but was:<1>`로 실패해 기존 `items.size > MAX_VISIBLE_LIVE_COUNT` 조건을 재현했다.
|
||||
- 2026-07-31: `HomeLiveAdapter`의 `hasMore`를 `showAllItem`으로 변경하고 `showAllItem = items.isNotEmpty()`를 적용했다. 동일 focused test 74개, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck`가 모두 `BUILD SUCCESSFUL`이었고 `git diff --check`는 출력 없이 성공했다. ktlint의 `.editorconfig disabled_rules` 및 Gradle deprecation warning은 기존 경고다.
|
||||
- 2026-07-31: REFACTOR에서는 신규 abstraction 없이 테스트명을 한글 의도에 맞게 정리하고 focused test와 ktlint를 재실행해 성공을 확인했다. 최종 완료 검증으로 전체 `:app:testDebugUnitTest --no-parallel --console=plain`도 실행해 162 suites, 1,199 tests, 실패 0·오류 0·skip 0을 확인했다.
|
||||
- 2026-07-31: Phase 18 코드 리뷰에서 PRD·Task와 `HomeLiveAdapter` 및 `HomeMainFragment` 호출 흐름을 대조해 확정 발견 사항이 없음을 확인했다. focused 74 tests, debug Kotlin compile, ktlint는 성공했고, 전체 unit test를 `--rerun-tasks`로 재실행해 162 suites·1,199 tests·실패 0·오류 0·skip 0을 확인했다. `lintDebug`는 변경되지 않은 `AndroidManifest.xml:316`의 `FacebookActivity` `MissingClass`를 포함한 기존 28 errors·767 warnings로 실패했으며, 이번 production 변경 파일에는 기존 `notifyDataSetChanged()` warning 외 신규 lint error가 없었다. 문서 기록 후 `./gradlew tasks --all --console=plain`도 성공했고 결과는 `reviews/phase18-live-all-item-review.md`에 기록했다.
|
||||
|
||||
### 완료 조건
|
||||
|
||||
- [x] 빈 `lives` 입력에서 adapter item이 0개이고 기존 Fragment의 라이브 섹션 숨김 정책이 유지된다.
|
||||
- [x] 라이브가 1개 이상 20개 이하이면 모든 라이브 뒤에 `전체` 항목이 표시된다.
|
||||
- [x] 라이브가 21개 이상이면 라이브 최대 20개와 `전체` 항목 1개만 표시된다.
|
||||
- [x] 기존 `전체` 디자인·문구·클릭 목적지와 라이브 item 입장 흐름이 변경되지 않는다.
|
||||
- [x] 변경 파일이 Phase 18 Files 범위 안이고 신규 파일·dependency·commit이 생성되지 않는다.
|
||||
|
||||
### 검증 방법
|
||||
|
||||
#### Phase 18 Gate
|
||||
|
||||
**Goal 실행 `P18-GATE`:** Phase 18의 0개·1개·20개·21개 이상 경계와 기존 `전체` 항목 회귀를 최종 판정한다.
|
||||
|
||||
- **시작 조건:** `P18-T1` 체크박스와 검증 기록 완료.
|
||||
- **완료 증거:** Task 18.1 REFACTOR 명령이 모두 성공하고 아래 대조를 완료한다.
|
||||
- **범위 밖:** Gate 통과를 위한 test 삭제·완화, `HomeMainFragment`·전체 라이브 화면·API 수정, 관련 없는 홈 코드 정리.
|
||||
|
||||
대조:
|
||||
|
||||
- [x] `HomeLiveAdapter.submitItems()`가 표시 라이브를 `take(20)`으로 제한한다.
|
||||
- [x] `showAllItem`은 원본 `items.isNotEmpty()`로만 결정된다.
|
||||
- [x] 기존 `MoreViewHolder`, `createMoreView()`, `onMoreClick` 연결은 변경되지 않는다.
|
||||
- [x] Git diff가 Phase 18 Files와 승인된 PRD 범위 안에 있고 커밋이 생성되지 않았다.
|
||||
|
||||
계획 기록:
|
||||
|
||||
- 2026-07-31: 사용자 인터뷰에서 라이브 0개는 기존처럼 섹션을 숨기고 1개 이상이면 최대 20개 뒤에 `전체` 항목을 항상 표시하는 정책을 확정했다. 기존 20개 상한·`전체` 디자인·클릭 목적지·로그인 가드·API 계약을 유지하고, `HomeLiveAdapter` 내부 상태명과 조건 및 `HomeMainFragmentLayoutTest` 경계 테스트만 변경하는 Phase 18을 작성했다. production·test 구현은 시작하지 않았다.
|
||||
- 2026-07-31: Phase 18을 TDD로 구현했다. RED는 라이브 1개에서 `itemCount`가 기대 2, 실제 1로 실패했고, GREEN은 `showAllItem = items.isNotEmpty()` 최소 변경 후 focused 74개 테스트 성공으로 확인했다. 전체 1,199 tests와 compile·ktlint·diff 검증도 성공했으며 기존 `MoreViewHolder`·클릭 연결·20개 cap은 변경하지 않았다.
|
||||
|
||||
## Decision Log
|
||||
|
||||
| 날짜 | ID | 상태 | 결정 | 근거 | 영향 Goal/문서 |
|
||||
@@ -1232,8 +1360,12 @@ git diff --check
|
||||
| 2026-07-31 | `DEC-017` | 확정 | 모든 `모두 팔로우` 동작은 공통 확인 절차를 사용하고, 현재 구현은 노출 중인 응원 크리에이터 섹션으로 제한한다. 신규 공통 abstraction 없이 기존 `V2ModalDialog`를 재사용한다. | 사용자 `deep-interview`의 B안 선택과 현재 `genreCreators` 숨김 정책 | `P17-T1`, `P17-GATE`, `prd.md`의 `2026-07-31 변경` |
|
||||
| 2026-07-31 | `DEC-018` | 확정 | Phase 7의 2026-06-05 보안 재리뷰에서 승인된 유료 미구매 원본 이미지 미로드 정책을 기준으로 삼고, commit `2d58a876`에서 재도입된 client-side blur 원본 로드를 회귀로 수정한다. | 보안 재리뷰·검증 기록, 현재 `HomePopularCommunityAdapter`와 반대 방향의 test 변경 이력 교차 검토 | `REV-P7-001`, `P7-R1` |
|
||||
| 2026-07-31 | `DEC-019` | 확정 | 두 번째 `Phase 12`와 그 하위 `Task 10.*`는 기존 기록을 보존하면서 `P12B` 계열 고유 별칭을 추가해 이후 리뷰와 회귀 작업에서 사용한다. | `work-plan-docs.md`의 Goal/Task 추적성 규칙과 현재 문서의 중복 식별자 | `REV-P12B-001`, `P12B-R1` |
|
||||
| 2026-07-31 | `DEC-020` | 확정 | 현재 진행 중인 라이브가 0개이면 섹션을 숨기고, 1개 이상이면 최대 20개 라이브 뒤에 `전체` 항목을 항상 표시한다. | 사용자 인터뷰 승인과 기존 `HomeLiveAdapter`·전체 라이브 이동 계약 확인 | `P18-T1`, `P18-GATE`, `prd.md`의 `2026-07-31 변경: 현재 진행 중인 라이브 전체 항목 상시 표시` |
|
||||
|
||||
## Verification Log
|
||||
- 2026-07-31: Phase 18 변경 코드 리뷰 및 최신 검증을 수행했다. `HomeLiveAdapter`의 0개·1~20개·21개 이상 경계와 기존 `MoreViewHolder`, 로그인 가드, `HomeOnAirLiveActivity` 이동 경로를 대조해 확정 발견 사항이 없음을 판정했다. focused 74 tests·compile·ktlint와 `--rerun-tasks` 전체 162 suites·1,199 tests가 실패 0·오류 0으로 성공했고 staged·unstaged diff check와 문서 변경 후 `./gradlew tasks --all --console=plain`도 성공했다. 프로젝트 전체 `lintDebug`는 이번 diff 밖의 기존 28 errors·767 warnings로 실패했으며 첫 오류는 `AndroidManifest.xml:316`의 `FacebookActivity` `MissingClass`다. 상세 결과는 `reviews/phase18-live-all-item-review.md`에 기록했다.
|
||||
- 2026-07-31: Phase 18 TDD와 Gate 검증을 완료했다. 구현 전 focused baseline 73개 성공 후 신규 경계 테스트가 라이브 1개에서 `expected:<2> but was:<1>`로 RED 실패했고, `HomeLiveAdapter`의 `hasMore`를 `showAllItem`으로 바꾸고 `items.isNotEmpty()` 조건을 적용한 뒤 focused 74개가 성공했다. `:app:testDebugUnitTest --no-parallel --console=plain` 전체 실행은 162 suites, 1,199 tests, 실패 0·오류 0·skip 0으로 성공했고 `:app:compileDebugKotlin`, `:app:ktlintCheck`, `git diff --check`도 성공했다. 기존 deprecation warning 외 실패는 없었으며 신규 파일·dependency·commit은 생성하지 않았다.
|
||||
- 2026-07-31: Phase 18 문서 준비 검증으로 PRD의 0개·1~20개·21개 이상 표시 계약과 Non-Goal을 `P18-T1` 및 `P18-GATE`에 대조했고 누락된 확정 요구사항이 없음을 확인했다. `P18`, `Task 18`, `showAllItem` 추적 검색과 placeholder/TODO 검색, `git diff --check`가 성공했으며 변경 파일은 `prd.md`, `plan-task.md` 두 문서뿐이다. `./gradlew tasks --all --console=plain` 최초 sandbox 실행은 사용자 Gradle cache lock 접근 제한으로 실패했고, 승인된 동일 명령 재실행은 `BUILD SUCCESSFUL`로 완료됐다. production·test 구현은 시작하지 않았고 커밋은 생성하지 않았다.
|
||||
- 2026-07-31: `REV-P7-003` 후속 `Task R7.3` / `P7-R3`를 실행했다. `HomeMainFragmentLayoutTest`의 source 문자열 검사를 제거하고 `HomePopularCommunityAdapterTest`에 실제 adapter/ViewHolder bind 회귀 2건을 추가해 잠금 유료 원본 미로드·기존 Coil 요청 해제·drawable 제거·overlay/가격 유지와 무료·구매 완료 URL 전달을 검증했다. 보안 분기 mutation에서는 잠금 test가 `HomePopularCommunityAdapterTest.kt:72`에서 의도대로 실패했고 원상 복구 후 다시 통과했다. 직접 영향 test·compile·ktlint와 전체 162 suites/1,198 tests가 실패 0·error 0으로 성공했고, 문서 반영 후 `./gradlew tasks --all --console=plain`도 BUILD SUCCESSFUL이었다. 최종 production 코드는 이번 Task에서 추가 변경하지 않았다. Phase별 리뷰를 재검색한 결과 새 확정 항목은 확인되지 않았다.
|
||||
- 2026-07-31: Phase별 리뷰 리포트 최종 문서 검증으로 `git diff --check`를 실행해 출력 없이 성공했고, `reviews/` 아래 Phase 1~17 및 별도 이력 Phase 12B 보고서 18개 존재와 `REV-P7-003` ↔ `Task R7.3` ↔ `P7-R3` 연결을 확인했다. `./gradlew tasks --all --console=plain` 최초 sandbox 실행은 사용자 Gradle cache lock 접근 제한으로 실패했으며, 승인된 동일 명령 재실행은 BUILD SUCCESSFUL로 완료되어 프로젝트 task 인식 문제와 분리했다.
|
||||
- 2026-07-31: 현재 working tree를 Phase별 리뷰 보고서와 다시 대조했다. 신규 확정 항목은 Phase 7의 유료 미구매 원본 이미지 미로드 테스트가 실제 adapter bind, 기존 request/drawable 제거, lock overlay와 가격 유지를 실행하지 않고 production source 문자열만 검사하는 회귀 보호 공백(`REV-P7-003`) 1건이다. 이를 `Task R7.3` / `P7-R3`의 미완료 실행형 회귀 테스트 보강 Task로 Phase 7에 추가했으며 production 코드는 변경하지 않았다. Task 12.2는 사용자 수동 확인 완료 상태로 Phase 5·6·8·9·10·11·12·13 리포트의 오래된 blocker/남은 항목을 현재 상태와 동기화했다.
|
||||
|
||||
@@ -21,6 +21,7 @@ Figma `home_001` 화면(`24:5514`)을 기준으로 메인 홈 추천 영역을
|
||||
- 추천 탭이 선택된 `HomeMainFragment`에 메인 홈 추천 UI를 구현한다.
|
||||
- Figma에서 기존 widget으로 대응 가능한 항목은 기존 v2 widget을 우선 재사용한다.
|
||||
- 재사용이 어려운 영역만 최소 범위 신규 UI 또는 adapter item으로 정의한다.
|
||||
- 현재 진행 중인 라이브가 1개 이상이면 라이브 가로 목록 마지막에 `전체` 항목을 항상 표시해 전체 라이브 목록으로 이동할 수 있게 한다.
|
||||
- `추천 필모그래피`, `또 다른 모습` 섹션은 만들지 않는다.
|
||||
- 최하단 사업자 정보 섹션은 표시하되, 기본 최대 3줄 말줄임과 `더보기`/`접기` 토글을 제공한다.
|
||||
- `HomeActiveCreatorItem.activityType`은 백엔드 code를 앱 내부 enum 또는 mapper로 변환하고, 표시 문구는 string resource 기반 다국어 처리를 적용한다.
|
||||
@@ -43,6 +44,7 @@ Figma `home_001` 화면(`24:5514`)을 기준으로 메인 홈 추천 영역을
|
||||
- 모두 팔로우 확인 절차를 위해 신규 Dialog component나 layout을 만들지 않고 기존 `V2ModalDialog`를 재사용한다.
|
||||
- 모두 팔로우 API endpoint, request body, 성공·실패 처리와 완료 버튼 UI는 변경하지 않는다.
|
||||
- 현재 숨김 상태인 `genreCreators` 섹션이나 모두 팔로우 버튼을 다시 노출하지 않는다.
|
||||
- 라이브 `전체` 항목의 디자인, 클릭 목적지, 로그인 가드와 전체 라이브 목록 화면 동작은 변경하지 않는다.
|
||||
|
||||
---
|
||||
|
||||
@@ -54,6 +56,7 @@ Figma `home_001` 화면(`24:5514`)을 기준으로 메인 홈 추천 영역을
|
||||
|
||||
## 6. User Stories
|
||||
- 사용자는 홈에서 현재 라이브 중인 크리에이터와 추천 콘텐츠를 빠르게 탐색하고 싶다.
|
||||
- 사용자는 현재 진행 중인 라이브가 적더라도 `전체` 항목을 통해 전체 라이브 목록 화면으로 이동하고 싶다.
|
||||
- 사용자는 배너를 스와이프하거나 터치해 관련 이벤트, 크리에이터, 시리즈, 외부 링크 또는 앱 내부 딥링크로 이동하고 싶다.
|
||||
- 사용자는 최근 활동한 크리에이터의 활동 유형을 `라이브`, `오디오`, `커뮤니티`처럼 이해 가능한 문구로 보고 싶다.
|
||||
- 사용자는 여러 크리에이터를 한 번에 팔로우하기 전에 확인창에서 동작을 검토하고, 확인하거나 취소할 수 있기를 원한다.
|
||||
@@ -141,6 +144,15 @@ data class HomePopularCommunityPostItem(
|
||||
- `HomePopularCommunityPostItem.price`, `existOrdered`는 추천 페이지용 `FeedCommunityView`의 유료 미구매 UI 판정에 사용한다.
|
||||
- `HomePopularCommunityPostItem.content`, `price`, `createdAt`, `likeCount`, `commentCount`는 인기 커뮤니티 feed 표시 데이터로 사용한다.
|
||||
|
||||
### 현재 진행 중인 라이브 `전체` 항목
|
||||
|
||||
#### Requirements
|
||||
- `lives`가 비어 있으면 기존 정책대로 라이브 섹션 전체를 숨기고 `전체` 항목도 표시하지 않는다.
|
||||
- `lives`가 1개 이상 20개 이하이면 모든 라이브 항목 뒤에 `전체` 항목을 표시한다.
|
||||
- `lives`가 21개 이상이면 기존 정책대로 라이브를 최대 20개까지 표시하고 마지막에 `전체` 항목을 표시한다.
|
||||
- `전체` 항목의 기존 크기, 색상, typography와 클릭 시 `HomeOnAirLiveActivity`로 이동하는 동작을 유지한다.
|
||||
- 라이브 item 표시 순서, item 클릭 입장 흐름, 추천 API와 전체 라이브 목록 API 계약은 변경하지 않는다.
|
||||
|
||||
### Activity Type 다국어 표시
|
||||
`HomeActiveCreatorItem.activityType`은 백엔드 enum code를 앱 표시용 enum으로 변환한다.
|
||||
|
||||
@@ -406,6 +418,7 @@ HomeRecommendation 화면
|
||||
- `HomeActiveCreatorItem.creatorId`가 UI model까지 보존되고, `LIVE` item은 `targetId` 유무에 따라 라이브 룸 또는 크리에이터 채널 route로 분기된다.
|
||||
- 최근 활동 `LIVE`의 `targetId == null && creatorId <= 0L` 입력에서 route가 생성되지 않는다.
|
||||
- 최근 활동 `LIVE`의 라이브 룸 진입이 `LiveActionCoordinator`를 사용해 로그인·본인인증·성인 콘텐츠 보기 설정 정책을 우회하지 않는다.
|
||||
- 현재 진행 중인 라이브가 0개이면 라이브 섹션과 `전체` 항목이 표시되지 않고, 1개 이상이면 최대 20개 라이브 뒤에 `전체` 항목이 표시된다.
|
||||
- 제외 대상인 `추천 필모그래피`, `또 다른 모습` 섹션이 화면에 생성되지 않는다.
|
||||
- 최근 응원이 많은 크리에이터 모두 팔로우 API success 후 버튼이 `모두 팔로우 완료`와 `ic_new_following` 상태로 변경된다.
|
||||
- 최근 응원이 많은 크리에이터의 기본 상태 모두 팔로우 버튼 터치 직후에는 확인창만 표시되고 API 호출 횟수는 `0`이다.
|
||||
@@ -428,6 +441,8 @@ HomeRecommendation 화면
|
||||
---
|
||||
|
||||
## 12. 검증 기록
|
||||
- 2026-07-31: 현재 진행 중인 라이브 `전체` 항목 상시 표시 요구사항을 TDD로 구현했다. 라이브 1개 입력의 adapter item 수가 기대 2, 실제 1로 실패하는 RED를 확인한 뒤 `HomeLiveAdapter`가 비어 있지 않은 입력에서 `전체` 항목을 추가하도록 최소 수정했다. focused `HomeMainFragmentLayoutTest` 74개와 전체 162 suites·1,199 tests, debug Kotlin compile, ktlint, diff 검증이 성공했으며 0개 숨김·20개 cap·기존 `전체` 디자인과 클릭 경로는 유지했다.
|
||||
- 2026-07-31: 사용자 인터뷰에서 현재 진행 중인 라이브가 0개이면 기존처럼 섹션을 숨기고, 1개 이상이면 최대 20개 라이브 뒤에 `전체` 항목을 항상 표시하는 정책을 확정했다. `HomeLiveAdapter.submitItems()`의 기존 `items.size > MAX_VISIBLE_LIVE_COUNT` 조건과 `HomeMainFragmentLayoutTest`의 21개 초과 회귀 테스트를 확인했으며, 기존 디자인·클릭 목적지·로그인 가드·API 계약은 변경하지 않는 최소 범위를 PRD에 반영했다.
|
||||
- 2026-07-31: PRD와 계획/TASK 보완 후 신규 범위의 placeholder·모순·요구사항 추적성을 자체 검토했다. `git status --short`로 변경 파일이 두 문서뿐임을 확인했고, placeholder 검색과 `git diff --check`는 출력 없이 성공했다. `./gradlew tasks --all`은 최초 sandbox 실행에서 사용자 Gradle cache lock 접근 제한으로 실패했으나 승인된 동일 명령 재실행은 `BUILD SUCCESSFUL`로 완료되어 계획에 기재한 Gradle task 이름의 유효성을 확인했다. production·test·resource 파일은 변경하지 않았다.
|
||||
- 2026-07-31: `deep-interview` 결과, 모든 `모두 팔로우` 동작에 API 호출 전 확인 절차를 적용하는 공통 정책을 확정했다. 현재 구현 대상은 실제 노출 중인 `최근 응원이 많은 크리에이터` 섹션으로 제한하고, 숨겨진 `genreCreators` UI는 다시 노출하지 않는다. 저장소의 `HomeMainFragment`가 `cheerCreators` 전체 id를 `HomeRecommendationViewModel.followCreators()`에 즉시 전달하는 현재 흐름과, 취소·확인 2버튼 및 중복 클릭 방지를 지원하는 기존 `V2ModalDialog`를 확인했다. 확인창은 제목 `모두 팔로우`, 설명 `목록의 크리에이터를 모두 팔로우하시겠어요?`, 확인 `팔로우 하기`, 취소 `취소`로 확정하고 한국어·영어·일본어 resource를 계획했다. 이번 요청은 PRD와 계획/TASK 보완까지만 수행하며 구현 코드는 변경하지 않는다.
|
||||
- 2026-07-31: `REV-P7-001` 후속으로 유료 미구매 인기 커뮤니티의 원본 이미지 미로드 보안 결정을 PRD에 재정렬했다. commit `2d58a876`에서 client-side blur 원본 로드가 재도입된 회귀를 복구해, 무료·구매 완료 이미지는 기존대로 로드하고 유료 미구매는 원본 `imageUrl` 요청 없이 lock overlay와 가격만 유지한다.
|
||||
@@ -507,3 +522,9 @@ HomeRecommendation 화면
|
||||
- 유료 미구매 인기 커뮤니티 item은 원본 `imageUrl`을 image loader에 전달하지 않는다.
|
||||
- 기존 Coil 요청과 drawable을 비우는 방식으로 원본 네트워크 요청/cache 노출을 막고, `FeedCommunityView.bind()`의 lock overlay와 가격 capsule 표시는 유지한다.
|
||||
- 무료 또는 구매 완료 item의 이미지 로딩, 커뮤니티 상세 이동, 구매 권한 판정, API/DTO 계약은 변경하지 않는다.
|
||||
|
||||
### 2026-07-31 변경: 현재 진행 중인 라이브 `전체` 항목 상시 표시
|
||||
- 현재 진행 중인 라이브가 0개이면 기존처럼 라이브 섹션 전체를 숨긴다.
|
||||
- 현재 진행 중인 라이브가 1개 이상이면 라이브 개수와 관계없이 목록 마지막에 `전체` 항목을 표시한다.
|
||||
- 라이브는 기존처럼 최대 20개까지 표시하므로 21개 이상일 때도 `라이브 20개 + 전체` 구성을 유지한다.
|
||||
- `전체` 항목의 디자인·클릭 목적지·로그인 가드와 라이브 item의 입장 흐름은 변경하지 않는다.
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
# Phase 18 현재 진행 중인 라이브 `전체` 항목 리뷰
|
||||
|
||||
## 1. 리뷰 정보
|
||||
|
||||
| 항목 | 내용 |
|
||||
|---|---|
|
||||
| 리뷰 대상 | Phase 18 / Task 18.1, P18-GATE |
|
||||
| 기준 commit 또는 working tree | `d592038e` 기반 Phase 18 staged working tree |
|
||||
| 리뷰 일자 | 2026-07-31 |
|
||||
| 리뷰어 | Codex |
|
||||
| 기준 문서 | `prd.md`, `plan-task.md` Phase 18 |
|
||||
| 리뷰 상태 | 판정 완료 |
|
||||
|
||||
## 2. 리뷰 목적과 범위
|
||||
|
||||
- 목적: 라이브가 비어 있지 않으면 기존 `전체` 항목을 항상 추가하고, 빈 목록·20개 cap·클릭 경로를 유지하는지 확인한다.
|
||||
- 포함: `HomeLiveAdapter`, `HomeMainFragment`의 섹션 표시와 `전체` 클릭 연결, `HomeMainFragmentLayoutTest`, Phase 18 문서.
|
||||
- 제외: 전체 라이브 API·화면, 라이브 item 입장 로직, 기존 프로젝트 전체 lint 부채 수정, 수동 UI 시각 확인.
|
||||
|
||||
## 3. 판정 기준
|
||||
|
||||
빈 목록 0개, 라이브 1~20개는 원본 개수와 `전체` 1개, 21개 이상은 라이브 20개와 `전체` 1개인지 판정했다. 기존 `MoreViewHolder`, 로그인 가드, `HomeOnAirLiveActivity` 이동 경로가 변경되지 않았는지도 대조했다.
|
||||
|
||||
## 4. 검토한 근거
|
||||
|
||||
### 문서와 코드
|
||||
|
||||
- 요구사항: `prd.md:147-154`, `prd.md:526-530`
|
||||
- 계획: `plan-task.md`의 `P18-T1`, `P18-GATE`
|
||||
- 코드: `HomeLiveAdapter.kt:16-55`, `HomeMainFragment.kt:213-219`, `HomeMainFragment.kt:572-575`, `HomeMainFragment.kt:682-685`
|
||||
- 테스트: `HomeMainFragmentLayoutTest.kt:1046-1095`, `HomeMainFragmentLoginGuardSourceTest`
|
||||
|
||||
### 실행 환경
|
||||
|
||||
```text
|
||||
OS: macOS 26.0 (25A354)
|
||||
Java: OpenJDK 17.0.15
|
||||
Gradle wrapper: 8.14.3
|
||||
기준 HEAD: d592038eddce8245e197aef48dbae7c7eb48585a
|
||||
```
|
||||
|
||||
### 실행한 검증
|
||||
|
||||
| 명령 또는 대조 | 결과 | 핵심 증거 |
|
||||
|---|---|---|
|
||||
| `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest" :app:compileDebugKotlin :app:ktlintCheck :app:lintDebug --no-parallel --console=plain` | 일부 성공 / lint 실패 | focused 74 tests 실패·오류 0, compile·ktlint 성공. `lintDebug`는 기존 범위에서 28 errors·767 warnings로 실패 |
|
||||
| `./gradlew :app:testDebugUnitTest --no-parallel --console=plain --rerun-tasks` | 성공 | 162 suites, 1,199 tests, 실패 0·오류 0·skip 0, exit code 0 |
|
||||
| `./gradlew tasks --all --console=plain` | 성공 | `BUILD SUCCESSFUL`, 문서 변경 후 task 인식 확인 |
|
||||
| `git diff --cached --check` 및 `git diff --check` | 성공 | 출력 없음, exit code 0 |
|
||||
| PRD·계획·호출 흐름 정적 대조 | 성공 | 0개 숨김, 20개 cap, 기존 `전체` ViewHolder·로그인 가드·이동 경로 유지 |
|
||||
|
||||
`lintDebug` 첫 오류는 변경되지 않은 `AndroidManifest.xml:316`의 `com.facebook.FacebookActivity` `MissingClass`다. 전체 lint 보고서의 이번 production 변경 파일에는 기존 `notifyDataSetChanged()` warning 1건만 있고, 변경된 줄에 신규 error는 없다.
|
||||
|
||||
## 5. 발견 사항 요약
|
||||
|
||||
확정 발견 사항 없음.
|
||||
|
||||
프로젝트 전체 `lintDebug` 실패는 staged diff에서 추가된 문제가 아니므로 Phase 18 수정 항목으로 전환하지 않는다.
|
||||
|
||||
## 6. 발견 사항 상세
|
||||
|
||||
없음.
|
||||
|
||||
## 7. 확정 항목의 plan·goal 전환
|
||||
|
||||
전환 항목 없음.
|
||||
|
||||
## 8. 리뷰 종료 판정
|
||||
|
||||
| 판정 항목 | 결과 | 근거 |
|
||||
|---|---|---|
|
||||
| 리뷰 범위 전체 확인 | 충족 | 코드·test·PRD·Task와 호출 흐름 대조 완료 |
|
||||
| 후보 항목 판정 완료 | 충족 | 후보 및 확정 발견 사항 없음 |
|
||||
| 확정 항목 plan 반영 | 해당 없음 | 전환할 review ID 없음 |
|
||||
| 보류 항목의 담당·재개 조건 기록 | 해당 없음 | 보류 없음 |
|
||||
| 검증 명령과 결과 기록 | 충족 | focused·전체 unit test·compile·ktlint·lint·diff 결과 기록 |
|
||||
|
||||
**최종 결론:** 확정 발견 사항 없음
|
||||
|
||||
**남은 항목:** Phase 18 범위에는 없음. 프로젝트 전체 `lintDebug` 기존 오류는 별도 작업 범위가 승인될 때 처리한다.
|
||||
|
||||
## 9. 수정 후 검증 기록
|
||||
|
||||
코드 수정 항목 없음.
|
||||
Reference in New Issue
Block a user