import SwiftUI struct CreatorChannelSeriesSection: View { let series: [CreatorChannelSeriesResponse] let onSelectTab: (CreatorChannelTab) -> Void let onTapSeries: (Int) -> Void init( series: [CreatorChannelSeriesResponse], onSelectTab: @escaping (CreatorChannelTab) -> Void, onTapSeries: @escaping (Int) -> Void = { _ in } ) { self.series = series self.onSelectTab = onSelectTab self.onTapSeries = onTapSeries } var body: some View { if series.isEmpty == false { VStack(alignment: .leading, spacing: SodaSpacing.s14) { SectionTitle(title: I18n.CreatorChannelHome.series) { onSelectTab(.series) } ScrollView(.horizontal, showsIndicators: false) { HStack(alignment: .top, spacing: SodaSpacing.s8) { ForEach(series) { item in CreatorChannelSeriesCard(series: item) { onTapSeries(item.seriesId) } } } .padding(.leading, SodaSpacing.s14) .padding(.trailing, SodaSpacing.s20) } } .padding(.top, SodaSpacing.s20) } } } private struct CreatorChannelSeriesCard: View { let series: CreatorChannelSeriesResponse let action: () -> Void private let baseDeviceWidth: CGFloat = 402 private let maxThumbnailWidth: CGFloat = 163 private let maxThumbnailHeight: CGFloat = 230 private var scale: CGFloat { min(1, UIScreen.main.bounds.width / baseDeviceWidth) } private var thumbnailWidth: CGFloat { maxThumbnailWidth * scale } private var thumbnailHeight: CGFloat { maxThumbnailHeight * scale } var body: some View { Button(action: action) { thumbnail } .buttonStyle(.plain) } private var thumbnail: some View { ZStack(alignment: .topLeading) { DownsampledKFImage( url: URL(string: series.coverImageUrl), size: CGSize(width: thumbnailWidth, height: thumbnailHeight) ) .background(Color.gray800) if series.isOriginal { HStack(spacing: 4) { Image("ic_series_original") .resizable() .scaledToFit() .frame(width: 14, height: 14) Image("img_new_only") .resizable() .scaledToFit() .frame(height: 14) } .padding(.horizontal, 8) .padding(.vertical, 5) .background(Color.gray900) } } .frame(width: thumbnailWidth, height: thumbnailHeight) .clipShape(RoundedRectangle(cornerRadius: SodaSpacing.s14, style: .continuous)) } } struct CreatorChannelSeriesSection_Previews: PreviewProvider { static var previews: some View { CreatorChannelSeriesSection( series: (1...3).map { index in CreatorChannelSeriesResponse( seriesId: index, title: "시리즈 제목", coverImageUrl: "https://picsum.photos/300/420?\(index)", numberOfContent: 10, isNew: index.isMultiple(of: 2), isOriginal: true ) }, onSelectTab: { _ in } ) .background(Color.black) .previewLayout(.sizeThatFits) } }