fix(live-room): 라이브 상세 SNS 링크 아이콘 매핑을 신규 필드에 맞춘다
This commit is contained in:
@@ -32,8 +32,9 @@ struct GetRoomDetailManager: Decodable {
|
|||||||
let introduce: String
|
let introduce: String
|
||||||
let youtubeUrl: String?
|
let youtubeUrl: String?
|
||||||
let instagramUrl: String?
|
let instagramUrl: String?
|
||||||
let websiteUrl: String?
|
let fancimmUrl: String?
|
||||||
let blogUrl: String?
|
let xUrl: String?
|
||||||
|
let kakaoOpenChatUrl: String?
|
||||||
let profileImageUrl: String
|
let profileImageUrl: String
|
||||||
let isCreator: Bool
|
let isCreator: Bool
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,46 +152,20 @@ struct LiveDetailView: View {
|
|||||||
.clipShape(Circle())
|
.clipShape(Circle())
|
||||||
|
|
||||||
VStack(spacing: 16.7) {
|
VStack(spacing: 16.7) {
|
||||||
HStack(spacing: 6.7) {
|
HStack(spacing: 8) {
|
||||||
Text(manager.nickname)
|
Text(manager.nickname)
|
||||||
.appFont(size: 16.7, weight: .medium)
|
.appFont(size: 16.7, weight: .medium)
|
||||||
.foregroundColor(Color(hex: "eeeeee"))
|
.foregroundColor(Color(hex: "eeeeee"))
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
if let websiteUrl = manager.websiteUrl, let url = URL(string: websiteUrl), UIApplication.shared.canOpenURL(url) {
|
ForEach(makeSnsItems(from: manager)) { item in
|
||||||
Image("ic_website_blue")
|
Image(item.iconName)
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(width: 33.3, height: 33.3)
|
.frame(width: 33.3, height: 33.3)
|
||||||
|
.contentShape(Rectangle())
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
UIApplication.shared.open(url)
|
openSnsLink(item.url)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let blogUrl = manager.blogUrl, let url = URL(string: blogUrl), UIApplication.shared.canOpenURL(url) {
|
|
||||||
Image("ic_blog_blue")
|
|
||||||
.resizable()
|
|
||||||
.frame(width: 33.3, height: 33.3)
|
|
||||||
.onTapGesture {
|
|
||||||
UIApplication.shared.open(url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let instagramUrl = manager.instagramUrl, let url = URL(string: instagramUrl), UIApplication.shared.canOpenURL(url) {
|
|
||||||
Image("ic_instagram_blue")
|
|
||||||
.resizable()
|
|
||||||
.frame(width: 33.3, height: 33.3)
|
|
||||||
.onTapGesture {
|
|
||||||
UIApplication.shared.open(url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let youtubeUrl = manager.youtubeUrl, let url = URL(string: youtubeUrl), UIApplication.shared.canOpenURL(url) {
|
|
||||||
Image("ic_youtube_play_blue")
|
|
||||||
.resizable()
|
|
||||||
.frame(width: 33.3, height: 33.3)
|
|
||||||
.onTapGesture {
|
|
||||||
UIApplication.shared.open(url)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -494,4 +468,59 @@ struct LiveDetailView: View {
|
|||||||
AppState.shared.back()
|
AppState.shared.back()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func makeSnsItems(from manager: GetRoomDetailManager) -> [LiveDetailSnsItem] {
|
||||||
|
var items = [LiveDetailSnsItem]()
|
||||||
|
|
||||||
|
appendSnsItem(items: &items, iconName: "ic_sns_youtube", url: manager.youtubeUrl)
|
||||||
|
appendSnsItem(items: &items, iconName: "ic_sns_instagram", url: manager.instagramUrl)
|
||||||
|
appendSnsItem(items: &items, iconName: "ic_sns_x", url: manager.xUrl)
|
||||||
|
appendSnsItem(items: &items, iconName: "ic_sns_fancimm", url: manager.fancimmUrl)
|
||||||
|
appendSnsItem(items: &items, iconName: "ic_sns_kakao", url: manager.kakaoOpenChatUrl)
|
||||||
|
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
|
||||||
|
private func appendSnsItem(items: inout [LiveDetailSnsItem], iconName: String, url: String?) {
|
||||||
|
guard let url else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let trimmed = url.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
|
||||||
|
guard !trimmed.isEmpty else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
items.append(LiveDetailSnsItem(iconName: iconName, url: trimmed))
|
||||||
|
}
|
||||||
|
|
||||||
|
private func openSnsLink(_ urlString: String) {
|
||||||
|
guard let url = normalizedUrl(urlString), UIApplication.shared.canOpenURL(url) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
UIApplication.shared.open(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func normalizedUrl(_ urlString: String) -> URL? {
|
||||||
|
let trimmed = urlString.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
|
||||||
|
guard !trimmed.isEmpty else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if trimmed.hasPrefix("http://") || trimmed.hasPrefix("https://") {
|
||||||
|
return URL(string: trimmed)
|
||||||
|
}
|
||||||
|
|
||||||
|
return URL(string: "https://\(trimmed)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct LiveDetailSnsItem: Identifiable {
|
||||||
|
let iconName: String
|
||||||
|
let url: String
|
||||||
|
|
||||||
|
var id: String { "\(iconName)-\(url)" }
|
||||||
}
|
}
|
||||||
|
|||||||
70
docs/20260324_라이브상세SNS아이콘적용.md
Normal file
70
docs/20260324_라이브상세SNS아이콘적용.md
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# 20260324 라이브 상세 SNS 아이콘 적용
|
||||||
|
|
||||||
|
## 작업 항목
|
||||||
|
- [x] `LiveDetailView` SNS 영역 아이콘을 `CreatorDetailDialogView`에서 사용하는 SNS 아이콘 에셋으로 변경
|
||||||
|
- QA: `instagram`, `fancimm`, `x`, `youtube`, `kakaoOpenChat` URL이 유효할 때만 아이콘이 표시된다.
|
||||||
|
- [x] `GetRoomDetailManager` 신규 SNS 필드(`youtube`, `instagram`, `x`, `fancimm`, `kakaoOpenChat`)를 모두 라이브 상세 SNS 영역에 반영
|
||||||
|
- QA: 5개 SNS가 누락 없이 표시 대상에 포함된다.
|
||||||
|
- [x] SNS 아이콘 크기를 기존과 동일하게 유지
|
||||||
|
- QA: 아이콘 `frame(width: 33.3, height: 33.3)`를 유지한다.
|
||||||
|
|
||||||
|
## 검증 항목
|
||||||
|
- [x] `lsp_diagnostics`로 변경 파일 오류 확인
|
||||||
|
- [x] `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build` 실행
|
||||||
|
|
||||||
|
## 검증 기록
|
||||||
|
- 일시: 2026-03-24
|
||||||
|
- 무엇: `LiveDetailView` SNS 아이콘 영역 변경 후 정적 진단
|
||||||
|
- 왜: 변경 파일의 컴파일/타입 문제 확인
|
||||||
|
- 어떻게: LSP 진단 실행
|
||||||
|
- 실행 명령: `lsp_diagnostics(filePath: SodaLive/Sources/Live/Room/Detail/LiveDetailView.swift)`
|
||||||
|
- 결과: `No such module 'Kingfisher'` 1건 확인(로컬 SourceKit 인덱싱 환경 이슈로 판단, 코드 문법 오류는 확인되지 않음)
|
||||||
|
|
||||||
|
- 일시: 2026-03-24
|
||||||
|
- 무엇: 앱 빌드 검증
|
||||||
|
- 왜: 수정 사항이 실제 프로젝트 빌드에 문제 없는지 확인
|
||||||
|
- 어떻게: Debug 빌드 수행
|
||||||
|
- 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build`
|
||||||
|
- 결과: `** BUILD SUCCEEDED **`
|
||||||
|
|
||||||
|
- 일시: 2026-03-24
|
||||||
|
- 무엇: 테스트 실행 가능 여부 확인
|
||||||
|
- 왜: 변경 후 회귀 테스트 수행 시도
|
||||||
|
- 어떻게: 스킴 test 액션 실행
|
||||||
|
- 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" test`
|
||||||
|
- 결과: `Scheme SodaLive is not currently configured for the test action.` (현재 스킴 테스트 미구성)
|
||||||
|
|
||||||
|
- 일시: 2026-03-24
|
||||||
|
- 무엇: 최종 수정(들여쓰기 정리) 후 재빌드 확인
|
||||||
|
- 왜: 최종 상태 기준으로 컴파일 성공 재확인
|
||||||
|
- 어떻게: Debug 빌드 재실행
|
||||||
|
- 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build`
|
||||||
|
- 결과: `** BUILD SUCCEEDED **`
|
||||||
|
|
||||||
|
- 일시: 2026-03-24
|
||||||
|
- 무엇: 최종 수정 후 테스트 액션 재확인
|
||||||
|
- 왜: 최종 상태 기준 테스트 가능 여부 재확인
|
||||||
|
- 어떻게: 스킴 test 액션 재실행
|
||||||
|
- 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" test`
|
||||||
|
- 결과: `Scheme SodaLive is not currently configured for the test action.` (현재 스킴 테스트 미구성)
|
||||||
|
|
||||||
|
- 일시: 2026-03-24
|
||||||
|
- 무엇: SNS 매핑/크기 수동 QA(정적 확인)
|
||||||
|
- 왜: 요청한 5개 SNS 반영 및 아이콘 크기 유지 여부를 최종 확인
|
||||||
|
- 어떻게: 소스 패턴 검색으로 매핑 개수와 뷰 프레임 확인
|
||||||
|
- 실행 명령: `grep count: appendSnsItem(... "ic_sns_", ...)`, `grep content: ForEach(makeSnsItems...), .frame(width: 33.3, height: 33.3)`
|
||||||
|
- 결과: `appendSnsItem` 5건 확인, SNS 렌더링 `ForEach` + `frame(width: 33.3, height: 33.3)` 확인
|
||||||
|
|
||||||
|
- 일시: 2026-03-24
|
||||||
|
- 무엇: SNS 순서 정리 후 최종 빌드
|
||||||
|
- 왜: 최종 코드 기준 컴파일 성공 여부 확정
|
||||||
|
- 어떻게: Debug 빌드 재실행
|
||||||
|
- 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build`
|
||||||
|
- 결과: `** BUILD SUCCEEDED **`
|
||||||
|
|
||||||
|
- 일시: 2026-03-24
|
||||||
|
- 무엇: SNS 순서 정리 후 최종 테스트 액션 확인
|
||||||
|
- 왜: 최종 코드 기준 테스트 실행 가능 여부 확정
|
||||||
|
- 어떻게: 스킴 test 액션 재실행
|
||||||
|
- 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" test`
|
||||||
|
- 결과: `Scheme SodaLive is not currently configured for the test action.` (현재 스킴 테스트 미구성)
|
||||||
Reference in New Issue
Block a user