feat(explorer): 채널 후원 목록/등록 기능을 추가한다
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
|
||||
struct ChannelDonationItemView: View {
|
||||
let item: GetChannelDonationListItem
|
||||
let previewLimit: Int?
|
||||
let isShowFullMessageOnTap: Bool
|
||||
|
||||
@State private var isExpanded = false
|
||||
|
||||
init(
|
||||
item: GetChannelDonationListItem,
|
||||
previewLimit: Int? = nil,
|
||||
isShowFullMessageOnTap: Bool = false
|
||||
) {
|
||||
self.item = item
|
||||
self.previewLimit = previewLimit
|
||||
self.isShowFullMessageOnTap = isShowFullMessageOnTap
|
||||
}
|
||||
|
||||
private var donationBackgroundColor: Color {
|
||||
if item.isSecret {
|
||||
return Color(hex: "59548f").opacity(0.8)
|
||||
}
|
||||
|
||||
if item.can >= 10000 {
|
||||
return Color(hex: "c25264").opacity(0.8)
|
||||
}
|
||||
|
||||
if item.can >= 5000 {
|
||||
return Color(hex: "d85e37").opacity(0.8)
|
||||
}
|
||||
|
||||
if item.can >= 1000 {
|
||||
return Color(hex: "d38c38").opacity(0.8)
|
||||
}
|
||||
|
||||
if item.can >= 500 {
|
||||
return Color(hex: "c25264").opacity(0.8)
|
||||
}
|
||||
|
||||
if item.can >= 100 {
|
||||
return Color(hex: "4d6aa4").opacity(0.8)
|
||||
}
|
||||
|
||||
if item.can >= 50 {
|
||||
return Color(hex: "2d7390").opacity(0.8)
|
||||
}
|
||||
|
||||
return Color(hex: "548f7d").opacity(0.8)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 10) {
|
||||
HStack(spacing: 11) {
|
||||
KFImage(URL(string: item.profileUrl))
|
||||
.cancelOnDisappear(true)
|
||||
.downsampling(size: CGSize(width: 40, height: 40))
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(width: 40, height: 40)
|
||||
.clipShape(Circle())
|
||||
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text(item.nickname)
|
||||
.appFont(size: 18, weight: .bold)
|
||||
.foregroundColor(.white)
|
||||
.lineLimit(1)
|
||||
|
||||
Text(item.relativeTimeText())
|
||||
.appFont(size: 14, weight: .regular)
|
||||
.foregroundColor(Color(hex: "78909C"))
|
||||
}
|
||||
|
||||
Spacer()
|
||||
}
|
||||
|
||||
highlightedMessageText(displayMessage)
|
||||
.appFont(size: 16, weight: .regular)
|
||||
.lineLimit(isExpanded ? nil : 2)
|
||||
.multilineTextAlignment(.leading)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
.padding(16)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.background(donationBackgroundColor)
|
||||
.cornerRadius(16)
|
||||
.onTapGesture {
|
||||
guard isShowFullMessageOnTap else { return }
|
||||
guard isTruncated else { return }
|
||||
isExpanded = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension ChannelDonationItemView {
|
||||
var normalizedMessage: String {
|
||||
item.message.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
}
|
||||
|
||||
var displayMessage: String {
|
||||
guard !isExpanded else { return normalizedMessage }
|
||||
guard let previewLimit else { return normalizedMessage }
|
||||
|
||||
if normalizedMessage.count > previewLimit {
|
||||
return String(normalizedMessage.prefix(previewLimit)) + "..."
|
||||
}
|
||||
|
||||
return normalizedMessage
|
||||
}
|
||||
|
||||
var isTruncated: Bool {
|
||||
guard let previewLimit else { return false }
|
||||
return normalizedMessage.count > previewLimit
|
||||
}
|
||||
|
||||
func highlightedMessageText(_ message: String) -> Text {
|
||||
let plainCanToken = "\(item.can)캔"
|
||||
let commaCanToken = "\(item.can.comma())캔"
|
||||
|
||||
let range = message.range(of: commaCanToken)
|
||||
?? message.range(of: plainCanToken)
|
||||
|
||||
guard let range else {
|
||||
return Text(message).foregroundColor(Color(hex: "CFD8DC"))
|
||||
}
|
||||
|
||||
let prefixText = String(message[..<range.lowerBound])
|
||||
let canText = String(message[range])
|
||||
let suffixText = String(message[range.upperBound...])
|
||||
|
||||
return Text(prefixText).foregroundColor(Color(hex: "CFD8DC"))
|
||||
+ Text(canText).foregroundColor(Color(hex: "FDCA2F"))
|
||||
+ Text(suffixText).foregroundColor(Color(hex: "CFD8DC"))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user