<commit_before>//
//  TappableView.swift
//  MyCards
//
//  Created by <NAME> on 13/11/16.
//

import UIKit

struct AnimationState {
    var performed: Bool = false
    var restoration: CGAffineTransform = .identity
}

class TappableView: UIView {

    fileprivate var touchingDownInside: Bool = false
    fileprivate let dimmedView: UIView
    fileprivate var animationState = AnimationState()
    let contentView: UIView
    var tapped: (() -> Void)?

    convenience init() {
        self.init(frame: .zero)
    }

    override init(frame: CGRect) {
        contentView = UIView(frame: .zero)
        dimmedView = UIView(frame: .zero)
        super.init(frame: frame)
        configureViews()
        configureConstraints()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        touchesDown(touches)
    }

    override open func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesMoved(touches, with: event)
        touchesDown(touches)
    }

    override open func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesEnded(touches, with: event)
        touchesUp()
    }

    override open func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesCancelled(touches, with: event)
        touchingDownInside = false
        touchesUp()
    }

    fileprivate func configureViews() {
        dimmedView.backgroundColor = nil
        addSubview(contentView)
        contentView.clipsToBounds = true
        addSubview(dimmedView)
        clipsToBounds = true
    }

    fileprivate func configureConstraints() {
        subviews.forEach { $0.translatesAutoresizingMaskIntoConstraints = false }
        var constraints: [NSLayoutConstraint] = []
        constraints += NSLayoutConstraint.filledInSuperview(contentView)
        constraints += NSLayoutConstraint.filledInSuperview(dimmedView)
        NSLayoutConstraint.activate(constraints)
    }
}

extension TappableView {
    fileprivate func forceTouchAvailable() -> Bool {
        return traitCollection.forceTouchCapability == .available
    }
    fileprivate func touchesDown(_ touches: Set<UITouch>) {
        touchingDownInside = boundsContain(touches)
        if touchingDownInside {
            animateTap()
        } else {
            undoTapAnimation()
        }
    }

    fileprivate func touchesUp(_ touches: Set<UITouch>? = nil) {
        undoTapAnimation()
        if touchingDownInside {
            tapped?()
        }
        clearTouchDownInside()
    }

    fileprivate func clearTouchDownInside() {
        touchingDownInside = false
    }
<commit_msg>Refactor TappableView<commit_after>//
//  TappableView.swift
//  MyCards
//
//  Created by <NAME> on 13/11/16.
//

import UIKit

struct AnimationState {
    var performed: Bool = false
    var restoration: CGAffineTransform = .identity
}

class TappableView: UIView {

    fileprivate var touchingDownInside: Bool = false
    fileprivate let dimmedView: UIView
    fileprivate var animationState = AnimationState()
    let contentView: UIView
    var tapped: (() -> Void)?

    convenience init() {
        self.init(frame: .zero)
    }

    override init(frame: CGRect) {
        contentView = UIView(frame: .zero)
        dimmedView = UIView(frame: .zero)
        super.init(frame: frame)
        configureViews()
        configureConstraints()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        touchingDownInside = boundsContain(touches)
        if touchingDownInside {
            animateTap()
        }
    }

    override open func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesMoved(touches, with: event)
        if !boundsContain(touches) {
            undoTapAnimation()
        }
    }

    override open func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesEnded(touches, with: event)
        touchesUp()
    }

    override open func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesCancelled(touches, with: event)
        touchingDownInside = false
        touchesUp()
    }

    fileprivate func configureViews() {
        dimmedView.backgroundColor = nil
        addSubview(contentView)
        contentView.clipsToBounds = true
        addSubview(dimmedView)
        clipsToBounds = true
    }

    fileprivate func configureConstraints() {
        subviews.forEach { $0.translatesAutoresizingMaskIntoConstraints = false }
        var constraints: [NSLayoutConstraint] = []
        constraints += NSLayoutConstraint.filledInSuperview(contentView)
        constraints += NSLayoutConstraint.filledInSuperview(dimmedView)
        NSLayoutConstraint.activate(constraints)
    }
}

extension TappableView {
    fileprivate func touchesUp(_ touches: Set<UITouch>? = nil) {
        undoTapAnimation()
        if touchingDownInside {
            tapped?()
        }
        touchingDownInside = false
    }

{'fraction_non_alphanumeric': 0.09016393442622951, 'fraction_numerical': 0.0026080476900149033, 'mean_word_length': 2.7078729281767955, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 19, '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': '6520030', 'n_tokens_mistral': 1593, 'n_tokens_neox': 1537, 'n_words': 352}