diff --git a/SodaLive/Sources/Content/Create/ContentCreateView.swift b/SodaLive/Sources/Content/Create/ContentCreateView.swift index 769f431..c048c89 100644 --- a/SodaLive/Sources/Content/Create/ContentCreateView.swift +++ b/SodaLive/Sources/Content/Create/ContentCreateView.swift @@ -24,6 +24,14 @@ struct ContentCreateView: View { @State private var isShowSelectTimeView = false var body: some View { + let normalizedCountryCode = UserDefaults + .string(forKey: .countryCode) + .trimmingCharacters(in: .whitespacesAndNewlines) + .uppercased() + let isKoreanCountry = normalizedCountryCode.isEmpty || normalizedCountryCode == "KR" + let isAdultContentVisible = UserDefaults.isAdultContentVisible() + let shouldShowAdultSetting = isAdultContentVisible && (!isKoreanCountry || UserDefaults.bool(forKey: .auth)) + BaseView(isLoading: $viewModel.isLoading) { GeometryReader { proxy in ZStack { @@ -448,34 +456,36 @@ struct ContentCreateView: View { .padding(.top, 26.7) .padding(.horizontal, 13.3) - VStack(spacing: 13.3) { - Text("연령 제한") - .appFont(size: 16.7, weight: .bold) - .foregroundColor(Color.grayee) - .frame(maxWidth: .infinity, alignment: .leading) - - HStack(spacing: 13.3) { - SelectButtonView(title: I18n.CreateContent.allAges, isChecked: !viewModel.isAdult) { - if viewModel.isAdult { - viewModel.isAdult = false - } - } - - SelectButtonView(title: I18n.CreateContent.over19, isChecked: viewModel.isAdult) { - if !viewModel.isAdult { - viewModel.isAdult = true + if shouldShowAdultSetting { + VStack(spacing: 13.3) { + Text("연령 제한") + .appFont(size: 16.7, weight: .bold) + .foregroundColor(Color.grayee) + .frame(maxWidth: .infinity, alignment: .leading) + + HStack(spacing: 13.3) { + SelectButtonView(title: I18n.CreateContent.allAges, isChecked: !viewModel.isAdult) { + if viewModel.isAdult { + viewModel.isAdult = false + } + } + + SelectButtonView(title: I18n.CreateContent.over19, isChecked: viewModel.isAdult) { + if !viewModel.isAdult { + viewModel.isAdult = true + } } } + + Text("성인콘텐츠를 전체관람가로 등록할 시 발생하는 법적 책임은 회사와 상관없이 콘텐츠를 등록한 본인에게 있습니다.\n콘텐츠 내용은 물론 제목도 19금 여부를 체크해 주시기 바랍니다.") + .appFont(size: 13.3, weight: .medium) + .foregroundColor(Color.mainRed3) + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.top, 13.3) } - - Text("성인콘텐츠를 전체관람가로 등록할 시 발생하는 법적 책임은 회사와 상관없이 콘텐츠를 등록한 본인에게 있습니다.\n콘텐츠 내용은 물론 제목도 19금 여부를 체크해 주시기 바랍니다.") - .appFont(size: 13.3, weight: .medium) - .foregroundColor(Color.mainRed3) - .frame(maxWidth: .infinity, alignment: .leading) - .padding(.top, 13.3) + .padding(.top, 26.7) + .padding(.horizontal, 13.3) } - .padding(.top, 26.7) - .padding(.horizontal, 13.3) VStack(spacing: 13.3) { Text("댓글 가능 여부") diff --git a/SodaLive/Sources/Live/Room/Create/LiveRoomCreateView.swift b/SodaLive/Sources/Live/Room/Create/LiveRoomCreateView.swift index db8a7ed..3b1a206 100644 --- a/SodaLive/Sources/Live/Room/Create/LiveRoomCreateView.swift +++ b/SodaLive/Sources/Live/Room/Create/LiveRoomCreateView.swift @@ -33,6 +33,14 @@ struct LiveRoomCreateView: View { } var body: some View { + let normalizedCountryCode = UserDefaults + .string(forKey: .countryCode) + .trimmingCharacters(in: .whitespacesAndNewlines) + .uppercased() + let isKoreanCountry = normalizedCountryCode.isEmpty || normalizedCountryCode == "KR" + let isAdultContentVisible = UserDefaults.isAdultContentVisible() + let shouldShowAdultSetting = isAdultContentVisible && (!isKoreanCountry || UserDefaults.bool(forKey: .auth)) + BaseView(isLoading: $viewModel.isLoading) { GeometryReader { proxy in ZStack { @@ -175,7 +183,7 @@ struct LiveRoomCreateView: View { .frame(width: screenSize().width - 26.7) .padding(.top, 33.3) - if UserDefaults.bool(forKey: .auth) { + if shouldShowAdultSetting { AdultSettingView() .frame(width: screenSize().width - 26.7) .padding(.top, 33.3) diff --git a/docs/20260327_라이브생성콘텐츠업로드연령제한표시조건수정.md b/docs/20260327_라이브생성콘텐츠업로드연령제한표시조건수정.md new file mode 100644 index 0000000..38114e4 --- /dev/null +++ b/docs/20260327_라이브생성콘텐츠업로드연령제한표시조건수정.md @@ -0,0 +1,67 @@ +# 20260327 라이브 생성·콘텐츠 업로드 연령제한 표시 조건 수정 + +## 개요 +- 라이브 생성 페이지와 콘텐츠 업로드 페이지의 연령제한 설정 UI 표시 조건을 정책에 맞게 통일한다. +- 표시 조건은 `isAdultContentVisible`를 필수로 하고, 접속국가가 한국(`KR` 또는 빈값)일 때만 `isAuth`를 추가로 요구한다. + +## 요구사항 요약 +- 대상 화면: + - 라이브 생성 (`LiveRoomCreateView`) + - 콘텐츠 업로드 (`ContentCreateView`) +- 표시 조건: + - 필수: `isAdultContentVisible == true` + - 추가: 접속국가가 한국이면 `isAuth == true` + +## 완료 기준 (Acceptance Criteria) +- [x] AC1: 라이브 생성 화면 연령제한 설정 UI가 `isAdultContentVisible == true`일 때만 표시된다. +- [x] AC2: 라이브 생성 화면에서 접속국가가 한국이면 `isAuth == true`일 때만 연령제한 설정 UI가 표시된다. +- [x] AC3: 콘텐츠 업로드 화면 연령제한 설정 UI가 동일 조건(`isAdultContentVisible` 필수 + 한국일 때 `isAuth` 추가)으로 표시된다. +- [x] AC4: 국가코드 판별은 기존 관례(공백 제거 + 대문자, 빈값은 한국 취급)를 따른다. +- [x] AC5: 수정 파일 진단, 빌드/테스트 결과와 한계를 문서 하단 검증 기록에 남긴다. + +## 구현 체크리스트 +- [x] 라이브 생성/콘텐츠 업로드 기존 UI 분기 코드 위치 확인 +- [x] 공통 표시 조건 계산식 정의 (`isAdultContentVisible`, `isKoreanCountry`, `isAuth`) +- [x] 라이브 생성 화면 조건 적용 +- [x] 콘텐츠 업로드 화면 조건 적용 +- [x] 수정 파일 진단 및 워크스페이스 빌드/테스트 실행 +- [x] 문서 체크리스트/검증 기록 업데이트 + +## 검증 계획 +- [x] 정적 진단: `lsp_diagnostics` (수정 파일 전체) +- [x] 빌드: + - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build` + - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build` +- [x] 테스트 시도: + - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" test` + - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" test` + +## 검증 기록 +- 일시: 2026-03-27 + - 무엇: 라이브 생성/콘텐츠 업로드 연령제한 UI 표시 조건 수정 계획 문서 작성 + - 왜: 구현 범위와 완료 기준을 먼저 고정해 요청된 조건만 정확히 반영하기 위함 + - 어떻게: docs 규칙에 맞춰 요구사항, 완료 기준, 검증 계획을 체크리스트로 문서화 + - 실행 명령/도구: `apply_patch(문서 생성)` + - 결과: 계획 문서 생성 완료 + +- 일시: 2026-03-27 + - 무엇: 라이브 생성/콘텐츠 업로드 연령제한 UI 표시 조건을 국가/설정 기반으로 수정 및 검증 + - 왜: 기존 조건(인증 기반 또는 무조건 노출)을 정책(`isAdultContentVisible` 필수 + 한국일 때 `isAuth` 필수)과 일치시키기 위함 + - 어떻게: + - `LiveRoomCreateView`에 `isKoreanCountry`, `isAdultContentVisible`, `shouldShowAdultSetting` 계산 추가 후 `AdultSettingView` 표시 분기 교체 + - `ContentCreateView`에 동일 계산 추가 후 연령 제한 섹션 전체를 `if shouldShowAdultSetting`으로 감싸 조건부 렌더링 적용 + - 국가코드는 기존 관례대로 `trim + uppercased`, 빈값은 한국 취급 + - 실행 명령/도구: + - 진단: `lsp_diagnostics(LiveRoomCreateView.swift)`, `lsp_diagnostics(ContentCreateView.swift)` + - 빌드: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build`, `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build` + - 테스트 시도: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" test`, `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" test` + - 로직 수동 검증(CLI): `xcrun swift -e "import Foundation; ... shouldShow(...) ..."` + - 결과: + - 두 스킴 Debug 빌드 모두 `** BUILD SUCCEEDED **` + - 테스트는 두 스킴 모두 `Scheme ... is not currently configured for the test action`으로 실행 불가 + - `lsp_diagnostics`는 SourceKit 환경에서 `No such module 'Kingfisher'`를 보고하지만, 실제 xcodebuild 통과로 컴파일 정상 확인 + - CLI 로직 검증 출력: + - `KR + visible=true + auth=true => true` + - `KR + visible=true + auth=false => false` + - `US + visible=true + auth=false => true` + - `US + visible=false + auth=true => false`