112 lines
3.6 KiB
Swift
112 lines
3.6 KiB
Swift
import SwiftUI
|
|
|
|
struct CreatorChannelDonationCard: View {
|
|
let donation: CreatorChannelDonationResponse
|
|
|
|
var body: some View {
|
|
VStack(alignment: .leading, spacing: SodaSpacing.s14) {
|
|
header
|
|
|
|
Text(donation.messageText)
|
|
.appFont(size: 16, weight: .regular)
|
|
.foregroundColor(.white)
|
|
.lineLimit(2)
|
|
.truncationMode(.tail)
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
.padding(.horizontal, SodaSpacing.s14)
|
|
}
|
|
.padding(.bottom, SodaSpacing.s14)
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
.background(Color.gray900)
|
|
.clipShape(RoundedRectangle(cornerRadius: SodaSpacing.s14, style: .continuous))
|
|
}
|
|
|
|
private var header: some View {
|
|
HStack(alignment: .center, spacing: SodaSpacing.s8) {
|
|
DownsampledKFImage(
|
|
url: URL(string: donation.profileImageUrl),
|
|
size: CGSize(width: 42, height: 42)
|
|
)
|
|
.background(Color.white.opacity(0.6))
|
|
.clipShape(Circle())
|
|
|
|
VStack(alignment: .leading, spacing: 2) {
|
|
Text(donation.nickname)
|
|
.appFont(size: 14, weight: .medium)
|
|
.foregroundColor(.black)
|
|
.lineLimit(1)
|
|
.truncationMode(.tail)
|
|
|
|
Text(donation.relativeTimeText())
|
|
.appFont(size: 14, weight: .regular)
|
|
.foregroundColor(Color.gray700)
|
|
.lineLimit(1)
|
|
}
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
|
|
canBadge
|
|
}
|
|
.padding(SodaSpacing.s14)
|
|
.background(donation.tierColor)
|
|
}
|
|
|
|
private var canBadge: some View {
|
|
HStack(spacing: 2) {
|
|
Image("ic_bar_cash")
|
|
.resizable()
|
|
.scaledToFit()
|
|
.frame(width: 18, height: 18)
|
|
|
|
Text("\(donation.can)캔")
|
|
.appFont(size: 14, weight: .regular)
|
|
.foregroundColor(.white)
|
|
.lineLimit(1)
|
|
}
|
|
.padding(.horizontal, SodaSpacing.s6)
|
|
.padding(.vertical, SodaSpacing.s4)
|
|
.background(Color.gray900)
|
|
.clipShape(Capsule())
|
|
}
|
|
}
|
|
|
|
extension CreatorChannelDonationResponse {
|
|
var messageText: String {
|
|
let trimmedMessage = message.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
return trimmedMessage.isEmpty ? "\(can)캔을 후원하였습니다" : trimmedMessage
|
|
}
|
|
|
|
func relativeTimeText(now: Date = Date()) -> String {
|
|
DateParser.relativeTimeText(fromUTC: createdAtUtc, fallback: createdAtUtc, now: now)
|
|
}
|
|
|
|
var tierColor: Color {
|
|
switch can {
|
|
case 1...50:
|
|
return Color(hex: "E2E2E2")
|
|
case 51...100:
|
|
return Color(hex: "73EE01")
|
|
case 101...500:
|
|
return Color(hex: "00EAFF")
|
|
default:
|
|
return Color(hex: "FF4C3C")
|
|
}
|
|
}
|
|
}
|
|
|
|
struct CreatorChannelDonationCard_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
CreatorChannelDonationCard(
|
|
donation: CreatorChannelDonationResponse(
|
|
nickname: "팬 이름 501",
|
|
profileImageUrl: "https://picsum.photos/120/120?4",
|
|
can: 501,
|
|
message: "501캔 이상 후원 컬러를 확인하는 Preview 샘플입니다.",
|
|
createdAtUtc: "2026-07-03T03:41:00Z"
|
|
)
|
|
)
|
|
.padding(SodaSpacing.s14)
|
|
.background(Color.black)
|
|
.previewLayout(.sizeThatFits)
|
|
}
|
|
}
|