| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- //
- // LNUserSearchOverviewListView.swift
- // Lanu
- //
- // Created by OpenAI Codex on 2026/3/19.
- //
- import Foundation
- import UIKit
- import SnapKit
- import MJRefresh
- protocol LNUserSearchOverviewListViewDelegate: NSObject {
- func onUserSearchOverviewListView(view: LNUserSearchOverviewListView, didClickMore tab: LNUserSearchTab)
- }
- class LNUserSearchOverviewListView: UIView {
- private let emptyView = LNNoMoreDataView()
- private let scrollView = UIScrollView()
-
- private let userMaxShowCount = 3
- private var userViews: [LNUserSearchUserCardView] = []
- private let userSectionView = UIView()
-
- private let roomMaxShowCount = 2
- private let roomStackView = LNMultiLineStackView()
- private var roomViews: [LNUserSearchRoomCardView] = []
- private let roomSectionView = UIView()
-
- private var curKeyword: String?
- weak var delegate: LNUserSearchOverviewListViewDelegate?
-
- override init(frame: CGRect) {
- super.init(frame: frame)
-
- setupViews()
- }
-
- func search(_ keyword: String) {
- userSectionView.isHidden = true
- roomSectionView.isHidden = true
-
- curKeyword = keyword
-
- reload()
- }
-
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- }
- extension LNUserSearchOverviewListView {
- private func reload() {
- guard let curKeyword else { return }
-
- LNGameMateManager.shared.mixSearch(keyword: curKeyword) { [weak self] res in
- guard let self else { return }
- scrollView.mj_header?.endRefreshing()
-
- guard let res else { return }
- emptyView.hide()
-
- if res.playmate.isEmpty {
- userSectionView.isHidden = true
- } else {
- userSectionView.isHidden = false
- for (index, userView) in userViews.enumerated() {
- if index < res.playmate.count {
- userView.update(res.playmate[index])
- userView.isHidden = false
- } else {
- userView.isHidden = true
- }
- }
- }
-
- if res.rooms.isEmpty {
- roomSectionView.isHidden = true
- } else {
- roomSectionView.isHidden = false
- var views: [UIView] = []
- for (index, roomView) in roomViews.enumerated() {
- if index < res.rooms.count {
- roomView.update(res.rooms[index])
- views.append(roomView)
- }
- }
- roomStackView.update(views)
- }
-
- if res.playmate.isEmpty, res.rooms.isEmpty {
- emptyView.showNoData(tips: .init(key: "A00244"))
- }
- }
- }
- }
- extension LNUserSearchOverviewListView {
- private func setupViews() {
- backgroundColor = .white
-
- let header = MJRefreshNormalHeader { [weak self] in
- guard let self else { return }
- reload()
- }
- header.lastUpdatedTimeLabel?.isHidden = true
- header.stateLabel?.isHidden = true
- scrollView.mj_header = header
- scrollView.showsVerticalScrollIndicator = false
- addSubview(scrollView)
- scrollView.snp.makeConstraints { make in
- make.edges.equalToSuperview()
- }
-
- let stackView = UIStackView()
- stackView.axis = .vertical
- scrollView.addSubview(stackView)
- stackView.snp.makeConstraints { make in
- make.edges.equalToSuperview()
- make.width.equalTo(scrollView)
- }
-
- stackView.addArrangedSubview(buildUserView())
- stackView.addArrangedSubview(buildRoomView())
-
- scrollView.addSubview(emptyView)
- emptyView.snp.makeConstraints { make in
- make.centerX.equalToSuperview()
- make.centerY.equalToSuperview().multipliedBy(0.6)
- }
- }
-
- private func buildHeader(title: String, action: @escaping () -> Void) -> UIView {
- let container = UIView()
-
- let titleLabel = UILabel()
- titleLabel.text = title
- titleLabel.font = .heading_h5
- titleLabel.textColor = .text_5
- container.addSubview(titleLabel)
- titleLabel.snp.makeConstraints { make in
- make.verticalEdges.equalToSuperview()
- make.leading.equalToSuperview().offset(16)
- }
-
- let config = UIImage.SymbolConfiguration(pointSize: 9)
- let button = UIButton(type: .system)
- button.setTitle(.init(key: "A00048"), for: .normal)
- button.setTitleColor(.text_4, for: .normal)
- button.titleLabel?.font = .body_xs
- button.semanticContentAttribute = .forceRightToLeft
- button.setImage(UIImage(systemName: "chevron.backward", withConfiguration: config), for: .normal)
- button.tintColor = .text_4
- button.imageView?.contentMode = .scaleAspectFit
- button.addAction(UIAction(handler: { _ in action() }), for: .touchUpInside)
- container.addSubview(button)
- button.snp.makeConstraints { make in
- make.trailing.equalToSuperview().offset(-16)
- make.centerY.equalToSuperview()
- }
-
- return container
- }
-
- private func buildUserView() -> UIView {
- let userHeader = buildHeader(title: .init(key: "A00366")) { [weak self] in
- guard let self else { return }
- delegate?.onUserSearchOverviewListView(view: self, didClickMore: .user)
- }
- userSectionView.addSubview(userHeader)
- userHeader.snp.makeConstraints { make in
- make.horizontalEdges.top.equalToSuperview()
- }
-
- let userStackView = UIStackView()
- userStackView.axis = .vertical
- userSectionView.addSubview(userStackView)
- userStackView.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview()
- make.top.equalTo(userHeader.snp.bottom).offset(5)
- make.bottom.equalToSuperview()
- }
-
- for _ in 0..<userMaxShowCount {
- let userView = LNUserSearchUserCardView()
- userStackView.addArrangedSubview(userView)
- userViews.append(userView)
- }
-
- return userSectionView
- }
-
- private func buildRoomView() -> UIView {
- let roomHeader = buildHeader(title: .init(key: "A00367")) { [weak self] in
- guard let self else { return }
- delegate?.onUserSearchOverviewListView(view: self, didClickMore: .rooms)
- }
- roomSectionView.addSubview(roomHeader)
- roomHeader.snp.makeConstraints { make in
- make.horizontalEdges.top.equalToSuperview()
- }
-
- roomStackView.axis = .horizontal
- roomStackView.itemSpacing = 13
- roomStackView.columns = 2
- roomStackView.itemDistribution = .equalSpacing
- roomSectionView.addSubview(roomStackView)
- roomStackView.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview().inset(16)
- make.bottom.equalToSuperview()
- make.top.equalTo(roomHeader.snp.bottom).offset(16)
- }
-
- for _ in 0..<roomMaxShowCount {
- let roomView = LNUserSearchRoomCardView()
- roomViews.append(roomView)
- }
- roomStackView.update(roomViews)
-
- return roomSectionView
- }
- }
|