diff --git a/SodaLive/Sources/Live/Room/Chat/LiveRoomChatItemView.swift b/SodaLive/Sources/Live/Room/Chat/LiveRoomChatItemView.swift index 1a9daee..0f15838 100644 --- a/SodaLive/Sources/Live/Room/Chat/LiveRoomChatItemView.swift +++ b/SodaLive/Sources/Live/Room/Chat/LiveRoomChatItemView.swift @@ -12,40 +12,48 @@ struct LiveRoomChatItemView: View { let chatMessage: LiveRoomNormalChat let onClickProfile: () -> Void + + private var rankValue: Int { + chatMessage.rank + 1 + } + + private var isTopRank: Bool { + (1...3).contains(rankValue) + } + + private var topRankCrownImageName: String? { + switch rankValue { + case 1: + return "img_rank_1" + case 2: + return "img_rank_2" + case 3: + return "img_rank_3" + default: + return nil + } + } var body: some View { HStack(alignment: .top, spacing: 13.3) { ZStack { - switch chatMessage.rank + 1 { - case -2: - Color(hex: "4999e3") - .frame(width: 33.3, height: 33.3, alignment: .top) - .clipShape(Circle()) - - case -1: - Color.button - .frame(width: 33.3, height: 33.3, alignment: .top) - .clipShape(Circle()) - - case 1: - Color(hex: "fdca2f") - .frame(width: 33.3, height: 33.3, alignment: .top) - .clipShape(Circle()) - - case 2: - Color(hex: "dcdcdc") - .frame(width: 33.3, height: 33.3, alignment: .top) - .clipShape(Circle()) - - case 3: - Color(hex: "c67e4a") - .frame(width: 33.3, height: 33.3, alignment: .top) - .clipShape(Circle()) - - default: - Color(hex: "bbbbbb") - .frame(width: 33.3, height: 33.3, alignment: .top) - .clipShape(Circle()) + if !isTopRank { + switch rankValue { + case -2: + Color(hex: "4999e3") + .frame(width: 33.3, height: 33.3, alignment: .top) + .clipShape(Circle()) + + case -1: + Color.button + .frame(width: 33.3, height: 33.3, alignment: .top) + .clipShape(Circle()) + + default: + Color(hex: "bbbbbb") + .frame(width: 33.3, height: 33.3, alignment: .top) + .clipShape(Circle()) + } } KFImage(URL(string: chatMessage.profileUrl)) @@ -60,42 +68,36 @@ struct LiveRoomChatItemView: View { .scaledToFill() .frame(width: 30, height: 30, alignment: .top) .clipShape(Circle()) - - VStack(alignment: .trailing, spacing: 0) { - Spacer() - - switch chatMessage.rank + 1 { - case -2: - Image("ic_badge_manager") + + if isTopRank { + if let topRankCrownImageName { + Image(topRankCrownImageName) .resizable() - .frame(width: 16.7, height: 16.7) - - case -1: - Image("ic_crown") - .resizable() - .frame(width: 16.7, height: 16.7) - - case 1: - Image("ic_crown_1") - .resizable() - .frame(width: 16.7, height: 16.7) - - case 2: - Image("ic_crown_2") - .resizable() - .frame(width: 16.7, height: 16.7) - - case 3: - Image("ic_crown_3") - .resizable() - .frame(width: 16.7, height: 16.7) - - default: - EmptyView() + .frame(width: 39, height: 38) } + } else { + VStack(alignment: .trailing, spacing: 0) { + Spacer() + + switch rankValue { + case -2: + Image("ic_badge_manager") + .resizable() + .frame(width: 16.7, height: 16.7) + + case -1: + Image("ic_crown") + .resizable() + .frame(width: 16.7, height: 16.7) + + default: + EmptyView() + } + } + .frame(width: 33.3, height: 33.3, alignment: .trailing) } - .frame(width: 33.3, height: 33.3, alignment: .trailing) } + .frame(width: isTopRank ? 39 : 33.3, height: isTopRank ? 38 : 33.3) .onTapGesture { onClickProfile() } VStack(alignment: .leading, spacing: 6.7) { diff --git a/docs/20260318_라이브채팅순위왕관이미지변경.md b/docs/20260318_라이브채팅순위왕관이미지변경.md new file mode 100644 index 0000000..38f3269 --- /dev/null +++ b/docs/20260318_라이브채팅순위왕관이미지변경.md @@ -0,0 +1,21 @@ +# 라이브 채팅 순위 왕관 이미지 변경 + +- [x] `LiveRoomChatItemView`의 1~3위 왕관 asset을 `img_rank_1~3`으로 변경한다. + - QA: 1~3위 분기에서 `Image("img_rank_1")`, `Image("img_rank_2")`, `Image("img_rank_3")` 사용 여부 코드 확인. +- [x] 1~3위 왕관 표시 시 프로필 영역을 39x38로 조정하고 왕관이 프로필을 감싸도록 오버레이 구조로 변경한다. + - QA: 1~3위 분기에서 컨테이너/왕관 프레임이 `39x38`로 적용되고 배경 색상 원형이 제거되었는지 코드 확인. +- [x] `-2`, `-1` 케이스는 기존 배경 + 우측 하단 배지(16.7) 동작을 유지한다. + - QA: `ic_badge_manager`, `ic_crown` 분기와 `.frame(width: 16.7, height: 16.7)` 유지 여부 코드 확인. +- [x] 변경 파일 진단 및 빌드 검증을 수행한다. + - QA: `lsp_diagnostics`, `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build` 결과 확인. + +--- + +## 검증 기록 + +- 코드 변경: `SodaLive/Sources/Live/Room/Chat/LiveRoomChatItemView.swift`에서 `rankValue`, `isTopRank`, `topRankCrownImageName`을 추가하고, 1~3위는 `Image("img_rank_1~3")`를 `39x38`로 오버레이하여 프로필(30x30)을 감싸도록 수정. +- 코드 변경: 1~3위 분기에서는 기존 배경 원(`fdca2f`, `dcdcdc`, `c67e4a`)과 우측 하단 소형 왕관(`ic_crown_1~3`) 표시를 제거. +- 코드 확인: `-2`, `-1`은 기존 원형 배경(`4999e3`, `Color.button`) + 우측 하단 배지(`ic_badge_manager`, `ic_crown`, `16.7x16.7`)를 유지. +- 진단 확인: `lsp_diagnostics` 실행 시 `No such module 'Kingfisher'`가 표시됨. 동일 import를 가진 `SodaLive/Sources/Home/HomeCreatorRankingItemView.swift`에서도 동일 진단 재현되어 로컬 SourceKit 환경 이슈로 기록. +- 빌드 검증: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build` 실행 결과 `** BUILD SUCCEEDED **` 확인. +- 테스트 검증: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -destination "platform=iOS Simulator,name=iPhone 16,OS=18.3.1" test` 실행 결과 `Scheme SodaLive is not currently configured for the test action.` 확인.