Files
sodalive-ios/SodaLive/Sources/Explorer/Profile/UserProfileDonationAllView.swift

301 lines
12 KiB
Swift

//
// UserProfileDonationAllView.swift
// SodaLive
//
// Created by klaus on 2023/08/29.
//
import SwiftUI
import Kingfisher
struct UserProfileDonationAllView: View {
let userId: Int
@StateObject var viewModel = UserProfileDonationAllViewModel()
var body: some View {
BaseView(isLoading: $viewModel.isLoading) {
VStack(spacing: 0) {
DetailNavigationBar(title: String(localized: "후원랭킹 전체보기"))
if userId == UserDefaults.int(forKey: .userId) {
VStack(spacing: 10.7) {
HStack(spacing: 10) {
Spacer()
Text("채널에 후원랭킹 활성화")
.appFont(size: 16, weight: .bold)
.foregroundColor(Color(hex: "eeeeee"))
Image(viewModel.isVisibleDonationRank ? "btn_toggle_on_big" : "btn_toggle_off_big")
.resizable()
.frame(width: 46.7, height: 27)
.onTapGesture {
viewModel.toggleVisibleDonationRank()
}
}
HStack(spacing: 0) {
Spacer()
Text("※ 비활성화하면 채널 내 후원랭킹이 표시되지 않으며,\n라이브 중에도 후원랭킹에 따른 뱃지가 반영되지 않습니다.")
.appFont(size: 12, weight: .medium)
.foregroundColor(Color(hex: "555555"))
.multilineTextAlignment(.trailing)
}
}
.padding(.top, 13.3)
.padding(.horizontal, 13.3)
HStack(spacing: 73) {
HStack(spacing: 8) {
Image(viewModel.donationRankingPeriod == .weekly ? "btn_square_select_checked" : "btn_square_select_normal")
.resizable()
.frame(width: 20, height: 20)
Text(I18n.DonationRanking.weekly)
.appFont(size: 14, weight: .medium)
.foregroundColor(Color(hex: "eeeeee"))
}
.onTapGesture {
viewModel.selectDonationRankingPeriod(.weekly)
}
HStack(spacing: 8) {
Image(viewModel.donationRankingPeriod == .cumulative ? "btn_square_select_checked" : "btn_square_select_normal")
.resizable()
.frame(width: 20, height: 20)
Text(I18n.DonationRanking.cumulative)
.appFont(size: 14, weight: .medium)
.foregroundColor(Color(hex: "eeeeee"))
}
.onTapGesture {
viewModel.selectDonationRankingPeriod(.cumulative)
}
}
.padding(.top, 13.3)
.padding(.horizontal, 13.3)
VStack(spacing: 13.3) {
HStack(spacing: 0) {
Text("오늘")
.appFont(size: 12, weight: .bold)
.foregroundColor(Color(hex: "eeeeee"))
Spacer()
Text("\(viewModel.accumulatedCansToday.comma())")
.appFont(size: 12, weight: .bold)
.foregroundColor(Color(hex: "eeeeee"))
Text("")
.appFont(size: 12, weight: .light)
.foregroundColor(Color(hex: "eeeeee"))
}
HStack(spacing: 0) {
Text("지난주")
.appFont(size: 12, weight: .bold)
.foregroundColor(Color(hex: "eeeeee"))
Spacer()
Text("\(viewModel.accumulatedCansLastWeek.comma())")
.appFont(size: 12, weight: .bold)
.foregroundColor(Color(hex: "eeeeee"))
Text("")
.appFont(size: 12, weight: .light)
.foregroundColor(Color(hex: "eeeeee"))
}
HStack(spacing: 0) {
Text("이번 달 어제까지")
.appFont(size: 12, weight: .bold)
.foregroundColor(Color(hex: "eeeeee"))
Spacer()
Text("\(viewModel.accumulatedCansThisMonth.comma())")
.appFont(size: 12, weight: .bold)
.foregroundColor(Color(hex: "eeeeee"))
Text("")
.appFont(size: 12, weight: .light)
.foregroundColor(Color(hex: "eeeeee"))
}
}
.padding(16.7)
.background(Color(hex: "13181b"))
.cornerRadius(8)
.padding(.top, 13.3)
.padding(.horizontal, 13.3)
HStack(spacing: 0) {
SeriesDetailTabView(
title: I18n.DonationRanking.weekly,
width: screenSize().width / 2,
isSelected: viewModel.selectedRankingPeriod == .weekly
) {
viewModel.selectViewRankingPeriod(.weekly)
}
SeriesDetailTabView(
title: I18n.DonationRanking.cumulative,
width: screenSize().width / 2,
isSelected: viewModel.selectedRankingPeriod == .cumulative
) {
viewModel.selectViewRankingPeriod(.cumulative)
}
}
.padding(.top, 13.3)
}
HStack(alignment: .center, spacing: 0) {
Text("전체")
.appFont(size: 14.7, weight: .medium)
.foregroundColor(Color(hex: "eeeeee"))
Text("\(viewModel.totalCount)")
.appFont(size: 12, weight: .medium)
.foregroundColor(Color(hex: "80d8ff"))
.padding(.leading, 6.7)
Text("")
.appFont(size: 12, weight: .medium)
.foregroundColor(Color(hex: "777777"))
Spacer()
}
.padding(.top, 13.3)
.padding(.horizontal, 13.3)
Rectangle()
.frame(width: screenSize().width - 26.7, height: 1)
.foregroundColor(Color(hex: "595959"))
.padding(.top, 6.7)
ScrollView(.vertical, showsIndicators: false) {
LazyVStack(spacing: 0) {
ForEach(0..<viewModel.userDonationRanking.count, id: \.self) { index in
let item = viewModel.userDonationRanking[index]
UserProfileDonationAllItemView(
index: index,
item: item,
withDonationCan: userId == UserDefaults.int(forKey: .userId),
itemCount: viewModel.userDonationRanking.count
)
.onAppear {
if index == viewModel.userDonationRanking.count - 1 {
viewModel.getCreatorProfileDonationRanking()
}
}
}
}
}
.padding(.vertical, 16.7)
.padding(.horizontal, 13.3)
}
.onAppear {
viewModel.userId = userId
viewModel.getCreatorProfileDonationRanking()
}
.sodaToast(isPresented: $viewModel.isShowPopup, message: viewModel.errorMessage, autohideIn: 2)
}
}
}
struct UserProfileDonationAllItemView: View {
let index: Int
let item: UserDonationRankingResponse
let withDonationCan: Bool
let itemCount: Int
let crowns = ["img_rank_1", "img_rank_2", "img_rank_3"]
var body: some View {
HStack(spacing: 0) {
ZStack(alignment: .center) {
KFImage(URL(string: item.profileImage))
.cancelOnDisappear(true)
.downsampling(
size: CGSize(
width: 60,
height: 60
)
)
.resizable()
.scaledToFill()
.frame(width: 60, height: 60, alignment: .top)
.clipShape(Circle())
if index < 3 {
Image(crowns[index])
.resizable()
.frame(width: 77, height: 75)
}
}
.frame(width: 77, height: 75)
Text("\(index + 1)")
.appFont(size: 13.3, weight: .bold)
.foregroundColor(Color(hex: "eeeeee"))
.padding(.leading, 20)
.padding(.trailing, 13.3)
let nickname = item.nickname.count > 10 ? "\(String(item.nickname.prefix(10)))..." : item.nickname
Text(nickname)
.appFont(size: 13.3, weight: .medium)
.foregroundColor(Color(hex: "eeeeee"))
Spacer()
if let donationCan = item.donationCan, donationCan > 0, withDonationCan {
Text("\(donationCan)")
.appFont(size: 13.3, weight: .medium)
.foregroundColor(Color(hex: "eeeeee"))
}
}
.padding(.horizontal, isTop3Index(index: index) ? 20 : 0)
.padding(.top, getTopPadding(index: index))
.padding(.bottom, getBottomPadding(index: index))
.background(Color(hex: "13181b").opacity(isTop3Index(index: index) ? 1 : 0))
.cornerRadius(4.7, corners: cornerRadiusConers(index: index))
.padding(.horizontal, isTop3Index(index: index) ? 0 : 6.7)
}
private func isTop3Index(index: Int) -> Bool {
return index == 0 || index == 1 || index == 2
}
private func getTopPadding(index: Int) -> CGFloat {
if index == 0 || index == 3 {
return 20
} else {
return 6.7
}
}
private func getBottomPadding(index: Int) -> CGFloat {
if (index == 0 && itemCount == 1) || (index == 1 && itemCount == 2) || index == 2 {
return 20
} else {
return 6.7
}
}
private func cornerRadiusConers(index: Int) -> UIRectCorner {
if (index == 0 && itemCount == 1) {
return [.topLeft, .topRight, .bottomLeft, .bottomRight]
} else if index == 0 {
return [.topLeft, .topRight]
} else if (index == 1 && itemCount == 2) || index == 2 {
return [.bottomLeft, .bottomRight]
} else {
return []
}
}
}