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

Support video in the picker #44

merged 10 commits into from
Apr 24, 2019

Conversation

amelia2801
Copy link
Contributor

Provide options to display images only, videos only, or both images and videos in the ImagePickerController

@carouselljenkins
Copy link

@HungnguyenVN, can you review this pull request?

@carouselljenkins
Copy link

1 Error
🚫 Please update CHANGELOG.md.

Generated by 🚫 Danger

public enum ImagePickerMediaType {

/// Show images and videos in ImagePickerController
case unknown
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be all ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

PHAsset has audio mediaType as well.
https://developer.apple.com/documentation/photokit/phassetmediatype

any better suggestion? or do u think can use all?

Copy link
Contributor

@daveluong daveluong Apr 22, 2019

Choose a reason for hiding this comment

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

.unknown doesn't make sense I feel. How about removing .unknown and bitmasking it using OptionSet?

https://developer.apple.com/documentation/swift/optionset

Then the API consumer can pass in any combination of mediaType they desire:
mediaType: ImagePickerMediaType = [.video, .image]
mediaType: ImagePickerMediaType = [.video, .audio]
mediaType: ImagePickerMediaType = .video
mediaType: ImagePickerMediaType = .all
...

@@ -32,6 +32,8 @@ internal final class PhotoGalleryCell: UICollectionViewCell {
return imageView
}()

private let videoPropertyView = VideoPropertyView()
Copy link
Contributor

@daveluong daveluong Apr 18, 2019

Choose a reason for hiding this comment

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

Wondering if we should have a different type of cell for video:

  • We won't need to set isHidden
  • Won't have redundant and hidden videoPropertyView on top of all the cells
  • Easy to reason about
  • It could get messy if we support more types with different UI in the future (live photo, panorama, etc..) if all of them reuse this cell

Copy link
Contributor Author

Choose a reason for hiding this comment

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

was thinking of that too, but the only diff is this VideoPropertyView. shall we subclass PhotoGalleryCell?
call it... GalleryVideoCell? and rename PhotoGalleryCell to GalleryPhotoCell.

class GalleryVideoCell: GalleryPhotoCell { }

case .video:
options.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.video.rawValue)
default:
break
Copy link
Contributor

Choose a reason for hiding this comment

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

I dont quite understand this. Shouldn't the fetch results contain both type of assets?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if we don't pass in the predicate, then yes it will fetch both type of assets

Copy link
Collaborator

Choose a reason for hiding this comment

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

It probably can be simplified as one switch:

switch configuration?.mediaType {
    case .image?:
        // ...
    case .video?:
        // ...            
    case nil:
        // ...
}

// See https://github.com/carousell/pickle/graphs/contributors for the list of project authors
//

internal final class VideoPropertyView: UIView {
Copy link
Contributor

Choose a reason for hiding this comment

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

internal is default

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's generally a good practice to specify explicit access control levels in a library. It implies that a method should only be made public in the future with careful consideration. The internal keyword is more about the documentation.

Copy link
Collaborator

@bcylin bcylin left a comment

Choose a reason for hiding this comment

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

Looks good overall 👍 Just left some minor suggestions.

case .video:
options.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.video.rawValue)
default:
break
Copy link
Collaborator

Choose a reason for hiding this comment

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

It probably can be simplified as one switch:

switch configuration?.mediaType {
    case .image?:
        // ...
    case .video?:
        // ...            
    case nil:
        // ...
}

private let videoIcon: UIImageView = {
let icon = UIImageView()
icon.tintColor = .white
icon.image = UIImage(named: "video-icon")?.withRenderingMode(.alwaysTemplate)
Copy link
Collaborator

Choose a reason for hiding this comment

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

You might need to specify the framework bundle that contains the image.

init?(named name: String, in bundle: Bundle?, compatibleWith traitCollection: UITraitCollection?)

@@ -18,6 +18,7 @@ internal extension UIColor {
static let gray = UIColor(hex: 0x8F939C)
static let darkGray = 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

// See https://github.com/carousell/pickle/graphs/contributors for the list of project authors
//

internal final class VideoPropertyView: UIView {
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's generally a good practice to specify explicit access control levels in a library. It implies that a method should only be made public in the future with careful consideration. The internal keyword is more about the documentation.

@amelia2801
Copy link
Contributor Author

@daveluong @bcylin i made some changes based on your comments. Please help review again 🙏
Do I need to update CHANGELOG? And when should we update version?

@bcylin
Copy link
Collaborator

bcylin commented Apr 23, 2019

It should be all right to add a ## Next release section in CHANGELOG.md.

Since the master branch is protected, I usually have another PR to run make bump version=<number> and update README if needed.

Copy link
Collaborator

@bcylin bcylin left a comment

Choose a reason for hiding this comment

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

👍

} else {
cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: GalleryPhotoCell.self), for: indexPath)
(cell as? GalleryPhotoCell)?.configure(with: asset, taggedText: text, configuration: configuration)
collectionView.deselectItem(at: indexPath, animated: false)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is the deselectItem(at:animated:) needed in L187 and L191?

This is already followed by:

if text != nil {
    collectionView.selectItem(at: indexPath, animated: false, scrollPosition: [])
} else {
    collectionView.deselectItem(at: indexPath, animated: false)
}


override func prepareForReuse() {
super.prepareForReuse()
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

The implementation is empty. It's nice to have it removed.

videoPropertyView.setSelected(true)
} else {
videoPropertyView.setSelected(false)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

videoPropertyView.setSelected(taggedText != nil)

It can be more concise, but it's a choice of coding style.

}

func setSelected(_ value: Bool) {
if value {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if value {
if isSelected {

@daveluong
Copy link
Contributor

Thank you @bcylin for helping us to review the PRs! Truly appreciate it :)

@amelia2801
Copy link
Contributor Author

Thank you @bcylin and @daveluong ! 😄

@amelia2801 amelia2801 merged commit f1aa077 into master Apr 24, 2019
@amelia2801 amelia2801 deleted the feature/video-support branch April 24, 2019 05:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants