233 lines
9.5 KiB
Swift
233 lines
9.5 KiB
Swift
//
|
|
// SeismicNetworkMinimalTableViewCell.swift
|
|
// Earthquake Network
|
|
//
|
|
// Created by Andrea Busi on 06/03/25.
|
|
// Copyright © 2025 Earthquake Network. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import Shogun
|
|
|
|
|
|
class SeismicNetworkMinimalTableViewCell: SeismicNetworkBaseTableViewCell {
|
|
|
|
// MARK: - UI
|
|
|
|
private lazy var magnitudeLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.font = UIFont.preferredFont(forTextStyle: .largeTitle)
|
|
label.textColor = .red
|
|
label.textAlignment = .center
|
|
return label
|
|
}()
|
|
|
|
private lazy var placeLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.font = UIFont.preferredFont(forTextStyle: .title2, weight: .semibold)
|
|
label.numberOfLines = 3
|
|
return label
|
|
}()
|
|
|
|
private lazy var timeLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.font = .preferredFont(forTextStyle: .body)
|
|
label.numberOfLines = 2
|
|
return label
|
|
}()
|
|
|
|
private lazy var distanceLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.font = .preferredFont(forTextStyle: .body)
|
|
label.numberOfLines = 2
|
|
return label
|
|
}()
|
|
|
|
private lazy var smartphonesLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.numberOfLines = 0
|
|
label.font = .preferredFont(forTextStyle: .body)
|
|
label.textAlignment = .center
|
|
label.numberOfLines = 2
|
|
return label
|
|
}()
|
|
|
|
private lazy var alertsLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.numberOfLines = 0
|
|
label.font = .preferredFont(forTextStyle: .body)
|
|
label.textAlignment = .center
|
|
label.numberOfLines = 2
|
|
return label
|
|
}()
|
|
|
|
// MARK: - Internal
|
|
|
|
/// Seismic to show
|
|
private var seismic: EQNSisma?
|
|
private var isPushSelected = false
|
|
private var informationTypes: Set<InformationType> = []
|
|
|
|
// MARK: - Setup
|
|
|
|
override func setupUI() {
|
|
super.setupUI()
|
|
|
|
// this variable is used to keep track of the previous view, in order to attach proper constraints
|
|
var previousView: UIView = containerView
|
|
|
|
// preliminary banner on top of the cell
|
|
if informationTypes.contains(.preliminary) {
|
|
let preliminaryLabel = UILabel()
|
|
preliminaryLabel.translatesAutoresizingMaskIntoConstraints = false
|
|
preliminaryLabel.text = NSLocalizedString("official_prelimiary", comment: "").uppercased()
|
|
preliminaryLabel.textAlignment = .center
|
|
preliminaryLabel.backgroundColor = .red
|
|
preliminaryLabel.textColor = .yellow
|
|
|
|
containerView.addSubview(preliminaryLabel)
|
|
preliminaryLabel.heightAnchor.constraint(equalToConstant: 30.0).isActive = true
|
|
preliminaryLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
|
|
preliminaryLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
|
|
preliminaryLabel.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
|
|
|
|
previousView = preliminaryLabel
|
|
}
|
|
|
|
containerView.addSubview(magnitudeLabel)
|
|
containerView.addSubview(placeLabel)
|
|
|
|
let titleTopAnchor = previousView == containerView ? containerView.layoutMarginsGuide.topAnchor : previousView.bottomAnchor
|
|
|
|
|
|
let stackViewInformations = UIStackView(arrangedSubviews: [timeLabel, distanceLabel])
|
|
stackViewInformations.translatesAutoresizingMaskIntoConstraints = false
|
|
stackViewInformations.axis = .horizontal
|
|
stackViewInformations.distribution = .fillEqually
|
|
stackViewInformations.spacing = Self.HorizontalSpacingDefault
|
|
containerView.addSubview(stackViewInformations)
|
|
|
|
let stackViewRight = UIStackView(arrangedSubviews: [placeLabel, stackViewInformations])
|
|
stackViewRight.translatesAutoresizingMaskIntoConstraints = false
|
|
stackViewRight.axis = .vertical
|
|
stackViewRight.distribution = .equalSpacing
|
|
stackViewRight.spacing = Self.VerticalSpacingDefault
|
|
|
|
let stackViewMain = UIStackView(arrangedSubviews: [magnitudeLabel, stackViewRight])
|
|
stackViewMain.translatesAutoresizingMaskIntoConstraints = false
|
|
stackViewMain.axis = .horizontal
|
|
stackViewMain.distribution = .fill
|
|
stackViewMain.spacing = Self.HorizontalSpacingDefault
|
|
containerView.addSubview(stackViewMain)
|
|
|
|
stackViewMain.topAnchor.constraint(equalTo: titleTopAnchor).isActive = true
|
|
stackViewMain.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
|
|
stackViewMain.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
|
|
magnitudeLabel.widthAnchor.constraint(equalToConstant: 60.0).isActive = true
|
|
|
|
previousView = stackViewMain
|
|
|
|
if informationTypes.contains(.realtimeSmartphones) || informationTypes.contains(.reportUsers) || informationTypes.contains(.intensityMap) {
|
|
let separator = addSeparator(constraintTo: previousView.bottomAnchor, constanst: Self.VerticalSpacingDefault)
|
|
|
|
let stackViewReports = UIStackView()
|
|
stackViewReports.translatesAutoresizingMaskIntoConstraints = false
|
|
stackViewReports.axis = .vertical
|
|
stackViewReports.distribution = .equalSpacing
|
|
stackViewReports.alignment = .center
|
|
stackViewReports.spacing = Self.VerticalSpacingDefault
|
|
|
|
if informationTypes.contains(.realtimeSmartphones) {
|
|
stackViewReports.addArrangedSubview(smartphonesLabel)
|
|
}
|
|
if informationTypes.contains(.reportUsers) {
|
|
stackViewReports.addArrangedSubview(alertsLabel)
|
|
}
|
|
if informationTypes.contains(.intensityMap) {
|
|
let buttonMap = EQNRoundedButton.make(title: "🎯 \(NSLocalizedString("shakemap", comment: ""))", target: self, action: #selector(intensityMapTapped(_:)))
|
|
stackViewReports.addArrangedSubview(buttonMap)
|
|
buttonMap.heightAnchor.constraint(equalToConstant: Self.DefaultButtonHeight).isActive = true
|
|
buttonMap.leadingAnchor.constraint(equalTo: stackViewReports.leadingAnchor).isActive = true
|
|
buttonMap.trailingAnchor.constraint(equalTo: stackViewReports.trailingAnchor).isActive = true
|
|
}
|
|
|
|
containerView.addSubview(stackViewReports)
|
|
stackViewReports.topAnchor.constraint(equalTo: separator.bottomAnchor, constant: Self.VerticalSpacingDefault).isActive = true
|
|
stackViewReports.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
|
|
stackViewReports.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
|
|
|
|
previousView = stackViewReports
|
|
}
|
|
|
|
previousView.bottomAnchor.constraint(equalTo: containerView.layoutMarginsGuide.bottomAnchor).isActive = true
|
|
|
|
containerView.eqn_applyShadowAndRoundedCorners()
|
|
gradientView.eqn_applyRoundedCorners()
|
|
}
|
|
|
|
private func updateUI() {
|
|
guard let seismic = seismic else { return }
|
|
|
|
let viewModel = SeismicNetworkMinimalViewModel(seismic: seismic)
|
|
|
|
gradientView.image = .gradient(from: viewModel.colors.startColor, to: viewModel.colors.endColor, with: .init(origin: .zero, size: .init(width: 500, height: 1)))
|
|
|
|
placeLabel.text = viewModel.place
|
|
placeLabel.textColor = isPushSelected ? AppTheme.Colors.pureBlue : AppTheme.shared.cardTextColor
|
|
magnitudeLabel.textColor = viewModel.colors.textColor
|
|
magnitudeLabel.text = viewModel.magnitude
|
|
timeLabel.text = "🕗 \(viewModel.time)"
|
|
distanceLabel.text = "📐 \(viewModel.distance)"
|
|
|
|
if !viewModel.smartphones.isEmpty {
|
|
smartphonesLabel.text = "🚨 \(viewModel.smartphones)"
|
|
}
|
|
if !viewModel.users.isEmpty {
|
|
alertsLabel.text = "⚠️ \(viewModel.users)"
|
|
}
|
|
}
|
|
|
|
// MARK: - Public
|
|
|
|
/// Configure the cell to display a seismic
|
|
/// - Parameters:
|
|
/// - seismic: Seismic to display
|
|
/// - type: Type of cell
|
|
/// - informations: Informations to show
|
|
public func configure(
|
|
with seismic: EQNSisma,
|
|
isPushSelected: Bool
|
|
) {
|
|
self.seismic = seismic
|
|
self.isPushSelected = isPushSelected
|
|
|
|
if seismic.preliminary.intValue > 0 {
|
|
informationTypes.insert(.preliminary)
|
|
}
|
|
if seismic.smartphoneNumber.intValue > 0 {
|
|
informationTypes.insert(.realtimeSmartphones)
|
|
}
|
|
if seismic.userNumber.intValue > 0 {
|
|
informationTypes.insert(.reportUsers)
|
|
}
|
|
if seismic.isoCode == "0" {
|
|
informationTypes.remove(.intensityMap)
|
|
}
|
|
|
|
recreateUI()
|
|
updateUI()
|
|
}
|
|
|
|
// MARK: - Actions
|
|
|
|
@objc private func intensityMapTapped(_ sender: Any) {
|
|
delegate?.seismicNetworkCellDidTapIntensityMapDetail(self)
|
|
}
|
|
}
|