<commit_before>import UIKit

protocol AddArticleToReadingListToolbarViewControllerDelegate: NSObjectProtocol {
    func viewControllerWillBeDismissed()
    func addedArticle(to readingList: ReadingList)
}

extension AddArticleToReadingListToolbarViewControllerDelegate {
    func viewControllerWillBeDismissed() {
        print("viewControllerWillBeDismissed")
    }
    
    func addedArticle(to readingList: ReadingList) {
        print("addedArticle")
    }
}

@objc(WMFAddArticleToReadingListToolbarController)
class AddArticleToReadingListToolbarController: NSObject, AddArticleToReadingListToolbarViewControllerDelegate {

    fileprivate let dataStore: MWKDataStore
    fileprivate let owner: UIViewController
    fileprivate let toolbar: AddArticleToReadingListToolbarViewController
    fileprivate let toolbarHeight: CGFloat = 50
    
    fileprivate var isToolbarVisible = false {
        didSet {
            guard isToolbarVisible != oldValue else {
                return
            }
            if isToolbarVisible {
                addToolbar()
                perform(#selector(dismissToolbar), with: self, afterDelay: 8)
            } else {
                removeToolbar()
            }
        }
    }
    
    @objc init(dataStore: MWKDataStore, owner: UIViewController) {
        self.dataStore = dataStore
        self.owner = owner
        self.toolbar = AddArticleToReadingListToolbarViewController(dataStore: dataStore)
        super.init()
        self.toolbar.delegate = self
    }
    
    func removeToolbar() {
        toolbar.willMove(toParentViewController: nil)
        toolbar.view.removeFromSuperview()
        toolbar.removeFromParentViewController()
        toolbar.reset()
    }
    
    func addToolbar() {
        // apply theme
        owner.addChildViewController(toolbar)
        toolbar.view.autoresizingMask = [.flexibleTopMargin, .flexibleWidth]
        owner.view.addSubview(toolbar.view)
        toolbar.didMove(toParentViewController: owner)
    }
    
    @objc func dismissToolbar() {
        setToolbar(visible: false, animated: true)
    }
    
    func setToolbar(visible: Bool, animated: Bool) {
        let frame = visible ? toolbarFrame.visible : toolbarFrame.hidden
        if animated {
            isToolbarVisible = visible
            // dispatch once to make sure animation doesn't start at a random spot
            toolbar.view.frame = toolbarFrame.hidden
            UIView.animate(withDuration: 0.4, delay: 0, options: [.curveEaseInOut, .beginFromCurrentState], animations: {
                self.toolbar.view.frame = frame
                self.owner.view.setNeedsLayout()
            }, completion: { (_) in
                if !visible {
                    self.isToolbarVisible = visible
                }
            })
        }
    }
    
    fileprivate lazy var toolbarFrame: (visible: CGRect, hidden: CGRect) = {
        let visible = CGRect(x: 0, y: owner.view.bounds.height - toolbarHeight, width: owner.view.bounds.size.width, height: toolbarHeight)
        let hidden = CGRect(x: 0, y: owner.view.bounds.height + toolbarHeight, width: owner.view.bounds.size.width, height: toolbarHeight)
        return (visible: visible, hidden: hidden)
    }()
    
    @objc func didSave(_ didSave: Bool, article: WMFArticle) {
        let didSaveOtherArticle = didSave && isToolbarVisible && article != toolbar.article
        let didUnsaveOtherArticle = !didSave && isToolbarVisible && article != toolbar.article
        
        guard !didUnsaveOtherArticle else {
            return
        }
        
        guard !didSaveOtherArticle else {
            toolbar.reset()
            NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(dismissToolbar), object: self) // object: nil?
            perform(#selector(dismissToolbar), with: self, afterDelay: 8)
            toolbar.article = article
            return
        }
        
        toolbar.article = article
        setToolbar(visible: didSave, animated: true)
    }
}

@objc(WMFAddArticleToReadingListToolbarViewController)
class AddArticleToReadingListToolbarViewController: UIViewController {
    
    fileprivate let dataStore: MWKDataStore
    fileprivate var theme: Theme = Theme.standard
    
    var article: WMFArticle? {
        didSet {
            let articleTitle = article?.displayTitle ?? "article"
            button.setTitle("Add \(articleTitle) to reading list", for: .normal)
        }
    }
    
    public init(dataStore: MWKDataStore) {
        self.dataStore = dataStore
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    fileprivate var button: AlignedImageButton = AlignedImageButton()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(button)
        button.titleLabel?.lineBreakMode = .byTruncatingTail
        button.verticalPadding = 5
        button.setImage(UIImage(named: "add-to-list"), for: .normal)
        button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
        button.sizeToFit()
        button.translatesAutoresizingMaskIntoConstraints = false
        let centerConstraint = button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        let leadingConstraint = button.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 12)
        let trailingConstraint = view.trailingAnchor.constraint(greaterThanOrEqualTo: button.trailingAnchor, constant: 12)
        centerConstraint.isActive = true
        leadingConstraint.isActive = true
        trailingConstraint.isActive = true
        apply(theme: theme)
    }
    
    func reset() {
        let articleTitle = article?.displayTitle ?? "article"
        button.setTitle("Add \(articleTitle) to reading list", for: .normal)
        button.setImage(UIImage(named: "add-to-list"), for: .normal)
        button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
    }
    
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        button.titleLabel?.setFont(with: .systemMedium, style: .subheadline, traitCollection: traitCollection)
    }
    
    public weak var delegate: AddArticleToReadingListToolbarViewControllerDelegate?
    
    @objc fileprivate func buttonPressed() {
        guard let article = article else {
            return
        }
        let addArticlesToReadingListViewController = AddArticlesToReadingListViewController(with: dataStore, articles: [article], theme: theme)
        addArticlesToReadingListViewController.delegate = self
        present(addArticlesToReadingListViewController, animated: true, completion: nil)
    }

}

extension AddArticleToReadingListToolbarViewController: AddArticlesToReadingListDelegate {
    func viewControllerWillBeDismissed() {
        delegate?.viewControllerWillBeDismissed()
    }
    
    func addedArticle(to readingList: ReadingList) {
        guard let name = readingList.isDefaultList ? CommonStrings.shortSavedTitle : readingList.name else {
            return
        }
        button.setTitle("Article added to \(name)", for: .normal)
        button.setImage(nil, for: .normal)
        button.removeTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
        delegate?.addedArticle(to: readingList)
    }
}

extension AddArticleToReadingListToolbarViewController: Themeable {
    func apply(theme: Theme) {
        self.theme = theme
        guard viewIfLoaded != nil else {
            return
        }
        view.backgroundColor = theme.colors.disabledLink
        button.setTitleColor(theme.colors.link, for: .normal)
    }<commit_msg>remove default implementation remove unused params<commit_after>import UIKit

protocol AddArticleToReadingListToolbarViewControllerDelegate: NSObjectProtocol {
    func viewControllerWillBeDismissed()
    func addedArticleToReadingList()
}

@objc(WMFAddArticleToReadingListToolbarController)
class AddArticleToReadingListToolbarController: NSObject, AddArticleToReadingListToolbarViewControllerDelegate {

    fileprivate let dataStore: MWKDataStore
    fileprivate let owner: UIViewController
    fileprivate let toolbar: AddArticleToReadingListToolbarViewController
    fileprivate let toolbarHeight: CGFloat = 50
    
    fileprivate var isToolbarVisible = false {
        didSet {
            guard isToolbarVisible != oldValue else {
                return
            }
            if isToolbarVisible {
                addToolbar()
                perform(#selector(dismissToolbar), with: self, afterDelay: 8)
            } else {
                removeToolbar()
            }
        }
    }
    
    @objc init(dataStore: MWKDataStore, owner: UIViewController) {
        self.dataStore = dataStore
        self.owner = owner
        self.toolbar = AddArticleToReadingListToolbarViewController(dataStore: dataStore)
        super.init()
        self.toolbar.delegate = self
    }
    
    func removeToolbar() {
        toolbar.willMove(toParentViewController: nil)
        toolbar.view.removeFromSuperview()
        toolbar.removeFromParentViewController()
        toolbar.reset()
    }
    
    func addToolbar() {
        // apply theme
        owner.addChildViewController(toolbar)
        toolbar.view.autoresizingMask = [.flexibleTopMargin, .flexibleWidth]
        owner.view.addSubview(toolbar.view)
        toolbar.didMove(toParentViewController: owner)
    }
    
    @objc func dismissToolbar() {
        setToolbar(visible: false, animated: true)
    }
    
    func setToolbar(visible: Bool, animated: Bool) {
        let frame = visible ? toolbarFrame.visible : toolbarFrame.hidden
        if animated {
            isToolbarVisible = visible
            // dispatch once to make sure animation doesn't start at a random spot
            toolbar.view.frame = toolbarFrame.hidden
            UIView.animate(withDuration: 0.4, delay: 0, options: [.curveEaseInOut, .beginFromCurrentState], animations: {
                self.toolbar.view.frame = frame
                self.owner.view.setNeedsLayout()
            }, completion: { (_) in
                if !visible {
                    self.isToolbarVisible = visible
                }
            })
        }
    }
    
    fileprivate lazy var toolbarFrame: (visible: CGRect, hidden: CGRect) = {
        let visible = CGRect(x: 0, y: owner.view.bounds.height - toolbarHeight, width: owner.view.bounds.size.width, height: toolbarHeight)
        let hidden = CGRect(x: 0, y: owner.view.bounds.height + toolbarHeight, width: owner.view.bounds.size.width, height: toolbarHeight)
        return (visible: visible, hidden: hidden)
    }()
    
    @objc func didSave(_ didSave: Bool, article: WMFArticle) {
        let didSaveOtherArticle = didSave && isToolbarVisible && article != toolbar.article
        let didUnsaveOtherArticle = !didSave && isToolbarVisible && article != toolbar.article
        
        guard !didUnsaveOtherArticle else {
            return
        }
        
        guard !didSaveOtherArticle else {
            toolbar.reset()
            NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(dismissToolbar), object: self) // object: nil?
            perform(#selector(dismissToolbar), with: self, afterDelay: 8)
            toolbar.article = article
            return
        }
        
        toolbar.article = article
        setToolbar(visible: didSave, animated: true)
    }
    
    // MARK: - AddArticleToReadingListToolbarViewControllerDelegate
    
    func viewControllerWillBeDismissed() {
        self.setToolbar(visible: false, animated: true)
    }
    
    func addedArticleToReadingList() {
        self.setToolbar(visible: true, animated: true)
    }
}

@objc(WMFAddArticleToReadingListToolbarViewController)
class AddArticleToReadingListToolbarViewController: UIViewController {
    
    fileprivate let dataStore: MWKDataStore
    fileprivate var theme: Theme = Theme.standard
    
    var article: WMFArticle? {
        didSet {
            let articleTitle = article?.displayTitle ?? "article"
            button.setTitle("Add \(articleTitle) to reading list", for: .normal)
        }
    }
    
    public init(dataStore: MWKDataStore) {
        self.dataStore = dataStore
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    fileprivate var button: AlignedImageButton = AlignedImageButton()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(button)
        button.titleLabel?.lineBreakMode = .byTruncatingTail
        button.verticalPadding = 5
        button.setImage(UIImage(named: "add-to-list"), for: .normal)
        button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
        button.sizeToFit()
        button.translatesAutoresizingMaskIntoConstraints = false
        let centerConstraint = button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        let leadingConstraint = button.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 12)
        let trailingConstraint = view.trailingAnchor.constraint(greaterThanOrEqualTo: button.trailingAnchor, constant: 12)
        centerConstraint.isActive = true
        leadingConstraint.isActive = true
        trailingConstraint.isActive = true
        apply(theme: theme)
    }
    
    func reset() {
        let articleTitle = article?.displayTitle ?? "article"
        button.setTitle("Add \(articleTitle) to reading list", for: .normal)
        button.setImage(UIImage(named: "add-to-list"), for: .normal)
        button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
    }
    
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        button.titleLabel?.setFont(with: .systemMedium, style: .subheadline, traitCollection: traitCollection)
    }
    
    public weak var delegate: AddArticleToReadingListToolbarViewControllerDelegate?
    
    @objc fileprivate func buttonPressed() {
        guard let article = article else {
            return
        }
        let addArticlesToReadingListViewController = AddArticlesToReadingListViewController(with: dataStore, articles: [article], theme: theme)
        addArticlesToReadingListViewController.delegate = self
        present(addArticlesToReadingListViewController, animated: true, completion: nil)
    }

}

extension AddArticleToReadingListToolbarViewController: AddArticlesToReadingListDelegate {
    func viewControllerWillBeDismissed() {
        delegate?.viewControllerWillBeDismissed()
    }
    
    func addedArticle(to readingList: ReadingList) {
        guard let name = readingList.isDefaultList ? CommonStrings.shortSavedTitle : readingList.name else {
            return
        }
        button.setTitle("Article added to \(name)", for: .normal)
        button.setImage(nil, for: .normal)
        button.removeTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
        delegate?.addedArticleToReadingList()
    }
}

extension AddArticleToReadingListToolbarViewController: Themeable {
    func apply(theme: Theme) {
        self.theme = theme
        guard viewIfLoaded != nil else {
            return
        }
        view.backgroundColor = theme.colors.disabledLink
        button.setTitleColor(theme.colors.link, for: .normal)
    }
{'fraction_non_alphanumeric': 0.08280254777070063, 'fraction_numerical': 0.0018014540307533938, 'mean_word_length': 2.7536826853417047, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '5043906', 'n_tokens_mistral': 4248, 'n_tokens_neox': 4049, 'n_words': 892}