콘텐츠 메인 모닝콜 탭
- 새로운 알람 전체보기
This commit is contained in:
		| @@ -145,4 +145,6 @@ enum AppStep { | ||||
|     case contentMain(startTab: ContentMainTab) | ||||
|      | ||||
|     case completedSeriesAll | ||||
|      | ||||
|     case newAlarmContentAll | ||||
| } | ||||
|   | ||||
| @@ -38,7 +38,7 @@ struct ContentNewAllView: View { | ||||
|                         }, | ||||
|                         selectedTheme: $viewModel.selectedTheme | ||||
|                     ) | ||||
|                     .padding(.horizontal, 13.3) | ||||
|                     .padding(.horizontal, 20) | ||||
|                      | ||||
|                     HStack(spacing: 0) { | ||||
|                         Text("전체") | ||||
|   | ||||
| @@ -0,0 +1,85 @@ | ||||
| // | ||||
| //  ContentMainAlarmAllView.swift | ||||
| //  SodaLive | ||||
| // | ||||
| //  Created by klaus on 2/22/25. | ||||
| // | ||||
|  | ||||
| import SwiftUI | ||||
|  | ||||
| struct ContentMainAlarmAllView: View { | ||||
|      | ||||
|     @StateObject var viewModel = ContentMainAlarmAllViewModel() | ||||
|      | ||||
|     let columns = [ | ||||
|         GridItem(.flexible(), alignment: .top), | ||||
|         GridItem(.flexible(), alignment: .top), | ||||
|         GridItem(.flexible(), alignment: .top) | ||||
|     ] | ||||
|      | ||||
|     var body: some View { | ||||
|         NavigationView { | ||||
|             BaseView(isLoading: $viewModel.isLoading) { | ||||
|                 VStack(alignment: .leading, spacing: 13.3) { | ||||
|                     DetailNavigationBar(title: "새로운 알람") | ||||
|                      | ||||
|                     Text("※ 최근 2주간 등록된 새로운 알람 입니다.") | ||||
|                         .font(.custom(Font.medium.rawValue, size: 14.7)) | ||||
|                         .foregroundColor(.graybb) | ||||
|                         .padding(.horizontal, 13.3) | ||||
|                         .padding(.vertical, 8) | ||||
|                         .frame(width: screenSize().width, alignment: .leading) | ||||
|                         .background(Color.gray22) | ||||
|                      | ||||
|                     ContentMainNewContentThemeView( | ||||
|                         themes: viewModel.themeList, | ||||
|                         selectTheme: { | ||||
|                             viewModel.selectedTheme = $0 | ||||
|                         }, | ||||
|                         selectedTheme: $viewModel.selectedTheme | ||||
|                     ) | ||||
|                     .padding(.horizontal, 20) | ||||
|                      | ||||
|                     HStack(spacing: 0) { | ||||
|                         Text("전체") | ||||
|                             .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                             .foregroundColor(Color(hex: "e2e2e2")) | ||||
|                          | ||||
|                         Text("\(viewModel.totalCount)") | ||||
|                             .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                             .foregroundColor(Color(hex: "ff5c49")) | ||||
|                             .padding(.leading, 8) | ||||
|                          | ||||
|                         Text("개") | ||||
|                             .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                             .foregroundColor(Color(hex: "e2e2e2")) | ||||
|                             .padding(.leading, 2) | ||||
|                     } | ||||
|                     .padding(.horizontal, 13.3) | ||||
|                      | ||||
|                     ScrollView(.vertical, showsIndicators: false) { | ||||
|                         LazyVGrid(columns: columns, spacing: 32) { | ||||
|                             ForEach(0..<viewModel.newContentList.count, id: \.self) { index in | ||||
|                                 ContentNewAllItemView(item: viewModel.newContentList[index]) | ||||
|                                     .onAppear { | ||||
|                                         if index == viewModel.newContentList.count - 1 { | ||||
|                                             viewModel.getContentMainAlarmAll() | ||||
|                                         } | ||||
|                                     } | ||||
|                             } | ||||
|                         } | ||||
|                         .padding(.horizontal, 13.3) | ||||
|                     } | ||||
|                 } | ||||
|                 .onAppear { | ||||
|                     viewModel.getContentMainAlarmAll() | ||||
|                 } | ||||
|             } | ||||
|             .navigationBarHidden(true) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #Preview { | ||||
|     ContentMainAlarmAllView() | ||||
| } | ||||
| @@ -0,0 +1,94 @@ | ||||
| // | ||||
| //  ContentMainAlarmAllViewModel.swift | ||||
| //  SodaLive | ||||
| // | ||||
| //  Created by klaus on 2/22/25. | ||||
| // | ||||
|  | ||||
| import Foundation | ||||
| import Combine | ||||
|  | ||||
| final class ContentMainAlarmAllViewModel: ObservableObject { | ||||
|      | ||||
|     private let repository = ContentMainTabAlarmRepository() | ||||
|     private var subscription = Set<AnyCancellable>() | ||||
|      | ||||
|     @Published var errorMessage = "" | ||||
|     @Published var isShowPopup = false | ||||
|     @Published var isLoading = false | ||||
|      | ||||
|     @Published var themeList = ["전체", "모닝콜", "슬립콜", "알람"] | ||||
|     @Published var newContentList = [GetAudioContentMainItem]() | ||||
|      | ||||
|     @Published var selectedTheme = "전체" { | ||||
|         didSet { | ||||
|             page = 1 | ||||
|             isLast = false | ||||
|             getContentMainAlarmAll() | ||||
|         } | ||||
|     } | ||||
|     @Published var totalCount = 0 | ||||
|      | ||||
|     var page = 1 | ||||
|     var isLast = false | ||||
|     private let pageSize = 20 | ||||
|      | ||||
|     func getContentMainAlarmAll() { | ||||
|         if (!isLast && !isLoading) { | ||||
|             isLoading = true | ||||
|              | ||||
|             repository.getContentMainAlarmAll( | ||||
|                 theme: selectedTheme == "전체" ? "" : selectedTheme, | ||||
|                 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 | ||||
|                     self.isLoading = false | ||||
|                     let responseData = response.data | ||||
|                      | ||||
|                     do { | ||||
|                         let jsonDecoder = JSONDecoder() | ||||
|                         let decoded = try jsonDecoder.decode(ApiResponse<GetNewContentAllResponse>.self, from: responseData) | ||||
|                         self.isLoading = false | ||||
|                          | ||||
|                         if let data = decoded.data, decoded.success { | ||||
|                             if page == 1 { | ||||
|                                 newContentList.removeAll() | ||||
|                             } | ||||
|                              | ||||
|                             self.totalCount = data.totalCount | ||||
|                              | ||||
|                             if !data.items.isEmpty { | ||||
|                                 page += 1 | ||||
|                                 self.newContentList.append(contentsOf: data.items) | ||||
|                             } 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) | ||||
|         } else { | ||||
|             isLoading = false | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -23,7 +23,10 @@ struct ContentMainTabAlarmView: View { | ||||
|                     if !viewModel.alarmThemeList.isEmpty { | ||||
|                         ContentMainNewContentViewV2( | ||||
|                             title: "새로운 알람", | ||||
|                             onClickMore: {}, | ||||
|                             onClickMore: { | ||||
|                                 AppState.shared | ||||
|                                     .setAppStep(step: .newAlarmContentAll) | ||||
|                             }, | ||||
|                             themeList: viewModel.alarmThemeList, | ||||
|                             contentList: viewModel.newAlarmContentList | ||||
|                         ) { | ||||
|   | ||||
| @@ -221,6 +221,9 @@ struct ContentView: View { | ||||
|             case .completedSeriesAll: | ||||
|                 CompletedSeriesView() | ||||
|                  | ||||
|             case .newAlarmContentAll: | ||||
|                 ContentMainAlarmAllView() | ||||
|                  | ||||
|             default: | ||||
|                 EmptyView() | ||||
|                     .frame(width: 0, height: 0, alignment: .topLeading) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Yu Sung
					Yu Sung