-
Notifications
You must be signed in to change notification settings - Fork 24
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
Conversation
@HungnguyenVN, can you review this pull request? |
Generated by 🚫 Danger |
public enum ImagePickerMediaType { | ||
|
||
/// Show images and videos in ImagePickerController | ||
case unknown |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be all
?
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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() |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
internal
is default
There was a problem hiding this comment.
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.
There was a problem hiding this 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 |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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.
@daveluong @bcylin i made some changes based on your comments. Please help review again 🙏 |
It should be all right to add a Since the master branch is protected, I usually have another PR to run |
There was a problem hiding this 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) |
There was a problem hiding this comment.
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() | ||
} |
There was a problem hiding this comment.
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) | ||
} |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if value { | |
if isSelected { |
Thank you @bcylin for helping us to review the PRs! Truly appreciate it :) |
Thank you @bcylin and @daveluong ! 😄 |
Provide options to display images only, videos only, or both images and videos in the ImagePickerController