<commit_before>//
//  This source file is part of the carousell/pickle open source project
//
//  Copyright © 2017 Carousell and the project authors
//  Licensed under Apache License v2.0
//
//  See https://github.com/carousell/pickle/blob/master/LICENSE for license information
//  See https://github.com/carousell/pickle/graphs/contributors for the list of project authors
//

// swiftlint:disable file_length

import UIKit
import Photos

/// Carousell flavoured image picker with multiple photo selections.
@objc
open class ImagePickerController: UINavigationController {

    // MARK: - Initialization

    /// An Objective-C compatible initializer without appearance configuration.
    ///
    /// - Parameter selectedAssets: Preselected image assets that will be highlighted.
    @objc
    public convenience init(selectedAssets: [PHAsset]) {
        self.init(selectedAssets: selectedAssets, configuration: nil)
    }

    /// Returns a newly initialized image picker controller with appearance configuration.
    ///
    /// - Parameters:
    ///   - selectedAssets: Preselected image assets that will be highlighted. Default is an empty array.
    ///   - configuration: Optional appearance configuration. Default is nil.
    public convenience init(selectedAssets: [PHAsset] = [], configuration: ImagePickerConfigurable? = nil) {
        self.init(selectedAssets: selectedAssets, configuration: configuration, cameraType: UIImagePickerController.self)
    }

    /// Returns a newly initialized image picker controller with a customized type of camera.
    ///
    /// - Parameters:
    ///   - selectedAssets: Preselected image assets that will be highlighted.
    ///   - configuration: Optional appearance configuration.
    ///   - cameraType: A UIViewController type that conforms to CameraCompatible protocol.
    public convenience init<T: UIViewController>(
        selectedAssets: [PHAsset],
        configuration: ImagePickerConfigurable?,
        cameraType: T.Type) where T: CameraCompatible {

        self.init(selectedAssets: selectedAssets, configuration: configuration, camera: cameraType.init)
    }

    /// Returns a newly initialized image picker controller with a closure for camera configuration.
    ///
    /// - Parameters:
    ///   - selectedAssets: Preselected image assets that will be highlighted.
    ///   - configuration: Optional appearance configuration.
    ///   - camera: A closure that returns a UIViewController that conforms to CameraCompatible protocol.
    public init<T: UIViewController>(
        selectedAssets: [PHAsset],
        configuration: ImagePickerConfigurable?,
        camera initializer: @escaping () -> T) where T: CameraCompatible {

        self.selectedAssets = selectedAssets
        self.configuration = configuration
        self.allowedSelections = configuration?.allowedSelections ?? .unlimited

        super.init(nibName: nil, bundle: nil)

        if let cancelBarButtonItem = configuration?.cancelBarButtonItem {
            cancelBarButtonItem.target = self
            cancelBarButtonItem.action = #selector(cancel(_:))
            self.cancelBarButton = cancelBarButtonItem
        }

        if let doneBarButtonItem = configuration?.doneBarButtonItem {
            doneBarButtonItem.target = self
            doneBarButtonItem.action = #selector(done(_:))
            self.doneBarButton = doneBarButtonItem
        }

        camera = { [weak self] in
            let camera = initializer()
            camera.sourceType = .camera
            camera.delegate = self
            return camera
        }
    }

    /// Returns an object initialized from data in a given unarchiver.
    ///
    /// - Parameters:
    ///   - coder: An unarchiver object.
    public required init?(coder aDecoder: NSCoder) {
        self.selectedAssets = []
        self.configuration = nil
        self.allowedSelections = .unlimited
        super.init(coder: aDecoder)
    }

    // MARK: - Properties

    /// The image picker's delegate object, which should conform to ImagePickerControllerDelegate.
    open override weak var delegate: UINavigationControllerDelegate? {
        didSet {
            imagePickerDelegate = delegate as? ImagePickerControllerDelegate
        }
    }

    /// A localized string that shows on the navigation bar.
    open override var title: String? {
        didSet {
            albumButton.title = title
            albumButton.isHidden = title?.isEmpty ?? true
        }
    }

    /// A localized string that shows above the photos.
    public var hint: NSAttributedString? {
        didSet {
            galleryViewController?.hint = hint
        }
    }

    fileprivate var selectedAssets: [PHAsset]
    fileprivate let configuration: ImagePickerConfigurable?
    fileprivate let allowedSelections: ImagePickerSelection

    fileprivate weak var imagePickerDelegate: ImagePickerControllerDelegate?
    fileprivate lazy var slideUpPresentation: UIViewControllerTransitioningDelegate = SlideUpPresentation()

    /// Avoid strong reference to the gallery view controller when it's removed from the navigation stack.
    fileprivate weak var galleryViewController: PhotoGalleryViewController? {
        didSet {
            // Remove the reference to the album button from the previous view controller.
            oldValue?.navigationItem.titleView = nil
            guard let galleryViewController = galleryViewController else {
                setViewControllers([], animated: false)
                return
            }
            setViewControllers([galleryViewController], animated: false)
            galleryViewController.hint = hint
            galleryViewController.delegate = self
            galleryViewController.navigationItem.setLeftBarButton(cancelBarButton, animated: true)
            galleryViewController.navigationItem.titleView = albumButton
            galleryViewController.navigationItem.setRightBarButton(doneBarButton, animated: true)
            doneBarButton.isEnabled = !selectedAssets.isEmpty<commit_msg>Fix the weak reference warnings of the gallery view controller<commit_after>//
//  This source file is part of the carousell/pickle open source project
//
//  Copyright © 2017 Carousell and the project authors
//  Licensed under Apache License v2.0
//
//  See https://github.com/carousell/pickle/blob/master/LICENSE for license information
//  See https://github.com/carousell/pickle/graphs/contributors for the list of project authors
//

// swiftlint:disable file_length

import UIKit
import Photos

/// Carousell flavoured image picker with multiple photo selections.
@objc
open class ImagePickerController: UINavigationController {

    // MARK: - Initialization

    /// An Objective-C compatible initializer without appearance configuration.
    ///
    /// - Parameter selectedAssets: Preselected image assets that will be highlighted.
    @objc
    public convenience init(selectedAssets: [PHAsset]) {
        self.init(selectedAssets: selectedAssets, configuration: nil)
    }

    /// Returns a newly initialized image picker controller with appearance configuration.
    ///
    /// - Parameters:
    ///   - selectedAssets: Preselected image assets that will be highlighted. Default is an empty array.
    ///   - configuration: Optional appearance configuration. Default is nil.
    public convenience init(selectedAssets: [PHAsset] = [], configuration: ImagePickerConfigurable? = nil) {
        self.init(selectedAssets: selectedAssets, configuration: configuration, cameraType: UIImagePickerController.self)
    }

    /// Returns a newly initialized image picker controller with a customized type of camera.
    ///
    /// - Parameters:
    ///   - selectedAssets: Preselected image assets that will be highlighted.
    ///   - configuration: Optional appearance configuration.
    ///   - cameraType: A UIViewController type that conforms to CameraCompatible protocol.
    public convenience init<T: UIViewController>(
        selectedAssets: [PHAsset],
        configuration: ImagePickerConfigurable?,
        cameraType: T.Type) where T: CameraCompatible {

        self.init(selectedAssets: selectedAssets, configuration: configuration, camera: cameraType.init)
    }

    /// Returns a newly initialized image picker controller with a closure for camera configuration.
    ///
    /// - Parameters:
    ///   - selectedAssets: Preselected image assets that will be highlighted.
    ///   - configuration: Optional appearance configuration.
    ///   - camera: A closure that returns a UIViewController that conforms to CameraCompatible protocol.
    public init<T: UIViewController>(
        selectedAssets: [PHAsset],
        configuration: ImagePickerConfigurable?,
        camera initializer: @escaping () -> T) where T: CameraCompatible {

        self.selectedAssets = selectedAssets
        self.configuration = configuration
        self.allowedSelections = configuration?.allowedSelections ?? .unlimited

        super.init(nibName: nil, bundle: nil)

        if let cancelBarButtonItem = configuration?.cancelBarButtonItem {
            cancelBarButtonItem.target = self
            cancelBarButtonItem.action = #selector(cancel(_:))
            self.cancelBarButton = cancelBarButtonItem
        }

        if let doneBarButtonItem = configuration?.doneBarButtonItem {
            doneBarButtonItem.target = self
            doneBarButtonItem.action = #selector(done(_:))
            self.doneBarButton = doneBarButtonItem
        }

        camera = { [weak self] in
            let camera = initializer()
            camera.sourceType = .camera
            camera.delegate = self
            return camera
        }
    }

    /// Returns an object initialized from data in a given unarchiver.
    ///
    /// - Parameters:
    ///   - coder: An unarchiver object.
    public required init?(coder aDecoder: NSCoder) {
        self.selectedAssets = []
        self.configuration = nil
        self.allowedSelections = .unlimited
        super.init(coder: aDecoder)
    }

    // MARK: - Properties

    /// The image picker's delegate object, which should conform to ImagePickerControllerDelegate.
    open override weak var delegate: UINavigationControllerDelegate? {
        didSet {
            imagePickerDelegate = delegate as? ImagePickerControllerDelegate
        }
    }

    /// A localized string that shows on the navigation bar.
    open override var title: String? {
        didSet {
            albumButton.title = title
            albumButton.isHidden = title?.isEmpty ?? true
        }
    }

    /// A localized string that shows above the photos.
    public var hint: NSAttributedString? {
        didSet {
            galleryViewController?.hint = hint
        }
    }

    fileprivate var selectedAssets: [PHAsset]
    fileprivate let configuration: ImagePickerConfigurable?
    fileprivate let allowedSelections: ImagePickerSelection

    fileprivate weak var imagePickerDelegate: ImagePickerControllerDelegate?
    fileprivate lazy var slideUpPresentation: UIViewControllerTransitioningDelegate = SlideUpPresentation()

    fileprivate var galleryViewController: PhotoGalleryViewController? {
        didSet {
            // Remove the reference to the album button from the previous view controller.
            oldValue?.navigationItem.titleView = nil
            guard let galleryViewController = galleryViewController else {
                setViewControllers([], animated: false)
                return
            }
            setViewControllers([galleryViewController], animated: false)
            galleryViewController.hint = hint
            galleryViewController.delegate = self
            galleryViewController.navigationItem.setLeftBarButton(cancelBarButton, animated: true)
            galleryViewController.navigationItem.titleView = albumButton
            galleryViewController.navigationItem.setRightBarButton(doneBarButton, animated: true)
            doneBarButton.isEnabled = !selectedAssets.isEmpty
{'fraction_non_alphanumeric': 0.07529744571095764, 'fraction_numerical': 0.0009984191696480573, 'mean_word_length': 2.7340789064927, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 4, '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': '3005331', 'n_tokens_mistral': 2884, 'n_tokens_neox': 2772, 'n_words': 886}