// // DiscoverRankViews.swift // Crush // // Created by Leon on 2025/9/8. // import SnapKit import UIKit enum DiscoverRankType { case chat case heartbeat case gift var localizedText: String { switch self { case .chat: return "Chat" case .heartbeat: return "Heartbeat" case .gift: return "Gift" } } } class DiscoverTopThreeRank: UIView { var stackH: UIStackView! var secondFlag = DiscoverTopThreeRankFlagView() var firstFlag = DiscoverTopThreeRankFlagView() var thirdFlag = DiscoverTopThreeRankFlagView() var consTopToSuperForSecondFlag: Constraint? var consBottomToSuperForSecondFlag: Constraint? var consTopToSuperForThirdFlag: Constraint? var consBottomToSuperForThirdFlag: Constraint? var type: DiscoverRankType = .chat{ didSet{ secondFlag.type = type firstFlag.type = type thirdFlag.type = type } } var datas: [AIDiscoverTop]? override init(frame: CGRect) { super.init(frame: frame) stackH = { let v = UIStackView() v.spacing = 4 v.distribution = .fillEqually v.alignment = .center addSubview(v) v.snp.makeConstraints { make in make.leading.trailing.top.bottom.equalToSuperview() make.height.equalTo(211) } return v }() firstFlag.setupRankPlace(1) secondFlag.setupRankPlace(2) thirdFlag.setupRankPlace(3) stackH.addArrangedSubview(secondFlag) secondFlag.snp.makeConstraints { make in self.consBottomToSuperForSecondFlag = make.bottom.equalToSuperview().constraint self.consTopToSuperForSecondFlag = make.top.equalToSuperview().offset(45).constraint } stackH.addArrangedSubview(firstFlag) firstFlag.snp.makeConstraints { make in make.bottom.equalToSuperview() make.top.equalToSuperview() } stackH.addArrangedSubview(thirdFlag) thirdFlag.snp.makeConstraints { make in self.consBottomToSuperForSecondFlag = make.bottom.equalToSuperview().constraint self.consTopToSuperForThirdFlag = make.top.equalToSuperview().offset(45).constraint } } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } // MARK: Public func showEmpty(_ empty: Bool) { if empty { stackH.isHidden = true showEmpty(text: "No character yet") } else { stackH.isHidden = false hideEmpty() } } func setup2nd3rdBottomPdding() { secondFlag.snp.updateConstraints { make in make.top.equalToSuperview().offset(14) make.bottom.equalToSuperview().offset(-24) } thirdFlag.snp.updateConstraints { make in make.top.equalToSuperview().offset(14) make.bottom.equalToSuperview().offset(-24) } setNeedsLayout() layoutIfNeeded() } // MARK: - Public func config(_ data: [AIDiscoverTop]?) { datas = data firstFlag.config(getRankData(no: 1)) secondFlag.config(getRankData(no: 2)) thirdFlag.config(getRankData(no: 3)) } // MARK: Helper private func getRankData(no: Int) -> AIDiscoverTop? { guard let validDatas = datas else { return nil } for per in validDatas { if per.rankNo ?? 0 == no { return per } } return validDatas.first } } /// Top three flag class DiscoverTopThreeRankFlagView: UIView { var cornerBlock: UIView! var imageView: UIImageView! // var maskGradient: GradientView! var topShadowIv : UIImageView! var overlay: UIImageView! var iconAndLabel: CLIconLabel! var rankLabel: UILabel! var topButton: UIButton! var top1: Bool = false { didSet { imageView.snp.makeConstraints { make in make.top.equalToSuperview() } } } var type: DiscoverRankType = .chat { didSet{ refreshIconLabelIcon() } } var data: AIDiscoverTop? override init(frame: CGRect) { super.init(frame: frame) //layer.masksToBounds = false cornerRadius = 8 cornerBlock = { let v = UIView() //v.cornerRadius = 8 addSubview(v) v.snp.makeConstraints { make in make.edges.equalToSuperview() } return v }() imageView = { let v = UIImageView() v.cornerRadius = 8 v.contentMode = .scaleAspectFill cornerBlock.addSubview(v) v.snp.makeConstraints { make in make.leading.trailing.bottom.equalToSuperview() make.top.equalToSuperview() } return v }() topShadowIv = { let v = UIImageView() v.image = UIImage(named: "discover_rank_flag_overlay") v.contentMode = .scaleToFill addSubview(v) v.snp.makeConstraints { make in make.leading.top.trailing.equalToSuperview() make.height.equalTo(40) } return v }() // maskGradient = { // let v = GradientView(colors: [UIColor.c.cbdi.withAlphaComponent(1), UIColor.c.cbdi.withAlphaComponent(0)], gradientType: .topToBottom) // addSubview(v) // v.snp.makeConstraints { make in // make.leading.top.trailing.equalToSuperview() // make.height.equalTo(40) // } // return v // }() overlay = { let v = UIImageView() addSubview(v) v.snp.makeConstraints { make in make.leading.trailing.equalToSuperview() make.bottom.equalToSuperview() } return v }() rankLabel = { let v = UILabel() v.textColor = .white v.font = .t.tnds addSubview(v) v.snp.makeConstraints { make in make.centerX.equalToSuperview() make.bottom.equalToSuperview().offset(-8) } return v }() iconAndLabel = { let v = CLIconLabel() addSubview(v) v.snp.makeConstraints { make in make.centerX.equalToSuperview() make.bottom.equalTo(rankLabel.snp.top).offset(-2) } return v }() topButton = { let v = UIButton() v.addTarget(self, action: #selector(tapTopButton), for: .touchUpInside) addSubview(v) v.snp.makeConstraints { make in make.edges.equalToSuperview() } return v }() //testData() } private func testData() { rankLabel.text = "1st" imageView.image = UIImage(named: "egpic") iconAndLabel.iconImageView.image = UIImage(named: "heartbeat") iconAndLabel.contentLabel.text = "37.8℃" } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func refreshIconLabelIcon(){ switch type { case .chat: iconAndLabel.iconImageView.image = MWIconFont.image(fromIcon: .chat, size: CGSize(width: 16, height: 16), color: .white) case .heartbeat: iconAndLabel.iconImageView.image = UIImage(named: "heartbeat") case .gift: iconAndLabel.iconImageView.image = UIImage(named: "icon_16_diamond") } } // MARK: Public func setupRankPlace(_ rank: Int){ if rank == 1{ setupOverlayImage(UIImage(named: "leaderboard_flag_top1")!) }else if rank == 2{ setupOverlayImage(UIImage(named: "leaderboard_flag_top2")!) // topShadowIv.snp.updateConstraints { make in // make.top.equalToSuperview().offset(-20) // } }else if rank == 3{ setupOverlayImage(UIImage(named: "leaderboard_flag_top3")!) // topShadowIv.snp.updateConstraints { make in // make.top.equalToSuperview().offset(-20) // } } } func config(_ data: AIDiscoverTop?) { self.data = data guard let rank = data else { return } rankLabel.text = rank.formateRankDisplayString() imageView.loadImage(rank.homeImageUrl) var content = "-" switch type { case .chat: content = rank.formateChatDisplay() case .heartbeat: content = rank.formateHeartbeatDisplay() case .gift: content = rank.formateGiftDisplay() } iconAndLabel.contentLabel.text = content } // MARK: - Helper private func setupOverlayImage(_ image: UIImage) { overlay.image = image let aspectRatio = image.size.height / image.size.width overlay.snp.makeConstraints { make in make.height.equalTo(overlay.snp.width).multipliedBy(aspectRatio) } } // MARK: - Action @objc private func tapTopButton(){ guard let rank = data, let aiId = rank.aiId else { return } //AppRouter.goAIRoleHome(aiId: aiId) AppRouter.goChatVC(aiId: aiId) } } class DiscoverHomeRankEntry: UIView { override init(frame: CGRect) { super.init(frame: frame) setupViews() setupData() setupEvent() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupViews() { } private func setupData() { } private func setupEvent() { } }