라이브 메뉴 설정 페이지 추가
This commit is contained in:
		| @@ -90,7 +90,7 @@ final class LiveRepository { | ||||
|     } | ||||
|      | ||||
|     func setManager(roomId: Int, userId: Int) -> AnyPublisher<Response, MoyaError> { | ||||
|         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<Response, MoyaError> { | ||||
| @@ -114,10 +114,10 @@ final class LiveRepository { | ||||
|     } | ||||
|      | ||||
|     func getUserProfile(roomId: Int, userId: Int) -> AnyPublisher<Response, MoyaError> { | ||||
|         api.requestPublisher(.getUserProfile(roomId: roomId, userId: userId)) | ||||
|         return api.requestPublisher(.getUserProfile(roomId: roomId, userId: userId)) | ||||
|     } | ||||
|      | ||||
|     func getAllMenuPreset(creatorId: Int) -> AnyPublisher<Response, MoyaError> { | ||||
|         api.requestPublisher(.getAllMenuPreset(creatorId: creatorId)) | ||||
|         return api.requestPublisher(.getAllMenuPreset(creatorId: creatorId)) | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										54
									
								
								SodaLive/Sources/Live/Room/Menu/MenuApi.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								SodaLive/Sources/Live/Room/Menu/MenuApi.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -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))"] | ||||
|     } | ||||
| } | ||||
							
								
								
									
										23
									
								
								SodaLive/Sources/Live/Room/Menu/MenuSettingsRepository.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								SodaLive/Sources/Live/Room/Menu/MenuSettingsRepository.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -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<MenuApi>() | ||||
|      | ||||
|     func getAllMenuPreset(creatorId: Int) -> AnyPublisher<Response, MoyaError> { | ||||
|         return api.requestPublisher(.getAllMenuPreset(creatorId: creatorId)) | ||||
|     } | ||||
|      | ||||
|     func saveMenu(menuId: Int, menu: String) -> AnyPublisher<Response, MoyaError> { | ||||
|         return api.requestPublisher(.saveMenu(request: UpdateLiveMenuRequest(id: menuId, menu: menu))) | ||||
|     } | ||||
| } | ||||
| @@ -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() | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -6,7 +6,139 @@ | ||||
| // | ||||
|  | ||||
| import Foundation | ||||
| import Moya | ||||
| import Combine | ||||
|  | ||||
| final class MenuSettingsViewModel: ObservableObject { | ||||
|      | ||||
|     private let repository = MenuSettingsRepository() | ||||
|     private var subscription = Set<AnyCancellable>() | ||||
|      | ||||
|     @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) | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										12
									
								
								SodaLive/Sources/Live/Room/Menu/UpdateLiveMenuRequest.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								SodaLive/Sources/Live/Room/Menu/UpdateLiveMenuRequest.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Yu Sung
					Yu Sung