diff --git a/SodaLive/Sources/Live/LiveRepository.swift b/SodaLive/Sources/Live/LiveRepository.swift index 270a35c..42f8fc2 100644 --- a/SodaLive/Sources/Live/LiveRepository.swift +++ b/SodaLive/Sources/Live/LiveRepository.swift @@ -90,7 +90,7 @@ final class LiveRepository { } func setManager(roomId: Int, userId: Int) -> AnyPublisher { - api.requestPublisher(.setManager(request: SetManagerOrSpeakerOrAudienceRequest(roomId: roomId, memberId: userId))) + return api.requestPublisher(.setManager(request: SetManagerOrSpeakerOrAudienceRequest(roomId: roomId, memberId: userId))) } func kickOut(roomId: Int, userId: Int) -> AnyPublisher { @@ -114,10 +114,10 @@ final class LiveRepository { } func getUserProfile(roomId: Int, userId: Int) -> AnyPublisher { - api.requestPublisher(.getUserProfile(roomId: roomId, userId: userId)) + return api.requestPublisher(.getUserProfile(roomId: roomId, userId: userId)) } func getAllMenuPreset(creatorId: Int) -> AnyPublisher { - api.requestPublisher(.getAllMenuPreset(creatorId: creatorId)) + return api.requestPublisher(.getAllMenuPreset(creatorId: creatorId)) } } diff --git a/SodaLive/Sources/Live/Room/Menu/MenuApi.swift b/SodaLive/Sources/Live/Room/Menu/MenuApi.swift new file mode 100644 index 0000000..b7c2534 --- /dev/null +++ b/SodaLive/Sources/Live/Room/Menu/MenuApi.swift @@ -0,0 +1,54 @@ +// +// MenuApi.swift +// SodaLive +// +// Created by klaus on 10/8/24. +// + +import Foundation +import Moya + +enum MenuApi { + case getAllMenuPreset(creatorId: Int) + case saveMenu(request: UpdateLiveMenuRequest) +} + +extension MenuApi: TargetType { + var baseURL: URL { + return URL(string: BASE_URL)! + } + + var path: String { + switch self { + case .getAllMenuPreset: + return "/live/room/menu/all" + + case .saveMenu: + return "/live/room/menu" + } + } + + var method: Moya.Method { + switch self { + case .getAllMenuPreset: + return .get + + case .saveMenu: + return .post + } + } + + var task: Moya.Task { + switch self { + case .getAllMenuPreset(let creatorId): + return .requestParameters(parameters: ["creatorId" : creatorId], encoding: URLEncoding.queryString) + + case .saveMenu(let request): + return .requestJSONEncodable(request) + } + } + + var headers: [String : String]? { + return ["Authorization": "Bearer \(UserDefaults.string(forKey: UserDefaultsKey.token))"] + } +} diff --git a/SodaLive/Sources/Live/Room/Menu/MenuSettingsRepository.swift b/SodaLive/Sources/Live/Room/Menu/MenuSettingsRepository.swift new file mode 100644 index 0000000..88195ce --- /dev/null +++ b/SodaLive/Sources/Live/Room/Menu/MenuSettingsRepository.swift @@ -0,0 +1,23 @@ +// +// MenuSettingsRepository.swift +// SodaLive +// +// Created by klaus on 10/8/24. +// + +import Foundation +import CombineMoya +import Combine +import Moya + +final class MenuSettingsRepository { + private let api = MoyaProvider() + + func getAllMenuPreset(creatorId: Int) -> AnyPublisher { + return api.requestPublisher(.getAllMenuPreset(creatorId: creatorId)) + } + + func saveMenu(menuId: Int, menu: String) -> AnyPublisher { + return api.requestPublisher(.saveMenu(request: UpdateLiveMenuRequest(id: menuId, menu: menu))) + } +} diff --git a/SodaLive/Sources/Live/Room/Menu/MenuSettingsView.swift b/SodaLive/Sources/Live/Room/Menu/MenuSettingsView.swift index bda1d77..885daaf 100644 --- a/SodaLive/Sources/Live/Room/Menu/MenuSettingsView.swift +++ b/SodaLive/Sources/Live/Room/Menu/MenuSettingsView.swift @@ -15,13 +15,84 @@ struct MenuSettingsView: View { var body: some View { BaseView(isLoading: $viewModel.isLoading) { - VStack(spacing: 0) { - DetailNavigationBar(title: "메뉴 설정") + VStack(spacing: 13.3) { + DetailNavigationBar(title: "메뉴 설정") { + isShowing = false + } - Text("메뉴 설정") + HStack(spacing: 13.3) { + SelectedButtonView( + title: "메뉴 1", + isActive: true, + isSelected: viewModel.selectedMenu == .MENU_1 + ) + .onTapGesture { + viewModel.selectMenuPreset(selectedMenuPreset: .MENU_1) + } + + SelectedButtonView( + title: "메뉴 2", + isActive: viewModel.menuList.count > 0, + isSelected: viewModel.selectedMenu == .MENU_2 + ) + .onTapGesture { + viewModel.selectMenuPreset(selectedMenuPreset: .MENU_2) + } + + SelectedButtonView( + title: "메뉴 3", + isActive: viewModel.menuList.count > 1, + isSelected: viewModel.selectedMenu == .MENU_3 + ) + .onTapGesture { + viewModel.selectMenuPreset(selectedMenuPreset: .MENU_3) + } + } + .padding(.horizontal, 13.3) + + TextViewWrapper( + text: $viewModel.menu, + placeholder: "메뉴판을 작성해주세요.", + textColorHex: "eeeeee", + backgroundColorHex: "303030" + ) + .frame(height: 350) + .cornerRadius(6.7) + .padding(.horizontal, 13.3) + + Text("저장하기") + .font(.custom(Font.bold.rawValue, size: 18.3)) + .foregroundColor(.white) + .padding(.vertical, 16) + .frame(maxWidth: .infinity) + .background(Color.button) + .cornerRadius(10) + .padding(.horizontal, 13.3) + .clipShape(Rectangle()) + .onTapGesture { viewModel.saveMenu() } Spacer() } + .onAppear { + viewModel.getAllMenuPreset { + self.isShowing = false + } + } + .popup(isPresented: $viewModel.isShowPopup, type: .toast, position: .bottom, autohideIn: 2) { + HStack { + Spacer() + Text(viewModel.errorMessage) + .padding(.vertical, 13.3) + .frame(width: screenSize().width - 66.7, alignment: .center) + .font(.custom(Font.medium.rawValue, size: 12)) + .background(Color.button) + .foregroundColor(Color.white) + .multilineTextAlignment(.leading) + .cornerRadius(20) + .padding(.bottom, 66.7) + Spacer() + } + } } } } diff --git a/SodaLive/Sources/Live/Room/Menu/MenuSettingsViewModel.swift b/SodaLive/Sources/Live/Room/Menu/MenuSettingsViewModel.swift index 831f865..c2716d4 100644 --- a/SodaLive/Sources/Live/Room/Menu/MenuSettingsViewModel.swift +++ b/SodaLive/Sources/Live/Room/Menu/MenuSettingsViewModel.swift @@ -6,7 +6,139 @@ // import Foundation +import Moya +import Combine final class MenuSettingsViewModel: ObservableObject { + + private let repository = MenuSettingsRepository() + private var subscription = Set() + @Published var isLoading = false + @Published var errorMessage = "" + @Published var isShowPopup = false + + private var menuId = 0 + @Published var menu = "" + @Published var menuList = [GetMenuPresetResponse]() + @Published var selectedMenu: SelectedMenu? = nil + + private var selectedMenuText = "" + + func selectMenuPreset(selectedMenuPreset: SelectedMenu) { + if menuList.isEmpty && (selectedMenuPreset == .MENU_2 || selectedMenuPreset == .MENU_3) { + errorMessage = "메뉴 1을 먼저 설정하세요" + isShowPopup = true + return + } + + if menuList.count == 1 && selectedMenuPreset == .MENU_3 { + errorMessage = "메뉴 1과 메뉴 2를 먼저 설정하세요" + isShowPopup = true + return + } + + if self.selectedMenu != selectedMenuPreset { + self.selectedMenu = selectedMenuPreset + + if menuList.count > selectedMenuPreset.rawValue { + let menu = menuList[selectedMenuPreset.rawValue] + self.menu = menu.menu + self.menuId = menu.id + self.selectedMenuText = menu.menu + } else { + self.menu = "" + self.menuId = 0 + self.selectedMenuText = "" + } + } + } + + func getAllMenuPreset(selectedMenu: SelectedMenu = .MENU_1, onFailure: @escaping () -> Void) { + isLoading = true + + repository.getAllMenuPreset(creatorId: UserDefaults.int(forKey: .userId)) + .sink { result in + switch result { + case .finished: + DEBUG_LOG("finish") + case .failure(let error): + ERROR_LOG(error.localizedDescription) + } + } receiveValue: { [unowned self] response in + self.isLoading = false + let responseData = response.data + + do { + let jsonDecoder = JSONDecoder() + let decoded = try jsonDecoder.decode(ApiResponse<[GetMenuPresetResponse]>.self, from: responseData) + + if let data = decoded.data, decoded.success { + self.menuList.removeAll() + self.menuList.append(contentsOf: data) + self.selectMenuPreset(selectedMenuPreset: selectedMenu) + } else { + onFailure() + if let message = decoded.message { + self.errorMessage = message + } else { + self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." + } + + self.isShowPopup = true + } + } catch { + onFailure() + self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." + self.isShowPopup = true + } + } + .store(in: &subscription) + } + + func saveMenu() { + if selectedMenuText == menu { + self.errorMessage = "저장되었습니다." + self.isShowPopup = true + return + } + + isLoading = true + + repository.saveMenu(menuId: menuId, menu: menu) + .sink { result in + switch result { + case .finished: + DEBUG_LOG("finish") + case .failure(let error): + ERROR_LOG(error.localizedDescription) + } + } receiveValue: { [unowned self] response in + self.isLoading = false + let responseData = response.data + + do { + let jsonDecoder = JSONDecoder() + let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData) + + if decoded.success { + self.errorMessage = "저장되었습니다." + self.isShowPopup = true + self.getAllMenuPreset(selectedMenu: self.selectedMenu ?? .MENU_1) {} + } else { + if let message = decoded.message { + self.errorMessage = message + } else { + self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." + } + + self.isShowPopup = true + } + } catch { + self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." + self.isShowPopup = true + } + } + .store(in: &subscription) + } } diff --git a/SodaLive/Sources/Live/Room/Menu/UpdateLiveMenuRequest.swift b/SodaLive/Sources/Live/Room/Menu/UpdateLiveMenuRequest.swift new file mode 100644 index 0000000..6616d0a --- /dev/null +++ b/SodaLive/Sources/Live/Room/Menu/UpdateLiveMenuRequest.swift @@ -0,0 +1,12 @@ +// +// UpdateLiveMenuRequest.swift +// SodaLive +// +// Created by klaus on 10/8/24. +// + +struct UpdateLiveMenuRequest: Encodable { + let id: Int + let menu: String + let isActive: Bool = false +}