Skip to content

[Feat] #283 - 홈화면 컬렉션 섹션 및 전체 컬렉션뷰 구현 - #292

Merged
Guryss merged 25 commits into
developfrom
Feat/#283
Oct 20, 2026
Merged

Guryss merged 25 commits into
developfrom
Feat/#283

Conversation

@Guryss

@Guryss Guryss commented Oct 12, 2026 •

Copy link
Copy Markdown
Member

💡 Issue


💭 Summary

홈 화면에 "컬렉션 모음.zip" 섹션을 추가하고, 섹션 제목에서 들어가는 전체 컬렉션뷰를 구현했어요.

탭바의 My 탭을 가리키는 "나만의 컬렉션을 만들어보세요" 툴팁도 함께 추가했어요.

두 화면 모두 서버의 GET /collections(모든 사용자의 공개 컬렉션 목록)를 사용해요.


🔑 Key Changes

Domain — BaseDomain

  • 툴팁 확인 여부를 저장하려고 기존 1회성 힌트 enum OnboardingHint에 myPageCollectionTooltip 케이스를 추가했어요.
  • 저장소·UseCase는 새로 만들지 않고 그대로 써요. 힌트끼리 서로 영향이 없는지 확인하는 테스트 1건을 추가했어요.

Domain — CollectionDomain

  • 회의 결정에 따라 공개 목록도 기존 CollectionCard를 같이 써요. 사용자별·좋아요·공개 목록이 카드 하나를 공유해요.
  • CollectionCard에 작성자(owner: Author?)와 내 컬렉션 여부(isMine)를 추가했어요.
  • owner는 옵셔널이에요. 사용자별·좋아요 목록 응답에는 소유자 정보가 없어서예요. 서버가 owner를 내려주면 non-optional로 다시 리팩터링할 예정이에요.
  • fetchPublicCollections(cursor:size:)와 LoadPublicCollectionsUseCase, Mock, 테스트 6건을 추가했어요.

Data — CollectionData

  • GET /collections를 연결했어요.
  • 비로그인도 조회할 수 있고 토큰이 있으면 차단한 작성자를 빼는 API라, 인증 정책은 usesTokenIfAvailable로 뒀어요.
  • 응답 구조가 기존 목록과 달라서 PublicCollectionsResponse DTO를 따로 만들었어요(전체 개수·공개 여부·대표 작품 없음, owner 있음).
  • isMine을 판정하려고 Repository가 AppStorage를 받아 로그인 사용자 ID(.userID)를 읽어요. CollectionDataFactory.makeRepository에 appStorage 인자가 추가됐어요.
  • Mapper는 DTO별로 두 개예요.
    • collectionCards: 사용자별·좋아요 목록. 사용자별은 요청한 userID를 소유자로 보고, 좋아요는 소유자를 몰라 nil을 넘겨요.
    • publicCollectionCards: 공개 목록. 응답의 owner.userId로 판정해요.
  • isPrivate은 세 목록 모두 서버의 isPublic을 뒤집은 값 그대로예요. 남의 비공개 컬렉션은 서버가 내려주지 않아요.

Data — AuthData·BaseData

  • 회원 탈퇴에 성공하면 온보딩 힌트 확인 기록을 모두 지워요(DefaultOnboardingHintRepository.resetAll()).
  • 탈퇴 후 재가입은 새 유저라 컬렉션 툴팁·작품 상세 평가 안내를 다시 보여줘요.
  • 로그아웃 후 재로그인은 같은 사람일 가능성이 높아 기록을 유지해요. 두 경우 모두 테스트를 추가했어요.

UI — WSSComponent

  • 컬렉션 표지 스택을 WSSCollectionCoverStack으로 승격했어요. 홈 섹션(4칸)과 목록(5칸)이 함께 써요.
  • 표지 크기를 카드 폭에 비례하게 바꿔서, 어느 기기에서든 같은 비율로 겹치게 했어요.
  • 예전에는 표지 크기가 고정이라 17 Pro Max처럼 넓은 기기에서 표지가 서로 떨어졌어요.
  • "{닉네임}님의 컬렉션" 작성자 라벨(WSSCollectionOwnerLabel)을 추가했어요.

UI — DesignSystem

  • 툴팁 말풍선 에셋(icCollectionTooltip)을 Figma 원본 그대로 추가했어요.

Feature — HomeFeature

  • "컬렉션 모음.zip" 섹션을 추가했어요. 가로 스크롤로 최대 10개, 표지 4칸이에요.
  • 위치는 상세탐색 배너 바로 아래, 오늘의 발견 위예요.
  • 섹션 제목 탭(home_collection_all)과 카드 탭(home_collectionlist)을 Amplitude로 트래킹해요.
  • 0건이거나 불러오기에 실패하면 섹션을 제목까지 숨겨요. 실패해도 홈 전체를 실패 뷰로 덮지 않고 로그만 남겨요.
  • 맨 위 섹션이라 늦게 들어오면 아래 섹션이 전부 밀려요. 그래서 응답을 컬렉션 → 콘텐츠 → 배지 순서로 꺼내, 첫 진입 때 콘텐츠와 같이 그려지게 했어요. 요청은 동시에 보내서 대기 시간은 그대로예요.

Feature — CollectionFeature

  • 전체 컬렉션뷰를 구현했어요. 20개씩 무한 스크롤하고, 당겨서 새로고침하면 햅틱이 울려요.
  • 상세에서 돌아오면 지금까지 받은 개수만큼(최대 100) 다시 받아요. 본인 컬렉션을 수정·삭제한 결과가 반영되고 스크롤 위치도 유지돼요.
  • 이 자동 갱신은 실패해도 보던 목록을 그대로 둬요. 사용자가 직접 당긴 새로고침은 지금처럼 실패 뷰를 보여줘요.
  • 컬렉션 목록 카드 헤더를 CollectionCardHeader로 추출해 전체 컬렉션뷰와 함께 써요.

App

  • 홈 → 전체 컬렉션뷰 → 컬렉션 상세 화면 전환을 연결했어요(PublicCollectionListAssembly).
  • "나만의 컬렉션을 만들어보세요" 툴팁을 추가했어요(CollectionTooltip, MainTabView).
    • 앱을 켤 때 아직 확인하지 않았으면 떠요. 홈·피드·서재 탭을 오가도 유지돼요.
    • 툴팁이 떠 있을 때 My 탭을 누르면 확인 처리되고, 이후로는 뜨지 않아요. 툴팁이 없을 때 누른 My 탭은 확인으로 치지 않아요.
    • 확인하지 않고 앱을 끄면 다음 실행 때 다시 떠요.
    • 각 탭의 첫 화면에 붙여서, 탭바가 숨는 push 화면에서는 보이지 않아요.
    • iOS 26 탭바는 화면 양옆에서 들어와 떠 있어서 Figma의 고정 여백으로는 꼬리가 My에서 벗어났어요. 화면 너비로 My 탭 중심을 계산해 꼬리를 맞췄어요.

📱 Simulation

홈 "컬렉션 모음.zip" 전체 컬렉션뷰
(첨부) (첨부)

🧑‍🧒‍🧒 To Reviewer

확인한 범위

  • Demo(Mock)로 17 Pro Max·13 mini에서 표지 겹침, 무한 스크롤, 상세 복귀 동작을 확인했어요.
  • dev 서버를 비로그인으로 호출해 응답 구조가 DTO와 맞는지 확인했어요.
  • 로그인 상태의 실서버 화면 흐름은 테스트 토큰이 만료돼 확인하지 못했어요. 로그인한 실기기에서 한 번 봐주세요.

봐주셨으면 하는 부분

  • 툴팁 꼬리 위치는 iOS 26 17 Pro Max에서만 실측했어요. iOS 18 이하와 다른 화면 너비에서 꼬리가 My를 잘 가리키는지 봐주세요.
  • 툴팁의 탭 전환·push 숨김·My 확인 처리 흐름은 디버그 TestFlight(1.10.3, 빌드 2026101701)로 확인 중이에요. 버전 번호는 아직 정해지지 않아 이 PR에는 버전 변경을 넣지 않았어요.
  • 표지가 카드 폭에 비례해서, 기존 마이페이지 컬렉션 목록 카드도 넓은 기기에서 표지가 조금 커져요(의도한 변경이에요).
  • 좋아요 목록은 응답에 소유자 정보가 없어서, 내 컬렉션에 좋아요를 눌렀어도 isMine이 false로 남아요. 지금은 이 값을 쓰는 화면이 없어요. 서버에 owner 추가를 요청할 때 함께 해결하려고 해요.
  • 홈 컬렉션 섹션에 Amplitude 이벤트를 추가했어요. 섹션 제목 탭은 home_collection_all, 카드 탭은 home_collectionlist예요. 원본 이벤트 리스트에 없는 이벤트라 기존 홈 이벤트 패턴(home_<섹션>_<대상>)으로 이름을 지었어요. 이 이름이 괜찮은지 봐주세요. 전체 컬렉션뷰에는 아직 이벤트를 걸지 않았어요.

※ Reference

🤖 Generated with Claude Code

Guryss and others added 16 commits October 12, 2026 14:29
작성자(owner)를 함께 보여줘야 해서 CollectionCard에 얹지 않고 PublicCollectionCard를 따로 둔다.
서버(GET /collections)가 전체 개수를 주지 않아 다른 목록과 달리 커서 페이지만 돌려준다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GET /collections는 비로그인도 조회할 수 있고 토큰이 있으면 차단 작성자를 빼므로 usesTokenIfAvailable로 둔다.
응답에 collectionsCount·isPublic·대표 작품이 없고 owner가 있어 CollectionsResponse를 재사용하지 않고 DTO를 분리했다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
홈 컬렉션 섹션(4칸)이 컬렉션 목록(5칸)과 같은 표지 겹침 스택을 써야 해서 슬롯 수를 인자로 받게 옮겼다.
WSSComponent는 BaseDomain까지만 알아 CollectionNovel 대신 표지 URL 배열을 받는다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
전체 컬렉션뷰 카드가 컬렉션 목록 카드와 같은 제목·"설명 · 작품 N" 헤더를 쓴다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
모든 사용자의 공개 컬렉션을 최신순 무한 스크롤로 보여주고, 당겨서 새로고침에 햅틱을 건다.
실패는 첫 페이지·더보기·새로고침 모두 NetworkErrorView로 표현한다(Feature 로드 실패 표현 계약).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
공개 컬렉션 첫 페이지(size 10)를 가로 스크롤 카드로 보여주고, 0건이면 제목까지 숨긴다.
배지와 같은 부수 콘텐츠라 실패해도 홈을 실패 뷰로 덮지 않고 로그만 남긴다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
표지 크기를 74×108로 고정한 채 간격만 역산해, 카드가 넓은 기기(17 Pro Max 5칸)에서 간격이 양수가 돼 표지가 떨어졌다.
Figma 겹침 비율(58/74)을 고정하고 표지 크기를 카드 폭에 비례시키는 Layout으로 바꿔 기기와 무관하게 같은 모양으로 겹친다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
공개 목록에 본인 공개 컬렉션도 섞여, 상세에서 수정·삭제·비공개 전환한 카드가 복귀 후에도 남았다.
CollectionListView와 같이 hasAppearedOnce로 복귀를 감지해 목록을 비우지 않고 첫 페이지로 교체한다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
컬렉션은 추천글과 선호장르 사이에 끼어드는 섹션이라, 배지 응답까지 기다리면 첫 진입 때 선호장르가 더 늦게 밀려난다.
배지는 헤더의 점 하나라 늦어도 레이아웃이 움직이지 않아 뒤로 뺐다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
첫 페이지(20개)만 다시 받으면 깊이 스크롤한 뒤 복귀할 때 목록이 잘려 위치가 튀었다.
지금까지 받은 개수만큼(서버 size 상한 100) 다시 받고, 사용자가 누르지 않은 갱신이라 실패하면 직전 목록을 유지한다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
동기화는 목록 길이와 마지막 카드를 유지해 마지막 셀의 onAppear가 다시 불리지 않으므로, 그동안 막힌 더보기를 버리면 하단에서 무한 스크롤이 멈췄다.
동기화 중 들어온(또는 동기화가 취소한) 더보기를 기억했다가 동기화가 끝나면 이어서 부른다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Guryss Guryss self-assigned this Oct 12, 2026
@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

테스트 커버리지 리포트

Module Coverage
AuthData 55.4%
AuthDomain 98.2%
BaseDomain 70.3%
CollectionDomain 98.4%
CollectionFeature 0.0%
CommentData 0.0%
CommentDomain 94.9%
FeedData 62.8%
FeedDomain 98.7%
HomeFeature 0.0%
LibraryFeature 0.0%
NotificationData 33.9%
NotificationDomain 100.0%
NotificationFeature 0.0%
NovelData 15.4%
NovelDetailFeature 0.0%
NovelDomain 92.9%
NovelReviewData 77.4%
NovelReviewDomain 96.8%
NovelReviewFeature 5.3%
ProfileData 46.1%
ProfileDomain 97.1%
RecommendationData 54.7%
RecommendationDomain 91.7%
SearchData 5.1%
SearchDomain 100.0%
SettingData 31.1%
SettingDomain 99.0%
SocialData 53.4%
SocialDomain 87.5%
SplashData 77.1%
SplashDomain 95.5%
SplashFeature 32.9%

Generated by CI on 2026-10-20 18:54 KST

Guryss and others added 5 commits October 12, 2026 15:43
표지를 maxWidth/maxHeight만 준 flexible frame으로 감싸 자식 크기가 하한이 되면서, scaledToFill 표지가 비율만큼 칸 밖으로 넘쳤다(세로로 긴 표지는 아래로, 가로로 긴 표지는 옆 칸으로).
WSSNovelCoverImage의 aspectRatio로 칸을 비율 고정·클립하고, 재현되도록 홈 Demo Mock 표지 비율을 섞었다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Guryss and others added 4 commits October 17, 2026 11:07
탈퇴 후 재가입은 새 유저라 컬렉션 툴팁·작품 상세 평가 안내를 다시 보여준다.
로그아웃/재로그인은 같은 사람일 가능성이 높아 기록을 유지한다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
회의 결정에 따라 사용자별·좋아요·공개 목록이 카드 하나를 공유한다.
owner는 사용자별·좋아요 목록 응답에 없어 옵셔널로 두고(서버가 주면 재리팩터링),
isMine은 로그인 ID(AppStorage .userID)와 소유자 ID를 비교해 Mapper에서 판정한다.
좋아요 목록은 소유자를 몰라 isMine이 false로 남는 한계를 문서에 기록했다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
원본 이벤트 리스트에 이 섹션 이벤트가 없어 기존 홈 이벤트 패턴으로 이름을 정했다
(제목 home_collection_all, 카드 home_collectionlist).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Guryss
Guryss merged commit b65354c into develop Oct 20, 2026
38 checks passed
@Guryss
Guryss deleted the Feat/#283 branch October 20, 2026 10:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] 홈화면 컬렉션 섹션 및 전체 컬렉션뷰 구현

1 participant