<commit_before>import Foundation
import KsApi
import Library
import Prelude
import UIKit

private enum Layout {
  enum RewardThumbnail {
    static let maxHeight: CGFloat = 130
    static let minWidth: CGFloat = 100
  }
}

final class PledgeDescriptionViewController: UIViewController {
  // MARK: - Properties

  private lazy var dateLabel: UILabel = { UILabel(frame: .zero) }()
  private lazy var descriptionStackView: UIStackView = { UIStackView(frame: .zero) }()
  private lazy var estimatedDeliveryLabel: UILabel = { UILabel(frame: .zero) }()
  private lazy var expandIconImageView: UIImageView = {
    UIImageView(frame: .zero)
      |> \.translatesAutoresizingMaskIntoConstraints .~ false
  }()

  private lazy var learnMoreTextView: UITextView = { UITextView(frame: .zero) |> \.delegate .~ self }()
  private lazy var longPressGestureRecognizer: UILongPressGestureRecognizer = {
    UILongPressGestureRecognizer(
      target: self, action: #selector(PledgeDescriptionViewController.depress(_:))
    )
      |> \.minimumPressDuration .~ CheckoutConstants.RewardCard.Transition
      .DepressAnimation.longPressMinimumDuration
      |> \.delegate .~ self
      |> \.cancelsTouchesInView .~ false
  }()

  internal lazy var rewardCardContainerShadowView: UIView = { UIView(frame: .zero) }()
  internal lazy var rewardCardContainerMaskView: UIView = { UIView(frame: .zero) }()
  private var rewardCardContainerShadowViewHeightConstraint: NSLayoutConstraint?
  private var rewardCardContainerShadowViewWidthConstraint: NSLayoutConstraint?
  internal lazy var rewardCardContainerView: RewardCardContainerView = {
    RewardCardContainerView(frame: .zero)
      |> \.delegate .~ self
      |> \.isUserInteractionEnabled .~ false
      |> \.translatesAutoresizingMaskIntoConstraints .~ false
  }()

  private lazy var rootStackView: UIStackView = {
    UIStackView(frame: .zero)
      |> \.translatesAutoresizingMaskIntoConstraints .~ false
  }()

  private let viewModel: PledgeDescriptionViewModelType = PledgeDescriptionViewModel()

  // MARK: - Lifecycle

  override func viewDidLoad() {
    super.viewDidLoad()

    self.configureSubviews()
    self.setupConstraints()
  }

  // MARK: - Styles

  override func bindStyles() {
    super.bindStyles()

    _ = self.view
      |> checkoutBackgroundStyle

    _ = self.rootStackView
      |> rootStackViewStyle

    _ = self.descriptionStackView
      |> descriptionStackViewStyle

    _ = self.estimatedDeliveryLabel
      |> checkoutBackgroundStyle
    _ = self.estimatedDeliveryLabel
      |> estimatedDeliveryLabelStyle

    _ = self.dateLabel
      |> checkoutBackgroundStyle
    _ = self.dateLabel
      |> dateLabelStyle

    _ = self.learnMoreTextView
      |> checkoutBackgroundStyle

    _ = self.learnMoreTextView
      |> learnMoreTextViewStyle

    _ = self.rewardCardContainerShadowView
      |> rewardCardContainerShadowViewStyle

    _ = self.expandIconImageView
      |> expandIconImageViewStyle

    _ = self.rewardCardContainerMaskView
      |> rewardCardContainerMaskViewStyle
  }

  override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    self.sizeAndTransformRewardCardView()
  }

  private func configureSubviews() {
    _ = (self.rootStackView, self.view)
      |> ksr_addSubviewToParent()
      |> ksr_constrainViewToEdgesInParent()

    _ = ([self.rewardCardContainerShadowView], self.rootStackView)
      |> ksr_addArrangedSubviewsToStackView()

    _ = (self.rewardCardContainerMaskView, self.rewardCardContainerShadowView)
      |> ksr_addSubviewToParent()
      |> ksr_constrainViewToEdgesInParent()

    _ = (self.expandIconImageView, self.rewardCardContainerShadowView)
      |> ksr_addSubviewToParent()

    _ = (self.rewardCardContainerView, self.rewardCardContainerMaskView)
      |> ksr_addSubviewToParent()

    self.rewardCardContainerShadowView.addGestureRecognizer(self.longPressGestureRecognizer)

    let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.rewardCardTapped))
    self.rewardCardContainerShadowView.addGestureRecognizer(tapGestureRecognizer)

    self.configureStackView()
  }

  private func setupConstraints() {
    self.rewardCardContainerShadowViewWidthConstraint = self.rewardCardContainerShadowView.widthAnchor
      .constraint(equalToConstant: 0)
    self.rewardCardContainerShadowViewHeightConstraint = self.rewardCardContainerShadowView.heightAnchor
      .constraint(equalToConstant: 0)

    let rewardCardContainerShadowViewConstraints = [
      self.rewardCardContainerShadowViewWidthConstraint,
      self.rewardCardContainerShadowViewHeightConstraint
    ]
    .compact()

    NSLayoutConstraint.activate([
      self.expandIconImageView.topAnchor
        .constraint(equalTo: self.rewardCardContainerShadowView.topAnchor, constant: -Styles.grid(1)),
      self.expandIconImageView.trailingAnchor
        .constraint(equalTo: self.rewardCardContainerShadowView.trailingAnchor, constant: Styles.grid(1)),
      self.rewardCardContainerView.widthAnchor.constraint(
        equalToConstant: CheckoutConstants.RewardCard.Layout.width
      ),
      self.rewardCardContainerView.leftAnchor.constraint(
        equalTo: self.rewardCardContainerShadowView.leftAnchor
      ),
      self.rewardCardContainerView.topAnchor.constraint(equalTo: self.rewardCardContainerShadowView.topAnchor)
    ] + rewardCardContainerShadowViewConstraints)
  }

  private func configureStackView() {
    let views = [
      self.estimatedDeliveryLabel,
      self.dateLabel,
      self.learnMoreTextView
    ]

    _ = (views, self.descriptionStackView)
      |> ksr_addArrangedSubviewsToStackView()

    _ = ([self.descriptionStackView], self.rootStackView)
      |> ksr_addArrangedSubviewsToStackView()
  }

  private func sizeAndTransformRewardCardView() {
    self.rewardCardContainerView.layoutIfNeeded()
<commit_msg>Prevent card layout calculations when the view is hidden (#922)<commit_after>import Foundation
import KsApi
import Library
import Prelude
import UIKit

private enum Layout {
  enum RewardThumbnail {
    static let maxHeight: CGFloat = 130
    static let minWidth: CGFloat = 100
  }
}

final class PledgeDescriptionViewController: UIViewController {
  // MARK: - Properties

  private lazy var dateLabel: UILabel = { UILabel(frame: .zero) }()
  private lazy var descriptionStackView: UIStackView = { UIStackView(frame: .zero) }()
  private lazy var estimatedDeliveryLabel: UILabel = { UILabel(frame: .zero) }()
  private lazy var expandIconImageView: UIImageView = {
    UIImageView(frame: .zero)
      |> \.translatesAutoresizingMaskIntoConstraints .~ false
  }()

  private lazy var learnMoreTextView: UITextView = { UITextView(frame: .zero) |> \.delegate .~ self }()
  private lazy var longPressGestureRecognizer: UILongPressGestureRecognizer = {
    UILongPressGestureRecognizer(
      target: self, action: #selector(PledgeDescriptionViewController.depress(_:))
    )
      |> \.minimumPressDuration .~ CheckoutConstants.RewardCard.Transition
      .DepressAnimation.longPressMinimumDuration
      |> \.delegate .~ self
      |> \.cancelsTouchesInView .~ false
  }()

  internal lazy var rewardCardContainerShadowView: UIView = { UIView(frame: .zero) }()
  internal lazy var rewardCardContainerMaskView: UIView = { UIView(frame: .zero) }()
  private var rewardCardContainerShadowViewHeightConstraint: NSLayoutConstraint?
  private var rewardCardContainerShadowViewWidthConstraint: NSLayoutConstraint?
  internal lazy var rewardCardContainerView: RewardCardContainerView = {
    RewardCardContainerView(frame: .zero)
      |> \.delegate .~ self
      |> \.isUserInteractionEnabled .~ false
      |> \.translatesAutoresizingMaskIntoConstraints .~ false
  }()

  private lazy var rootStackView: UIStackView = {
    UIStackView(frame: .zero)
      |> \.translatesAutoresizingMaskIntoConstraints .~ false
  }()

  private let viewModel: PledgeDescriptionViewModelType = PledgeDescriptionViewModel()

  // MARK: - Lifecycle

  override func viewDidLoad() {
    super.viewDidLoad()

    self.configureSubviews()
    self.setupConstraints()
  }

  // MARK: - Styles

  override func bindStyles() {
    super.bindStyles()

    _ = self.view
      |> checkoutBackgroundStyle

    _ = self.rootStackView
      |> rootStackViewStyle

    _ = self.descriptionStackView
      |> descriptionStackViewStyle

    _ = self.estimatedDeliveryLabel
      |> checkoutBackgroundStyle
    _ = self.estimatedDeliveryLabel
      |> estimatedDeliveryLabelStyle

    _ = self.dateLabel
      |> checkoutBackgroundStyle
    _ = self.dateLabel
      |> dateLabelStyle

    _ = self.learnMoreTextView
      |> checkoutBackgroundStyle

    _ = self.learnMoreTextView
      |> learnMoreTextViewStyle

    _ = self.rewardCardContainerShadowView
      |> rewardCardContainerShadowViewStyle

    _ = self.expandIconImageView
      |> expandIconImageViewStyle

    _ = self.rewardCardContainerMaskView
      |> rewardCardContainerMaskViewStyle
  }

  override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    self.sizeAndTransformRewardCardView()
  }

  private func configureSubviews() {
    _ = (self.rootStackView, self.view)
      |> ksr_addSubviewToParent()
      |> ksr_constrainViewToEdgesInParent()

    _ = ([self.rewardCardContainerShadowView], self.rootStackView)
      |> ksr_addArrangedSubviewsToStackView()

    _ = (self.rewardCardContainerMaskView, self.rewardCardContainerShadowView)
      |> ksr_addSubviewToParent()
      |> ksr_constrainViewToEdgesInParent()

    _ = (self.expandIconImageView, self.rewardCardContainerShadowView)
      |> ksr_addSubviewToParent()

    _ = (self.rewardCardContainerView, self.rewardCardContainerMaskView)
      |> ksr_addSubviewToParent()

    self.rewardCardContainerShadowView.addGestureRecognizer(self.longPressGestureRecognizer)

    let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.rewardCardTapped))
    self.rewardCardContainerShadowView.addGestureRecognizer(tapGestureRecognizer)

    self.configureStackView()
  }

  private func setupConstraints() {
    self.rewardCardContainerShadowViewWidthConstraint = self.rewardCardContainerShadowView.widthAnchor
      .constraint(equalToConstant: 0)
    self.rewardCardContainerShadowViewHeightConstraint = self.rewardCardContainerShadowView.heightAnchor
      .constraint(equalToConstant: 0)

    let rewardCardContainerShadowViewConstraints = [
      self.rewardCardContainerShadowViewWidthConstraint,
      self.rewardCardContainerShadowViewHeightConstraint
    ]
    .compact()

    NSLayoutConstraint.activate([
      self.expandIconImageView.topAnchor
        .constraint(equalTo: self.rewardCardContainerShadowView.topAnchor, constant: -Styles.grid(1)),
      self.expandIconImageView.trailingAnchor
        .constraint(equalTo: self.rewardCardContainerShadowView.trailingAnchor, constant: Styles.grid(1)),
      self.rewardCardContainerView.widthAnchor.constraint(
        equalToConstant: CheckoutConstants.RewardCard.Layout.width
      ),
      self.rewardCardContainerView.leftAnchor.constraint(
        equalTo: self.rewardCardContainerShadowView.leftAnchor
      ),
      self.rewardCardContainerView.topAnchor.constraint(equalTo: self.rewardCardContainerShadowView.topAnchor)
    ] + rewardCardContainerShadowViewConstraints)
  }

  private func configureStackView() {
    let views = [
      self.estimatedDeliveryLabel,
      self.dateLabel,
      self.learnMoreTextView
    ]

    _ = (views, self.descriptionStackView)
      |> ksr_addArrangedSubviewsToStackView()

    _ = ([self.descriptionStackView], self.rootStackView)
      |> ksr_addArrangedSubviewsToStackView()
  }

  private func sizeAndTransformRewardCardView() {
    guard !self.view.isHidden else { return }

    self.rewardCardContainerView.layoutIfNeeded()

{'fraction_non_alphanumeric': 0.084086112283664, 'fraction_numerical': 0.001941747572815534, 'mean_word_length': 4.14819643633203, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '419748', 'n_tokens_mistral': 3537, 'n_tokens_neox': 3294, 'n_words': 537}