From a6ef1d89cee3e665e034d470755213eb7780ccd8 Mon Sep 17 00:00:00 2001 From: Yu Sung Date: Sat, 15 Nov 2025 03:28:03 +0900 Subject: [PATCH] =?UTF-8?q?feat(series-all-day-of-week):=20=EC=8B=9C?= =?UTF-8?q?=EB=A6=AC=EC=A6=88=20=EC=A0=84=EC=B2=B4=EB=B3=B4=EA=B8=B0=20?= =?UTF-8?q?=EC=9A=94=EC=9D=BC=EB=B3=84=20=ED=83=AD=20API=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DayOfWeek/SeriesMainDayOfWeekView.swift | 57 +++++++++++++++- .../SeriesMainDayOfWeekViewModel.swift | 66 +++++++++++++++++++ .../Content/Series/Main/SeriesMainApi.swift | 15 +++++ .../Series/Main/SeriesMainRepository.swift | 12 ++++ 4 files changed, 149 insertions(+), 1 deletion(-) diff --git a/SodaLive/Sources/Content/Series/Main/DayOfWeek/SeriesMainDayOfWeekView.swift b/SodaLive/Sources/Content/Series/Main/DayOfWeek/SeriesMainDayOfWeekView.swift index d6d7ecd..daecf5e 100644 --- a/SodaLive/Sources/Content/Series/Main/DayOfWeek/SeriesMainDayOfWeekView.swift +++ b/SodaLive/Sources/Content/Series/Main/DayOfWeek/SeriesMainDayOfWeekView.swift @@ -8,8 +8,63 @@ import SwiftUI struct SeriesMainDayOfWeekView: View { + + @StateObject var viewModel = SeriesMainDayOfWeekViewModel() + + @State private var dayOfWeek: SeriesPublishedDaysOfWeek = .SAT + + private let dayOfWeekItems: [DayOfWeek] = [ + DayOfWeek(dayOfWeekStr: "월", dayOfWeek: .MON), + DayOfWeek(dayOfWeekStr: "화", dayOfWeek: .TUE), + DayOfWeek(dayOfWeekStr: "수", dayOfWeek: .WED), + DayOfWeek(dayOfWeekStr: "목", dayOfWeek: .THU), + DayOfWeek(dayOfWeekStr: "금", dayOfWeek: .FRI), + DayOfWeek(dayOfWeekStr: "토", dayOfWeek: .SAT), + DayOfWeek(dayOfWeekStr: "일", dayOfWeek: .SUN), + DayOfWeek(dayOfWeekStr: "랜덤", dayOfWeek: .RANDOM), + ] + + // 요일 숫자에 맞춰 배열 + private let dayOfWeeks: [SeriesPublishedDaysOfWeek] = [ + .RANDOM, + .SUN, + .MON, + .TUE, + .WED, + .THU, + .FRI, + .SAT + ] + var body: some View { - Text("시리즈 전체보기 요일별") + ZStack { + VStack(spacing: 16) { + + } + .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() + } + } + .onAppear { + dayOfWeek = dayOfWeeks[Calendar.current.component(.weekday, from: Date())] + viewModel.getDayOfWeekSeriesList(dayOfWeek: dayOfWeek) + } + + if viewModel.isLoading { + LoadingView() + } + } } } diff --git a/SodaLive/Sources/Content/Series/Main/DayOfWeek/SeriesMainDayOfWeekViewModel.swift b/SodaLive/Sources/Content/Series/Main/DayOfWeek/SeriesMainDayOfWeekViewModel.swift index 078ab53..e47410f 100644 --- a/SodaLive/Sources/Content/Series/Main/DayOfWeek/SeriesMainDayOfWeekViewModel.swift +++ b/SodaLive/Sources/Content/Series/Main/DayOfWeek/SeriesMainDayOfWeekViewModel.swift @@ -6,3 +6,69 @@ // import Foundation +import Combine + +final class SeriesMainDayOfWeekViewModel: ObservableObject { + private let repository = SeriesMainRepository() + private var subscription = Set() + + @Published var isLoading = false + @Published var errorMessage = "" + @Published var isShowPopup = false + + @Published var seriesList: [SeriesListItem] = [] + + private var page = 1 + private var isLast = false + private let pageSize = 20 + + func getDayOfWeekSeriesList(dayOfWeek: SeriesPublishedDaysOfWeek) { + if !isLoading && !isLast { + isLoading = true + + repository.getDayOfWeekSeriesList(dayOfWeek: dayOfWeek, page: page, size: pageSize) + .sink { result in + switch result { + case .finished: + DEBUG_LOG("finish") + case .failure(let error): + ERROR_LOG(error.localizedDescription) + } + } receiveValue: { [unowned self] response in + let responseData = response.data + + do { + let jsonDecoder = JSONDecoder() + let decoded = try jsonDecoder.decode(ApiResponse<[SeriesListItem]>.self, from: responseData) + + if let data = decoded.data, decoded.success { + if page == 1 { + self.seriesList.removeAll() + } + + if !data.isEmpty { + page += 1 + self.seriesList.append(contentsOf: data) + } else { + isLast = true + } + } else { + if let message = decoded.message { + self.errorMessage = message + } else { + self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." + } + + self.isShowPopup = true + } + } catch { + self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." + self.isShowPopup = true + } + + self.isLoading = false + } + .store(in: &subscription) + } + } +} diff --git a/SodaLive/Sources/Content/Series/Main/SeriesMainApi.swift b/SodaLive/Sources/Content/Series/Main/SeriesMainApi.swift index bbb1c8e..c23cf34 100644 --- a/SodaLive/Sources/Content/Series/Main/SeriesMainApi.swift +++ b/SodaLive/Sources/Content/Series/Main/SeriesMainApi.swift @@ -11,6 +11,7 @@ import Moya enum SeriesMainApi { case fetchHome(isAdultContentVisible: Bool, contentType: ContentType) case getRecommendSeriesList(isAdultContentVisible: Bool, contentType: ContentType) + case getDayOfWeekSeriesList(dayOfWeek: SeriesPublishedDaysOfWeek, isAdultContentVisible: Bool, contentType: ContentType, page: Int, size: Int) } extension SeriesMainApi: TargetType { @@ -22,6 +23,9 @@ extension SeriesMainApi: TargetType { case .getRecommendSeriesList: return "/audio-content/series/main/recommend" + + case .getDayOfWeekSeriesList: + return "/audio-content/series/main/day-of-week" } } @@ -41,6 +45,17 @@ extension SeriesMainApi: TargetType { "contentType": contentType, ] as [String : Any] + return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString) + + case .getDayOfWeekSeriesList(let dayOfWeek, let isAdultContentVisible, let contentType, let page, let size): + var parameters = [ + "dayOfWeek": dayOfWeek, + "isAdultContentVisible": isAdultContentVisible, + "contentType": contentType, + "page": page - 1, + "size": size + ] as [String : Any] + return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString) } } diff --git a/SodaLive/Sources/Content/Series/Main/SeriesMainRepository.swift b/SodaLive/Sources/Content/Series/Main/SeriesMainRepository.swift index 84661ac..4b87985 100644 --- a/SodaLive/Sources/Content/Series/Main/SeriesMainRepository.swift +++ b/SodaLive/Sources/Content/Series/Main/SeriesMainRepository.swift @@ -30,4 +30,16 @@ class SeriesMainRepository { ) ) } + + func getDayOfWeekSeriesList(dayOfWeek: SeriesPublishedDaysOfWeek, page: Int, size: Int) -> AnyPublisher { + return api.requestPublisher( + .getDayOfWeekSeriesList( + dayOfWeek: dayOfWeek, + isAdultContentVisible: UserDefaults.isAdultContentVisible(), + contentType: ContentType(rawValue: UserDefaults.string(forKey: .contentPreference)) ?? ContentType.ALL, + page: page, + size: size + ) + ) + } }