룰렛 프리뷰 다이얼로그 추가
This commit is contained in:
		| @@ -121,6 +121,7 @@ struct RouletteSettingsView: View { | ||||
|                                     .foregroundColor(Color(hex: "3bb9f1")) | ||||
|                             ) | ||||
|                             .onTapGesture { | ||||
|                                 viewModel.onClickPreview() | ||||
|                             } | ||||
|                          | ||||
|                         Text("설정완료") | ||||
| @@ -143,6 +144,32 @@ struct RouletteSettingsView: View { | ||||
|                             .frame(width: screenSize().width, height: 15.3) | ||||
|                     } | ||||
|                 } | ||||
|                  | ||||
|                 if let preview = viewModel.previewData, viewModel.isShowPreview { | ||||
|                     RoulettePreviewDialog( | ||||
|                         isShowing: $viewModel.isShowPreview, | ||||
|                         title: "룰렛 미리보기", | ||||
|                         onClickSpin: nil, | ||||
|                         preview: preview | ||||
|                     ) | ||||
|                 } | ||||
|             } | ||||
|             .popup(isPresented: $viewModel.isShowErrorPopup, type: .toast, position: .top, autohideIn: 1.3) { | ||||
|                 GeometryReader { geo in | ||||
|                     HStack { | ||||
|                         Spacer() | ||||
|                         Text(viewModel.errorMessage) | ||||
|                             .padding(.vertical, 13.3) | ||||
|                             .frame(width: geo.size.width - 66.7, alignment: .center) | ||||
|                             .font(.custom(Font.medium.rawValue, size: 12)) | ||||
|                             .background(Color(hex: "9970ff")) | ||||
|                             .foregroundColor(Color.white) | ||||
|                             .multilineTextAlignment(.center) | ||||
|                             .cornerRadius(20) | ||||
|                             .padding(.top, 66.7) | ||||
|                         Spacer() | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             .onAppear { | ||||
|                 viewModel.getRoulette(creatorId: UserDefaults.int(forKey: .userId)) | ||||
|   | ||||
| @@ -25,6 +25,15 @@ final class RouletteSettingsViewModel: ObservableObject { | ||||
|     @Published var isActive = false | ||||
|     @Published var options = [RouletteOption]() | ||||
|      | ||||
|     @Published var isShowPreview = false { | ||||
|         didSet { | ||||
|             if !isShowPreview { | ||||
|                 previewData = nil | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     @Published var previewData: RoulettePreview? = nil | ||||
|      | ||||
|     var can = 5 | ||||
|      | ||||
|     func plusWeight(index: Int) { | ||||
| @@ -118,4 +127,24 @@ final class RouletteSettingsViewModel: ObservableObject { | ||||
|             } | ||||
|             .store(in: &subscription) | ||||
|     } | ||||
|      | ||||
|     func onClickPreview() { | ||||
|         isLoading = true | ||||
|          | ||||
|         var items = [RoulettePreviewItem]() | ||||
|         for option in options { | ||||
|             if option.title.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { | ||||
|                 isLoading = false | ||||
|                 errorMessage = "옵션은 빈칸일 수 없습니다." | ||||
|                 isShowErrorPopup = true | ||||
|                 return | ||||
|             } | ||||
|              | ||||
|             items.append(RoulettePreviewItem(title: option.title, percent: "\(option.percentage)%")) | ||||
|         } | ||||
|          | ||||
|         previewData = RoulettePreview(can: self.can, items: items) | ||||
|         isLoading = false | ||||
|         isShowPreview = true | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										18
									
								
								SodaLive/Sources/Live/Room/Routlette/RoulettePreview.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								SodaLive/Sources/Live/Room/Routlette/RoulettePreview.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| // | ||||
| //  RoulettePreview.swift | ||||
| //  SodaLive | ||||
| // | ||||
| //  Created by klaus on 2023/12/06. | ||||
| // | ||||
|  | ||||
| import Foundation | ||||
|  | ||||
| struct RoulettePreview { | ||||
|     let can: Int | ||||
|     let items: [RoulettePreviewItem] | ||||
| } | ||||
|  | ||||
| struct RoulettePreviewItem { | ||||
|     let title: String | ||||
|     let percent: String | ||||
| } | ||||
							
								
								
									
										120
									
								
								SodaLive/Sources/Live/Room/Routlette/RoulettePreviewDialog.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								SodaLive/Sources/Live/Room/Routlette/RoulettePreviewDialog.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,120 @@ | ||||
| // | ||||
| //  RoulettePreviewDialog.swift | ||||
| //  SodaLive | ||||
| // | ||||
| //  Created by klaus on 2023/12/06. | ||||
| // | ||||
|  | ||||
| import SwiftUI | ||||
|  | ||||
| struct RoulettePreviewDialog: View { | ||||
|      | ||||
|     @Binding var isShowing: Bool | ||||
|      | ||||
|     let title: String? | ||||
|     let onClickSpin: (() -> Void)? | ||||
|     let preview: RoulettePreview | ||||
|      | ||||
|     var body: some View { | ||||
|         GeometryReader { geo in | ||||
|             ZStack { | ||||
|                 VStack(spacing: 0) { | ||||
|                     HStack(spacing: 0) { | ||||
|                         Text(title ?? "룰렛") | ||||
|                             .font(.custom(Font.bold.rawValue, size: 18.3)) | ||||
|                             .foregroundColor(.white) | ||||
|                          | ||||
|                         Spacer() | ||||
|                          | ||||
|                         if let _ = onClickSpin { | ||||
|                             HStack(spacing: 6.7) { | ||||
|                                 Image("ic_can") | ||||
|                                 Text("\(UserDefaults.int(forKey: .can))") | ||||
|                                     .font(.custom(Font.bold.rawValue, size: 16)) | ||||
|                                     .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                 Image("ic_forward") | ||||
|                             } | ||||
|                             .onTapGesture { | ||||
|                                 isShowing = false | ||||
|                                 DispatchQueue.main.async { | ||||
|                                     AppState.shared.setAppStep(step: .canCharge(refresh: {}, afterCompletionToGoBack: true)) | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     .padding(.top, 16.7) | ||||
|                     .padding(.horizontal, 13.3) | ||||
|                      | ||||
|                     LazyVStack(alignment: .leading, spacing: 13.3) { | ||||
|                         ForEach(preview.items.indices, id: \.self) { index in | ||||
|                             HStack(spacing:13.3) { | ||||
|                                 Text("\(index + 1)") | ||||
|                                     .font(.custom(Font.bold.rawValue, size: 14.7)) | ||||
|                                     .foregroundColor(Color(hex: "e2e2e2")) | ||||
|                                  | ||||
|                                 Text("\(preview.items[index].title) (\(preview.items[index].percent))") | ||||
|                                     .font(.custom(Font.medium.rawValue, size: 14.7)) | ||||
|                                     .foregroundColor(Color(hex: "e2e2e2")) | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     .padding(.top, 13.3) | ||||
|                     .padding(.horizontal, 13.3) | ||||
|                      | ||||
|                     HStack(spacing: 13.3) { | ||||
|                         Text("취소") | ||||
|                             .font(.custom(Font.bold.rawValue, size: 16)) | ||||
|                             .foregroundColor(Color(hex: "3bb9f1")) | ||||
|                             .padding(.horizontal, 18) | ||||
|                             .padding(.vertical, 16) | ||||
|                             .overlay( | ||||
|                                 RoundedRectangle(cornerRadius: 10) | ||||
|                                     .stroke(Color(hex: "3bb9f1"), lineWidth: 1) | ||||
|                             ) | ||||
|                             .onTapGesture { | ||||
|                                 isShowing = false | ||||
|                             } | ||||
|                          | ||||
|                         Text("\(preview.can)캔으로 룰렛 돌리기") | ||||
|                             .font(.custom(Font.bold.rawValue, size: 16)) | ||||
|                             .foregroundColor(.white) | ||||
|                             .padding(.vertical, 16) | ||||
|                             .frame(maxWidth: .infinity) | ||||
|                             .background(Color(hex: "3bb9f1")) | ||||
|                             .cornerRadius(10) | ||||
|                             .onTapGesture { | ||||
|                                 if let onClickSpin = onClickSpin { | ||||
|                                     onClickSpin() | ||||
|                                 } | ||||
|                                 isShowing = false | ||||
|                             } | ||||
|                     } | ||||
|                     .padding(.top, 26.7) | ||||
|                 } | ||||
|                 .padding(13.3) | ||||
|                 .background(Color(hex: "222222")) | ||||
|                 .cornerRadius(16.7) | ||||
|                 .padding(.horizontal, 13.3) | ||||
|             } | ||||
|             .frame(width: geo.size.width, height: geo.size.height) | ||||
|             .background(Color.black.opacity(0.7)) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| struct RoulettePreviewDialog_Previews: PreviewProvider { | ||||
|     static var previews: some View { | ||||
|         RoulettePreviewDialog( | ||||
|             isShowing: .constant(true), | ||||
|             title: nil, | ||||
|             onClickSpin: nil, | ||||
|             preview: RoulettePreview( | ||||
|                 can: 100, | ||||
|                 items: [ | ||||
|                     RoulettePreviewItem(title: "옵션1", percent: "10%"), | ||||
|                     RoulettePreviewItem(title: "옵션2", percent: "90%"), | ||||
|                 ] | ||||
|             ) | ||||
|         ) | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Yu Sung
					Yu Sung