Skip to content

Commit

Permalink
Merge pull request #44 from carousell/feature/video-support
Browse files Browse the repository at this point in the history
Support video in the picker
  • Loading branch information
amelia2801 committed Apr 24, 2019
2 parents 36265af + c4ee19a commit f1aa077
Show file tree
Hide file tree
Showing 16 changed files with 215 additions and 21 deletions.
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)
}

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

0 comments on commit f1aa077

Please sign in to comment.