| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 |
- //
- // LNIMChatGameMateOrderView.swift
- // Lanu
- //
- // Created by OneeChan on 2025/12/31.
- //
- import Foundation
- import UIKit
- import SnapKit
- import Combine
- class LNIMChatGameMateOrderView: UIView {
- private let stackView = UIStackView()
-
- private let gameIc = UIImageView()
- private let titleLabel = UILabel()
- private let titleArrow = UIImageView.arrowImageView(size: 12)
- private let descLabel = UILabel()
-
- private let contentArrow = UIImageView.arrowImageView(size: 12)
-
- private let replyView = UIView()
- private let replyRemainLabel = UILabel()
- private var countDownTimer: Timer?
-
- private let actionView = UIView()
-
- private let extraView = UIView()
- private let extraLabel = UILabel()
-
- private var curOrder: LNUnfinishedOrderVO?
-
- weak var viewModel: LNIMChatViewModel? {
- didSet {
- viewModel?.$myOrders.sink { [weak self] list in
- guard let self else { return }
- isHidden = list.isEmpty == true
- if let first = list.first {
- update(first)
- }
- }.store(in: &bag)
- }
- }
-
- override init(frame: CGRect) {
- super.init(frame: frame)
-
- setupViews()
- }
-
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- }
- extension LNIMChatGameMateOrderView {
- private func startCountDown() {
- stopCountDown()
-
- updateRemain()
- let timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in
- guard let self else { return }
- if updateRemain() {
- stopCountDown()
- viewModel?.getUnfinishOrder()
- }
- }
- RunLoop.current.add(timer, forMode: .common)
- countDownTimer = timer
- }
-
- private func stopCountDown() {
- countDownTimer?.invalidate()
- countDownTimer = nil
- }
-
- @discardableResult
- private func updateRemain() -> Bool {
- guard let curOrder else { return true }
- let remain = 3600 - (Int(curTime) - curOrder.createTime / 1_000)
- replyRemainLabel.text = remain.timeCountDisplay
- return remain <= 0
- }
- }
- extension LNIMChatGameMateOrderView {
- private func update(_ order: LNUnfinishedOrderVO) {
- curOrder = order
-
- let isCreator = order.buyerUserNo.isMyUid
-
- gameIc.sd_setImage(with: URL(string: order.categoryIcon))
- descLabel.text = "\(order.bizCategoryName)/\(order.unit) x \(order.purchaseQty)"
- extraLabel.text = .init(key: "A00056", order.customerRemark)
-
- actionView.isHidden = true
- extraView.isHidden = true
- replyView.isHidden = true
- titleArrow.isHidden = true
- contentArrow.isHidden = true
- stopCountDown()
-
- switch order.status {
- case .created, .waitingForAccept:
- titleLabel.text = .init(key: "A00078")
- titleArrow.isHidden = false
- replyView.isHidden = false
- let remain = 3600 - (Int(curTime) - order.createTime / 1_000)
- replyRemainLabel.text = remain.timeCountDisplay
- startCountDown()
- if !isCreator {
- actionView.isHidden = false
- }
- case .accepted:
- titleLabel.text = .init(key: "A00079")
- contentArrow.isHidden = false
- if !isCreator, !order.customerRemark.isEmpty {
- extraView.isHidden = false
- }
- case .servicing:
- titleLabel.text = .init(key: "A00080")
- contentArrow.isHidden = false
- if !isCreator, !order.customerRemark.isEmpty {
- extraView.isHidden = false
- }
- case .completed, .refunded, .rejected, .serviceDone, .cancelled:
- break
- }
-
- stackView.snp.updateConstraints { make in
- make.verticalEdges.equalToSuperview().inset((!extraView.isHidden || !actionView.isHidden) ? 6 : 11)
- }
- }
-
- private func setupViews() {
- let container = UIView()
- container.backgroundColor = .fill
- container.layer.cornerRadius = 12
- container.onTap { [weak self] in
- guard let self else { return }
- if curOrder?.buyerUserNo.isMyUid != false {
- pushToOrderList()
- } else {
- pushToOrderRecord()
- }
- }
- addSubview(container)
- container.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview().inset(16)
- make.bottom.equalToSuperview()
- make.top.equalToSuperview().offset(8)
- }
-
- stackView.axis = .vertical
- stackView.spacing = 6
- container.addSubview(stackView)
- stackView.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview().inset(16)
- make.verticalEdges.equalToSuperview().inset(11)
- }
-
- let orderView = buildOrderView()
- stackView.addArrangedSubview(orderView)
-
- let actionView = buildActionView()
- stackView.addArrangedSubview(actionView)
-
- let extraView = buildExtraView()
- stackView.addArrangedSubview(extraView)
- }
-
- private func buildOrderView() -> UIView {
- let container = UIView()
- container.snp.makeConstraints { make in
- make.height.equalTo(50)
- }
-
- let replyView = buildReplyView()
- container.addSubview(replyView)
- replyView.snp.makeConstraints { make in
- make.centerY.equalToSuperview()
- make.trailing.equalToSuperview()
- }
-
- let infoView = buildInfoView()
- container.addSubview(infoView)
- infoView.snp.makeConstraints { make in
- make.centerY.equalToSuperview()
- make.leading.equalToSuperview()
- make.trailing.lessThanOrEqualTo(replyView.snp.leading).offset(-16)
- }
-
- contentArrow.tintColor = .text_4
- container.addSubview(contentArrow)
- contentArrow.snp.makeConstraints { make in
- make.centerY.equalToSuperview()
- make.trailing.equalToSuperview()
- }
-
- return container
- }
-
- private func buildReplyView() -> UIView {
- replyView.isHidden = true
-
- let replyTitleLabel = UILabel()
- replyTitleLabel.font = .body_s
- replyTitleLabel.text = .init(key: "A00081")
- replyTitleLabel.textColor = .text_5
- replyView.addSubview(replyTitleLabel)
- replyTitleLabel.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview()
- make.top.equalToSuperview()
- }
-
- replyRemainLabel.font = .heading_h5
- replyRemainLabel.textColor = .text_5
- replyView.addSubview(replyRemainLabel)
- replyRemainLabel.snp.makeConstraints { make in
- make.centerX.equalToSuperview()
- make.bottom.equalToSuperview()
- make.top.equalTo(replyTitleLabel.snp.bottom).offset(1)
- }
-
- return replyView
- }
-
- private func buildInfoView() -> UIView {
- let container = UIView()
-
- container.addSubview(gameIc)
- gameIc.snp.makeConstraints { make in
- make.leading.equalToSuperview()
- make.verticalEdges.equalToSuperview()
- make.width.height.equalTo(50)
- }
-
- let textView = UIView()
- container.addSubview(textView)
- textView.snp.makeConstraints { make in
- make.centerY.equalToSuperview()
- make.leading.equalTo(gameIc.snp.trailing).offset(1)
- make.trailing.lessThanOrEqualToSuperview()
- }
-
- titleLabel.font = .heading_h5
- titleLabel.textColor = .text_5
- textView.addSubview(titleLabel)
- titleLabel.snp.makeConstraints { make in
- make.leading.equalToSuperview()
- make.top.equalToSuperview()
- }
-
- titleArrow.tintColor = .text_4
- textView.addSubview(titleArrow)
- titleArrow.snp.makeConstraints { make in
- make.leading.equalTo(titleLabel.snp.trailing).offset(5)
- make.centerY.equalTo(titleLabel)
- make.trailing.lessThanOrEqualToSuperview()
- }
-
- descLabel.font = .body_s
- descLabel.textColor = .text_3
- textView.addSubview(descLabel)
- descLabel.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview()
- make.bottom.equalToSuperview()
- make.top.equalTo(titleLabel.snp.bottom).offset(2)
- }
-
- return container
- }
-
- private func buildActionView() -> UIView {
- actionView.snp.makeConstraints { make in
- make.height.equalTo(40)
- }
-
- let reject = UIButton()
- reject.setTitle(.init(key: "A00082"), for: .normal)
- reject.setTitleColor(.text_4, for: .normal)
- reject.titleLabel?.font = .body_s
- reject.contentEdgeInsets = .init(top: 7, left: 40, bottom: 7, right: 40)
- reject.layer.cornerRadius = 15
- reject.layer.borderWidth = 1
- reject.layer.borderColor = .text_3
- reject.setContentHuggingPriority(.defaultHigh, for: .horizontal)
- reject.addAction(UIAction(handler: { [weak self] _ in
- guard let self else { return }
- guard let curOrder else { return }
- LNOrderManager.shared.rejectOrder(orderId: curOrder.orderId) { success in }
- }), for: .touchUpInside)
- actionView.addSubview(reject)
- reject.snp.makeConstraints { make in
- make.leading.equalToSuperview()
- make.centerY.equalToSuperview()
- make.height.equalTo(30)
- }
-
- let accept = UIButton()
- accept.setTitle(.init(key: "A00083"), for: .normal)
- accept.setTitleColor(.text_1, for: .normal)
- accept.titleLabel?.font = .heading_h5
- accept.layer.cornerRadius = 15
- accept.clipsToBounds = true
- accept.setBackgroundImage(.primary_8, for: .normal)
- accept.addAction(UIAction(handler: { [weak self] _ in
- guard let self else { return }
- guard let curOrder else { return }
- LNOrderManager.shared.acceptOrder(orderId: curOrder.orderId) { success in }
- }), for: .touchUpInside)
- actionView.addSubview(accept)
- accept.snp.makeConstraints { make in
- make.centerY.equalToSuperview()
- make.height.equalTo(30)
- make.leading.equalTo(reject.snp.trailing).offset(12)
- make.trailing.equalToSuperview()
- }
-
- return actionView
- }
-
- private func buildExtraView() -> UIView {
- let line = UIView()
- line.backgroundColor = .fill_2
- extraView.addSubview(line)
- line.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview().inset(-4)
- make.top.equalToSuperview()
- make.height.equalTo(0.5)
- }
-
- extraLabel.font = .body_xs
- extraLabel.textColor = .text_4
- extraLabel.numberOfLines = 0
- extraView.addSubview(extraLabel)
- extraLabel.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview()
- make.top.equalTo(line.snp.bottom).offset(5)
- make.bottom.equalToSuperview().offset(-2)
- }
-
- return extraView
- }
- }
- #if DEBUG
- import SwiftUI
- struct LNIMChatGameMateOrderViewPreview: UIViewRepresentable {
- func makeUIView(context: Context) -> some UIView {
- let container = UIView()
- container.backgroundColor = .lightGray
-
- let view = LNIMChatGameMateOrderView()
- container.addSubview(view)
- view.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview()
- make.centerY.equalToSuperview()
- }
-
- return container
- }
-
- func updateUIView(_ uiView: UIViewType, context: Context) { }
- }
- #Preview(body: {
- LNIMChatGameMateOrderViewPreview()
- })
- #endif
|