LNAutoReplyListViewController.swift 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. //
  2. // LNAutoReplyListViewController.swift
  3. // Gami
  4. //
  5. // Created by OneeChan on 2026/3/9.
  6. //
  7. import Foundation
  8. import UIKit
  9. import SnapKit
  10. import MJRefresh
  11. import Combine
  12. extension UIView {
  13. func pushToAutoReplyList() {
  14. let vc = LNAutoReplyListViewController()
  15. navigationController?.pushViewController(vc, animated: true)
  16. }
  17. }
  18. class LNAutoReplyListViewController: LNViewController {
  19. private let emptyView = LNNoMoreDataView()
  20. private let tipsCreateButton = UIButton()
  21. private let tableView = UITableView()
  22. private let createButton = UIButton()
  23. private var isLoading = false
  24. private var items: [LNAutoReplyVO] = []
  25. override func viewDidLoad() {
  26. super.viewDidLoad()
  27. setupViews()
  28. LNEventDeliver.addObserver(self)
  29. tableView.mj_header?.beginRefreshing()
  30. }
  31. }
  32. extension LNAutoReplyListViewController: LNGameMateManagerNotify {
  33. func onAutoReplyCreated(item: LNAutoReplyVO) {
  34. loadList()
  35. }
  36. func onAutoReplyDeleted(id: String) {
  37. loadList()
  38. }
  39. func onAutoReplyModified(item: LNAutoReplyVO) {
  40. loadList()
  41. }
  42. }
  43. extension LNAutoReplyListViewController {
  44. private func loadList() {
  45. guard !isLoading else { return }
  46. isLoading = true
  47. LNGameMateManager.shared.getAutoReplayList { [weak self] res in
  48. guard let self else { return }
  49. isLoading = false
  50. tableView.mj_header?.endRefreshing()
  51. tipsCreateButton.isHidden = true
  52. if let list = res?.list {
  53. items = list
  54. tableView.reloadData()
  55. if items.isEmpty {
  56. emptyView.showNoData(icon: .icNoDataRelationEmpty,
  57. tips: .init(key: "B00122"))
  58. tipsCreateButton.isHidden = false
  59. createButton.isHidden = true
  60. } else {
  61. emptyView.hide()
  62. createButton.isHidden = false
  63. }
  64. } else {
  65. if items.isEmpty {
  66. emptyView.showNetworkError()
  67. createButton.isHidden = true
  68. }
  69. }
  70. }
  71. }
  72. private func toCreateNewOne() {
  73. let sheet = LNBottomSheetMenu()
  74. sheet.update([
  75. .init(key: "B00119"),
  76. .init(key: "B00120")
  77. ]) { [weak self] index, _ in
  78. guard let self else { return }
  79. let item = LNAutoReplyVO()
  80. if index == 0 {
  81. item.type = .text
  82. } else {
  83. item.type = .voice
  84. }
  85. item.status = .pass
  86. view.pushToAutoRelyEdit(num: items.count, item: item)
  87. }
  88. sheet.popup()
  89. }
  90. }
  91. extension LNAutoReplyListViewController: UITableViewDataSource {
  92. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  93. items.count
  94. }
  95. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  96. let cell = tableView.dequeueReusableCell(withIdentifier: LNAutoReplyItemCell.className, for: indexPath) as! LNAutoReplyItemCell
  97. cell.update(indexPath.row, item: items[indexPath.row])
  98. return cell
  99. }
  100. }
  101. extension LNAutoReplyListViewController {
  102. private func setupViews() {
  103. title = .init(key: "B00112")
  104. view.backgroundColor = .primary_1
  105. let header = MJRefreshNormalHeader { [weak self] in
  106. guard let self else { return }
  107. loadList()
  108. }
  109. header.lastUpdatedTimeLabel?.isHidden = true
  110. header.stateLabel?.isHidden = true
  111. tableView.mj_header = header
  112. tableView.backgroundColor = .clear
  113. tableView.dataSource = self
  114. tableView.separatorStyle = .none
  115. tableView.allowsSelection = false
  116. tableView.contentInset = .init(top: 2, left: 0, bottom: -view.commonBottomInset + 47, right: 0)
  117. tableView.register(LNAutoReplyItemCell.self, forCellReuseIdentifier: LNAutoReplyItemCell.className)
  118. view.addSubview(tableView)
  119. tableView.snp.makeConstraints { make in
  120. make.edges.equalToSuperview()
  121. }
  122. emptyView.tipsLabel.textColor = .black.withAlphaComponent(0.2)
  123. emptyView.isHidden = true
  124. tableView.addSubview(emptyView)
  125. emptyView.snp.makeConstraints { make in
  126. make.centerX.equalToSuperview()
  127. make.centerY.equalToSuperview().multipliedBy(0.6)
  128. }
  129. tipsCreateButton.isHidden = true
  130. tipsCreateButton.layer.cornerRadius = 23.5
  131. tipsCreateButton.clipsToBounds = true
  132. tipsCreateButton.setBackgroundImage(.primary_8, for: .normal)
  133. tipsCreateButton.setTitle(.init(key: "B00115"), for: .normal)
  134. tipsCreateButton.titleLabel?.font = .heading_h3
  135. tipsCreateButton.setTitleColor(.text_1, for: .normal)
  136. tipsCreateButton.addAction(UIAction(handler: { [weak self] _ in
  137. guard let self else { return }
  138. toCreateNewOne()
  139. }), for: .touchUpInside)
  140. emptyView.addActionView(tipsCreateButton)
  141. tipsCreateButton.snp.makeConstraints { make in
  142. make.width.equalTo(189)
  143. make.height.equalTo(47)
  144. }
  145. let bottomMenu = UIView()
  146. view.addSubview(bottomMenu)
  147. bottomMenu.snp.makeConstraints { make in
  148. make.horizontalEdges.equalToSuperview()
  149. make.bottom.equalToSuperview()
  150. }
  151. let bottomGradient = CAGradientLayer()
  152. bottomGradient.colors = [
  153. UIColor.white.withAlphaComponent(0).cgColor,
  154. UIColor.white.cgColor,
  155. UIColor.white.cgColor
  156. ]
  157. bottomGradient.locations = [0, 0.5, 1]
  158. bottomGradient.startPoint = .init(x: 0, y: 0)
  159. bottomGradient.endPoint = .init(x: 0, y: 1)
  160. bottomMenu.layer.addSublayer(bottomGradient)
  161. bottomMenu.publisher(for: \.bounds).removeDuplicates().sink { [weak bottomGradient] newValue in
  162. guard let bottomGradient else { return }
  163. bottomGradient.frame = newValue
  164. }.store(in: &cancellables)
  165. createButton.layer.cornerRadius = 23.5
  166. createButton.clipsToBounds = true
  167. createButton.setBackgroundImage(.primary_8, for: .normal)
  168. createButton.setTitle(.init(key: "B00115"), for: .normal)
  169. createButton.titleLabel?.font = .heading_h3
  170. createButton.setTitleColor(.text_1, for: .normal)
  171. createButton.isHidden = true
  172. createButton.addAction(UIAction(handler: { [weak self] _ in
  173. guard let self else { return }
  174. toCreateNewOne()
  175. }), for: .touchUpInside)
  176. bottomMenu.addSubview(createButton)
  177. createButton.snp.makeConstraints { make in
  178. make.horizontalEdges.equalToSuperview().inset(16)
  179. make.bottom.equalToSuperview().offset(view.commonBottomInset)
  180. make.top.equalToSuperview()
  181. make.height.equalTo(47)
  182. }
  183. }
  184. }