예약 업로드 추가
This commit is contained in:
		| @@ -16,6 +16,8 @@ struct ContentCreateView: View { | ||||
|     @State private var isShowPhotoPicker = false | ||||
|     @State private var isShowSelectAudioView = false | ||||
|     @State private var isShowSelectThemeView = false | ||||
|     @State private var isShowSelectDateView = false | ||||
|     @State private var isShowSelectTimeView = false | ||||
|      | ||||
|     var body: some View { | ||||
|         BaseView(isLoading: $viewModel.isLoading) { | ||||
| @@ -37,7 +39,7 @@ struct ContentCreateView: View { | ||||
|                                             .resizable() | ||||
|                                             .scaledToFill() | ||||
|                                             .frame(width: 107, height: 107) | ||||
|                                             .background(Color(hex: "3e3358")) | ||||
|                                             .background(Color(hex: "13181b")) | ||||
|                                             .cornerRadius(8) | ||||
|                                             .clipped() | ||||
|                                     } else { | ||||
| @@ -46,13 +48,13 @@ struct ContentCreateView: View { | ||||
|                                             .scaledToFit() | ||||
|                                             .padding(13.3) | ||||
|                                             .frame(width: 107, height: 107) | ||||
|                                             .background(Color(hex: "3e3358")) | ||||
|                                             .background(Color(hex: "13181b")) | ||||
|                                             .cornerRadius(8) | ||||
|                                     } | ||||
|                                      | ||||
|                                     Image("ic_camera") | ||||
|                                         .padding(10) | ||||
|                                         .background(Color(hex: "9970ff")) | ||||
|                                         .background(Color(hex: "3bb9f1")) | ||||
|                                         .cornerRadius(30) | ||||
|                                         .offset(x: 50, y: 36) | ||||
|                                 } | ||||
| @@ -67,15 +69,15 @@ struct ContentCreateView: View { | ||||
|                                  | ||||
|                                 Text(viewModel.fileName.trimmingCharacters(in: .whitespacesAndNewlines) == "" ? "파일선택" : viewModel.fileName) | ||||
|                                     .font(.custom(Font.medium.rawValue, size: 16.7)) | ||||
|                                     .foregroundColor(Color(hex: "9970ff")) | ||||
|                                     .foregroundColor(Color(hex: "3bb9f1")) | ||||
|                                     .padding(.vertical, 10) | ||||
|                                     .frame(maxWidth: .infinity) | ||||
|                                     .background(Color(hex: "9970ff").opacity(0.2)) | ||||
|                                     .background(Color(hex: "13181b")) | ||||
|                                     .cornerRadius(5.3) | ||||
|                                     .overlay( | ||||
|                                         RoundedCorner(radius: 8) | ||||
|                                             .stroke(lineWidth: 2) | ||||
|                                             .foregroundColor(Color(hex: "9970ff")) | ||||
|                                             .foregroundColor(Color(hex: "3bb9f1")) | ||||
|                                     ) | ||||
|                                     .padding(.top, 13.3) | ||||
|                                     .onTapGesture { isShowSelectAudioView = true } | ||||
| @@ -150,16 +152,16 @@ struct ContentCreateView: View { | ||||
|                                          viewModel.theme!.theme : | ||||
|                                             "테마 선택") | ||||
|                                     .font(.custom(Font.bold.rawValue, size: 16.7)) | ||||
|                                     .foregroundColor(Color(hex: "9970ff")) | ||||
|                                     .foregroundColor(Color(hex: "3bb9f1")) | ||||
|                                 } | ||||
|                                 .padding(.vertical, viewModel.theme != nil ? 8 : 13.3) | ||||
|                                 .frame(maxWidth: .infinity) | ||||
|                                 .background(Color(hex: "9970ff").opacity(0.2)) | ||||
|                                 .background(Color(hex: "13181b")) | ||||
|                                 .cornerRadius(24) | ||||
|                                 .overlay( | ||||
|                                     RoundedRectangle(cornerRadius: 24) | ||||
|                                         .stroke(lineWidth: 2) | ||||
|                                         .foregroundColor(Color(hex: "9970ff")) | ||||
|                                         .foregroundColor(Color(hex: "3bb9f1")) | ||||
|                                 ) | ||||
|                                 .padding(.top, 13.3) | ||||
|                                 .onTapGesture { | ||||
| @@ -287,6 +289,62 @@ struct ContentCreateView: View { | ||||
|                                     } | ||||
|                                     .padding(.top, 26.7) | ||||
|                                 } | ||||
|                                  | ||||
|                                 if !viewModel.isFree { | ||||
|                                     VStack(spacing: 10) { | ||||
|                                         Text("미리듣기 시간 설정") | ||||
|                                             .font(.custom(Font.bold.rawValue, size: 16.7)) | ||||
|                                             .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                             .frame(maxWidth: .infinity, alignment: .leading) | ||||
|                                          | ||||
|                                         Text("미리듣기 시간을 직접 설정하지 않으면 콘텐츠 앞부분 30초가 자동으로 설정됩니다. 미리듣기의 시간제한은 없습니다.") | ||||
|                                             .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                                             .foregroundColor(Color(hex: "777777")) | ||||
|                                             .frame(maxWidth: .infinity, alignment: .leading) | ||||
|                                          | ||||
|                                         HStack(spacing: 13.3) { | ||||
|                                             VStack(spacing: 5.3) { | ||||
|                                                 Text("시작 시간") | ||||
|                                                     .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                                                     .foregroundColor(Color(hex: "d2d2d2")) | ||||
|                                                     .frame(maxWidth: .infinity, alignment: .leading) | ||||
|                                                  | ||||
|                                                 TextField("00:00:00", text: $viewModel.previewStartTime) | ||||
|                                                     .autocapitalization(.none) | ||||
|                                                     .disableAutocorrection(true) | ||||
|                                                     .font(.custom(Font.bold.rawValue, size: 14.6)) | ||||
|                                                     .foregroundColor(Color(hex: "777777")) | ||||
|                                                     .padding(.vertical, 16.7) | ||||
|                                                     .padding(.horizontal, 13.3) | ||||
|                                                     .background(Color(hex: "222222")) | ||||
|                                                     .cornerRadius(6.7) | ||||
|                                                     .keyboardType(.default) | ||||
|                                                     .multilineTextAlignment(.center) | ||||
|                                             } | ||||
|                                              | ||||
|                                             VStack(spacing: 5.3) { | ||||
|                                                 Text("종료 시간") | ||||
|                                                     .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                                                     .foregroundColor(Color(hex: "d2d2d2")) | ||||
|                                                     .frame(maxWidth: .infinity, alignment: .leading) | ||||
|                                                  | ||||
|                                                 TextField("00:00:30", text: $viewModel.previewEndTime) | ||||
|                                                     .autocapitalization(.none) | ||||
|                                                     .disableAutocorrection(true) | ||||
|                                                     .font(.custom(Font.bold.rawValue, size: 14.6)) | ||||
|                                                     .foregroundColor(Color(hex: "777777")) | ||||
|                                                     .padding(.vertical, 16.7) | ||||
|                                                     .padding(.horizontal, 13.3) | ||||
|                                                     .background(Color(hex: "222222")) | ||||
|                                                     .cornerRadius(6.7) | ||||
|                                                     .keyboardType(.default) | ||||
|                                                     .multilineTextAlignment(.center) | ||||
|                                             } | ||||
|                                         } | ||||
|                                         .padding(.top, 3.3) | ||||
|                                     } | ||||
|                                     .padding(.top, 26.7) | ||||
|                                 } | ||||
|                             } | ||||
|                             .padding(.top, 26.7) | ||||
|                             .padding(.horizontal, 13.3) | ||||
| @@ -343,62 +401,79 @@ struct ContentCreateView: View { | ||||
|                             .padding(.top, 26.7) | ||||
|                             .padding(.horizontal, 13.3) | ||||
|                              | ||||
|                             if !viewModel.isFree { | ||||
|                                 VStack(spacing: 10) { | ||||
|                                     Text("미리듣기 시간 설정") | ||||
|                                         .font(.custom(Font.bold.rawValue, size: 16.7)) | ||||
|                                         .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                         .frame(maxWidth: .infinity, alignment: .leading) | ||||
|                                      | ||||
|                                     Text("미리듣기 시간을 직접 설정하지 않으면 콘텐츠 앞부분 30초가 자동으로 설정됩니다. 미리듣기의 시간제한은 없습니다.") | ||||
|                                         .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                                         .foregroundColor(Color(hex: "777777")) | ||||
|                                         .frame(maxWidth: .infinity, alignment: .leading) | ||||
|                                      | ||||
|                                     HStack(spacing: 13.3) { | ||||
|                                         VStack(spacing: 5.3) { | ||||
|                                             Text("시작 시간") | ||||
|                                                 .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                                                 .foregroundColor(Color(hex: "d2d2d2")) | ||||
|                                                 .frame(maxWidth: .infinity, alignment: .leading) | ||||
|                                              | ||||
|                                             TextField("00:00:00", text: $viewModel.previewStartTime) | ||||
|                                                 .autocapitalization(.none) | ||||
|                                                 .disableAutocorrection(true) | ||||
|                                                 .font(.custom(Font.bold.rawValue, size: 14.6)) | ||||
|                                                 .foregroundColor(Color(hex: "777777")) | ||||
|                                                 .padding(.vertical, 16.7) | ||||
|                                                 .padding(.horizontal, 13.3) | ||||
|                                                 .background(Color(hex: "222222")) | ||||
|                                                 .cornerRadius(6.7) | ||||
|                                                 .keyboardType(.default) | ||||
|                                                 .multilineTextAlignment(.center) | ||||
|                                         } | ||||
|                                          | ||||
|                                         VStack(spacing: 5.3) { | ||||
|                                             Text("종료 시간") | ||||
|                                                 .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                                                 .foregroundColor(Color(hex: "d2d2d2")) | ||||
|                                                 .frame(maxWidth: .infinity, alignment: .leading) | ||||
|                                              | ||||
|                                             TextField("00:00:30", text: $viewModel.previewEndTime) | ||||
|                                                 .autocapitalization(.none) | ||||
|                                                 .disableAutocorrection(true) | ||||
|                                                 .font(.custom(Font.bold.rawValue, size: 14.6)) | ||||
|                                                 .foregroundColor(Color(hex: "777777")) | ||||
|                                                 .padding(.vertical, 16.7) | ||||
|                                                 .padding(.horizontal, 13.3) | ||||
|                                                 .background(Color(hex: "222222")) | ||||
|                                                 .cornerRadius(6.7) | ||||
|                                                 .keyboardType(.default) | ||||
|                                                 .multilineTextAlignment(.center) | ||||
|                             VStack(spacing: 13.3) { | ||||
|                                 Text("예약 공개") | ||||
|                                     .font(.custom(Font.bold.rawValue, size: 16.7)) | ||||
|                                     .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                     .frame(maxWidth: .infinity, alignment: .leading) | ||||
|                                  | ||||
|                                 HStack(spacing: 13.3) { | ||||
|                                     SelectButtonView(title: "지금 공개", isChecked: !viewModel.isActiveReservation) { | ||||
|                                         if viewModel.isActiveReservation { | ||||
|                                             viewModel.isActiveReservation = false | ||||
|                                         } | ||||
|                                     } | ||||
|                                      | ||||
|                                     SelectButtonView(title: "예약 공개", isChecked: viewModel.isActiveReservation) { | ||||
|                                         if !viewModel.isActiveReservation { | ||||
|                                             viewModel.isActiveReservation = true | ||||
|                                         } | ||||
|                                     } | ||||
|                                     .padding(.top, 3.3) | ||||
|                                 } | ||||
|                                 .padding(.top, 26.7) | ||||
|                                 .padding(.horizontal, 13.3) | ||||
|                                  | ||||
|                                 if viewModel.isActiveReservation { | ||||
|                                     HStack(spacing: 13.3) { | ||||
|                                         VStack(alignment: .leading, spacing: 6.7) { | ||||
|                                             Text("예약 날짜") | ||||
|                                                 .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                                                 .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                              | ||||
|                                             Button(action: { | ||||
|                                                 hideKeyboard() | ||||
|                                                 self.isShowSelectDateView = true | ||||
|                                             }) { | ||||
|                                                 Text(viewModel.releaseDateString) | ||||
|                                                     .font(.custom(Font.medium.rawValue, size: 14.7)) | ||||
|                                                     .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                                     .frame(maxWidth: .infinity) | ||||
|                                                     .frame(height: 48.7) | ||||
|                                                     .overlay( | ||||
|                                                         RoundedRectangle(cornerRadius: 6.7) | ||||
|                                                             .stroke(Color(hex: "3bb9f1"), lineWidth: 1.3) | ||||
|                                                     ) | ||||
|                                             } | ||||
|                                         } | ||||
|                                          | ||||
|                                         VStack(alignment: .leading, spacing: 6.7) { | ||||
|                                             Text("예약 시간") | ||||
|                                                 .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                                                 .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                              | ||||
|                                             Button(action: { | ||||
|                                                 hideKeyboard() | ||||
|                                                 self.isShowSelectTimeView = true | ||||
|                                             }) { | ||||
|                                                 Text(viewModel.releaseTimeString) | ||||
|                                                     .font(.custom(Font.medium.rawValue, size: 14.7)) | ||||
|                                                     .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                                     .frame(maxWidth: .infinity) | ||||
|                                                     .frame(height: 48.7) | ||||
|                                                     .overlay( | ||||
|                                                         RoundedRectangle(cornerRadius: 6.7) | ||||
|                                                             .stroke(Color(hex: "3bb9f1"), lineWidth: 1.3) | ||||
|                                                     ) | ||||
|                                             } | ||||
|                                         } | ||||
|                                     } | ||||
|                                     .padding(.horizontal, 13.3) | ||||
|                                     .padding(.vertical, 14.2) | ||||
|                                     .frame(maxWidth: .infinity) | ||||
|                                     .background(Color(hex: "222222")) | ||||
|                                     .padding(.top, 22.7) | ||||
|                                 } | ||||
|                             } | ||||
|                             .padding(.top, 26.7) | ||||
|                             .padding(.horizontal, 13.3) | ||||
|                              | ||||
|                             VStack(spacing: 0) { | ||||
|                                 HStack(alignment: .top, spacing: 0) { | ||||
| @@ -407,7 +482,7 @@ struct ContentCreateView: View { | ||||
|                                         .foregroundColor(Color.white) | ||||
|                                         .frame(height: 50) | ||||
|                                         .frame(maxWidth: .infinity) | ||||
|                                         .background(Color(hex: "9970ff")) | ||||
|                                         .background(Color(hex: "3bb9f1")) | ||||
|                                         .cornerRadius(10) | ||||
|                                         .padding(13.3) | ||||
|                                 } | ||||
| @@ -449,6 +524,14 @@ struct ContentCreateView: View { | ||||
|                         } | ||||
|                     } | ||||
|                      | ||||
|                     if isShowSelectDateView { | ||||
|                         SelectDatePicker(selectedDate: $viewModel.releaseDate, isShowing: $isShowSelectDateView) | ||||
|                     } | ||||
|                      | ||||
|                     if isShowSelectTimeView { | ||||
|                         QuarterTimePickerView(selectedTime: $viewModel.releaseTime, isShowing: $isShowSelectTimeView) | ||||
|                     } | ||||
|                      | ||||
|                     if isShowPhotoPicker { | ||||
|                         ImagePicker( | ||||
|                             isShowing: $isShowPhotoPicker, | ||||
| @@ -494,7 +577,7 @@ struct ContentCreateView: View { | ||||
|                                 .padding(.vertical, 13.3) | ||||
|                                 .frame(width: screenSize().width - 66.7, alignment: .center) | ||||
|                                 .font(.custom(Font.medium.rawValue, size: 12)) | ||||
|                                 .background(Color(hex: "9970ff")) | ||||
|                                 .background(Color(hex: "3bb9f1")) | ||||
|                                 .foregroundColor(Color.white) | ||||
|                                 .multilineTextAlignment(.center) | ||||
|                                 .cornerRadius(20) | ||||
|   | ||||
| @@ -34,6 +34,7 @@ final class ContentCreateViewModel: ObservableObject { | ||||
|     } | ||||
|      | ||||
|     @Published var isAvailableComment = true | ||||
|     @Published var isActiveReservation = false | ||||
|     @Published var isAdult = false | ||||
|     @Published var priceString = "0" { | ||||
|         didSet { | ||||
| @@ -63,6 +64,20 @@ final class ContentCreateViewModel: ObservableObject { | ||||
|      | ||||
|     @Published var previewStartTime: String = "" | ||||
|     @Published var previewEndTime: String = "" | ||||
|     @Published var releaseDateString: String = Date().convertDateFormat(dateFormat: "yyyy.MM.dd") | ||||
|     @Published var releaseTimeString: String = Date().convertDateFormat(dateFormat: "a hh:mm") | ||||
|      | ||||
|     var releaseDate = Date() { | ||||
|         willSet { | ||||
|             releaseDateString = newValue.convertDateFormat(dateFormat: "yyyy.MM.dd") | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     var releaseTime = Date() { | ||||
|         willSet { | ||||
|             releaseTimeString = newValue.convertDateFormat(dateFormat: "a hh:mm") | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     var placeholder = "내용을 입력하세요" | ||||
|      | ||||
| @@ -75,6 +90,8 @@ final class ContentCreateViewModel: ObservableObject { | ||||
|                 detail: detail, | ||||
|                 tags: hashtags, | ||||
|                 price: price, | ||||
|                 releaseDate: isActiveReservation ? "\(releaseDate.convertDateFormat(dateFormat: "yyyy-MM-dd")) \(releaseTime.convertDateFormat(dateFormat: "HH:mm"))" : nil, | ||||
|                 timezone: TimeZone.current.identifier, | ||||
|                 themeId: theme!.id, | ||||
|                 isAdult: isAdult, | ||||
|                 isOnlyRental: isOnlyRental, | ||||
|   | ||||
| @@ -12,6 +12,8 @@ struct CreateAudioContentRequest: Encodable { | ||||
|     let detail: String | ||||
|     let tags: String | ||||
|     let price: Int | ||||
|     let releaseDate: String? | ||||
|     let timezone: String | ||||
|     let themeId: Int | ||||
|     let isAdult: Bool | ||||
|     let isOnlyRental: Bool | ||||
|   | ||||
							
								
								
									
										63
									
								
								SodaLive/Sources/Content/Create/QuarterTimePickerView.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								SodaLive/Sources/Content/Create/QuarterTimePickerView.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| // | ||||
| //  QuarterTimePickerView.swift | ||||
| //  SodaLive | ||||
| // | ||||
| //  Created by klaus on 2024/01/10. | ||||
| // | ||||
|  | ||||
| import SwiftUI | ||||
|  | ||||
| struct QuarterTimePickerView: View { | ||||
|      | ||||
|     @Binding var selectedTime: Date | ||||
|     @Binding var isShowing: Bool | ||||
|      | ||||
|     var body: some View { | ||||
|         GeometryReader { proxy in | ||||
|             ZStack { | ||||
|                 Color | ||||
|                     .black | ||||
|                     .opacity(0.5) | ||||
|                     .edgesIgnoringSafeArea(.all) | ||||
|                  | ||||
|                 VStack(spacing: 0) { | ||||
|                     DatePicker( | ||||
|                         "", | ||||
|                         selection: $selectedTime, | ||||
|                         displayedComponents: .hourAndMinute | ||||
|                     ) | ||||
|                     .datePickerStyle(WheelDatePickerStyle()) | ||||
|                     .labelsHidden() | ||||
|                     .environment(\.locale, Locale.init(identifier: "ko")) | ||||
|                     .frame(width: proxy.size.width - 53.4) | ||||
|                     .onAppear { | ||||
|                         UIDatePicker.appearance().minuteInterval = 15 | ||||
|                     } | ||||
|                     .onDisappear { | ||||
|                         UIDatePicker.appearance().minuteInterval = 1 | ||||
|                     } | ||||
|                      | ||||
|                     Button(action: { self.isShowing = false }) { | ||||
|                         Text("확인") | ||||
|                             .font(.system(size: 16)) | ||||
|                             .foregroundColor(Color(hex: "eeeeee")) | ||||
|                             .padding(.vertical, 10) | ||||
|                             .frame(width: proxy.size.width) | ||||
|                     } | ||||
|                 } | ||||
|                 .background(Color(hex: "222222")) | ||||
|                 .cornerRadius(6.7) | ||||
|             } | ||||
|             .frame(width: proxy.size.width) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| struct QuarterTimePickerView_Previews: PreviewProvider { | ||||
|     static var previews: some View { | ||||
|         QuarterTimePickerView( | ||||
|             selectedTime: .constant(Date()), | ||||
|             isShowing: .constant(true) | ||||
|         ) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										53
									
								
								SodaLive/Sources/Content/Create/SelectDatePicker.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								SodaLive/Sources/Content/Create/SelectDatePicker.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| // | ||||
| //  SelectDatePicker.swift | ||||
| //  SodaLive | ||||
| // | ||||
| //  Created by klaus on 2024/01/10. | ||||
| // | ||||
|  | ||||
| import SwiftUI | ||||
|  | ||||
| struct SelectDatePicker: View { | ||||
|      | ||||
|     @Binding var selectedDate: Date | ||||
|     @Binding var isShowing: Bool | ||||
|      | ||||
|     var body: some View { | ||||
|         GeometryReader { proxy in | ||||
|             ZStack { | ||||
|                 Color | ||||
|                     .black | ||||
|                     .opacity(0.5) | ||||
|                     .edgesIgnoringSafeArea(.all) | ||||
|                  | ||||
|                 VStack(spacing: 0) { | ||||
|                     DatePicker("", selection: $selectedDate, in: Date()..., displayedComponents: .date) | ||||
|                         .datePickerStyle(WheelDatePickerStyle()) | ||||
|                         .labelsHidden() | ||||
|                         .environment(\.locale, Locale.init(identifier: "ko")) | ||||
|                         .frame(width: proxy.size.width) | ||||
|                      | ||||
|                     Button(action: { self.isShowing = false }) { | ||||
|                         Text("확인") | ||||
|                             .font(.system(size: 16)) | ||||
|                             .foregroundColor(Color(hex: "eeeeee")) | ||||
|                             .padding(.vertical, 10) | ||||
|                             .frame(width: proxy.size.width - 53.4) | ||||
|                     } | ||||
|                 } | ||||
|                 .background(Color(hex: "222222")) | ||||
|                 .cornerRadius(6.7) | ||||
|             } | ||||
|             .frame(width: proxy.size.width) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| struct SelectDatePicker_Previews: PreviewProvider { | ||||
|     static var previews: some View { | ||||
|         SelectDatePicker( | ||||
|             selectedDate: .constant(Date()), | ||||
|             isShowing: .constant(true) | ||||
|         ) | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Yu Sung
					Yu Sung