콘텐츠 메인 무료 탭
- 크리에이터 소개 전체보기
This commit is contained in:
		| @@ -151,4 +151,6 @@ enum AppStep { | |||||||
|     case newAsmrContentAll |     case newAsmrContentAll | ||||||
|      |      | ||||||
|     case newReplayContentAll |     case newReplayContentAll | ||||||
|  |      | ||||||
|  |     case introduceCreatorAll | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,67 @@ | |||||||
|  | // | ||||||
|  | //  ContentMainIntroduceCreatorAllView.swift | ||||||
|  | //  SodaLive | ||||||
|  | // | ||||||
|  | //  Created by klaus on 2/22/25. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | import SwiftUI | ||||||
|  |  | ||||||
|  | struct ContentMainIntroduceCreatorAllView: View { | ||||||
|  |      | ||||||
|  |     @StateObject var viewModel = ContentMainIntroduceCreatorAllViewModel() | ||||||
|  |      | ||||||
|  |     let columns = [ | ||||||
|  |         GridItem(.flexible()), | ||||||
|  |         GridItem(.flexible()), | ||||||
|  |         GridItem(.flexible()) | ||||||
|  |     ] | ||||||
|  |      | ||||||
|  |     var body: some View { | ||||||
|  |         NavigationView { | ||||||
|  |             BaseView(isLoading: $viewModel.isLoading) { | ||||||
|  |                 VStack(spacing: 13.3) { | ||||||
|  |                     DetailNavigationBar(title: "크리에이터 소개") | ||||||
|  |                      | ||||||
|  |                     ScrollView(.vertical, showsIndicators: false) { | ||||||
|  |                         LazyVGrid(columns: columns, spacing: 13.3) { | ||||||
|  |                             ForEach(0..<viewModel.introduceCreatorList.count, id: \.self) { index in | ||||||
|  |                                 let item = viewModel.introduceCreatorList[index] | ||||||
|  |                                 ContentNewAllItemView(item: item) | ||||||
|  |                                     .onAppear { | ||||||
|  |                                         if index == viewModel.introduceCreatorList.count - 1 { | ||||||
|  |                                             viewModel.getIntroduceCreatorList() | ||||||
|  |                                         } | ||||||
|  |                                     } | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                         .padding(.horizontal, 13.3) | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 .onAppear { | ||||||
|  |                     viewModel.getIntroduceCreatorList() | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             .navigationBarHidden(true) | ||||||
|  |             .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() | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #Preview { | ||||||
|  |     ContentMainIntroduceCreatorAllView() | ||||||
|  | } | ||||||
| @@ -0,0 +1,74 @@ | |||||||
|  | // | ||||||
|  | //  ContentMainIntroduceCreatorAllViewModel.swift | ||||||
|  | //  SodaLive | ||||||
|  | // | ||||||
|  | //  Created by klaus on 2/22/25. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | import Foundation | ||||||
|  | import Combine | ||||||
|  |  | ||||||
|  | final class ContentMainIntroduceCreatorAllViewModel: ObservableObject { | ||||||
|  |     private let repository = ContentMainTabFreeRepository() | ||||||
|  |     private var subscription = Set<AnyCancellable>() | ||||||
|  |      | ||||||
|  |     @Published var errorMessage = "" | ||||||
|  |     @Published var isShowPopup = false | ||||||
|  |     @Published var isLoading = false | ||||||
|  |      | ||||||
|  |     @Published var introduceCreatorList: [GetAudioContentMainItem] = [] | ||||||
|  |      | ||||||
|  |     var page = 1 | ||||||
|  |     var isLast = false | ||||||
|  |     private let size = 20 | ||||||
|  |      | ||||||
|  |     func getIntroduceCreatorList() { | ||||||
|  |         if (!isLast && !isLoading) { | ||||||
|  |             isLoading = true | ||||||
|  |             repository.getIntroduceCreatorList(page: page, size: size) | ||||||
|  |                 .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<[GetAudioContentMainItem]>.self, from: responseData) | ||||||
|  |                         self.isLoading = false | ||||||
|  |                          | ||||||
|  |                         if let data = decoded.data, decoded.success { | ||||||
|  |                             if page == 1 { | ||||||
|  |                                 introduceCreatorList.removeAll() | ||||||
|  |                             } | ||||||
|  |                              | ||||||
|  |                             if !data.isEmpty { | ||||||
|  |                                 page += 1 | ||||||
|  |                                 self.introduceCreatorList.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) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -23,7 +23,10 @@ struct ContentMainTabFreeView: View { | |||||||
|                     if let introduceCreator = viewModel.introduceCreator { |                     if let introduceCreator = viewModel.introduceCreator { | ||||||
|                         ContentMainNewContentViewV2( |                         ContentMainNewContentViewV2( | ||||||
|                             title: introduceCreator.title, |                             title: introduceCreator.title, | ||||||
|                             onClickMore: {}, |                             onClickMore: { | ||||||
|  |                                 AppState.shared | ||||||
|  |                                     .setAppStep(step: .introduceCreatorAll) | ||||||
|  |                             }, | ||||||
|                             themeList: [], |                             themeList: [], | ||||||
|                             contentList: introduceCreator.items |                             contentList: introduceCreator.items | ||||||
|                         ) { _ in } |                         ) { _ in } | ||||||
|   | |||||||
| @@ -230,6 +230,9 @@ struct ContentView: View { | |||||||
|             case .newReplayContentAll: |             case .newReplayContentAll: | ||||||
|                 ContentMainReplayAllView() |                 ContentMainReplayAllView() | ||||||
|                  |                  | ||||||
|  |             case .introduceCreatorAll: | ||||||
|  |                 ContentMainIntroduceCreatorAllView() | ||||||
|  |                  | ||||||
|             default: |             default: | ||||||
|                 EmptyView() |                 EmptyView() | ||||||
|                     .frame(width: 0, height: 0, alignment: .topLeading) |                     .frame(width: 0, height: 0, alignment: .topLeading) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Yu Sung
					Yu Sung