feat(home): 장르 크리에이터 섹션을 연결한다

This commit is contained in:
Yu Sung
2026-06-29 20:47:46 +09:00
parent 561e991050
commit 2727cdc7cb
8 changed files with 225 additions and 12 deletions

View File

@@ -0,0 +1,147 @@
import SwiftUI
struct MainHomeGenreCreatorSection: View {
let items: [HomeGenreCreatorGroupItem]
let isFollowAllCompleted: (String) -> Bool
let isFollowAllLoading: (String) -> Bool
let onTapCreator: (Int) -> Void
let onTapFollowAll: ([Int], String) -> Void
init(
items: [HomeGenreCreatorGroupItem],
isFollowAllCompleted: @escaping (String) -> Bool = { _ in false },
isFollowAllLoading: @escaping (String) -> Bool = { _ in false },
onTapCreator: @escaping (Int) -> Void = { _ in },
onTapFollowAll: @escaping ([Int], String) -> Void = { _, _ in }
) {
self.items = items
self.isFollowAllCompleted = isFollowAllCompleted
self.isFollowAllLoading = isFollowAllLoading
self.onTapCreator = onTapCreator
self.onTapFollowAll = onTapFollowAll
}
var body: some View {
if !items.isEmpty {
ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(alignment: .top, spacing: SodaSpacing.s4) {
ForEach(Array(items.enumerated()), id: \.offset) { index, item in
let followKey = "genre-\(index)-\(item.genreName)"
MainHomeCreatorGroupSection(
title: item.genreName,
creators: item.creators,
isFollowAllCompleted: isFollowAllCompleted(followKey),
isFollowAllLoading: isFollowAllLoading(followKey),
onTapCreator: onTapCreator,
onTapFollowAll: {
onTapFollowAll(item.creators.map(\.creatorId), followKey)
}
)
}
}
.padding(.leading, SodaSpacing.s14)
.padding(.trailing, SodaSpacing.s20)
}
}
}
}
struct MainHomeCreatorGroupSection: View {
let title: String
let creators: [HomeCreatorItem]
let isFollowAllCompleted: Bool
let isFollowAllLoading: Bool
let onTapCreator: (Int) -> Void
let onTapFollowAll: () -> Void
init(
title: String,
creators: [HomeCreatorItem],
isFollowAllCompleted: Bool = false,
isFollowAllLoading: Bool = false,
onTapCreator: @escaping (Int) -> Void = { _ in },
onTapFollowAll: @escaping () -> Void = {}
) {
self.title = title
self.creators = creators
self.isFollowAllCompleted = isFollowAllCompleted
self.isFollowAllLoading = isFollowAllLoading
self.onTapCreator = onTapCreator
self.onTapFollowAll = onTapFollowAll
}
var body: some View {
VStack(alignment: .leading, spacing: SodaSpacing.s14) {
Text(title)
.appFont(.heading3)
.foregroundColor(.white)
.lineLimit(1)
.truncationMode(.tail)
LazyVGrid(columns: columns, alignment: .center, spacing: SodaSpacing.s14) {
ForEach(creators.prefix(8), id: \.self) { creator in
CreatorProfileItem(
imageUrl: creator.creatorProfileImage,
name: creator.creatorNickname,
imageSize: CGSize(width: 75, height: 75),
spacing: SodaSpacing.s6
) {
onTapCreator(creator.creatorId)
}
.frame(width: 75)
}
}
FollowAllButton(
isCompleted: isFollowAllCompleted,
isLoading: isFollowAllLoading,
action: onTapFollowAll
)
}
.padding(SodaSpacing.s14)
.frame(width: 374)
.background(cardBackground)
.clipShape(RoundedRectangle(cornerRadius: SodaSpacing.s14, style: .continuous))
}
private var columns: [GridItem] {
Array(repeating: GridItem(.fixed(75), spacing: SodaSpacing.s14), count: 4)
}
private var cardBackground: some View {
LinearGradient(
stops: [
.init(color: Color.gray900, location: 0),
.init(color: Color.gray900, location: 0.29327),
.init(color: Color.soda700, location: 1)
],
startPoint: .top,
endPoint: .bottom
)
}
}
struct MainHomeGenreCreatorSection_Previews: PreviewProvider {
private static let previewImageUrl = "https://picsum.photos/200/200"
static var previews: some View {
MainHomeGenreCreatorSection(
items: [
HomeGenreCreatorGroupItem(
genreName: I18n.HomeRecommendation.genreCreatorSectionTitle,
creators: (1...8).map {
HomeCreatorItem(
creatorId: $0,
creatorNickname: "크리에이터이름",
creatorProfileImage: previewImageUrl
)
}
)
]
)
.padding(.vertical, SodaSpacing.s20)
.background(Color.black)
.previewLayout(.sizeThatFits)
}
}