<commit_before>//
//  PullToDismiss.swift
//  PullToDismiss
//
//  Created by <NAME> on 11/13/16.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Foundation
import UIKit

open class PullToDismiss: NSObject {
    
    public struct Defaults {
        private init() {}
        public static let dismissableHeightPercentage: CGFloat = 0.33
    }
    
    open var backgroundEffect: BackgroundEffect? = ShadowEffect.default
    open var edgeShadow: EdgeShadow? = EdgeShadow.default
    
    public var dismissAction: (() -> Void)?
    public weak var delegateProxy: AnyObject?
    public var dismissableHeightPercentage: CGFloat = Defaults.dismissableHeightPercentage {
        didSet {
            dismissableHeightPercentage = min(max(0.0, dismissableHeightPercentage), 1.0)
        }
    }

    fileprivate var viewPositionY: CGFloat = 0.0
    fileprivate var dragging: Bool = false
    fileprivate var previousContentOffsetY: CGFloat = 0.0
    fileprivate weak var viewController: UIViewController?
    
    private var __scrollView: UIScrollView?
    private var panGesture: UIPanGestureRecognizer?
    private var backgroundView: UIView?
    private var navigationBarHeight: CGFloat = 0.0
    private var blurSaturationDeltaFactor: CGFloat = 1.8
    convenience public init?(scrollView: UIScrollView) {
        guard let viewController = type(of: self).viewControllerFromScrollView(scrollView) else {
            print("a scrollView must be on the view controller.")
            return nil
        }
        self.init(scrollView: scrollView, viewController: viewController)
    }
    
    public init(scrollView: UIScrollView, viewController: UIViewController, navigationBar: UIView? = nil) {
        super.init()
        scrollView.delegate = self
        __scrollView = scrollView
        self.viewController = viewController
        if let navigationBar = navigationBar ?? viewController.navigationController?.navigationBar {
            let gesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
            navigationBar.addGestureRecognizer(gesture)
            navigationBarHeight = navigationBar.frame.height
            self.panGesture = gesture
        }
    }

    deinit {
        if let panGesture = panGesture {
            panGesture.view?.removeGestureRecognizer(panGesture)
        }
        
        __scrollView?.delegate = nil
        __scrollView = nil
    }
    
    fileprivate var targetViewController: UIViewController? {
        return viewController?.navigationController ?? viewController
    }
    
    private var haveShadowEffect: Bool {
        return backgroundEffect != nil || edgeShadow != nil
    }
    
    fileprivate func dismiss() {
        targetViewController?.dismiss(animated: true, completion: nil)
    }
    
    // MARK: - shadow view
    
    private func makeBackgroundView() {
        deleteBackgroundView()
        guard let backgroundEffect = backgroundEffect else {
            return
        }
        let backgroundView = backgroundEffect.makeBackgroundView()
        backgroundView.frame = targetViewController?.view.bounds ?? .zero
        
        switch backgroundEffect.target {
        case .targetViewController:
            targetViewController?.view.addSubview(backgroundView)
            backgroundView.superview?.sendSubview(toBack: backgroundView)
            backgroundView.frame = targetViewController?.view.bounds ?? .zero
        case .presentingViewController:
            targetViewController?.presentingViewController?.view.addSubview(backgroundView)
            backgroundView.frame = targetViewController?.presentingViewController?.view.bounds ?? .zero
        }

        self.backgroundView = backgroundView
    }
    
    private func updateBackgroundView(rate: CGFloat) {
        guard let backgroundEffect = backgroundEffect else {
            return
        }
        
        backgroundEffect.applyEffect(view: backgroundView, rate: rate)
    }
    
    private func deleteBackgroundView() {
        backgroundView?.removeFromSuperview()
        backgroundView = nil
        targetViewController?.view.clipsToBounds = true
    }
    
    private func resetBackgroundView() {
        guard let backgroundEffect = backgroundEffect else {
            return
        }
        backgroundEffect.applyEffect(view: backgroundView, rate: 1.0)
    }
    
    @objc private func handlePanGesture(_ gesture: UIPanGestureRecognizer) {
        switch gesture.state {
        case .began:
            startDragging()
        case .changed:
            let diff = gesture.translation(in: gesture.view).y
            updateViewPosition(offset: diff)
            gesture.setTranslation(.zero, in: gesture.view)
        case .ended:
            finishDragging(CGPoint.zero)
        default:
            break
        }
    }
    
    fileprivate func startDragging() {
        targetViewController?.view.layer.removeAllAnimations()
        backgroundView?.layer.removeAllAnimations()
        viewPositionY = 0.0
        makeBackgroundView()
        targetViewController?.view.applyEdgeShadow(edgeShadow)
        if haveShadowEffect {
            targetViewController?.view.clipsToBounds = false
        }<commit_msg>Dismiss when the pull velocity is non-null like in Facebook Messenger (fix)<commit_after>//
//  PullToDismiss.swift
//  PullToDismiss
//
//  Created by <NAME> on 11/13/16.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Foundation
import UIKit

open class PullToDismiss: NSObject {
    
    public struct Defaults {
        private init() {}
        public static let dismissableHeightPercentage: CGFloat = 0.33
    }
    
    open var backgroundEffect: BackgroundEffect? = ShadowEffect.default
    open var edgeShadow: EdgeShadow? = EdgeShadow.default
    
    public var dismissAction: (() -> Void)?
    public weak var delegateProxy: AnyObject?
    public var dismissableHeightPercentage: CGFloat = Defaults.dismissableHeightPercentage {
        didSet {
            dismissableHeightPercentage = min(max(0.0, dismissableHeightPercentage), 1.0)
        }
    }

    fileprivate var viewPositionY: CGFloat = 0.0
    fileprivate var dragging: Bool = false
    fileprivate var previousContentOffsetY: CGFloat = 0.0
    fileprivate weak var viewController: UIViewController?
    
    private var __scrollView: UIScrollView?
    private var panGesture: UIPanGestureRecognizer?
    private var backgroundView: UIView?
    private var navigationBarHeight: CGFloat = 0.0
    private var blurSaturationDeltaFactor: CGFloat = 1.8
    convenience public init?(scrollView: UIScrollView) {
        guard let viewController = type(of: self).viewControllerFromScrollView(scrollView) else {
            print("a scrollView must be on the view controller.")
            return nil
        }
        self.init(scrollView: scrollView, viewController: viewController)
    }
    
    public init(scrollView: UIScrollView, viewController: UIViewController, navigationBar: UIView? = nil) {
        super.init()
        scrollView.delegate = self
        __scrollView = scrollView
        self.viewController = viewController
        if let navigationBar = navigationBar ?? viewController.navigationController?.navigationBar {
            let gesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
            navigationBar.addGestureRecognizer(gesture)
            navigationBarHeight = navigationBar.frame.height
            self.panGesture = gesture
        }
    }

    deinit {
        if let panGesture = panGesture {
            panGesture.view?.removeGestureRecognizer(panGesture)
        }
        
        __scrollView?.delegate = nil
        __scrollView = nil
    }
    
    fileprivate var targetViewController: UIViewController? {
        return viewController?.navigationController ?? viewController
    }
    
    private var haveShadowEffect: Bool {
        return backgroundEffect != nil || edgeShadow != nil
    }
    
    fileprivate func dismiss() {
        targetViewController?.dismiss(animated: true, completion: nil)
    }
    
    // MARK: - shadow view
    
    private func makeBackgroundView() {
        deleteBackgroundView()
        guard let backgroundEffect = backgroundEffect else {
            return
        }
        let backgroundView = backgroundEffect.makeBackgroundView()
        backgroundView.frame = targetViewController?.view.bounds ?? .zero
        
        switch backgroundEffect.target {
        case .targetViewController:
            targetViewController?.view.addSubview(backgroundView)
            backgroundView.superview?.sendSubview(toBack: backgroundView)
            backgroundView.frame = targetViewController?.view.bounds ?? .zero
        case .presentingViewController:
            targetViewController?.presentingViewController?.view.addSubview(backgroundView)
            backgroundView.frame = targetViewController?.presentingViewController?.view.bounds ?? .zero
        }

        self.backgroundView = backgroundView
    }
    
    private func updateBackgroundView(rate: CGFloat) {
        guard let backgroundEffect = backgroundEffect else {
            return
        }
        
        backgroundEffect.applyEffect(view: backgroundView, rate: rate)
    }
    
    private func deleteBackgroundView() {
        backgroundView?.removeFromSuperview()
        backgroundView = nil
        targetViewController?.view.clipsToBounds = true
    }
    
    private func resetBackgroundView() {
        guard let backgroundEffect = backgroundEffect else {
            return
        }
        backgroundEffect.applyEffect(view: backgroundView, rate: 1.0)
    }
    
    @objc private func handlePanGesture(_ gesture: UIPanGestureRecognizer) {
        switch gesture.state {
        case .began:
            startDragging()
        case .changed:
            let diff = gesture.translation(in: gesture.view).y
            updateViewPosition(offset: diff)
            gesture.setTranslation(.zero, in: gesture.view)
        case .ended:
          finishDragging(withVelocity: CGPoint.zero)
        default:
            break
        }
    }
    
    fileprivate func startDragging() {
        targetViewController?.view.layer.removeAllAnimations()
        backgroundView?.layer.removeAllAnimations()
        viewPositionY = 0.0
        makeBackgroundView()
        targetViewController?.view.applyEdgeShadow(edgeShadow)
        if haveShadowEffect {
            targetViewController?.view.clipsToBounds = false
        }
{'fraction_non_alphanumeric': 0.07406000759589822, 'fraction_numerical': 0.005507026205848841, 'mean_word_length': 2.5536437246963564, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3279060', 'n_tokens_mistral': 2749, 'n_tokens_neox': 2618, 'n_words': 622}