feat(creator): 시리즈 섹션을 연결한다

This commit is contained in:
Yu Sung
2026-07-03 15:07:24 +09:00
parent 32174cd0af
commit ed6240fdd0
9 changed files with 188 additions and 5 deletions

View File

@@ -159,7 +159,8 @@ struct CreatorChannelView: View {
onTapLive: showLiveDetail,
onTapContent: showContentDetail,
onTapDonate: showDonationDialog,
onTapSchedule: handleScheduleTap
onTapSchedule: handleScheduleTap,
onTapSeries: showSeriesDetail
)
} else {
CreatorChannelPlaceholderTabView(title: viewModel.selectedTab.title)
@@ -201,6 +202,11 @@ struct CreatorChannelView: View {
)
}
private func showSeriesDetail(_ seriesId: Int) {
guard seriesId > 0 else { return }
AppState.shared.setAppStep(step: .seriesDetail(seriesId: seriesId))
}
private func showCommunity(_ creatorId: Int) {
guard creatorId > 0 else { return }
AppState.shared.setAppStep(step: .creatorCommunityAll(creatorId: creatorId))

View File

@@ -0,0 +1,117 @@
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)
}
}

View File

@@ -7,6 +7,7 @@ struct CreatorChannelHomeView: View {
let onTapContent: (Int) -> Void
let onTapDonate: () -> Void
let onTapSchedule: (CreatorActivityType, Int) -> Void
let onTapSeries: (Int) -> Void
init(
response: CreatorChannelHomeResponse,
@@ -14,7 +15,8 @@ struct CreatorChannelHomeView: View {
onTapLive: @escaping (Int) -> Void = { _ in },
onTapContent: @escaping (Int) -> Void = { _ in },
onTapDonate: @escaping () -> Void = {},
onTapSchedule: @escaping (CreatorActivityType, Int) -> Void = { _, _ in }
onTapSchedule: @escaping (CreatorActivityType, Int) -> Void = { _, _ in },
onTapSeries: @escaping (Int) -> Void = { _ in }
) {
self.response = response
self.onSelectTab = onSelectTab
@@ -22,6 +24,7 @@ struct CreatorChannelHomeView: View {
self.onTapContent = onTapContent
self.onTapDonate = onTapDonate
self.onTapSchedule = onTapSchedule
self.onTapSeries = onTapSeries
}
var body: some View {
@@ -54,6 +57,12 @@ struct CreatorChannelHomeView: View {
onSelectTab: onSelectTab,
onTapContent: onTapContent
)
CreatorChannelSeriesSection(
series: response.series,
onSelectTab: onSelectTab,
onTapSeries: onTapSeries
)
}
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color.black)