95 lines
3.1 KiB
Swift
95 lines
3.1 KiB
Swift
import SwiftUI
|
|
|
|
struct CreatorChannelCommunityGridItem: View {
|
|
let post: CreatorChannelCommunityPostItem
|
|
let isOwnPost: Bool
|
|
let onTapPurchase: () -> Void
|
|
let onTapDetail: () -> Void
|
|
|
|
var body: some View {
|
|
GeometryReader { proxy in
|
|
ZStack {
|
|
if isPaidLocked {
|
|
Button(action: onTapPurchase) {
|
|
Color.gray400
|
|
.overlay(paidPriceOverlay)
|
|
}
|
|
.buttonStyle(.plain)
|
|
} else {
|
|
tileContent(proxy: proxy)
|
|
.contentShape(Rectangle())
|
|
.onTapGesture(perform: onTapDetail)
|
|
}
|
|
}
|
|
.frame(width: proxy.size.width, height: proxy.size.width)
|
|
.clipped()
|
|
.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))
|
|
}
|
|
}
|