// // HomePageRootController.swift // Crush // // Created by Leon on 2025/7/22. // import UIKit import Combine class HomePageRootController: CLTabRootController { var navTitleLabel: CLLabel! var filterButton: EPIconGhostButton! var filterConditionCount: Int = 0 lazy var viewModel = MeetViewModel() @Published var filterModel = RolesFilterModel() private var cancellables = Set() override func viewDidLoad() { super.viewDidLoad() //container.viewModel = viewModel container.setupViewModel(vm: viewModel) // Do any additional setup after loading the view. // view.showEmpty(text: "首页 Coming soon") // if APIConfig.environment == .test { #if DEBUG let debugButton = { let v = UIButton() v.setTitle("Debug Entrances", for: .normal) v.titleLabel?.font = .t.tlm v.setTitleColor(.yellow, for: .normal) v.layer.borderColor = UIColor.yellow.cgColor v.layer.borderWidth = 1 v.addTarget(self, action: #selector(tapDebugButton), for: .touchUpInside) navigationView.addSubview(v) v.snp.makeConstraints { make in // make.leading.equalToSuperview().offset(24) make.centerX.equalToSuperview() make.height.equalTo(30) make.centerY.equalTo(navigationView.backButton) } return v }() debugButton.isHidden = false // } #endif setupViews() setupDatas() setupEvents() } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) } private func setupViews() { navigationView.bgView.alpha = 0 navTitleLabel = { let v = CLLabel() v.font = .t.tdm navigationView.addSubview(v) v.snp.makeConstraints { make in make.centerY.equalTo(navigationView.titleLabel) make.leading.equalToSuperview().offset(24) } return v }() filterButton = { let v = EPIconGhostButton(radius: .none, iconSize: .medium, iconCode: .filterFill) v.addTarget(self, action: #selector(tapFilter), for: .touchUpInside) v.setBackgroundImage(nil, for: .highlighted) navigationView.rightStackH.addArrangedSubview(v) navigationView.paddingRightForRightStack = 24 v.snp.makeConstraints { _ in // make.size.equalTo(v.bgImageSize()) } return v }() filterButton.titleLabel?.font = .t.tll filterButton.setTitleColor(.text, for: .normal) filterButton.touchAreaInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10) filterButton.layer.masksToBounds = false navTitleLabel.text = "Encounter" } private func setupDatas() { setupOrResetFilterModel() // viewModel.loadCards() loadFirstCards() } private func setupOrResetFilterModel(loadNewData: Bool = false){ filterModel = RolesFilterModel() if !UserCore.shared.isLogin(){ filterModel.sex = [.female] filterModel.age = .AGE_1 } viewModel.filterModel = filterModel if loadNewData{ loadFirstCards() } } private func tryShowMeetGuide(){ guard isDisplaying else{ return } if AppCache.fetchCache(key: CacheKey.meetGuideSeen.rawValue, type: Bool.self) ?? false == false{ let vc = HomeMeetGuideController() vc.show() } } private func loadFirstCards(){ Hud.showIndicator() viewModel.loadCards {[weak self] _, cards in if cards.count > 0{ self?.tryShowMeetGuide() } Hud.hideIndicator() } } private func setupEvents() { $filterModel.sink {[weak self] model in self?.setupFilterCount(model.filterCount()) }.store(in: &cancellables) NotificationCenter.default.addObserver(self, selector: #selector(notifyLogin), name: AppNotificationName.userLoginSuccess.notificationName, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(notifyLogout), name: AppNotificationName.userLogout.notificationName, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(notifyNetworkRestore), name: AppNotificationName.networkRestored.notificationName, object: nil) } // MARK: - Helper func setupFilterCount(_ count: Int) { filterConditionCount = count if count > 0 { filterButton.optionalIconColor = .text filterButton.setTitle(" (\(count))", for: .normal) } else { filterButton.optionalIconColor = .text filterButton.setTitle("", for: .normal) } filterButton.layoutIfNeeded() } // MARK: - Function private func showSecretAdmirerAlert(){ let content = "Someone is secretly in love with you\n" let alert = Alert(title: "Secret Admirer", text: content, image: UIImage(named: "heart_meet_48")!) alert.masTopToImageBgForImageView?.update(offset: 42) alert.setupContentStackSpacing(14) alert.setupBottomBlurImage(image: UIImage.egpic ) let aString = NSAttributedString.getIconTitleAttributeByWords(words: "20 unlock", iconImage: UIImage.icon32Diamond, iconSize: CGSize(width: 24, height: 24), textFont: .t.tll, textColor: .white) let confirmCoin = AlertAction(attributedTitle: aString, actionStyle: .confirm) { dlog("tap confirm coin") } let cancel = AlertAction(title: "Cancel", actionStyle: .cancel, block: nil) // alert.addAction(confirm) alert.addAction(confirmCoin) alert.addAction(cancel) alert.show() alert.layoutIfNeeded() } func setupFilter(filter: RolesFilterModel){ viewModel.filterModel = filter Hud.showIndicator() viewModel.loadCards { _, _ in Hud.hideIndicator() } } // MARK: - Action @objc private func tapFilter() { // #warning("test") // showMatched() // showSecretAdmirerAlert() let vc = RolesFilterController() vc.filterType = .meet vc.rolesFilterModel = filterModel presentNaviRootVc(vc: vc) vc.completion = {[weak self] model in self?.filterModel = model // dlog("完成fitler选择:\(model)") self?.setupFilter(filter: model) } } @objc private func tapDebugButton() { UIWindow.getTopViewController()?.navigationController?.pushViewController(TestEntrancesController(), animated: true) // #warning("test") // container.testFunction() } // MARK: - Notification @objc private func notifyLogin(){ setupOrResetFilterModel(loadNewData: true) } @objc private func notifyLogout(){ setupOrResetFilterModel(loadNewData: true) } @objc private func notifyNetworkRestore(){ if viewModel.cards.count == 0{ loadFirstCards() } } }