| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- //
- // LNOrderAcceptSettingsViewController.swift
- // Gami
- //
- // Created by OneeChan on 2026/1/23.
- //
- import Foundation
- import UIKit
- import SnapKit
- extension UIView {
- func pushToOrderAcceptSettings() {
- let vc = LNOrderAcceptSettingsViewController()
- navigationController?.pushViewController(vc, animated: true)
- }
- }
- class LNOrderAcceptSettingsViewController: LNViewController {
- private let timeLabel = UILabel()
- private var selectTime: (from: Int, to: Int) = (0, 1) {
- didSet {
- if selectTime.from + 24 == selectTime.to || selectTime.from == selectTime.to {
- timeLabel.text = .init(key: "B00100")
- return
- }
- let fromTime = String(format: "%02d:00", selectTime.from)
- let toTime: String = if selectTime.to > 23 {
- .init(key: "B00084") + String(format: "%02d:00", selectTime.to - 24)
- } else {
- String(format: "%02d:00", selectTime.to)
- }
- timeLabel.text = fromTime + "~" + toTime
- }
- }
-
- private let dateLabel = UILabel()
- private var selectDate: [LNOrderAcceptWeekDay] = [] {
- didSet {
- dateLabel.text = selectedDateDesc()
- }
- }
-
- private let autoReplySwitch = UISwitch()
- private var isAutoReply: Bool = false {
- didSet {
- autoReplySwitch.isOn = isAutoReply
- }
- }
-
- private var config: LNOrderAcceptConfig?
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- setupViews()
-
- loadConfig()
- }
- }
- extension LNOrderAcceptSettingsViewController {
- private func loadConfig() {
- showLoading()
- LNGameMateManager.shared.getOrderAccetpConfig { [weak self] config in
- dismissLoading()
- guard let self else { return }
- guard let config else {
- navigationController?.popViewController(animated: true)
- return
- }
-
- let components = config.timeRange.components(separatedBy: "-")
- if components.count == 2 {
- let from = extractHourFromTimeString(components[0])
- var to = extractHourFromTimeString(components[1])
- if to <= from {
- to += 24
- }
- selectTime = (from, to)
- } else {
- selectTime = (0, 1)
- }
-
- selectDate = config.weekNums
- isAutoReply = config.autoWelcomeOpen
- self.config = config
- }
- }
-
- private func saveConfig() {
- let timeRange = String(format: "%02d:00", selectTime.from) + "-" + String(format: "%02d:00", selectTime.to >= 24 ? selectTime.to - 24 : selectTime.to)
- if let config,
- config.weekNums == selectDate,
- config.timeRange == timeRange {
- return
- }
-
- showLoading()
- let newConfig = LNOrderAcceptConfig()
- newConfig.weekNums = selectDate
- newConfig.timeRange = timeRange
- LNGameMateManager.shared.setOrderAcceptConfig(config: newConfig) { _ in
- dismissLoading()
- }
- }
-
- private func extractHourFromTimeString(_ timeString: String) -> Int {
- let components = timeString.components(separatedBy: ":")
-
- guard components.count == 2 else {
- return 0
- }
-
- let hourString = components[0]
- guard let hour = Int(hourString) else {
- return 0
- }
-
- guard hour >= 0 && hour <= 23 else {
- return 0
- }
-
- return hour
- }
-
- private func selectedDateDesc() -> String {
- guard !selectDate.isEmpty else { return "" }
- var mergedSegments: [String] = []
- var start = selectDate[0]
- var end = selectDate[0]
-
- for day in selectDate {
- if day == selectDate[0] {
- continue
- }
- // 如果当前星期与上一个连续,更新结束值
- if day.rawValue == end.rawValue + 1 {
- end = day
- } else {
- // 不连续则保存当前段,并重置起始/结束
- mergedSegments.append(mergeSegment(start: start, end: end))
- start = day
- end = day
- }
- }
- mergedSegments.append(mergeSegment(start: start, end: end))
-
- return mergedSegments.joined(separator: ",")
- }
-
- private func mergeSegment(start: LNOrderAcceptWeekDay, end: LNOrderAcceptWeekDay) -> String {
- let formatter = DateFormatter()
- formatter.locale = curLocal
- let symbols = formatter.weekdaySymbols!
-
- var segments: [String] = []
-
- segments.append(symbols[start.rawValue - 1])
- if start != end {
- segments.append(.init(key: "B00081"))
- segments.append(symbols[end.rawValue - 1])
- }
- return segments.joined(separator: LNAppConfig.shared.curLang == .chiness ? "" : " ")
- }
- }
- extension LNOrderAcceptSettingsViewController {
- private func setupViews() {
- title = .init(key: "B00078")
- view.backgroundColor = .primary_1
-
- let stackView = UIStackView()
- stackView.axis = .vertical
- stackView.spacing = 10
- view.addSubview(stackView)
- stackView.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview().inset(16)
- make.top.equalToSuperview().offset(12)
- }
-
- timeLabel.font = .body_s
- timeLabel.textColor = .text_4
- let timeRangeView = buildItemView(title: .init(key: "B00079"), contentView: timeLabel)
- timeRangeView.onTap { [weak self] in
- guard let self else { return }
- let panel = LNHourRangePickerPanel()
- panel.setTitles(.init(key: "B00082"), desc: .init(key: "B00083"))
- panel.setDefault(from: selectTime.from, to: selectTime.to)
- panel.handler = { [weak self] from, to in
- guard let self else { return }
- selectTime = (from, to)
- saveConfig()
- }
- panel.popup()
- }
- stackView.addArrangedSubview(timeRangeView)
-
- dateLabel.font = .body_s
- dateLabel.textColor = .text_4
- let weekdayView = buildItemView(title: .init(key: "B00080"), contentView: dateLabel)
- weekdayView.onTap { [weak self] in
- guard let self else { return }
- let formatter = DateFormatter()
- formatter.locale = curLocal
-
- let panel = LNMultiSelectionPanel()
- panel.setTitles(.init(key: "B00085"), desc: .init(key: "B00086"))
- panel.update(formatter.weekdaySymbols, curSelected: selectDate.map({ $0.text }))
- panel.handler = { [weak self] indexs in
- guard let self else { return }
- var dates: [LNOrderAcceptWeekDay] = []
- for index in indexs {
- dates.append(LNOrderAcceptWeekDay.allCases[index])
- }
- selectDate = dates
- saveConfig()
- }
- panel.popup()
- }
- stackView.addArrangedSubview(weekdayView)
-
- stackView.addArrangedSubview(buildWelcomeView())
- }
-
- private func buildItemView(title: String, contentView: UIView) -> UIView {
- let container = UIView()
- container.layer.cornerRadius = 12
- container.backgroundColor = .fill
- container.snp.makeConstraints { make in
- make.height.equalTo(60)
- }
-
- let arrow = UIImageView.arrowImageView(size: 14)
- arrow.tintColor = .text_4
- container.addSubview(arrow)
- arrow.snp.makeConstraints { make in
- make.centerY.equalToSuperview()
- make.trailing.equalToSuperview().offset(-12)
- }
-
- contentView.setContentHuggingPriority(.defaultLow, for: .horizontal)
- contentView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
- container.addSubview(contentView)
- contentView.snp.makeConstraints { make in
- make.centerY.equalToSuperview()
- make.trailing.equalTo(arrow.snp.leading).offset(-2)
- }
-
- let titleLabel = UILabel()
- titleLabel.font = .heading_h4
- titleLabel.textColor = .text_5
- titleLabel.text = title
- titleLabel.setContentHuggingPriority(.required, for: .horizontal)
- titleLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
- container.addSubview(titleLabel)
- titleLabel.snp.makeConstraints { make in
- make.centerY.equalToSuperview()
- make.leading.equalToSuperview().offset(12)
- make.trailing.lessThanOrEqualTo(contentView.snp.leading).offset(-12)
- }
-
- return container
- }
-
- private func buildWelcomeView() -> UIView {
- let container = UIView()
- container.layer.cornerRadius = 12
- container.backgroundColor = .fill
- container.onTap { [weak self] in
- guard let self else { return }
- view.pushToAutoReplyList()
- }
-
- let holder = UIView()
- container.addSubview(holder)
- holder.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview()
- make.top.equalToSuperview()
- make.height.equalTo(53)
- }
-
- let arrow = UIImageView.arrowImageView(size: 14)
- arrow.tintColor = .text_4
- holder.addSubview(arrow)
- arrow.snp.makeConstraints { make in
- make.centerY.equalToSuperview()
- make.trailing.equalToSuperview().offset(-12)
- }
-
- let titleLabel = UILabel()
- titleLabel.font = .heading_h4
- titleLabel.textColor = .text_5
- titleLabel.text = .init(key: "B00112")
- holder.addSubview(titleLabel)
- titleLabel.snp.makeConstraints { make in
- make.centerY.equalToSuperview()
- make.leading.equalToSuperview().offset(12)
- make.trailing.lessThanOrEqualTo(arrow.snp.leading).offset(-12)
- }
-
- let openView = UIView()
- container.addSubview(openView)
- openView.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview()
- make.top.equalTo(holder.snp.bottom)
- make.bottom.equalToSuperview().offset(-8)
- }
-
- let tipsLabel = UILabel()
- tipsLabel.font = .body_s
- tipsLabel.textColor = .text_5
- tipsLabel.text = .init(key: "B00113")
- openView.addSubview(tipsLabel)
- tipsLabel.snp.makeConstraints { make in
- make.centerY.equalToSuperview()
- make.leading.equalToSuperview().offset(12)
- }
-
- let scaleX: CGFloat = 40.0 / 51.0
- let scaleY: CGFloat = 24.5 / 31.0
- autoReplySwitch.onTintColor = .primary_5
- autoReplySwitch.transform = CGAffineTransform(scaleX: scaleX, y: scaleY)
- autoReplySwitch.addAction(UIAction(handler: { [weak self] _ in
- guard let self else { return }
- showLoading()
- LNGameMateManager.shared.enableAutoReplay(on: autoReplySwitch.isOn) { [weak self] success in
- dismissLoading()
- guard let self else { return }
- guard success else {
- autoReplySwitch.isOn.toggle()
- return
- }
- isAutoReply = autoReplySwitch.isOn
- }
- }), for: .valueChanged)
- openView.addSubview(autoReplySwitch)
- autoReplySwitch.snp.makeConstraints { make in
- make.verticalEdges.equalToSuperview()
- make.trailing.equalToSuperview().offset(-12)
- }
-
- return container
- }
- }
|