라이브 정보 수정

- 연령 제한 설정 추가
This commit is contained in:
Yu Sung 2024-09-11 14:58:55 +09:00
parent 8aa69f02fc
commit 3db59e6236
5 changed files with 85 additions and 29 deletions

View File

@ -42,13 +42,13 @@ struct SodaDialog: View {
VStack(spacing: 0) { VStack(spacing: 0) {
Text(title) Text(title)
.font(.custom(Font.bold.rawValue, size: 18.3)) .font(.custom(Font.bold.rawValue, size: 18.3))
.foregroundColor(Color(hex: "bbbbbb")) .foregroundColor(Color.graybb)
.padding(.top, 40) .padding(.top, 40)
Text(desc) Text(desc)
.font(.custom(Font.medium.rawValue, size: 15)) .font(.custom(Font.medium.rawValue, size: 15))
.foregroundColor(Color(hex: "bbbbbb")) .foregroundColor(Color.graybb)
.multilineTextAlignment(.center) .multilineTextAlignment(.leading)
.padding(.top, 12) .padding(.top, 12)
.padding(.horizontal, 13.3) .padding(.horizontal, 13.3)
.fixedSize(horizontal: false, vertical: true) .fixedSize(horizontal: false, vertical: true)
@ -57,14 +57,14 @@ struct SodaDialog: View {
if cancelButtonTitle.count > 0 { if cancelButtonTitle.count > 0 {
Text(cancelButtonTitle) Text(cancelButtonTitle)
.font(.custom(Font.bold.rawValue, size: 15.3)) .font(.custom(Font.bold.rawValue, size: 15.3))
.foregroundColor(Color(hex: "3bb9f1")) .foregroundColor(Color.button)
.padding(.vertical, 16) .padding(.vertical, 16)
.frame(width: (geo.size.width - 66.7) / 3) .frame(width: (geo.size.width - 66.7) / 3)
.background(Color(hex: "13181b")) .background(Color.bg)
.cornerRadius(8) .cornerRadius(8)
.overlay( .overlay(
RoundedRectangle(cornerRadius: 8) RoundedRectangle(cornerRadius: 8)
.stroke(Color(hex: "3bb9f1"), lineWidth: 1) .stroke(Color.button, lineWidth: 1)
) )
.onTapGesture { .onTapGesture {
cancelButtonAction() cancelButtonAction()
@ -73,10 +73,10 @@ struct SodaDialog: View {
Text(confirmButtonTitle) Text(confirmButtonTitle)
.font(.custom(Font.bold.rawValue, size: 15.3)) .font(.custom(Font.bold.rawValue, size: 15.3))
.foregroundColor(Color(hex: "ffffff")) .foregroundColor(Color.white)
.padding(.vertical, 16) .padding(.vertical, 16)
.frame(width: (geo.size.width - 66.7) * 2 / 3) .frame(width: (geo.size.width - 66.7) * 2 / 3)
.background(Color(hex: "3bb9f1")) .background(Color.button)
.cornerRadius(8) .cornerRadius(8)
.onTapGesture { .onTapGesture {
confirmButtonAction() confirmButtonAction()
@ -86,7 +86,7 @@ struct SodaDialog: View {
.padding(.bottom, 16.7) .padding(.bottom, 16.7)
} }
.frame(width: geo.size.width - 26.7, alignment: .center) .frame(width: geo.size.width - 26.7, alignment: .center)
.background(Color(hex: "222222")) .background(Color.gray22)
.cornerRadius(10) .cornerRadius(10)
} }
} }

View File

@ -15,6 +15,7 @@ struct LiveRoomInfoEditDialog: View {
@State private var title = "" @State private var title = ""
@State private var notice = "" @State private var notice = ""
@State private var isAdult = false
let placeholder = "라이브 공지를 입력하세요" let placeholder = "라이브 공지를 입력하세요"
@ -23,24 +24,26 @@ struct LiveRoomInfoEditDialog: View {
let isLoading: Bool let isLoading: Bool
let coverImageUrl: String? let coverImageUrl: String?
let coverImage: UIImage? let coverImage: UIImage?
var confirmAction: (String, String) -> Void var confirmAction: (String, String, Bool) -> Void
init( init(
isShowing: Binding<Bool>, isShowing: Binding<Bool>,
isShowPhotoPicker: Binding<Bool>, isShowPhotoPicker: Binding<Bool>,
viewModel: LiveRoomViewModel, viewModel: LiveRoomViewModel,
isAdult: Bool,
isLoading: Bool, isLoading: Bool,
currentTitle: String, currentTitle: String,
currentNotice: String, currentNotice: String,
coverImageUrl: String, coverImageUrl: String,
coverImage: UIImage?, coverImage: UIImage?,
confirmAction: @escaping (String, String) -> Void confirmAction: @escaping (String, String, Bool) -> Void
) { ) {
self._isShowing = isShowing self._isShowing = isShowing
self._isShowPhotoPicker = isShowPhotoPicker self._isShowPhotoPicker = isShowPhotoPicker
self._viewModel = StateObject(wrappedValue: viewModel) self._viewModel = StateObject(wrappedValue: viewModel)
self.isLoading = isLoading self.isLoading = isLoading
self.isAdult = isAdult
self.title = currentTitle self.title = currentTitle
self.notice = currentNotice self.notice = currentNotice
@ -116,6 +119,30 @@ struct LiveRoomInfoEditDialog: View {
ContentInputView() ContentInputView()
.padding(.top, 33.3) .padding(.top, 33.3)
if UserDefaults.bool(forKey: .auth) {
VStack(alignment: .leading, spacing: 8) {
Text("연령제한")
.font(.custom(Font.bold.rawValue, size: 16.7))
.foregroundColor(Color.grayee)
HStack(spacing: 0) {
Text("19세 이상")
.font(.custom(Font.medium.rawValue, size: 13.3))
.foregroundColor(Color.grayee)
Spacer()
Image(isAdult ? "btn_toggle_on_big" : "btn_toggle_off_big")
.resizable()
.frame(width: 33.3, height: 20)
.onTapGesture {
isAdult.toggle()
}
}
}
.padding(.top, 33.3)
}
LiveRoomMenuSelectView( LiveRoomMenuSelectView(
menu: $viewModel.menu, menu: $viewModel.menu,
isActivate: $viewModel.isActivateMenu, isActivate: $viewModel.isActivateMenu,
@ -152,7 +179,8 @@ struct LiveRoomInfoEditDialog: View {
.onTapGesture { .onTapGesture {
confirmAction( confirmAction(
title, title,
notice.trimmingCharacters(in: .whitespacesAndNewlines) != placeholder ? notice : "" notice.trimmingCharacters(in: .whitespacesAndNewlines) != placeholder ? notice : "",
isAdult
) )
isShowing = false isShowing = false
} }
@ -169,7 +197,7 @@ struct LiveRoomInfoEditDialog: View {
} }
} }
} }
.background(Color(hex: "222222").edgesIgnoringSafeArea(.all)) .background(Color.gray22.edgesIgnoringSafeArea(.all))
if viewModel.isShowPopup { if viewModel.isShowPopup {
LiveRoomDialogView( LiveRoomDialogView(
@ -198,7 +226,7 @@ struct LiveRoomInfoEditDialog: View {
VStack(alignment: .leading, spacing: 0) { VStack(alignment: .leading, spacing: 0) {
Text("제목") Text("제목")
.font(.custom(Font.bold.rawValue, size: 16.7)) .font(.custom(Font.bold.rawValue, size: 16.7))
.foregroundColor(Color(hex: "eeeeee")) .foregroundColor(Color.grayee)
TextField("라이브 제목을 입력하세요", text: $title) TextField("라이브 제목을 입력하세요", text: $title)
.autocapitalization(.none) .autocapitalization(.none)

View File

@ -16,4 +16,5 @@ struct EditLiveRoomInfoRequest: Encodable {
var menuPanId: Int = 0 var menuPanId: Int = 0
var menuPan: String = "" var menuPan: String = ""
var isActiveMenuPan: Bool? = nil var isActiveMenuPan: Bool? = nil
var isAdult: Bool? = nil
} }

View File

@ -43,6 +43,13 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
@Published var isShowReportPopup = false @Published var isShowReportPopup = false
@Published var isShowErrorPopup = false @Published var isShowErrorPopup = false
@Published var isShowUserProfilePopup = false @Published var isShowUserProfilePopup = false
@Published var changeIsAdult = false {
didSet {
if changeIsAdult && !UserDefaults.bool(forKey: .auth) {
agora.speakerMute(true)
}
}
}
@Published var popupContent = "" @Published var popupContent = ""
@Published var popupCancelTitle: String? = nil @Published var popupCancelTitle: String? = nil
@ -342,6 +349,10 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
getTotalDonationCan() getTotalDonationCan()
if data.isAdult && !UserDefaults.bool(forKey: .auth) {
changeIsAdult = true
}
if (userId > 0 && data.creatorId == UserDefaults.int(forKey: .userId)) { if (userId > 0 && data.creatorId == UserDefaults.int(forKey: .userId)) {
let nickname = getUserNicknameAndProfileUrl(accountId: userId).nickname let nickname = getUserNicknameAndProfileUrl(accountId: userId).nickname
onSuccess(nickname) onSuccess(nickname)
@ -707,7 +718,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
agora.sendMessageToPeer(peerId: peerId, rawMessage: LiveRoomRequestType.REQUEST_SPEAKER_ALLOW.rawValue.data(using: .utf8)!, completion: nil) agora.sendMessageToPeer(peerId: peerId, rawMessage: LiveRoomRequestType.REQUEST_SPEAKER_ALLOW.rawValue.data(using: .utf8)!, completion: nil)
} }
func editLiveRoomInfo(title: String, notice: String) { func editLiveRoomInfo(title: String, notice: String, isAdult: Bool) {
let request = EditLiveRoomInfoRequest( let request = EditLiveRoomInfoRequest(
title: liveRoomInfo!.title != title ? title : nil, title: liveRoomInfo!.title != title ? title : nil,
notice: liveRoomInfo!.notice != notice ? notice : nil, notice: liveRoomInfo!.notice != notice ? notice : nil,
@ -716,10 +727,11 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
timezone: nil, timezone: nil,
menuPanId: isActivateMenu ? menuId : 0, menuPanId: isActivateMenu ? menuId : 0,
menuPan: isActivateMenu ? menu : "", menuPan: isActivateMenu ? menu : "",
isActiveMenuPan: isActivateMenu isActiveMenuPan: isActivateMenu,
isAdult: liveRoomInfo!.isAdult != isAdult ? isAdult : nil
) )
if (request.title == nil && request.notice == nil && coverImage == nil && menu == liveRoomInfo?.menuPan) { if (request.title == nil && request.notice == nil && coverImage == nil && menu == liveRoomInfo?.menuPan && request.isAdult == nil) {
self.errorMessage = "변경사항이 없습니다." self.errorMessage = "변경사항이 없습니다."
self.isShowErrorPopup = true self.isShowErrorPopup = true
return return
@ -730,7 +742,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
let encoder = JSONEncoder() let encoder = JSONEncoder()
encoder.outputFormatting = .withoutEscapingSlashes encoder.outputFormatting = .withoutEscapingSlashes
if (request.title != nil || request.notice != nil || menu != liveRoomInfo?.menuPan) { if (request.title != nil || request.notice != nil || request.isAdult != nil || menu != liveRoomInfo?.menuPan) {
let jsonData = try? encoder.encode(request) let jsonData = try? encoder.encode(request)
if let jsonData = jsonData { if let jsonData = jsonData {
multipartData.append(MultipartFormData(provider: .data(jsonData), name: "request")) multipartData.append(MultipartFormData(provider: .data(jsonData), name: "request"))

View File

@ -151,6 +151,7 @@ struct LiveRoomViewV2: View {
ScrollView(.vertical, showsIndicators: false) { ScrollView(.vertical, showsIndicators: false) {
scrollObservableView scrollObservableView
if !viewModel.changeIsAdult || UserDefaults.bool(forKey: .auth) {
LiveRoomChatView(messages: viewModel.messages) { LiveRoomChatView(messages: viewModel.messages) {
if $0 != UserDefaults.int(forKey: .userId) { if $0 != UserDefaults.int(forKey: .userId) {
viewModel.getUserProfile(userId: $0) viewModel.getUserProfile(userId: $0)
@ -164,6 +165,7 @@ struct LiveRoomViewV2: View {
} }
} }
} }
}
.rotationEffect(Angle(degrees: 180)) .rotationEffect(Angle(degrees: 180))
.onTapGesture { hideKeyboard() } .onTapGesture { hideKeyboard() }
.onPreferenceChange(ScrollOffsetKey.self) { .onPreferenceChange(ScrollOffsetKey.self) {
@ -398,6 +400,17 @@ struct LiveRoomViewV2: View {
} }
} }
if viewModel.changeIsAdult && !UserDefaults.bool(forKey: .auth) {
SodaDialog(
title: "알림",
desc: "지금 참여하던 라이브는 '19세 이상' 연령제한이 설정되어 정보통신망 이용촉진 및 정보 보호 등에 관한 법률 및 청소년 보호법의 규정에 의해 만 19세 미만의 청소년은 이용할 수 없습니다.\n마이페이지에서 본인인증 후 다시 이용하시기 바랍니다.",
confirmButtonTitle: "확인",
confirmButtonAction: {
viewModel.quitRoom()
}
)
}
if viewModel.isShowQuitPopup { if viewModel.isShowQuitPopup {
SodaDialog( SodaDialog(
title: "라이브 나가기", title: "라이브 나가기",
@ -646,15 +659,17 @@ struct LiveRoomViewV2: View {
isShowing: $viewModel.isShowEditRoomInfoDialog, isShowing: $viewModel.isShowEditRoomInfoDialog,
isShowPhotoPicker: $viewModel.isShowPhotoPicker, isShowPhotoPicker: $viewModel.isShowPhotoPicker,
viewModel: viewModel, viewModel: viewModel,
isAdult: liveRoomInfo.isAdult,
isLoading: viewModel.isLoading, isLoading: viewModel.isLoading,
currentTitle: liveRoomInfo.title, currentTitle: liveRoomInfo.title,
currentNotice: liveRoomInfo.notice, currentNotice: liveRoomInfo.notice,
coverImageUrl: liveRoomInfo.coverImageUrl, coverImageUrl: liveRoomInfo.coverImageUrl,
coverImage: viewModel.coverImage coverImage: viewModel.coverImage
) { newTitle, newNotice in ) { newTitle, newNotice, isAdult in
self.viewModel.editLiveRoomInfo( self.viewModel.editLiveRoomInfo(
title: newTitle, title: newTitle,
notice: newNotice notice: newNotice,
isAdult: isAdult
) )
} }
} else { } else {