// // LNVisitorsViewController.swift // Gami // // Created by OneeChan on 2026/1/25. // import Foundation import UIKit import SnapKit import Combine import MJRefresh extension UIView { func pushToVisitors() { let vc = LNVisitorsViewController() navigationController?.pushViewController(vc, animated: true) } } class LNVisitorsViewController: LNViewController { private let emptyView = LNNoMoreDataView() private let permissionView = LNIMNotificationPermissionView() private let tableView = UITableView() private var visitors: [LNVisitorItemVO] = [] private var nextTag: String? override func viewDidLoad() { super.viewDidLoad() setupViews() tableView.mj_header?.beginRefreshing() } } extension LNVisitorsViewController { private func loadList() { LNGameMateManager.shared.getVisitorsList(next: nextTag) { [weak self] list, next in guard let self else { return } guard let list else { tableView.mj_header?.endRefreshing() tableView.mj_footer?.endRefreshingWithNoMoreData() return } if nextTag?.isEmpty != false { visitors = list } else { visitors.append(contentsOf: list) } nextTag = next if visitors.isEmpty { emptyView.showNoData(icon: .icNoDataRelationEmpty) } else { emptyView.hide() } tableView.reloadData() self.tableView.mj_header?.endRefreshing() if next?.isEmpty != false { tableView.mj_footer?.endRefreshingWithNoMoreData() } else { tableView.mj_footer?.endRefreshing() } } } } extension LNVisitorsViewController: UITableViewDataSource, UITableViewDelegate { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { visitors.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: LNVisitorItemCell.className, for: indexPath) as! LNVisitorItemCell let item = visitors[indexPath.row] cell.update(item) return cell } } extension LNVisitorsViewController { private func setupViews() { title = .init(key: "B00091") view.backgroundColor = .primary_1 view.addSubview(emptyView) emptyView.snp.makeConstraints { make in make.centerX.equalToSuperview() make.centerY.equalToSuperview().multipliedBy(0.6) } let stackView = UIStackView() stackView.axis = .vertical view.addSubview(stackView) stackView.snp.makeConstraints { make in make.horizontalEdges.equalToSuperview() make.top.equalToSuperview().offset(10) make.bottom.equalToSuperview() } stackView.addArrangedSubview(buildPermission()) stackView.addArrangedSubview(buildList()) } private func buildPermission() -> UIView { let container = UIView() permissionView.publisher(for: \.isHidden).removeDuplicates().sink { [weak container] newValue in guard let container else { return } container.isHidden = newValue }.store(in: &cancellables) container.addSubview(permissionView) permissionView.snp.makeConstraints { make in make.horizontalEdges.equalToSuperview() make.bottom.equalToSuperview().offset(-10) make.top.equalToSuperview() } return container } private func buildList() -> UIView { let header = MJRefreshNormalHeader { [weak self] in guard let self else { return } nextTag = nil loadList() } header.lastUpdatedTimeLabel?.isHidden = true header.stateLabel?.isHidden = true tableView.mj_header = header let footer = MJRefreshAutoNormalFooter { [weak self] in guard let self else { return } loadList() } footer.setTitle("", for: .noMoreData) footer.setTitle(.init(key: "A00046"), for: .idle) tableView.delegate = self tableView.dataSource = self tableView.allowsSelection = false tableView.showsVerticalScrollIndicator = false tableView.separatorStyle = .none tableView.backgroundColor = .clear tableView.contentInset = .init(top: 0, left: 0, bottom: -view.commonBottomInset, right: 0) tableView.register(LNVisitorItemCell.self, forCellReuseIdentifier: LNVisitorItemCell.className) return tableView } }