From a22e2e7a519ca0a47ab2172c83fcd401958395ff Mon Sep 17 00:00:00 2001 From: Yu Sung Date: Wed, 6 Dec 2023 21:18:57 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A3=B0=EB=A0=9B=20=ED=94=84=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=8B=A4=EC=9D=B4=EC=96=BC=EB=A1=9C=EA=B7=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Config/RouletteSettingsView.swift | 27 ++++ .../Config/RouletteSettingsViewModel.swift | 29 +++++ .../Live/Room/Routlette/RoulettePreview.swift | 18 +++ .../Routlette/RoulettePreviewDialog.swift | 120 ++++++++++++++++++ 4 files changed, 194 insertions(+) create mode 100644 SodaLive/Sources/Live/Room/Routlette/RoulettePreview.swift create mode 100644 SodaLive/Sources/Live/Room/Routlette/RoulettePreviewDialog.swift diff --git a/SodaLive/Sources/Live/Room/Routlette/Config/RouletteSettingsView.swift b/SodaLive/Sources/Live/Room/Routlette/Config/RouletteSettingsView.swift index 7074633..7d8d1cc 100644 --- a/SodaLive/Sources/Live/Room/Routlette/Config/RouletteSettingsView.swift +++ b/SodaLive/Sources/Live/Room/Routlette/Config/RouletteSettingsView.swift @@ -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)) diff --git a/SodaLive/Sources/Live/Room/Routlette/Config/RouletteSettingsViewModel.swift b/SodaLive/Sources/Live/Room/Routlette/Config/RouletteSettingsViewModel.swift index 04bdef7..cc34754 100644 --- a/SodaLive/Sources/Live/Room/Routlette/Config/RouletteSettingsViewModel.swift +++ b/SodaLive/Sources/Live/Room/Routlette/Config/RouletteSettingsViewModel.swift @@ -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 + } } diff --git a/SodaLive/Sources/Live/Room/Routlette/RoulettePreview.swift b/SodaLive/Sources/Live/Room/Routlette/RoulettePreview.swift new file mode 100644 index 0000000..4066f31 --- /dev/null +++ b/SodaLive/Sources/Live/Room/Routlette/RoulettePreview.swift @@ -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 +} diff --git a/SodaLive/Sources/Live/Room/Routlette/RoulettePreviewDialog.swift b/SodaLive/Sources/Live/Room/Routlette/RoulettePreviewDialog.swift new file mode 100644 index 0000000..1984040 --- /dev/null +++ b/SodaLive/Sources/Live/Room/Routlette/RoulettePreviewDialog.swift @@ -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%"), + ] + ) + ) + } +}