feat(home): 랭킹 소식 카드를 추가한다
This commit is contained in:
@@ -3127,6 +3127,22 @@ If you block this user, the following features will be restricted.
|
||||
pick(ko: "최근 소식", en: "Recent news", ja: "最近のニュース")
|
||||
}
|
||||
|
||||
static func rankingMessagePrefix(_ title: String) -> String {
|
||||
pick(
|
||||
ko: "\(title)님이 이번 주 랭킹 ",
|
||||
en: "\(title) reached ",
|
||||
ja: "\(title)さんが今週のランキング"
|
||||
)
|
||||
}
|
||||
|
||||
static func rankingRankText(_ rank: Int) -> String {
|
||||
pick(ko: "\(rank)위", en: "No. \(rank)", ja: "\(rank)位")
|
||||
}
|
||||
|
||||
static var rankingMessageSuffix: String {
|
||||
pick(ko: "에 올랐어요!", en: " in this week's ranking!", ja: "に入りました!")
|
||||
}
|
||||
|
||||
static var audioTag: String {
|
||||
pick(ko: "오디오", en: "Audio", ja: "オーディオ")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
import SwiftUI
|
||||
|
||||
struct MainHomeFollowingRankingNewsCard: View {
|
||||
private let imageUrl: String?
|
||||
private let title: String
|
||||
private let rank: Int
|
||||
private let action: () -> Void
|
||||
|
||||
init(
|
||||
creatorRanking: FollowingCreatorRankingNewsResponse,
|
||||
onTapCreator: @escaping (Int) -> Void = { _ in }
|
||||
) {
|
||||
self.imageUrl = creatorRanking.profileImageUrl
|
||||
self.title = creatorRanking.nickname
|
||||
self.rank = creatorRanking.rank
|
||||
self.action = { onTapCreator(creatorRanking.creatorId) }
|
||||
}
|
||||
|
||||
init(
|
||||
contentRanking: FollowingContentRankingNewsResponse,
|
||||
onTapContent: @escaping (Int) -> Void = { _ in }
|
||||
) {
|
||||
self.imageUrl = contentRanking.contentImageUrl
|
||||
self.title = contentRanking.title
|
||||
self.rank = contentRanking.rank
|
||||
self.action = { onTapContent(contentRanking.contentId) }
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
Button(action: action) {
|
||||
HStack(alignment: .center, spacing: SodaSpacing.s14) {
|
||||
RankingThumbnailView(imageUrl: imageUrl, rank: rank)
|
||||
|
||||
rankingMessage
|
||||
.appFont(size: 16, weight: .medium)
|
||||
.lineSpacing(0)
|
||||
.multilineTextAlignment(.leading)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
.padding(SodaSpacing.s14)
|
||||
.background(Color.gray900)
|
||||
.clipShape(RoundedRectangle(cornerRadius: SodaRadius.r14, style: .continuous))
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
|
||||
private var rankingMessage: Text {
|
||||
Text(I18n.HomeFollowing.rankingMessagePrefix(title))
|
||||
.foregroundColor(.white)
|
||||
+ Text(I18n.HomeFollowing.rankingRankText(rank))
|
||||
.foregroundColor(Color.soda400)
|
||||
+ Text(I18n.HomeFollowing.rankingMessageSuffix)
|
||||
.foregroundColor(.white)
|
||||
}
|
||||
}
|
||||
|
||||
private struct RankingThumbnailView: View {
|
||||
let imageUrl: String?
|
||||
let rank: Int
|
||||
|
||||
var body: some View {
|
||||
ZStack(alignment: .bottomTrailing) {
|
||||
DownsampledKFImage(url: imageUrl.flatMap(URL.init(string:)), size: CGSize(width: 80, height: 80))
|
||||
.clipShape(RoundedRectangle(cornerRadius: SodaRadius.r14, style: .continuous))
|
||||
|
||||
LinearGradient(
|
||||
colors: [Color.black.opacity(0), Color.black.opacity(0.5)],
|
||||
startPoint: .top,
|
||||
endPoint: .bottom
|
||||
)
|
||||
.clipShape(RoundedRectangle(cornerRadius: SodaRadius.r14, style: .continuous))
|
||||
|
||||
Text("\(rank)")
|
||||
.appFont(size: 40, weight: .regular, family: .pattaya)
|
||||
.foregroundStyle(
|
||||
LinearGradient(
|
||||
colors: [.white, Color(hex: "EEEEEE")],
|
||||
startPoint: .top,
|
||||
endPoint: .bottom
|
||||
)
|
||||
)
|
||||
.shadow(color: Color.black.opacity(0.48), radius: 2)
|
||||
.offset(x: 0, y: 24)
|
||||
}
|
||||
.frame(width: 80, height: 80)
|
||||
}
|
||||
}
|
||||
|
||||
struct MainHomeFollowingRankingNewsCard_Previews: PreviewProvider {
|
||||
private static let previewImageUrl = "https://picsum.photos/500/500"
|
||||
|
||||
static var previews: some View {
|
||||
VStack(spacing: SodaSpacing.s12) {
|
||||
MainHomeFollowingRankingNewsCard(
|
||||
creatorRanking: FollowingCreatorRankingNewsResponse(
|
||||
rank: 2,
|
||||
creatorId: 1,
|
||||
nickname: "크리",
|
||||
profileImageUrl: previewImageUrl
|
||||
)
|
||||
)
|
||||
|
||||
MainHomeFollowingRankingNewsCard(
|
||||
contentRanking: FollowingContentRankingNewsResponse(
|
||||
rank: 4,
|
||||
contentId: 10,
|
||||
contentImageUrl: previewImageUrl,
|
||||
title: "콘텐츠 제목"
|
||||
)
|
||||
)
|
||||
}
|
||||
.padding(SodaSpacing.s14)
|
||||
.background(Color.black)
|
||||
.previewLayout(.sizeThatFits)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user