feat: 메인 라이브
- 여러개로 나눠져 있던 API 하나로 병합
This commit is contained in:
		
							
								
								
									
										13
									
								
								SodaLive/Sources/Live/GetLatestFinishedLiveResponse.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								SodaLive/Sources/Live/GetLatestFinishedLiveResponse.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					//
 | 
				
			||||||
 | 
					//  GetLatestFinishedLiveResponse.swift
 | 
				
			||||||
 | 
					//  SodaLive
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//  Created by klaus on 7/22/25.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct GetLatestFinishedLiveResponse: Decodable {
 | 
				
			||||||
 | 
					    let memberId: Int
 | 
				
			||||||
 | 
					    let nickname: String
 | 
				
			||||||
 | 
					    let profileImageUrl: String
 | 
				
			||||||
 | 
					    let timeAgo: String
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -40,6 +40,7 @@ enum LiveApi {
 | 
				
			|||||||
    case likeHeart(request: LiveRoomLikeHeartRequest)
 | 
					    case likeHeart(request: LiveRoomLikeHeartRequest)
 | 
				
			||||||
    case getTotalHeartCount(roomId: Int)
 | 
					    case getTotalHeartCount(roomId: Int)
 | 
				
			||||||
    case heartStatus(roomId: Int)
 | 
					    case heartStatus(roomId: Int)
 | 
				
			||||||
 | 
					    case getLiveMain(isAdultContentVisible: Bool, contentType: ContentType)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extension LiveApi: TargetType {
 | 
					extension LiveApi: TargetType {
 | 
				
			||||||
@@ -141,12 +142,15 @@ extension LiveApi: TargetType {
 | 
				
			|||||||
            
 | 
					            
 | 
				
			||||||
        case .heartStatus(let roomId):
 | 
					        case .heartStatus(let roomId):
 | 
				
			||||||
            return "/live/room/\(roomId)/heart-list"
 | 
					            return "/live/room/\(roomId)/heart-list"
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        case .getLiveMain:
 | 
				
			||||||
 | 
					            return "/api/live"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    var method: Moya.Method {
 | 
					    var method: Moya.Method {
 | 
				
			||||||
        switch self {
 | 
					        switch self {
 | 
				
			||||||
        case .roomList, .recentVisitRoomUsers, .getReservations, .getReservation, .getRoomDetail, .getTags, .getRecentRoomInfo, .getRoomInfo, .donationStatus, .donationTotal, .getDonationMessageList, .getUserProfile, .getAllMenuPreset, .getTotalHeartCount, .heartStatus:
 | 
					        case .roomList, .recentVisitRoomUsers, .getReservations, .getReservation, .getRoomDetail, .getTags, .getRecentRoomInfo, .getRoomInfo, .donationStatus, .donationTotal, .getDonationMessageList, .getUserProfile, .getAllMenuPreset, .getTotalHeartCount, .heartStatus, .getLiveMain:
 | 
				
			||||||
            return .get
 | 
					            return .get
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
        case .makeReservation, .enterRoom, .createRoom, .quitRoom, .donation, .refundDonation, .kickOut, .likeHeart:
 | 
					        case .makeReservation, .enterRoom, .createRoom, .quitRoom, .donation, .refundDonation, .kickOut, .likeHeart:
 | 
				
			||||||
@@ -248,6 +252,18 @@ extension LiveApi: TargetType {
 | 
				
			|||||||
            
 | 
					            
 | 
				
			||||||
        case .likeHeart(let request):
 | 
					        case .likeHeart(let request):
 | 
				
			||||||
            return .requestJSONEncodable(request)
 | 
					            return .requestJSONEncodable(request)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        case .getLiveMain(let isAdultContentVisible, let contentType):
 | 
				
			||||||
 | 
					            let parameters = [
 | 
				
			||||||
 | 
					                "timezone": TimeZone.current.identifier,
 | 
				
			||||||
 | 
					                "isAdultContentVisible": isAdultContentVisible,
 | 
				
			||||||
 | 
					                "contentType": contentType
 | 
				
			||||||
 | 
					            ] as [String: Any]
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            return .requestParameters(
 | 
				
			||||||
 | 
					                parameters: parameters,
 | 
				
			||||||
 | 
					                encoding: URLEncoding.queryString
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								SodaLive/Sources/Live/LiveMainResponse.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								SodaLive/Sources/Live/LiveMainResponse.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					//
 | 
				
			||||||
 | 
					//  LiveMainResponse.swift
 | 
				
			||||||
 | 
					//  SodaLive
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//  Created by klaus on 7/22/25.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Foundation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct LiveMainResponse: Decodable {
 | 
				
			||||||
 | 
					    let liveOnAirRoomList: [GetRoomListResponse]
 | 
				
			||||||
 | 
					    let communityPostList: [GetCommunityPostListResponse]
 | 
				
			||||||
 | 
					    let recommendLiveList: [GetRecommendLiveResponse]
 | 
				
			||||||
 | 
					    let latestFinishedLiveList: [GetLatestFinishedLiveResponse]
 | 
				
			||||||
 | 
					    let replayLive: [AudioContentMainItem]
 | 
				
			||||||
 | 
					    let followingChannelList: [GetRecommendChannelResponse]
 | 
				
			||||||
 | 
					    let liveReservationRoomList: [GetRoomListResponse]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -132,4 +132,13 @@ final class LiveRepository {
 | 
				
			|||||||
    func heartStatus(roomId: Int) -> AnyPublisher<Response, MoyaError> {
 | 
					    func heartStatus(roomId: Int) -> AnyPublisher<Response, MoyaError> {
 | 
				
			||||||
        return api.requestPublisher(.heartStatus(roomId: roomId))
 | 
					        return api.requestPublisher(.heartStatus(roomId: roomId))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    func getLiveMain() -> AnyPublisher<Response, MoyaError> {
 | 
				
			||||||
 | 
					        return api.requestPublisher(
 | 
				
			||||||
 | 
					            .getLiveMain(
 | 
				
			||||||
 | 
					                isAdultContentVisible: UserDefaults.isAdultContentVisible(),
 | 
				
			||||||
 | 
					                contentType: ContentType(rawValue: UserDefaults.string(forKey: .contentPreference)) ?? ContentType.ALL
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -69,7 +69,7 @@ struct LiveView: View {
 | 
				
			|||||||
                                    }
 | 
					                                    }
 | 
				
			||||||
                                },
 | 
					                                },
 | 
				
			||||||
                                onClickRefresh: {
 | 
					                                onClickRefresh: {
 | 
				
			||||||
                                    viewModel.getSummary()
 | 
					                                    viewModel.getLiveMain()
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            )
 | 
					                            )
 | 
				
			||||||
                            
 | 
					                            
 | 
				
			||||||
@@ -92,7 +92,7 @@ struct LiveView: View {
 | 
				
			|||||||
                            
 | 
					                            
 | 
				
			||||||
                            SectionLiveReservationView(
 | 
					                            SectionLiveReservationView(
 | 
				
			||||||
                                items: viewModel.liveReservationItems,
 | 
					                                items: viewModel.liveReservationItems,
 | 
				
			||||||
                                onClickCancel: { viewModel.getSummary() },
 | 
					                                onClickCancel: { viewModel.getLiveMain() },
 | 
				
			||||||
                                onClickStart: { roomId in
 | 
					                                onClickStart: { roomId in
 | 
				
			||||||
                                    if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
 | 
					                                    if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
 | 
				
			||||||
                                        processStart(roomId: roomId)
 | 
					                                        processStart(roomId: roomId)
 | 
				
			||||||
@@ -119,7 +119,7 @@ struct LiveView: View {
 | 
				
			|||||||
                        .padding(.vertical, 24)
 | 
					                        .padding(.vertical, 24)
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    .onAppear {
 | 
					                    .onAppear {
 | 
				
			||||||
                        viewModel.getSummary()
 | 
					                        viewModel.getLiveMain()
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
@@ -159,10 +159,7 @@ struct LiveView: View {
 | 
				
			|||||||
                )
 | 
					                )
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            if viewModel.isFollowedChannelLoading ||
 | 
					            if viewModel.isLoading {
 | 
				
			||||||
                viewModel.isRecommendChannelLoading ||
 | 
					 | 
				
			||||||
                viewModel.isRecommendLiveLoading ||
 | 
					 | 
				
			||||||
                viewModel.isLoading {
 | 
					 | 
				
			||||||
                LoadingView()
 | 
					                LoadingView()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -188,7 +185,7 @@ struct LiveView: View {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    private func onCreateSuccess(response: CreateLiveRoomResponse) {
 | 
					    private func onCreateSuccess(response: CreateLiveRoomResponse) {
 | 
				
			||||||
        viewModel.getSummary()
 | 
					        viewModel.getLiveMain()
 | 
				
			||||||
        if let _ = response.channelName {
 | 
					        if let _ = response.channelName {
 | 
				
			||||||
            viewModel.enterRoom(roomId: response.id!)
 | 
					            viewModel.enterRoom(roomId: response.id!)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,14 +21,13 @@ final class LiveViewModel: ObservableObject {
 | 
				
			|||||||
    @Published private(set) var recommendChannelItems: [GetRecommendChannelResponse] = []
 | 
					    @Published private(set) var recommendChannelItems: [GetRecommendChannelResponse] = []
 | 
				
			||||||
    @Published private(set) var followedChannelItems: [GetRecommendChannelResponse] = []
 | 
					    @Published private(set) var followedChannelItems: [GetRecommendChannelResponse] = []
 | 
				
			||||||
    @Published private(set) var communityPostItems: [GetCommunityPostListResponse] = []
 | 
					    @Published private(set) var communityPostItems: [GetCommunityPostListResponse] = []
 | 
				
			||||||
 | 
					    @Published private(set) var replayLiveItems: [AudioContentMainItem] = []
 | 
				
			||||||
 | 
					    @Published private(set) var latestFinishedLiveItems: [GetLatestFinishedLiveResponse] = []
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    @Published var errorMessage = ""
 | 
					    @Published var errorMessage = ""
 | 
				
			||||||
    @Published var isShowPopup = false
 | 
					    @Published var isShowPopup = false
 | 
				
			||||||
    @Published var isRefresh = false
 | 
					    @Published var isRefresh = false
 | 
				
			||||||
    @Published var isLoading = false
 | 
					    @Published var isLoading = false
 | 
				
			||||||
    @Published var isRecommendLiveLoading = false
 | 
					 | 
				
			||||||
    @Published var isRecommendChannelLoading = false
 | 
					 | 
				
			||||||
    @Published var isFollowedChannelLoading = false
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    @Published var paymentDialogTitle = ""
 | 
					    @Published var paymentDialogTitle = ""
 | 
				
			||||||
    @Published var paymentDialogDesc = ""
 | 
					    @Published var paymentDialogDesc = ""
 | 
				
			||||||
@@ -81,47 +80,10 @@ final class LiveViewModel: ObservableObject {
 | 
				
			|||||||
        passwordDialogConfirmAction = { _ in }
 | 
					        passwordDialogConfirmAction = { _ in }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    func getSummary() {
 | 
					    func getLiveMain() {
 | 
				
			||||||
        if !UserDefaults.string(forKey: UserDefaultsKey.token).trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
 | 
					 | 
				
			||||||
            getFollowedChannelList()
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        getRecommendChannelList()
 | 
					 | 
				
			||||||
        getRecommendLive()
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        if !UserDefaults.string(forKey: UserDefaultsKey.token).trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
 | 
					 | 
				
			||||||
            getLatestPostListFromCreatorsYouFollow()
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        isLoading = true
 | 
					        isLoading = true
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        liveNowItems.removeAll()
 | 
					        repository.getLiveMain()
 | 
				
			||||||
        liveReservationItems.removeAll()
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        let liveNow = repository.roomList(
 | 
					 | 
				
			||||||
            request: GetRoomListRequest(
 | 
					 | 
				
			||||||
                timezone: TimeZone.current.identifier,
 | 
					 | 
				
			||||||
                dateString: nil,
 | 
					 | 
				
			||||||
                status: .NOW,
 | 
					 | 
				
			||||||
                isAdultContentVisible: UserDefaults.isAdultContentVisible(),
 | 
					 | 
				
			||||||
                page: 1,
 | 
					 | 
				
			||||||
                size: 10
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        let liveReservation = repository.roomList(
 | 
					 | 
				
			||||||
            request: GetRoomListRequest(
 | 
					 | 
				
			||||||
                timezone: TimeZone.current.identifier,
 | 
					 | 
				
			||||||
                dateString: nil,
 | 
					 | 
				
			||||||
                status: .RESERVATION,
 | 
					 | 
				
			||||||
                isAdultContentVisible: UserDefaults.isAdultContentVisible(),
 | 
					 | 
				
			||||||
                page: 1,
 | 
					 | 
				
			||||||
                size: 10
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        Publishers
 | 
					 | 
				
			||||||
            .CombineLatest(liveNow, liveReservation)
 | 
					 | 
				
			||||||
            .sink { result in
 | 
					            .sink { result in
 | 
				
			||||||
                switch result {
 | 
					                switch result {
 | 
				
			||||||
                case .finished:
 | 
					                case .finished:
 | 
				
			||||||
@@ -129,52 +91,35 @@ final class LiveViewModel: ObservableObject {
 | 
				
			|||||||
                case .failure(let error):
 | 
					                case .failure(let error):
 | 
				
			||||||
                    ERROR_LOG(error.localizedDescription)
 | 
					                    ERROR_LOG(error.localizedDescription)
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } receiveValue: { (now, reservation) in
 | 
					            } receiveValue: { [unowned self] response in
 | 
				
			||||||
                let nowData = now.data
 | 
					 | 
				
			||||||
                let reservationData = reservation.data
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                let jsonDecoder = JSONDecoder()
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                do {
 | 
					 | 
				
			||||||
                    let nowDecoded = try jsonDecoder.decode(ApiResponse<[GetRoomListResponse]>.self, from: nowData)
 | 
					 | 
				
			||||||
                    if let data = nowDecoded.data, nowDecoded.success {
 | 
					 | 
				
			||||||
                        self.liveNowItems.removeAll()
 | 
					 | 
				
			||||||
                        self.liveNowItems.append(contentsOf: data)
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        if let message = nowDecoded.message {
 | 
					 | 
				
			||||||
                            self.errorMessage = message
 | 
					 | 
				
			||||||
                        } else {
 | 
					 | 
				
			||||||
                            self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        
 | 
					 | 
				
			||||||
                        self.isShowPopup = true
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } catch {
 | 
					 | 
				
			||||||
                    self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
 | 
					 | 
				
			||||||
                    self.isShowPopup = true
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                do {
 | 
					 | 
				
			||||||
                    let reservationDecoded = try jsonDecoder.decode(ApiResponse<[GetRoomListResponse]>.self, from: reservationData)
 | 
					 | 
				
			||||||
                    if let data = reservationDecoded.data, reservationDecoded.success {
 | 
					 | 
				
			||||||
                        self.liveReservationItems.removeAll()
 | 
					 | 
				
			||||||
                        self.liveReservationItems.append(contentsOf: data)
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        if let message = reservationDecoded.message {
 | 
					 | 
				
			||||||
                            self.errorMessage = message
 | 
					 | 
				
			||||||
                        } else {
 | 
					 | 
				
			||||||
                            self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        
 | 
					 | 
				
			||||||
                        self.isShowPopup = true
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } catch {
 | 
					 | 
				
			||||||
                    self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
 | 
					 | 
				
			||||||
                    self.isShowPopup = true
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                self.isLoading = false
 | 
					                self.isLoading = false
 | 
				
			||||||
                self.isRefresh = false
 | 
					                let responseData = response.data
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                do {
 | 
				
			||||||
 | 
					                    let jsonDecoder = JSONDecoder()
 | 
				
			||||||
 | 
					                    let decoded = try jsonDecoder.decode(ApiResponse<LiveMainResponse>.self, from: responseData)
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    if let data = decoded.data, decoded.success {
 | 
				
			||||||
 | 
					                        self.liveNowItems = data.liveOnAirRoomList
 | 
				
			||||||
 | 
					                        self.liveReservationItems = data.liveReservationRoomList
 | 
				
			||||||
 | 
					                        self.recommendLiveItems = data.recommendLiveList
 | 
				
			||||||
 | 
					                        self.followedChannelItems = data.followingChannelList
 | 
				
			||||||
 | 
					                        self.communityPostItems = data.communityPostList
 | 
				
			||||||
 | 
					                        self.replayLiveItems = data.replayLive
 | 
				
			||||||
 | 
					                        self.latestFinishedLiveItems = data.latestFinishedLiveList
 | 
				
			||||||
 | 
					                    } 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)
 | 
					            .store(in: &subscription)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -245,7 +190,7 @@ final class LiveViewModel: ObservableObject {
 | 
				
			|||||||
                    let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
 | 
					                    let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    if decoded.success {
 | 
					                    if decoded.success {
 | 
				
			||||||
                        getSummary()
 | 
					                        getLiveMain()
 | 
				
			||||||
                        enterRoom(roomId: roomId)
 | 
					                        enterRoom(roomId: roomId)
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        if let message = decoded.message {
 | 
					                        if let message = decoded.message {
 | 
				
			||||||
@@ -463,7 +408,7 @@ final class LiveViewModel: ObservableObject {
 | 
				
			|||||||
                        onClickParticipant: {},
 | 
					                        onClickParticipant: {},
 | 
				
			||||||
                        onClickReservation: { self.reservationLiveRoom(roomId: roomId) },
 | 
					                        onClickReservation: { self.reservationLiveRoom(roomId: roomId) },
 | 
				
			||||||
                        onClickStart: { self.startLive(roomId: roomId) },
 | 
					                        onClickStart: { self.startLive(roomId: roomId) },
 | 
				
			||||||
                        onClickCancel: { self.getSummary() }
 | 
					                        onClickCancel: { self.getLiveMain() }
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -528,7 +473,7 @@ final class LiveViewModel: ObservableObject {
 | 
				
			|||||||
                    let decoded = try jsonDecoder.decode(ApiResponse<MakeLiveReservationResponse>.self, from: responseData)
 | 
					                    let decoded = try jsonDecoder.decode(ApiResponse<MakeLiveReservationResponse>.self, from: responseData)
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    if let response = decoded.data, decoded.success {
 | 
					                    if let response = decoded.data, decoded.success {
 | 
				
			||||||
                        self.getSummary()
 | 
					                        self.getLiveMain()
 | 
				
			||||||
                        AppState.shared.setAppStep(step: .liveReservationComplete(response: response))
 | 
					                        AppState.shared.setAppStep(step: .liveReservationComplete(response: response))
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        if let message = decoded.message {
 | 
					                        if let message = decoded.message {
 | 
				
			||||||
@@ -546,156 +491,4 @@ final class LiveViewModel: ObservableObject {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            .store(in: &subscription)
 | 
					            .store(in: &subscription)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    private func getFollowedChannelList() {
 | 
					 | 
				
			||||||
        followedChannelItems.removeAll()
 | 
					 | 
				
			||||||
        isFollowedChannelLoading = true
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        liveRecommendRepository.getFollowedChannelList()
 | 
					 | 
				
			||||||
            .sink { result in
 | 
					 | 
				
			||||||
                switch result {
 | 
					 | 
				
			||||||
                case .finished:
 | 
					 | 
				
			||||||
                    DEBUG_LOG("finish")
 | 
					 | 
				
			||||||
                case .failure(let error):
 | 
					 | 
				
			||||||
                    ERROR_LOG(error.localizedDescription)
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } receiveValue: { [unowned self] response in
 | 
					 | 
				
			||||||
                self.isFollowedChannelLoading = false
 | 
					 | 
				
			||||||
                let responseData = response.data
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                do {
 | 
					 | 
				
			||||||
                    let jsonDecoder = JSONDecoder()
 | 
					 | 
				
			||||||
                    let decoded = try jsonDecoder.decode(ApiResponse<[GetRecommendChannelResponse]>.self, from: responseData)
 | 
					 | 
				
			||||||
                    
 | 
					 | 
				
			||||||
                    if let data = decoded.data, decoded.success {
 | 
					 | 
				
			||||||
                        self.followedChannelItems.append(contentsOf: data)
 | 
					 | 
				
			||||||
                    } 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)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    private func getRecommendChannelList() {
 | 
					 | 
				
			||||||
        recommendChannelItems.removeAll()
 | 
					 | 
				
			||||||
        isRecommendChannelLoading = true
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        liveRecommendRepository.getRecommendChannelList()
 | 
					 | 
				
			||||||
            .sink { result in
 | 
					 | 
				
			||||||
                switch result {
 | 
					 | 
				
			||||||
                case .finished:
 | 
					 | 
				
			||||||
                    DEBUG_LOG("finish")
 | 
					 | 
				
			||||||
                case .failure(let error):
 | 
					 | 
				
			||||||
                    ERROR_LOG(error.localizedDescription)
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } receiveValue: { [unowned self] response in
 | 
					 | 
				
			||||||
                self.isRecommendChannelLoading = false
 | 
					 | 
				
			||||||
                let responseData = response.data
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                do {
 | 
					 | 
				
			||||||
                    let jsonDecoder = JSONDecoder()
 | 
					 | 
				
			||||||
                    let decoded = try jsonDecoder.decode(ApiResponse<[GetRecommendChannelResponse]>.self, from: responseData)
 | 
					 | 
				
			||||||
                    
 | 
					 | 
				
			||||||
                    if let data = decoded.data, decoded.success {
 | 
					 | 
				
			||||||
                        self.recommendChannelItems.append(contentsOf: data)
 | 
					 | 
				
			||||||
                    } 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)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    private func getRecommendLive() {
 | 
					 | 
				
			||||||
        recommendLiveItems.removeAll()
 | 
					 | 
				
			||||||
        isRecommendLiveLoading = true
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        liveRecommendRepository.getRecommendLive()
 | 
					 | 
				
			||||||
            .sink { result in
 | 
					 | 
				
			||||||
                switch result {
 | 
					 | 
				
			||||||
                case .finished:
 | 
					 | 
				
			||||||
                    DEBUG_LOG("finish")
 | 
					 | 
				
			||||||
                case .failure(let error):
 | 
					 | 
				
			||||||
                    ERROR_LOG(error.localizedDescription)
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } receiveValue: { [unowned self] response in
 | 
					 | 
				
			||||||
                self.isRecommendLiveLoading = false
 | 
					 | 
				
			||||||
                let responseData = response.data
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                do {
 | 
					 | 
				
			||||||
                    let jsonDecoder = JSONDecoder()
 | 
					 | 
				
			||||||
                    let decoded = try jsonDecoder.decode(ApiResponse<[GetRecommendLiveResponse]>.self, from: responseData)
 | 
					 | 
				
			||||||
                    
 | 
					 | 
				
			||||||
                    if let data = decoded.data, decoded.success {
 | 
					 | 
				
			||||||
                        self.recommendLiveItems.append(contentsOf: data)
 | 
					 | 
				
			||||||
                    } 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)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    private func getLatestPostListFromCreatorsYouFollow() {
 | 
					 | 
				
			||||||
        communityPostItems.removeAll()
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        creatorCommunityRepository.getLatestPostListFromCreatorsYouFollow()
 | 
					 | 
				
			||||||
            .sink { result in
 | 
					 | 
				
			||||||
                switch result {
 | 
					 | 
				
			||||||
                case .finished:
 | 
					 | 
				
			||||||
                    DEBUG_LOG("finish")
 | 
					 | 
				
			||||||
                case .failure(let error):
 | 
					 | 
				
			||||||
                    ERROR_LOG(error.localizedDescription)
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } receiveValue: { [unowned self] response in
 | 
					 | 
				
			||||||
                self.isRecommendLiveLoading = false
 | 
					 | 
				
			||||||
                let responseData = response.data
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                do {
 | 
					 | 
				
			||||||
                    let jsonDecoder = JSONDecoder()
 | 
					 | 
				
			||||||
                    let decoded = try jsonDecoder.decode(ApiResponse<[GetCommunityPostListResponse]>.self, from: responseData)
 | 
					 | 
				
			||||||
                    
 | 
					 | 
				
			||||||
                    if let data = decoded.data, decoded.success {
 | 
					 | 
				
			||||||
                        self.communityPostItems.append(contentsOf: data)
 | 
					 | 
				
			||||||
                    } 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)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user