120 lines
3.9 KiB
Swift
120 lines
3.9 KiB
Swift
import SwiftUI
|
|
|
|
struct CreatorChannelCommunityGridItem: View {
|
|
let post: CreatorChannelCommunityPostItem
|
|
let isOwnPost: Bool
|
|
let onTapDetail: () -> Void
|
|
|
|
var body: some View {
|
|
GeometryReader { proxy in
|
|
ZStack {
|
|
if isPaidLocked {
|
|
Color.gray800
|
|
.overlay(paidPriceOverlay)
|
|
} else {
|
|
tileContent(proxy: proxy)
|
|
}
|
|
}
|
|
.frame(width: proxy.size.width, height: proxy.size.width)
|
|
.clipped()
|
|
.contentShape(Rectangle())
|
|
.onTapGesture(perform: onTapDetail)
|
|
.overlay(alignment: .topTrailing) {
|
|
if post.isPinned {
|
|
Image("ic_pin")
|
|
.resizable()
|
|
.scaledToFit()
|
|
.frame(width: 18, height: 18)
|
|
.padding(6)
|
|
.shadow(color: .black.opacity(0.45), radius: 2, x: 0, y: 1)
|
|
.allowsHitTesting(false)
|
|
}
|
|
}
|
|
}
|
|
.aspectRatio(1, contentMode: .fit)
|
|
}
|
|
|
|
@ViewBuilder
|
|
private func tileContent(proxy: GeometryProxy) -> some View {
|
|
if let imageUrl = post.imageUrl, !imageUrl.isEmpty {
|
|
DownsampledKFImage(url: URL(string: imageUrl), size: CGSize(width: proxy.size.width, height: proxy.size.width))
|
|
.frame(width: proxy.size.width, height: proxy.size.width)
|
|
.aspectRatio(1, contentMode: .fill)
|
|
.clipped()
|
|
} else {
|
|
ZStack {
|
|
Color.gray900
|
|
|
|
Text(fallbackText)
|
|
.appFont(size: 12, weight: .medium)
|
|
.foregroundColor(.white)
|
|
.multilineTextAlignment(.center)
|
|
.lineLimit(3)
|
|
.padding(SodaSpacing.s8)
|
|
}
|
|
}
|
|
}
|
|
|
|
private var paidPriceOverlay: some View {
|
|
VStack(spacing: SodaSpacing.s4) {
|
|
Image("ic_new_community_lock")
|
|
.resizable()
|
|
.renderingMode(.template)
|
|
.foregroundColor(.white)
|
|
.frame(width: 24, height: 24)
|
|
|
|
HStack(spacing: SodaSpacing.s6) {
|
|
Image("ic_bar_cash")
|
|
.resizable()
|
|
.frame(width: 20, height: 20)
|
|
|
|
Text("\(post.price)")
|
|
.appFont(size: 16, weight: .medium)
|
|
.foregroundColor(.black)
|
|
}
|
|
.padding(SodaSpacing.s8)
|
|
.background(Color.white)
|
|
.clipShape(Capsule())
|
|
}
|
|
}
|
|
|
|
private var isPaidLocked: Bool {
|
|
post.price > 0 && post.existOrdered == false && isOwnPost == false
|
|
}
|
|
|
|
private var fallbackText: String {
|
|
let content = post.content.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
guard !content.isEmpty else { return "-" }
|
|
return String(content.prefix(18))
|
|
}
|
|
}
|
|
|
|
struct CreatorChannelCommunityGridItem_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
CreatorChannelCommunityGridItem(
|
|
post: CreatorChannelCommunityPostItem(
|
|
postId: 1,
|
|
creatorId: 10,
|
|
creatorNickname: "크리에이터 이름",
|
|
creatorProfileUrl: "https://picsum.photos/600",
|
|
createdAtUtc: "2026-08-10T00:00:00Z",
|
|
content: "유료 커뮤니티 게시글",
|
|
imageUrl: nil,
|
|
audioUrl: nil,
|
|
price: 30,
|
|
isCommentAvailable: true,
|
|
likeCount: 5,
|
|
commentCount: 2,
|
|
isPinned: true,
|
|
existOrdered: false,
|
|
isLiked: false
|
|
),
|
|
isOwnPost: false,
|
|
onTapDetail: {}
|
|
)
|
|
.frame(width: 134, height: 134)
|
|
.background(Color.black)
|
|
.previewLayout(.sizeThatFits)
|
|
}
|
|
}
|