// // ContentAllView.swift // SodaLive // // Created by klaus on 11/14/25. // import SwiftUI struct ContentAllView: View { @StateObject var viewModel = ContentAllViewModel() var isFree: Bool = false var isPointAvailableOnly: Bool = false var body: some View { NavigationView { BaseView(isLoading: $viewModel.isLoading) { VStack(spacing: 0) { DetailNavigationBar(title: isFree ? String(localized: "무료 콘텐츠 전체") : isPointAvailableOnly ? String(localized: "포인트 대여 전체") : String(localized: "콘텐츠 전체")) if !viewModel.themeList.isEmpty { ContentMainContentThemeView( themeList: viewModel.themeList, selectTheme: viewModel.selectTheme, selectedTheme: $viewModel.selectedTheme ) } HStack(spacing: 12) { Spacer() Text("최신순") .appFont(size: 16, weight: .medium) .foregroundColor( Color(hex: "e2e2e2") .opacity(viewModel.sort == .NEWEST ? 1 : 0.5) ) .onTapGesture { if viewModel.sort != .NEWEST { viewModel.sort = .NEWEST } } Text("인기순") .appFont(size: 16, weight: .medium) .foregroundColor( Color(hex: "e2e2e2") .opacity(viewModel.sort == .POPULARITY ? 1 : 0.5) ) .onTapGesture { if viewModel.sort != .POPULARITY { viewModel.sort = .POPULARITY } } } .padding(.vertical, 16) .padding(.horizontal, 24) ScrollView(.vertical, showsIndicators: false) { let horizontalPadding: CGFloat = 24 let gridSpacing: CGFloat = 16 let itemSize = (screenSize().width - (horizontalPadding * 2) - gridSpacing) / 2 LazyVGrid( columns: Array( repeating: GridItem( .flexible(), spacing: gridSpacing, alignment: .topLeading ), count: 2 ), alignment: .leading, spacing: gridSpacing ) { ForEach(viewModel.contentList.indices, id: \.self) { idx in let item = viewModel.contentList[idx] NavigationLink { ContentDetailView(contentId: item.contentId) } label: { VStack(alignment: .leading, spacing: 0) { ZStack(alignment: .top) { DownsampledKFImage( url: URL(string: item.coverImageUrl), size: CGSize(width: itemSize, height: itemSize) ) .cornerRadius(16) HStack(alignment: .top, spacing: 0) { Spacer() if item.isPointAvailable { Image("ic_point") .padding(.top, 6) .padding(.trailing, 6) } } } Text(item.title) .font(.custom(Font.preRegular.rawValue, size: 18)) .foregroundColor(.white) .multilineTextAlignment(.leading) .fixedSize(horizontal: false, vertical: true) .lineLimit(1) .padding(.horizontal, 6) .padding(.top, 8) Text(item.creatorNickname) .font(.custom(Font.preRegular.rawValue, size: 14)) .foregroundColor(Color(hex: "78909C")) .lineLimit(1) .padding(.horizontal, 6) .padding(.top, 4) } .frame(width: itemSize) .contentShape(Rectangle()) .onAppear { if idx == viewModel.contentList.count - 1 { viewModel.fetchData() } } } } } .padding(horizontalPadding) } } .onAppear { viewModel.isFree = isFree viewModel.isPointAvailableOnly = isPointAvailableOnly viewModel.getThemeList() viewModel.fetchData() } } } } } #Preview { ContentAllView() }