LNSkillCommentsView.swift 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. //
  2. // LNSkillCommentsView.swift
  3. // Gami
  4. //
  5. // Created by OneeChan on 2026/2/3.
  6. //
  7. import Foundation
  8. import UIKit
  9. import SnapKit
  10. class LNSkillCommentsView: UIView {
  11. private let starLabel = UILabel()
  12. private let countLabel = UILabel()
  13. private let stackView = UIStackView()
  14. private var curSkill: LNGameMateSkillDetailVO?
  15. override init(frame: CGRect) {
  16. super.init(frame: frame)
  17. setupViews()
  18. }
  19. func update(_ detail: LNGameMateSkillDetailVO) {
  20. curSkill = detail
  21. starLabel.text = "\(detail.star)"
  22. LNGameMateManager.shared.getSkillCommentList(id: detail.id) { [weak self] res in
  23. guard let self else { return }
  24. guard let res else { return }
  25. isHidden = res.list.isEmpty
  26. countLabel.text = "(\(res.total))"
  27. reloadList(res.list)
  28. }
  29. }
  30. required init?(coder: NSCoder) {
  31. fatalError("init(coder:) has not been implemented")
  32. }
  33. }
  34. extension LNSkillCommentsView {
  35. private func reloadList(_ list: [LNSkillCommentVO]) {
  36. stackView.arrangedSubviews.forEach {
  37. stackView.removeArrangedSubview($0)
  38. $0.removeFromSuperview()
  39. }
  40. let comments = list.prefix(3)
  41. comments.forEach {
  42. let itemView = LNSkillCommentItemView()
  43. itemView.update($0)
  44. stackView.addArrangedSubview(itemView)
  45. if $0.userNo != comments.last?.userNo {
  46. let line = UIView()
  47. line.backgroundColor = .fill_2
  48. line.snp.makeConstraints { make in
  49. make.height.equalTo(1)
  50. }
  51. stackView.addArrangedSubview(line)
  52. }
  53. }
  54. }
  55. private func setupViews() {
  56. let header = buildHeader()
  57. addSubview(header)
  58. header.snp.makeConstraints { make in
  59. make.horizontalEdges.equalToSuperview()
  60. make.top.equalToSuperview().offset(18)
  61. }
  62. stackView.axis = .vertical
  63. stackView.spacing = 0
  64. addSubview(stackView)
  65. stackView.snp.makeConstraints { make in
  66. make.horizontalEdges.equalToSuperview()
  67. make.top.equalTo(header.snp.bottom)
  68. make.bottom.equalToSuperview()
  69. }
  70. }
  71. private func buildHeader() -> UIView {
  72. let container = UIView()
  73. container.onTap { [weak self] in
  74. guard let self else { return }
  75. guard let curSkill else { return }
  76. let panel = LNSkillCommentsPanel()
  77. panel.update(curSkill.id)
  78. panel.popup(self)
  79. }
  80. let starIc = UIImageView(image: .icStarFill)
  81. container.addSubview(starIc)
  82. starIc.snp.makeConstraints { make in
  83. make.leading.equalToSuperview()
  84. make.centerY.equalToSuperview()
  85. make.width.height.equalTo(16)
  86. }
  87. starLabel.font = .heading_h3
  88. starLabel.textColor = .text_5
  89. container.addSubview(starLabel)
  90. starLabel.snp.makeConstraints { make in
  91. make.verticalEdges.equalToSuperview()
  92. make.leading.equalTo(starIc.snp.trailing).offset(4)
  93. }
  94. let dotView = UIView()
  95. dotView.backgroundColor = .text_3
  96. dotView.layer.cornerRadius = 2
  97. container.addSubview(dotView)
  98. dotView.snp.makeConstraints { make in
  99. make.centerY.equalToSuperview()
  100. make.leading.equalTo(starLabel.snp.trailing).offset(8)
  101. make.width.height.equalTo(4)
  102. }
  103. let titleLabel = UILabel()
  104. titleLabel.text = .init(key: "A00163")
  105. titleLabel.font = .heading_h3
  106. titleLabel.textColor = .text_5
  107. container.addSubview(titleLabel)
  108. titleLabel.snp.makeConstraints { make in
  109. make.centerY.equalToSuperview()
  110. make.leading.equalTo(dotView.snp.trailing).offset(8)
  111. }
  112. countLabel.font = .heading_h4
  113. countLabel.textColor = .text_5
  114. container.addSubview(countLabel)
  115. countLabel.snp.makeConstraints { make in
  116. make.leading.equalTo(titleLabel.snp.trailing)
  117. make.centerY.equalTo(titleLabel)
  118. }
  119. let arrow = UIImageView.arrowImageView(size: 10)
  120. arrow.tintColor = .text_4
  121. container.addSubview(arrow)
  122. arrow.snp.makeConstraints { make in
  123. make.trailing.equalToSuperview()
  124. make.centerY.equalToSuperview()
  125. }
  126. let moreLabel = UILabel()
  127. moreLabel.text = .init(key: "A00048")
  128. moreLabel.font = .body_s
  129. moreLabel.textColor = .text_5
  130. container.addSubview(moreLabel)
  131. moreLabel.snp.makeConstraints { make in
  132. make.centerY.equalToSuperview()
  133. make.trailing.equalTo(arrow.snp.leading).offset(-4)
  134. }
  135. return container
  136. }
  137. }
  138. class LNSkillCommentItemView: UIView {
  139. private let avatar = UIImageView()
  140. private let nameLabel = UILabel()
  141. private let starView = LNFiveStarScoreView()
  142. private let commentLabel = UILabel()
  143. private let timeLabel = UILabel()
  144. private var comment: LNSkillCommentVO?
  145. override init(frame: CGRect) {
  146. super.init(frame: frame)
  147. setupViews()
  148. }
  149. func update(_ comment: LNSkillCommentVO) {
  150. avatar.showAvatar(comment.avatar)
  151. nameLabel.text = comment.nickname
  152. starView.score = comment.star
  153. commentLabel.text = comment.comment
  154. timeLabel.text = TimeInterval(comment.time / 1_000).tencentIMTimeDesc
  155. self.comment = comment
  156. }
  157. required init?(coder: NSCoder) {
  158. fatalError("init(coder:) has not been implemented")
  159. }
  160. }
  161. extension LNSkillCommentItemView {
  162. private func setupViews() {
  163. avatar.layer.cornerRadius = 21
  164. avatar.clipsToBounds = true
  165. addSubview(avatar)
  166. avatar.snp.makeConstraints { make in
  167. make.leading.equalToSuperview()
  168. make.top.equalToSuperview().offset(18)
  169. make.width.height.equalTo(42)
  170. }
  171. nameLabel.font = .heading_h4
  172. nameLabel.textColor = .text_5
  173. addSubview(nameLabel)
  174. nameLabel.snp.makeConstraints { make in
  175. make.leading.equalTo(avatar.snp.trailing).offset(10)
  176. make.top.equalTo(avatar)
  177. }
  178. starView.icSize = 13
  179. starView.spacing = 2
  180. addSubview(starView)
  181. starView.snp.makeConstraints { make in
  182. make.trailing.equalToSuperview()
  183. make.centerY.equalTo(nameLabel)
  184. make.leading.greaterThanOrEqualTo(nameLabel.snp.trailing).offset(16)
  185. }
  186. commentLabel.font = .body_m
  187. commentLabel.textColor = .text_5
  188. commentLabel.numberOfLines = 0
  189. addSubview(commentLabel)
  190. commentLabel.snp.makeConstraints { make in
  191. make.leading.equalTo(nameLabel)
  192. make.top.equalTo(nameLabel.snp.bottom).offset(4)
  193. make.trailing.equalToSuperview()
  194. }
  195. timeLabel.font = .body_xs
  196. timeLabel.textColor = .text_3
  197. addSubview(timeLabel)
  198. timeLabel.snp.makeConstraints { make in
  199. make.leading.equalTo(nameLabel)
  200. make.top.equalTo(commentLabel.snp.bottom).offset(4)
  201. make.bottom.equalToSuperview().offset(-18)
  202. }
  203. }
  204. }