Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support video in the picker #44

Merged
merged 10 commits into from
Apr 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Change Log

## Next release

* Add support for video selection [#44](https://github.com/carousell/pickle/pull/44)

## v1.4.0

* Swift 4.2 [#32](https://github.com/carousell/pickle/pull/32)
Expand Down
5 changes: 4 additions & 1 deletion Example/CarousellImagePickerController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ internal class CarousellImagePickerController: ImagePickerController {
string: "You can choose up to \(selectionsLimit) photos for your listing.\n",
attributes: [
.font: UIFont.systemFont(ofSize: 12),
.foregroundColor: UIColor.darkGray,
.foregroundColor: UIColor.gray,
.backgroundColor: UIColor.white,
.paragraphStyle: subtitleStyle
]
Expand Down Expand Up @@ -108,4 +108,7 @@ private struct CarousellTheme: ImagePickerConfigurable {

let hintTextMargin: UIEdgeInsets? = .zero

// MARK: Media Types

var mediaType: ImagePickerMediaType? = .all
}
6 changes: 6 additions & 0 deletions Example/Images.xcassets/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
16 changes: 12 additions & 4 deletions Pickle.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; };
607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; };
607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
9402FADB226F057500C77100 /* GalleryVideoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9402FADA226F057500C77100 /* GalleryVideoCell.swift */; };
94F4BF192264609C00E7A672 /* VideoPropertyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94F4BF182264609C00E7A672 /* VideoPropertyView.swift */; };
B55833221EC08E180061E182 /* CarousellImagePickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55833211EC08E180061E182 /* CarousellImagePickerController.swift */; };
B563515E1F06278E00B5A46D /* UITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B563515D1F06278E00B5A46D /* UITests.swift */; };
B57BEA34216AAF6300A2C776 /* Pickle.h in Headers */ = {isa = PBXBuildFile; fileRef = B57BEA32216AAF6300A2C776 /* Pickle.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand All @@ -35,7 +37,7 @@
B57BEA70216AAFD700A2C776 /* PhotoGalleryCameraCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57BEA54216AAFD700A2C776 /* PhotoGalleryCameraCell.swift */; };
B57BEA71216AAFD700A2C776 /* SlideUpPresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57BEA55216AAFD700A2C776 /* SlideUpPresentation.swift */; };
B57BEA72216AAFD700A2C776 /* ImagePickerControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57BEA56216AAFD700A2C776 /* ImagePickerControllerDelegate.swift */; };
B57BEA73216AAFD700A2C776 /* PhotoGalleryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57BEA57216AAFD700A2C776 /* PhotoGalleryCell.swift */; };
B57BEA73216AAFD700A2C776 /* GalleryPhotoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57BEA57216AAFD700A2C776 /* GalleryPhotoCell.swift */; };
B57BEA74216AAFD700A2C776 /* ImagePickerConfigurable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57BEA58216AAFD700A2C776 /* ImagePickerConfigurable.swift */; };
B57BEA75216AAFD700A2C776 /* PhotoGalleryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57BEA59216AAFD700A2C776 /* PhotoGalleryViewController.swift */; };
B57BEA76216AAFD700A2C776 /* PhotoAlbumTitleButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57BEA5A216AAFD700A2C776 /* PhotoAlbumTitleButton.swift */; };
Expand Down Expand Up @@ -92,6 +94,8 @@
607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
7D176E52E185B871CF8D97C4 /* Pods_PickleUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PickleUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9402FADA226F057500C77100 /* GalleryVideoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GalleryVideoCell.swift; sourceTree = "<group>"; };
94F4BF182264609C00E7A672 /* VideoPropertyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPropertyView.swift; sourceTree = "<group>"; };
B55833211EC08E180061E182 /* CarousellImagePickerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CarousellImagePickerController.swift; sourceTree = "<group>"; };
B563515B1F06278E00B5A46D /* PickleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PickleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
B563515D1F06278E00B5A46D /* UITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -120,7 +124,7 @@
B57BEA54216AAFD700A2C776 /* PhotoGalleryCameraCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoGalleryCameraCell.swift; sourceTree = "<group>"; };
B57BEA55216AAFD700A2C776 /* SlideUpPresentation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SlideUpPresentation.swift; sourceTree = "<group>"; };
B57BEA56216AAFD700A2C776 /* ImagePickerControllerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImagePickerControllerDelegate.swift; sourceTree = "<group>"; };
B57BEA57216AAFD700A2C776 /* PhotoGalleryCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoGalleryCell.swift; sourceTree = "<group>"; };
B57BEA57216AAFD700A2C776 /* GalleryPhotoCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GalleryPhotoCell.swift; sourceTree = "<group>"; };
B57BEA58216AAFD700A2C776 /* ImagePickerConfigurable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImagePickerConfigurable.swift; sourceTree = "<group>"; };
B57BEA59216AAFD700A2C776 /* PhotoGalleryViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoGalleryViewController.swift; sourceTree = "<group>"; };
B57BEA5A216AAFD700A2C776 /* PhotoAlbumTitleButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoAlbumTitleButton.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -274,7 +278,9 @@
B57BEA53216AAFD700A2C776 /* PhotoDetailViewController.swift */,
B57BEA54216AAFD700A2C776 /* PhotoGalleryCameraCell.swift */,
B57BEA5E216AAFD700A2C776 /* PhotoGalleryCameraIconView.swift */,
B57BEA57216AAFD700A2C776 /* PhotoGalleryCell.swift */,
B57BEA57216AAFD700A2C776 /* GalleryPhotoCell.swift */,
9402FADA226F057500C77100 /* GalleryVideoCell.swift */,
94F4BF182264609C00E7A672 /* VideoPropertyView.swift */,
20DB284D22560DB000037FEF /* LiveView.swift */,
20FC48022256FAC3004CCD1D /* CameraSessionHandler.swift */,
20DB284E22560DB000037FEF /* PhotoGalleryLiveViewCell.swift */,
Expand Down Expand Up @@ -535,10 +541,12 @@
B57BEA6E216AAFD700A2C776 /* PhotoAlbumsTableView.swift in Sources */,
B57BEA7C216AAFD700A2C776 /* PhotoAlbumsViewController.swift in Sources */,
B57BEA76216AAFD700A2C776 /* PhotoAlbumTitleButton.swift in Sources */,
9402FADB226F057500C77100 /* GalleryVideoCell.swift in Sources */,
B57BEA6F216AAFD700A2C776 /* PhotoDetailViewController.swift in Sources */,
B57BEA70216AAFD700A2C776 /* PhotoGalleryCameraCell.swift in Sources */,
B57BEA7A216AAFD700A2C776 /* PhotoGalleryCameraIconView.swift in Sources */,
B57BEA73216AAFD700A2C776 /* PhotoGalleryCell.swift in Sources */,
94F4BF192264609C00E7A672 /* VideoPropertyView.swift in Sources */,
B57BEA73216AAFD700A2C776 /* GalleryPhotoCell.swift in Sources */,
B57BEA6B216AAFD700A2C776 /* PhotoGalleryHintLabel.swift in Sources */,
20FC48032256FAC3004CCD1D /* CameraSessionHandler.swift in Sources */,
B57BEA77216AAFD700A2C776 /* PhotoGalleryTagLabel.swift in Sources */,
Expand Down
12 changes: 12 additions & 0 deletions Pickle/Assets/Images.xcassets/video-icon.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "video-icon.pdf"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import UIKit
import Photos

internal final class PhotoGalleryCell: UICollectionViewCell {
internal class GalleryPhotoCell: UICollectionViewCell {

override init(frame: CGRect) {
super.init(frame: frame)
Expand Down Expand Up @@ -92,7 +92,7 @@ internal final class PhotoGalleryCell: UICollectionViewCell {
self.taggedText = taggedText
}

private func setUpSubviews() {
func setUpSubviews() {
// Set the cell as the accessibility element for UI tests to work.
isAccessibilityElement = true

Expand All @@ -114,5 +114,4 @@ internal final class PhotoGalleryCell: UICollectionViewCell {
tagLabel.topAnchor.constraint(equalTo: overlayView.topAnchor, constant: 10).isActive = true
tagLabel.trailingAnchor.constraint(equalTo: overlayView.trailingAnchor, constant: -10).isActive = true
}

}
42 changes: 42 additions & 0 deletions Pickle/Classes/GalleryVideoCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// 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
//

import UIKit
import Photos

internal final class GalleryVideoCell: GalleryPhotoCell {

private let videoPropertyView = VideoPropertyView()

override func setUpSubviews() {
super.setUpSubviews()

contentView.addSubview(videoPropertyView)
videoPropertyView.translatesAutoresizingMaskIntoConstraints = false
videoPropertyView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
videoPropertyView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
videoPropertyView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
videoPropertyView.heightAnchor.constraint(equalToConstant: 24).isActive = true
}

override func configure(
with asset: PHAsset,
taggedText: String? = nil,
configuration: ImagePickerConfigurable?) {

super.configure(
with: asset,
taggedText: taggedText,
configuration: configuration)

videoPropertyView.configure(duration: asset.duration)
videoPropertyView.setSelected(taggedText != nil)
}
}
23 changes: 23 additions & 0 deletions Pickle/Classes/ImagePickerConfigurable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,31 @@ public protocol ImagePickerConfigurable {

/// Specifies whether the camera button shows a live preview.
var isLiveCameraViewEnabled: Bool? { get }

// MARK: - Media Types

/// Specifies the supported media types
var mediaType: ImagePickerMediaType? { get }
}

// Options that represents media type selections in ImagePickerController
public struct ImagePickerMediaType: OptionSet {

public let rawValue: Int

public init(rawValue: Int) {
self.rawValue = rawValue
}

/// Only show images in ImagePickerController
public static let image = ImagePickerMediaType(rawValue: 1 << 0)

/// Only show videos in ImagePickerController
public static let video = ImagePickerMediaType(rawValue: 1 << 1)

/// Show images and videos in ImagePickerController
public static let all: ImagePickerMediaType = [.image, .video]
}

/// An enum that represents photo selections allowed in ImagePickerController.
public enum ImagePickerSelection {
Expand Down
4 changes: 4 additions & 0 deletions Pickle/Classes/Parameters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,8 @@ public struct Parameters: ImagePickerConfigurable {
/// Specifies whether the camera button shows a live preview.
public var isLiveCameraViewEnabled: Bool?

// MARK: - Media Types

/// Specifies the supported media types
public var mediaType: ImagePickerMediaType?
}
2 changes: 1 addition & 1 deletion Pickle/Classes/PhotoAlbumCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ internal final class PhotoAlbumCell: UITableViewCell {

private lazy var subtitleLabel: UILabel = {
let label = UILabel()
label.textColor = UIColor.Palette.gray
label.textColor = UIColor.Palette.grey
return label
}()

Expand Down
2 changes: 1 addition & 1 deletion Pickle/Classes/PhotoGalleryCameraIconView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal final class PhotoGalleryCameraIconView: UIView {
let label = UILabel()
label.text = Bundle(for: type(of: self)).localizedString(forKey: "imagePicker.button.camera", value: "", table: nil).uppercased()
label.font = UIFont.forCameraButton
label.textColor = UIColor.Palette.gray
label.textColor = UIColor.Palette.grey
return label
}()

Expand Down
4 changes: 2 additions & 2 deletions Pickle/Classes/PhotoGalleryHintLabel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ internal final class PhotoGalleryHintLabel: UILabel {
private lazy var borderLayer: CALayer = {
let layer = CALayer()
layer.borderWidth = 1 / UIScreen.main.scale
layer.borderColor = UIColor.Palette.lightGray.cgColor
layer.borderColor = UIColor.Palette.lightGrey.cgColor
layer.rasterizationScale = UIScreen.main.scale
layer.shouldRasterize = true
return layer
Expand All @@ -77,7 +77,7 @@ internal final class PhotoGalleryHintLabel: UILabel {
numberOfLines = 0
textAlignment = .center
font = UIFont.forHintLabel
textColor = UIColor.Palette.darkGray
textColor = UIColor.Palette.grey
}

}
31 changes: 25 additions & 6 deletions Pickle/Classes/PhotoGalleryViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,18 @@ internal final class PhotoGalleryViewController: UIViewController,
internal private(set) lazy var fetchResult: PHFetchResult<PHAsset> = {
let options = PHFetchOptions()
options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
options.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.image.rawValue)

switch configuration?.mediaType {
case .all?:
options.predicate = nil
case .image?:
options.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.image.rawValue)
case .video?:
options.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.video.rawValue)
default:
options.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.image.rawValue)
}

return PHAsset.fetchAssets(in: self.album, options: options)
}()

Expand All @@ -108,7 +119,8 @@ internal final class PhotoGalleryViewController: UIViewController,
collectionView.delegate = self
collectionView.backgroundColor = UIColor.white
collectionView.register(PhotoGalleryCameraCell.self, forCellWithReuseIdentifier: String(describing: PhotoGalleryCameraCell.self))
collectionView.register(PhotoGalleryCell.self, forCellWithReuseIdentifier: String(describing: PhotoGalleryCell.self))
collectionView.register(GalleryPhotoCell.self, forCellWithReuseIdentifier: String(describing: GalleryPhotoCell.self))
collectionView.register(GalleryVideoCell.self, forCellWithReuseIdentifier: String(describing: GalleryVideoCell.self))
collectionView.register(PhotoGalleryLiveViewCell.self, forCellWithReuseIdentifier: String(describing: PhotoGalleryLiveViewCell.self))
collectionView.allowsMultipleSelection = true
return collectionView
Expand Down Expand Up @@ -164,15 +176,22 @@ internal final class PhotoGalleryViewController: UIViewController,
}
}

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: PhotoGalleryCell.self), for: indexPath)
let index = isCameraCompatible ? indexPath.row - 1 : indexPath.row
let asset = fetchResult[index]

if let text = delegate?.photoGalleryViewController(self, taggedTextForPhoto: asset) {
(cell as? PhotoGalleryCell)?.configure(with: asset, taggedText: text, configuration: configuration)
let text = delegate?.photoGalleryViewController(self, taggedTextForPhoto: asset)
var cell: UICollectionViewCell
if asset.mediaType == .video {
cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: GalleryVideoCell.self), for: indexPath)
(cell as? GalleryVideoCell)?.configure(with: asset, taggedText: text, configuration: configuration)
} else {
cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: GalleryPhotoCell.self), for: indexPath)
(cell as? GalleryPhotoCell)?.configure(with: asset, taggedText: text, configuration: configuration)
}

if text != nil {
collectionView.selectItem(at: indexPath, animated: false, scrollPosition: [])
} else {
(cell as? PhotoGalleryCell)?.configure(with: asset, configuration: configuration)
collectionView.deselectItem(at: indexPath, animated: false)
}

Expand Down
6 changes: 3 additions & 3 deletions Pickle/Classes/UIColor+Palette.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ internal extension UIColor {

internal enum Palette {
static let blue = UIColor(hex: 0x2984C0)
static let lightGray = UIColor(hex: 0x8F939C)
static let gray = UIColor(hex: 0x8F939C)
static let darkGray = UIColor(hex: 0x8F939C)
static let lightGrey = UIColor(hex: 0x8F939C)
static let grey = UIColor(hex: 0x8F939C)
static let magnesium = UIColor(hex: 0xB2B2B2)
static let darkGrey = UIColor(hex: 0x4B4D52)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's already a darkGray, perhaps it needs a different name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed that 0x8F939C is duplicated for lightGray, gray, and darkGray 😂
So, I removed darkGray to be replaced with darkGrey.
Also, renamed other "gray" to "grey" to follow UK spelling

}

internal convenience init(hex: Int) {
Expand Down
Loading