Merge branch 'charlesmchen/improveAttachmentApprovalView'

This commit is contained in:
Matthew Chen 2017-04-13 13:50:14 -04:00
commit 9882eeea93
5 changed files with 104 additions and 19 deletions

View file

@ -7,6 +7,7 @@
#import "Asserts.h"
#import "AttachmentSharing.h"
#import "Environment.h"
#import "FLAnimatedImage.h"
#import "NotificationsManager.h"
#import "OWSAnyTouchGestureRecognizer.h"
#import "OWSCallNotificationsAdaptee.h"

View file

@ -3,6 +3,7 @@
//
import Foundation
import MediaPlayer
class AttachmentApprovalViewController: UIViewController {
@ -14,6 +15,8 @@ class AttachmentApprovalViewController: UIViewController {
var successCompletion : (() -> Void)?
var videoPlayer: MPMoviePlayerController?
// MARK: Initializers
@available(*, unavailable, message:"use attachment: constructor instead.")
@ -60,29 +63,75 @@ class AttachmentApprovalViewController: UIViewController {
createButtonRow(attachmentPreviewView:attachmentPreviewView)
if attachment.isImage {
if attachment.isAnimatedImage {
createAnimatedPreview(attachmentPreviewView:attachmentPreviewView)
} else if attachment.isImage {
createImagePreview(attachmentPreviewView:attachmentPreviewView)
} else if attachment.isVideo {
createVideoPreview(attachmentPreviewView:attachmentPreviewView)
} else if attachment.isAudio {
createAudioPreview(attachmentPreviewView:attachmentPreviewView)
} else {
createGenericPreview(attachmentPreviewView:attachmentPreviewView)
}
}
private func createAudioPreview(attachmentPreviewView: UIView) {
// TODO: Add audio player.
createGenericPreview(attachmentPreviewView:attachmentPreviewView)
}
private func createAnimatedPreview(attachmentPreviewView: UIView) {
// Use Flipboard FLAnimatedImage library to display gifs
guard let animatedImage = FLAnimatedImage(gifData:attachment.data) else {
createGenericPreview(attachmentPreviewView:attachmentPreviewView)
return
}
let animatedImageView = FLAnimatedImageView()
animatedImageView.animatedImage = animatedImage
animatedImageView.contentMode = .scaleAspectFit
attachmentPreviewView.addSubview(animatedImageView)
animatedImageView.autoPinWidthToSuperview()
animatedImageView.autoPinHeightToSuperview()
}
private func createImagePreview(attachmentPreviewView: UIView) {
var image = attachment.image
if image == nil {
image = UIImage(data:attachment.data)
}
if image != nil {
let imageView = UIImageView(image:image)
imageView.layer.minificationFilter = kCAFilterTrilinear
imageView.layer.magnificationFilter = kCAFilterTrilinear
imageView.contentMode = .scaleAspectFit
attachmentPreviewView.addSubview(imageView)
imageView.autoPinWidthToSuperview()
imageView.autoPinHeightToSuperview()
} else {
guard image != nil else {
createGenericPreview(attachmentPreviewView:attachmentPreviewView)
return
}
let imageView = UIImageView(image:image)
imageView.layer.minificationFilter = kCAFilterTrilinear
imageView.layer.magnificationFilter = kCAFilterTrilinear
imageView.contentMode = .scaleAspectFit
attachmentPreviewView.addSubview(imageView)
imageView.autoPinWidthToSuperview()
imageView.autoPinHeightToSuperview()
}
private func createVideoPreview(attachmentPreviewView: UIView) {
guard let dataUrl = attachment.getTemporaryDataUrl() else {
createGenericPreview(attachmentPreviewView:attachmentPreviewView)
return
}
guard let videoPlayer = MPMoviePlayerController(contentURL:dataUrl) else {
createGenericPreview(attachmentPreviewView:attachmentPreviewView)
return
}
videoPlayer.prepareToPlay()
videoPlayer.controlStyle = .default
videoPlayer.shouldAutoplay = false
attachmentPreviewView.addSubview(videoPlayer.view)
self.videoPlayer = videoPlayer
videoPlayer.view.autoPinWidthToSuperview()
videoPlayer.view.autoPinHeightToSuperview()
}
private func createGenericPreview(attachmentPreviewView: UIView) {
@ -125,9 +174,17 @@ class AttachmentApprovalViewController: UIViewController {
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = NumberFormatter.Style.decimal
let fileSizeLabel = UILabel()
let fileSize = attachment.data.count
let kOneKilobyte = 1024
let kOneMegabyte = kOneKilobyte * kOneKilobyte
let fileSizeText = (fileSize > kOneMegabyte
? numberFormatter.string(from: NSNumber(value: fileSize / kOneMegabyte))! + " mb"
: (fileSize > kOneKilobyte
? numberFormatter.string(from: NSNumber(value: fileSize / kOneKilobyte))! + " kb"
: numberFormatter.string(from: NSNumber(value: fileSize))!))
fileSizeLabel.text = String(format:NSLocalizedString("ATTACHMENT_APPROVAL_FILE_SIZE_FORMAT",
comment: "Format string for file size label in call interstitial view"),
numberFormatter.string(from: NSNumber(value: attachment.data.count))!)
comment: "Format string for file size label in call interstitial view. Embeds: {{file size as 'N mb' or 'N kb'}}."),
fileSizeText)
fileSizeLabel.textColor = UIColor.white
fileSizeLabel.font = labelFont

View file

@ -110,12 +110,9 @@ typedef enum : NSUInteger {
}
- (BOOL)pasteBoardHasPossibleAttachment {
if ([SignalAttachment pasteboardHasPossibleAttachment]) {
// We don't want to load/convert images more than once so we
// only do a cursory validation pass at this time.
return YES;
}
return NO;
// We don't want to load/convert images more than once so we
// only do a cursory validation pass at this time.
return [SignalAttachment pasteboardHasPossibleAttachment];
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {

View file

@ -64,6 +64,8 @@ class SignalAttachment: NSObject {
let data: Data
internal var temporaryDataUrl: URL?
// Attachment types are identified using UTIs.
//
// See: https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html
@ -109,6 +111,30 @@ class SignalAttachment: NSObject {
super.init()
}
// MARK: Methods
public func getTemporaryDataUrl() -> URL? {
if temporaryDataUrl == nil {
let directory = NSTemporaryDirectory()
guard let fileExtension = self.fileExtension else {
return nil
}
let fileName = NSUUID().uuidString + "." + fileExtension
guard let fileUrl = NSURL.fileURL(withPathComponents: [directory, fileName]) else {
return nil
}
do {
try data.write(to: fileUrl)
} catch {
Logger.error("\(SignalAttachment.TAG) Could not write data to disk: \(dataUTI)")
assertionFailure()
return nil
}
temporaryDataUrl = fileUrl
}
return temporaryDataUrl
}
var hasError: Bool {
return error != nil
}
@ -237,6 +263,10 @@ class SignalAttachment: NSObject {
return SignalAttachment.outputImageUTISet.contains(dataUTI)
}
public var isAnimatedImage: Bool {
return SignalAttachment.animatedImageUTISet.contains(dataUTI)
}
public var isVideo: Bool {
return SignalAttachment.videoUTISet.contains(dataUTI)
}

View file

@ -56,7 +56,7 @@
"ATTACHMENT_APPROVAL_FILE_EXTENSION_FORMAT" = "File type: %@";
/* Format string for file size label in call interstitial view */
"ATTACHMENT_APPROVAL_FILE_SIZE_FORMAT" = "File size: %@";
"ATTACHMENT_APPROVAL_FILE_SIZE_FORMAT" = "Size: %@";
/* Label for 'send' button in the 'attachment approval' dialog. */
"ATTACHMENT_APPROVAL_SEND_BUTTON" = "Send";