LNReportViewController.swift 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. //
  2. // LNReportViewController.swift
  3. // Lanu
  4. //
  5. // Created by OneeChan on 2025/12/12.
  6. //
  7. import Foundation
  8. import UIKit
  9. import SnapKit
  10. extension UIView {
  11. func pushToReport(uid: String) {
  12. let vc = LNReportViewController(uid: uid)
  13. navigationController?.pushViewController(vc, animated: true)
  14. }
  15. }
  16. class LNReportViewController: LNViewController {
  17. private let uid: String
  18. private let maxUpload = 6
  19. private let textInputView = LNCommonTextView()
  20. private let imageUploadView = LNMultiImagesUploadView()
  21. private let submitButton = UIButton()
  22. init(uid: String) {
  23. self.uid = uid
  24. super.init(nibName: nil, bundle: nil)
  25. }
  26. override func viewDidLoad() {
  27. super.viewDidLoad()
  28. setupViews()
  29. updateSubmitButton()
  30. }
  31. required init?(coder: NSCoder) {
  32. fatalError("init(coder:) has not been implemented")
  33. }
  34. }
  35. extension LNReportViewController: UITextViewDelegate {
  36. func textViewDidChange(_ textView: UITextView) {
  37. updateSubmitButton()
  38. }
  39. }
  40. extension LNReportViewController {
  41. private func updateSubmitButton() {
  42. if !textInputView.text.isEmpty {
  43. submitButton.setBackgroundImage(.primary_8, for: .normal)
  44. submitButton.isEnabled = true
  45. } else {
  46. submitButton.setBackgroundImage(nil, for: .normal)
  47. submitButton.isEnabled = false
  48. }
  49. }
  50. private func setupViews() {
  51. title = .init(key: "A00043")
  52. view.backgroundColor = .primary_1
  53. let scrollView = UIScrollView()
  54. view.addSubview(scrollView)
  55. scrollView.snp.makeConstraints { make in
  56. make.edges.equalToSuperview()
  57. }
  58. let fakeView = UIView()
  59. scrollView.addSubview(fakeView)
  60. fakeView.snp.makeConstraints { make in
  61. make.horizontalEdges.equalToSuperview()
  62. make.top.equalToSuperview()
  63. make.width.equalToSuperview()
  64. make.height.equalTo(0)
  65. }
  66. let textView = buildTextView()
  67. scrollView.addSubview(textView)
  68. textView.snp.makeConstraints { make in
  69. make.horizontalEdges.equalToSuperview().inset(16)
  70. make.top.equalToSuperview().offset(16)
  71. }
  72. let photoView = buildPhotoView()
  73. scrollView.addSubview(photoView)
  74. photoView.snp.makeConstraints { make in
  75. make.horizontalEdges.equalToSuperview().inset(16)
  76. make.top.equalTo(textView.snp.bottom).offset(16)
  77. make.bottom.equalToSuperview().offset(-view.safeBottomInset - 47)
  78. }
  79. let submit = buildSubmit()
  80. view.addSubview(submit)
  81. submit.snp.makeConstraints { make in
  82. make.horizontalEdges.equalToSuperview().inset(16)
  83. make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom)
  84. }
  85. view.onTap { [weak self] in
  86. guard let self else { return }
  87. view.endEditing(true)
  88. }
  89. }
  90. private func buildTextView() -> UIView {
  91. let container = UIView()
  92. container.backgroundColor = .fill
  93. container.layer.cornerRadius = 12
  94. let titleLabel = UILabel()
  95. titleLabel.text = .init(key: "A00239")
  96. titleLabel.font = .heading_h4
  97. titleLabel.textColor = .text_5
  98. container.addSubview(titleLabel)
  99. titleLabel.snp.makeConstraints { make in
  100. make.top.equalToSuperview().offset(16)
  101. make.horizontalEdges.equalToSuperview().inset(16)
  102. }
  103. textInputView.maxInput = LNReportManager.reportExtraMaxInput
  104. textInputView.delegate = self
  105. container.addSubview(textInputView)
  106. textInputView.snp.makeConstraints { make in
  107. make.horizontalEdges.equalToSuperview().inset(16)
  108. make.top.equalTo(titleLabel.snp.bottom).offset(8)
  109. make.bottom.equalToSuperview().offset(-16)
  110. make.height.equalTo(150)
  111. }
  112. return container
  113. }
  114. private func buildPhotoView() -> UIView {
  115. let container = UIView()
  116. container.backgroundColor = .fill
  117. container.layer.cornerRadius = 12
  118. let titleLabel = UILabel()
  119. titleLabel.text = .init(key: "A00177", maxUpload)
  120. titleLabel.font = .heading_h4
  121. titleLabel.textColor = .text_5
  122. container.addSubview(titleLabel)
  123. titleLabel.snp.makeConstraints { make in
  124. make.top.equalToSuperview().offset(16)
  125. make.horizontalEdges.equalToSuperview().inset(16)
  126. }
  127. let descLabel = UILabel()
  128. descLabel.text = .init(key: "A00178")
  129. descLabel.font = .body_s
  130. descLabel.textColor = .text_4
  131. container.addSubview(descLabel)
  132. descLabel.snp.makeConstraints { make in
  133. make.horizontalEdges.equalToSuperview().inset(16)
  134. make.top.equalTo(titleLabel.snp.bottom).offset(2)
  135. }
  136. imageUploadView.maxPhoto = maxUpload
  137. container.addSubview(imageUploadView)
  138. imageUploadView.snp.makeConstraints { make in
  139. make.horizontalEdges.equalToSuperview().inset(16)
  140. make.top.equalTo(descLabel.snp.bottom).offset(16)
  141. make.bottom.equalToSuperview().offset(-16)
  142. make.height.equalTo(0).priority(.low)
  143. }
  144. return container
  145. }
  146. private func buildSubmit() -> UIView {
  147. submitButton.clipsToBounds = true
  148. submitButton.backgroundColor = .fill_4
  149. submitButton.layer.cornerRadius = 23.5
  150. submitButton.setTitle(.init(key: "A00240"), for: .normal)
  151. submitButton.titleLabel?.font = .heading_h3
  152. submitButton.addAction(UIAction(handler: { [weak self] _ in
  153. guard let self else { return }
  154. LNReportManager.shared.reportUser(
  155. uid: uid, content: textInputView.text,
  156. photos: imageUploadView.curFileUrls)
  157. { [weak self] success in
  158. guard let self else { return }
  159. guard success else { return }
  160. showToast(.init(key: "A00241"))
  161. navigationController?.popViewController(animated: true)
  162. }
  163. }), for: .touchUpInside)
  164. submitButton.snp.makeConstraints { make in
  165. make.height.equalTo(47)
  166. }
  167. return submitButton
  168. }
  169. }
  170. #if DEBUG
  171. import SwiftUI
  172. struct LNReportViewControllerPreview: UIViewControllerRepresentable {
  173. func makeUIViewController(context: Context) -> some UIViewController {
  174. LNReportViewController(uid: "")
  175. }
  176. func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
  177. }
  178. }
  179. #Preview(body: {
  180. LNReportViewControllerPreview()
  181. })
  182. #endif