라이브 성별 제한 옵션 추가
라이브 생성과 수정 요청에 성별 제한 값을 포함한다. 라이브 정보 조회 응답에 성별 제한 값을 제공한다.
This commit is contained in:
@@ -672,6 +672,12 @@ enum I18n {
|
|||||||
static var allAges: String { pick(ko: "전체 연령", en: "All ages", ja: "全年齢") }
|
static var allAges: String { pick(ko: "전체 연령", en: "All ages", ja: "全年齢") }
|
||||||
static var over19: String { pick(ko: "19세 이상", en: "19+", ja: "R-18") }
|
static var over19: String { pick(ko: "19세 이상", en: "19+", ja: "R-18") }
|
||||||
|
|
||||||
|
// 성별 제한
|
||||||
|
static var genderRestrictionTitle: String { pick(ko: "성별 제한", en: "Gender restriction", ja: "性別制限") }
|
||||||
|
static var genderAll: String { pick(ko: "전체", en: "All", ja: "全体") }
|
||||||
|
static var genderMaleOnly: String { pick(ko: "남자만", en: "Male only", ja: "男性のみ") }
|
||||||
|
static var genderFemaleOnly: String { pick(ko: "여자만", en: "Female only", ja: "女性のみ") }
|
||||||
|
|
||||||
// 최근 데이터 관련 토스트/알림
|
// 최근 데이터 관련 토스트/알림
|
||||||
static var recentDataLoaded: String { pick(ko: "최근데이터를 불러왔습니다.", en: "Recent data has been loaded.", ja: "最新データを読み込みました。") }
|
static var recentDataLoaded: String { pick(ko: "최근데이터를 불러왔습니다.", en: "Recent data has been loaded.", ja: "最新データを読み込みました。") }
|
||||||
static var recentDataLoadFailed: String { pick(ko: "최근데이터를 불러오지 못했습니다.\n다시 시도해 주세요.", en: "Failed to load recent data.\ntry again.", ja: "最近のデータを読み込めませんでした。\n恐れ入りますが、もう一度お試しください。") }
|
static var recentDataLoadFailed: String { pick(ko: "최근데이터를 불러오지 못했습니다.\n다시 시도해 주세요.", en: "Failed to load recent data.\ntry again.", ja: "最近のデータを読み込めませんでした。\n恐れ入りますが、もう一度お試しください。") }
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ struct CreateLiveRoomRequest: Encodable {
|
|||||||
let tags: [String]
|
let tags: [String]
|
||||||
let numberOfPeople: Int
|
let numberOfPeople: Int
|
||||||
var isAdult: Bool = false
|
var isAdult: Bool = false
|
||||||
|
var genderRestriction: LiveRoomCreateViewModel.GenderRestriction = .ALL
|
||||||
var price = 0
|
var price = 0
|
||||||
var type: LiveRoomCreateViewModel.LiveRoomType = .OPEN
|
var type: LiveRoomCreateViewModel.LiveRoomType = .OPEN
|
||||||
var password: String? = nil
|
var password: String? = nil
|
||||||
|
|||||||
@@ -13,4 +13,5 @@ struct GetRecentRoomInfoResponse: Decodable {
|
|||||||
let coverImageUrl: String
|
let coverImageUrl: String
|
||||||
let coverImagePath: String
|
let coverImagePath: String
|
||||||
let numberOfPeople: Int
|
let numberOfPeople: Int
|
||||||
|
let genderRestriction: LiveRoomCreateViewModel.GenderRestriction
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,6 +175,10 @@ struct LiveRoomCreateView: View {
|
|||||||
AdultSettingView()
|
AdultSettingView()
|
||||||
.frame(width: screenSize().width - 26.7)
|
.frame(width: screenSize().width - 26.7)
|
||||||
.padding(.top, 33.3)
|
.padding(.top, 33.3)
|
||||||
|
|
||||||
|
GenderRestrictionView()
|
||||||
|
.frame(width: screenSize().width - 26.7)
|
||||||
|
.padding(.top, 33.3)
|
||||||
}
|
}
|
||||||
|
|
||||||
PriceSettingView()
|
PriceSettingView()
|
||||||
@@ -699,6 +703,56 @@ struct LiveRoomCreateView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
func GenderRestrictionView() -> some View {
|
||||||
|
VStack(spacing: 13.3) {
|
||||||
|
Text(I18n.CreateLive.genderRestrictionTitle)
|
||||||
|
.appFont(size: 16.7, weight: .bold)
|
||||||
|
.foregroundColor(Color.grayee)
|
||||||
|
.frame(width: screenSize().width - 26.7, alignment: .leading)
|
||||||
|
|
||||||
|
HStack(spacing: 13.3) {
|
||||||
|
GenderRestrictionSelectButton(
|
||||||
|
title: I18n.CreateLive.genderAll,
|
||||||
|
restriction: .ALL,
|
||||||
|
buttonWidth: (screenSize().width - 53) / 3
|
||||||
|
)
|
||||||
|
|
||||||
|
GenderRestrictionSelectButton(
|
||||||
|
title: I18n.CreateLive.genderMaleOnly,
|
||||||
|
restriction: .MALE_ONLY,
|
||||||
|
buttonWidth: (screenSize().width - 53) / 3
|
||||||
|
)
|
||||||
|
|
||||||
|
GenderRestrictionSelectButton(
|
||||||
|
title: I18n.CreateLive.genderFemaleOnly,
|
||||||
|
restriction: .FEMALE_ONLY,
|
||||||
|
buttonWidth: (screenSize().width - 53) / 3
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
func GenderRestrictionSelectButton(
|
||||||
|
title: String,
|
||||||
|
restriction: LiveRoomCreateViewModel.GenderRestriction,
|
||||||
|
buttonWidth: CGFloat
|
||||||
|
) -> some View {
|
||||||
|
SelectedButtonView(
|
||||||
|
title: title,
|
||||||
|
isActive: true,
|
||||||
|
isSelected: viewModel.genderRestriction == restriction
|
||||||
|
)
|
||||||
|
.frame(width: buttonWidth)
|
||||||
|
.onTapGesture {
|
||||||
|
hideKeyboard()
|
||||||
|
if viewModel.genderRestriction != restriction {
|
||||||
|
viewModel.genderRestriction = restriction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
func PriceSettingView() -> some View {
|
func PriceSettingView() -> some View {
|
||||||
VStack(spacing: 13.3) {
|
VStack(spacing: 13.3) {
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ final class LiveRoomCreateViewModel: ObservableObject {
|
|||||||
case OPEN, PRIVATE
|
case OPEN, PRIVATE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum GenderRestriction: String, Codable {
|
||||||
|
case ALL, MALE_ONLY, FEMALE_ONLY
|
||||||
|
}
|
||||||
|
|
||||||
let prices = [0, 100, 300, 500, 1000, 2000]
|
let prices = [0, 100, 300, 500, 1000, 2000]
|
||||||
|
|
||||||
@Published var isLoading = false
|
@Published var isLoading = false
|
||||||
@@ -61,6 +65,7 @@ final class LiveRoomCreateViewModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Published var isAdult = false
|
@Published var isAdult = false
|
||||||
|
@Published var genderRestriction: GenderRestriction = .ALL
|
||||||
@Published var priceString = "0" {
|
@Published var priceString = "0" {
|
||||||
didSet {
|
didSet {
|
||||||
if priceString.count > 5 {
|
if priceString.count > 5 {
|
||||||
@@ -134,6 +139,7 @@ final class LiveRoomCreateViewModel: ObservableObject {
|
|||||||
self.coverImageUrl = data.coverImageUrl
|
self.coverImageUrl = data.coverImageUrl
|
||||||
self.coverImagePath = data.coverImagePath
|
self.coverImagePath = data.coverImagePath
|
||||||
self.numberOfPeople = String(data.numberOfPeople)
|
self.numberOfPeople = String(data.numberOfPeople)
|
||||||
|
self.genderRestriction = data.genderRestriction
|
||||||
|
|
||||||
self.errorMessage = I18n.CreateLive.recentDataLoaded
|
self.errorMessage = I18n.CreateLive.recentDataLoaded
|
||||||
self.isShowPopup = true
|
self.isShowPopup = true
|
||||||
@@ -173,6 +179,7 @@ final class LiveRoomCreateViewModel: ObservableObject {
|
|||||||
tags: tags,
|
tags: tags,
|
||||||
numberOfPeople: Int(numberOfPeople)!,
|
numberOfPeople: Int(numberOfPeople)!,
|
||||||
isAdult: isAdult,
|
isAdult: isAdult,
|
||||||
|
genderRestriction: genderRestriction,
|
||||||
price: price,
|
price: price,
|
||||||
type: roomType,
|
type: roomType,
|
||||||
password: (roomType == .PRIVATE && !password.trimmingCharacters(in: .whitespaces).isEmpty) ? password : nil,
|
password: (roomType == .PRIVATE && !password.trimmingCharacters(in: .whitespaces).isEmpty) ? password : nil,
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ struct GetRoomDetailResponse: Decodable {
|
|||||||
let notice: String
|
let notice: String
|
||||||
let isPaid: Bool
|
let isPaid: Bool
|
||||||
let isAdult: Bool
|
let isAdult: Bool
|
||||||
|
let genderRestriction: LiveRoomCreateViewModel.GenderRestriction?
|
||||||
let isPrivateRoom: Bool
|
let isPrivateRoom: Bool
|
||||||
let password: String?
|
let password: String?
|
||||||
let tags: [String]
|
let tags: [String]
|
||||||
|
|||||||
@@ -17,4 +17,5 @@ struct EditLiveRoomInfoRequest: Encodable {
|
|||||||
var menuPan: String = ""
|
var menuPan: String = ""
|
||||||
var isActiveMenuPan: Bool? = nil
|
var isActiveMenuPan: Bool? = nil
|
||||||
var isAdult: Bool? = nil
|
var isAdult: Bool? = nil
|
||||||
|
var genderRestriction: LiveRoomCreateViewModel.GenderRestriction? = nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,12 +46,16 @@ struct LiveRoomEditView: View {
|
|||||||
.frame(width: screenSize().width - 26.7)
|
.frame(width: screenSize().width - 26.7)
|
||||||
.padding(.top, 33.3)
|
.padding(.top, 33.3)
|
||||||
|
|
||||||
|
GenderRestrictionView()
|
||||||
|
.frame(width: screenSize().width - 26.7)
|
||||||
|
.padding(.top, 33.3)
|
||||||
|
|
||||||
if !viewModel.isLoading {
|
if !viewModel.isLoading {
|
||||||
Text("라이브 수정")
|
Text("라이브 수정")
|
||||||
.appFont(size: 18.3, weight: .bold)
|
.appFont(size: 18.3, weight: .bold)
|
||||||
.foregroundColor(Color.white)
|
.foregroundColor(Color.white)
|
||||||
.frame(width: screenSize().width - 26.7, height: 50)
|
.frame(width: screenSize().width - 26.7, height: 50)
|
||||||
.background(Color(hex: "9970ff"))
|
.background(Color.button)
|
||||||
.cornerRadius(10)
|
.cornerRadius(10)
|
||||||
.padding(.top, 30)
|
.padding(.top, 30)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
@@ -87,7 +91,7 @@ struct LiveRoomEditView: View {
|
|||||||
.padding(.vertical, 13.3)
|
.padding(.vertical, 13.3)
|
||||||
.frame(width: geo.size.width - 66.7, alignment: .center)
|
.frame(width: geo.size.width - 66.7, alignment: .center)
|
||||||
.appFont(size: 12, weight: .medium)
|
.appFont(size: 12, weight: .medium)
|
||||||
.background(Color(hex: "9970ff"))
|
.background(Color.button)
|
||||||
.foregroundColor(Color.white)
|
.foregroundColor(Color.white)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
.cornerRadius(20)
|
.cornerRadius(20)
|
||||||
@@ -175,7 +179,7 @@ struct LiveRoomEditView: View {
|
|||||||
.frame(width: buttonWidth, height: 48.7)
|
.frame(width: buttonWidth, height: 48.7)
|
||||||
.overlay(
|
.overlay(
|
||||||
RoundedRectangle(cornerRadius: 6.7)
|
RoundedRectangle(cornerRadius: 6.7)
|
||||||
.stroke(Color(hex: "9970ff"), lineWidth: 1.3)
|
.stroke(Color.button, lineWidth: 1.3)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,7 +199,7 @@ struct LiveRoomEditView: View {
|
|||||||
.frame(width: buttonWidth, height: 48.7)
|
.frame(width: buttonWidth, height: 48.7)
|
||||||
.overlay(
|
.overlay(
|
||||||
RoundedRectangle(cornerRadius: 6.7)
|
RoundedRectangle(cornerRadius: 6.7)
|
||||||
.stroke(Color(hex: "9970ff"), lineWidth: 1.3)
|
.stroke(Color.button, lineWidth: 1.3)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,6 +232,56 @@ struct LiveRoomEditView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
func GenderRestrictionView() -> some View {
|
||||||
|
VStack(spacing: 13.3) {
|
||||||
|
Text(I18n.CreateLive.genderRestrictionTitle)
|
||||||
|
.appFont(size: 16.7, weight: .bold)
|
||||||
|
.foregroundColor(Color(hex: "eeeeee"))
|
||||||
|
.frame(width: screenSize().width - 26.7, alignment: .leading)
|
||||||
|
|
||||||
|
HStack(spacing: 13.3) {
|
||||||
|
GenderRestrictionSelectButton(
|
||||||
|
title: I18n.CreateLive.genderAll,
|
||||||
|
restriction: .ALL,
|
||||||
|
buttonWidth: (screenSize().width - 53) / 3
|
||||||
|
)
|
||||||
|
|
||||||
|
GenderRestrictionSelectButton(
|
||||||
|
title: I18n.CreateLive.genderMaleOnly,
|
||||||
|
restriction: .MALE_ONLY,
|
||||||
|
buttonWidth: (screenSize().width - 53) / 3
|
||||||
|
)
|
||||||
|
|
||||||
|
GenderRestrictionSelectButton(
|
||||||
|
title: I18n.CreateLive.genderFemaleOnly,
|
||||||
|
restriction: .FEMALE_ONLY,
|
||||||
|
buttonWidth: (screenSize().width - 53) / 3
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
func GenderRestrictionSelectButton(
|
||||||
|
title: String,
|
||||||
|
restriction: LiveRoomCreateViewModel.GenderRestriction,
|
||||||
|
buttonWidth: CGFloat
|
||||||
|
) -> some View {
|
||||||
|
SelectedButtonView(
|
||||||
|
title: title,
|
||||||
|
isActive: true,
|
||||||
|
isSelected: viewModel.genderRestriction == restriction
|
||||||
|
)
|
||||||
|
.frame(width: buttonWidth)
|
||||||
|
.onTapGesture {
|
||||||
|
hideKeyboard()
|
||||||
|
if viewModel.genderRestriction != restriction {
|
||||||
|
viewModel.genderRestriction = restriction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
func SelectDateView() -> some View {
|
func SelectDateView() -> some View {
|
||||||
GeometryReader { proxy in
|
GeometryReader { proxy in
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ final class LiveRoomEditViewModel: ObservableObject {
|
|||||||
@Published var numberOfPeople = ""
|
@Published var numberOfPeople = ""
|
||||||
@Published var reservationDateString: String = ""
|
@Published var reservationDateString: String = ""
|
||||||
@Published var reservationTimeString: String = ""
|
@Published var reservationTimeString: String = ""
|
||||||
|
@Published var genderRestriction: LiveRoomCreateViewModel.GenderRestriction = .ALL
|
||||||
|
|
||||||
@Published var errorMessage = ""
|
@Published var errorMessage = ""
|
||||||
@Published var isShowPopup = false
|
@Published var isShowPopup = false
|
||||||
@@ -51,6 +52,7 @@ final class LiveRoomEditViewModel: ObservableObject {
|
|||||||
title = room!.title
|
title = room!.title
|
||||||
notice = room!.notice
|
notice = room!.notice
|
||||||
numberOfPeople = String(room!.numberOfParticipantsTotal)
|
numberOfPeople = String(room!.numberOfParticipantsTotal)
|
||||||
|
genderRestriction = room!.genderRestriction ?? .ALL
|
||||||
|
|
||||||
if let beginDate = room!.beginDateTimeUtc.parseUtcIsoDate() {
|
if let beginDate = room!.beginDateTimeUtc.parseUtcIsoDate() {
|
||||||
reservationDate = beginDate
|
reservationDate = beginDate
|
||||||
@@ -80,14 +82,16 @@ final class LiveRoomEditViewModel: ObservableObject {
|
|||||||
notice: room.notice != notice ? notice : nil,
|
notice: room.notice != notice ? notice : nil,
|
||||||
numberOfPeople: room.numberOfParticipantsTotal != Int(numberOfPeople)! ? Int(numberOfPeople)! : nil,
|
numberOfPeople: room.numberOfParticipantsTotal != Int(numberOfPeople)! ? Int(numberOfPeople)! : nil,
|
||||||
beginDateTimeString: beginDateTimeStr != beginDateTime ? beginDateTime : nil,
|
beginDateTimeString: beginDateTimeStr != beginDateTime ? beginDateTime : nil,
|
||||||
timezone: TimeZone.current.identifier
|
timezone: TimeZone.current.identifier,
|
||||||
|
genderRestriction: (room.genderRestriction ?? .ALL) != genderRestriction ? genderRestriction : nil
|
||||||
)
|
)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
request.title == nil &&
|
request.title == nil &&
|
||||||
request.notice == nil &&
|
request.notice == nil &&
|
||||||
request.numberOfPeople == nil &&
|
request.numberOfPeople == nil &&
|
||||||
request.beginDateTimeString == nil
|
request.beginDateTimeString == nil &&
|
||||||
|
request.genderRestriction == nil
|
||||||
) {
|
) {
|
||||||
self.errorMessage = "변경사항이 없습니다."
|
self.errorMessage = "변경사항이 없습니다."
|
||||||
self.isShowPopup = true
|
self.isShowPopup = true
|
||||||
|
|||||||
Reference in New Issue
Block a user