Addressed PR changes

Added NVActivityIndicatorView to the SessionShareExtension.
Removed the SignalAttachmentType.
pull/548/head
Morgan Pretty 3 years ago
parent a7661da41a
commit 2fedba4cea

@ -22,6 +22,7 @@ target 'SessionShareExtension' do
pod 'CryptoSwift', :inhibit_warnings => true pod 'CryptoSwift', :inhibit_warnings => true
pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true
pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master', :inhibit_warnings => true pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master', :inhibit_warnings => true
pod 'NVActivityIndicatorView', :inhibit_warnings => true
pod 'PromiseKit', :inhibit_warnings => true pod 'PromiseKit', :inhibit_warnings => true
pod 'PureLayout', '~> 3.1.8', :inhibit_warnings => true pod 'PureLayout', '~> 3.1.8', :inhibit_warnings => true
pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true

@ -29,6 +29,7 @@ PODS:
- NVActivityIndicatorView (5.0.1): - NVActivityIndicatorView (5.0.1):
- NVActivityIndicatorView/Base (= 5.0.1) - NVActivityIndicatorView/Base (= 5.0.1)
- NVActivityIndicatorView/Base (5.0.1) - NVActivityIndicatorView/Base (5.0.1)
- OpenSSL-Universal (1.1.1200)
- PromiseKit (6.13.1): - PromiseKit (6.13.1):
- PromiseKit/CorePromise (= 6.13.1) - PromiseKit/CorePromise (= 6.13.1)
- PromiseKit/Foundation (= 6.13.1) - PromiseKit/Foundation (= 6.13.1)
@ -43,7 +44,7 @@ PODS:
- SAMKeychain (1.5.3) - SAMKeychain (1.5.3)
- SignalCoreKit (1.0.0): - SignalCoreKit (1.0.0):
- CocoaLumberjack - CocoaLumberjack
- GRKOpenSSLFramework - OpenSSL-Universal
- Sodium (0.8.0) - Sodium (0.8.0)
- SQLCipher (4.4.0): - SQLCipher (4.4.0):
- SQLCipher/standard (= 4.4.0) - SQLCipher/standard (= 4.4.0)
@ -147,6 +148,7 @@ SPEC REPOS:
- GRKOpenSSLFramework - GRKOpenSSLFramework
- HKDFKit - HKDFKit
- NVActivityIndicatorView - NVActivityIndicatorView
- OpenSSL-Universal
- PromiseKit - PromiseKit
- PureLayout - PureLayout
- Reachability - Reachability
@ -196,11 +198,12 @@ SPEC CHECKSUMS:
HKDFKit: c058305d6f64b84f28c50bd7aa89574625bcb62a HKDFKit: c058305d6f64b84f28c50bd7aa89574625bcb62a
Mantle: 2fa750afa478cd625a94230fbf1c13462f29395b Mantle: 2fa750afa478cd625a94230fbf1c13462f29395b
NVActivityIndicatorView: 738e843cb8924e9e4fc3e559d0728031624bf860 NVActivityIndicatorView: 738e843cb8924e9e4fc3e559d0728031624bf860
OpenSSL-Universal: 3b8c0d6268fbd5d3ac44f97338e2fd16a73d9dbf
PromiseKit: 28fda91c973cc377875d8c0ea4f973013c05b6db PromiseKit: 28fda91c973cc377875d8c0ea4f973013c05b6db
PureLayout: a4afb3d79dd958564ce33d22c89f407280d8e6a8 PureLayout: a4afb3d79dd958564ce33d22c89f407280d8e6a8
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
SignalCoreKit: 4562b2bbd9830077439ca003f952a798457d4ea5 SignalCoreKit: 1fbd8732163ef76de16cd1107d1fa3684b607e5d
Sodium: 63c0ca312a932e6da481689537d4b35568841bdc Sodium: 63c0ca312a932e6da481689537d4b35568841bdc
SQLCipher: e434ed542b24f38ea7b36468a13f9765e1b5c072 SQLCipher: e434ed542b24f38ea7b36468a13f9765e1b5c072
SwiftProtobuf: 241400280f912735c1e1b9fe675fdd2c6c4d42e2 SwiftProtobuf: 241400280f912735c1e1b9fe675fdd2c6c4d42e2
@ -208,6 +211,6 @@ SPEC CHECKSUMS:
YYImage: 6db68da66f20d9f169ceb94dfb9947c3867b9665 YYImage: 6db68da66f20d9f169ceb94dfb9947c3867b9665
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
PODFILE CHECKSUM: 50e6a35c838ba28d2ee02bc6018fdd297c04e55f PODFILE CHECKSUM: e7aa4e20c8329a413eadd5e6f0d900340810f4c7
COCOAPODS: 1.10.1 COCOAPODS: 1.11.2

@ -20,18 +20,6 @@ public enum SignalAttachmentError: Error {
case couldNotResizeImage case couldNotResizeImage
} }
@objc
public enum SignalAttachmentType: Int {
case text
case oversizeText
case image
case animatedImage
case video
case audio
case url
case unknown
}
extension String { extension String {
public var filenameWithoutExtension: String { public var filenameWithoutExtension: String {
return (self as NSString).deletingPathExtension return (self as NSString).deletingPathExtension
@ -446,19 +434,6 @@ public class SignalAttachment: NSObject {
private class var mediaUTISet: Set<String> { private class var mediaUTISet: Set<String> {
return audioUTISet.union(videoUTISet).union(animatedImageUTISet).union(inputImageUTISet) return audioUTISet.union(videoUTISet).union(animatedImageUTISet).union(inputImageUTISet)
} }
@objc
public var fileType: SignalAttachmentType {
if isAnimatedImage { return .animatedImage }
if isImage { return .image }
if isVideo { return .video }
if isAudio { return .audio }
if isUrl { return .url }
if isOversizeText { return .oversizeText }
if isText { return .text }
return .unknown
}
@objc @objc
public var isImage: Bool { public var isImage: Bool {

@ -44,37 +44,36 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
} }
private lazy var validImage: UIImage? = { private lazy var validImage: UIImage? = {
switch attachment.fileType { if attachment.isImage {
case .image: guard
guard attachment.isValidImage,
attachment.isValidImage, let image: UIImage = attachment.image(),
let image: UIImage = attachment.image(), image.size.width > 0,
image.size.width > 0, image.size.height > 0
image.size.height > 0 else {
else { return nil
return nil }
}
return image
return image }
else if attachment.isVideo {
case .video: guard
guard attachment.isValidVideo,
attachment.isValidVideo, let image: UIImage = attachment.videoPreview(),
let image: UIImage = attachment.videoPreview(), image.size.width > 0,
image.size.width > 0, image.size.height > 0
image.size.height > 0 else {
else { return nil
return nil }
}
return image
default: return nil return image
} }
return nil
}() }()
private lazy var validAnimatedImage: YYImage? = { private lazy var validAnimatedImage: YYImage? = {
guard guard
attachment.fileType == .animatedImage, attachment.isAnimatedImage,
attachment.isValidImage, attachment.isValidImage,
let dataUrl: URL = attachment.dataUrl, let dataUrl: URL = attachment.dataUrl,
let image: YYImage = YYImage(contentsOfFile: dataUrl.path), let image: YYImage = YYImage(contentsOfFile: dataUrl.path),
@ -153,22 +152,19 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
view.isHidden = true view.isHidden = true
// Override the image to the correct one // Override the image to the correct one
switch attachment.fileType { if attachment.isImage || attachment.isVideo {
case .image, .video: if let validImage: UIImage = validImage {
if let validImage: UIImage = validImage { view.layer.minificationFilter = .trilinear
view.layer.minificationFilter = .trilinear view.layer.magnificationFilter = .trilinear
view.layer.magnificationFilter = .trilinear view.image = validImage
view.image = validImage }
} }
else if attachment.isUrl {
case .url: view.clipsToBounds = true
view.clipsToBounds = true view.image = UIImage(named: "Link")?.withTint(Colors.text)
view.image = UIImage(named: "Link")?.withTint(Colors.text) view.contentMode = .center
view.contentMode = .center view.backgroundColor = (isDarkMode ? .black : UIColor.black.withAlphaComponent(0.06))
view.backgroundColor = (isDarkMode ? .black : UIColor.black.withAlphaComponent(0.06)) view.layer.cornerRadius = 8
view.layer.cornerRadius = 8
default: break
} }
return view return view
@ -225,7 +221,7 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
let stackView: UIStackView = UIStackView() let stackView: UIStackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical stackView.axis = .vertical
stackView.alignment = (attachment.fileType == .url ? .leading : .center) stackView.alignment = (attachment.isUrl ? .leading : .center)
stackView.distribution = .fill stackView.distribution = .fill
switch mode { switch mode {
@ -257,35 +253,33 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
} }
// Content // Content
switch attachment.fileType { if attachment.isUrl {
case .image, .animatedImage, .video: break // No title for these // If we have no link preview info at this point then assume link previews are disabled
if let linkPreviewURL: String = linkPreviewInfo?.url {
case .url:
// If we have no link preview info at this point then assume link previews are disabled
guard let linkPreviewURL: String = linkPreviewInfo?.url else {
label.text = "vc_share_link_previews_disabled_title".localized()
break
}
label.font = .boldSystemFont(ofSize: Values.smallFontSize) label.font = .boldSystemFont(ofSize: Values.smallFontSize)
label.text = linkPreviewURL label.text = linkPreviewURL
label.textAlignment = .left label.textAlignment = .left
label.lineBreakMode = .byTruncatingTail label.lineBreakMode = .byTruncatingTail
label.numberOfLines = 2 label.numberOfLines = 2
}
default: else {
if let fileName: String = attachment.sourceFilename?.trimmingCharacters(in: .whitespacesAndNewlines), fileName.count > 0 { label.text = "vc_share_link_previews_disabled_title".localized()
label.text = fileName }
} }
else if let fileExtension: String = attachment.fileExtension { // Title for everything except these types
label.text = String( else if !attachment.isImage && !attachment.isAnimatedImage && !attachment.isVideo {
format: "ATTACHMENT_APPROVAL_FILE_EXTENSION_FORMAT".localized(), if let fileName: String = attachment.sourceFilename?.trimmingCharacters(in: .whitespacesAndNewlines), fileName.count > 0 {
fileExtension.uppercased() label.text = fileName
) }
} else if let fileExtension: String = attachment.fileExtension {
label.text = String(
label.textAlignment = .center format: "ATTACHMENT_APPROVAL_FILE_EXTENSION_FORMAT".localized(),
label.lineBreakMode = .byTruncatingMiddle fileExtension.uppercased()
)
}
label.textAlignment = .center
label.lineBreakMode = .byTruncatingMiddle
} }
// Hide the label if it has no content // Hide the label if it has no content
@ -314,32 +308,30 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
} }
// Content // Content
switch attachment.fileType { if attachment.isUrl {
case .image, .animatedImage, .video: break // No size for these // We only load Link Previews for HTTPS urls so append an explanation for not
if let linkPreviewURL: String = linkPreviewInfo?.url {
case .url:
// If we have no link preview info at this point then assume link previews are disabled
guard let linkPreviewURL: String = linkPreviewInfo?.url else {
label.text = "vc_share_link_previews_disabled_explanation".localized()
label.textColor = Colors.text
label.textAlignment = .center
label.numberOfLines = 0
break
}
// We only load Link Previews for HTTPS urls so append an explanation for not
if let targetUrl: URL = URL(string: linkPreviewURL), targetUrl.scheme?.lowercased() != "https" { if let targetUrl: URL = URL(string: linkPreviewURL), targetUrl.scheme?.lowercased() != "https" {
label.font = UIFont.ows_regularFont(withSize: Values.verySmallFontSize) label.font = UIFont.ows_regularFont(withSize: Values.verySmallFontSize)
label.text = "vc_share_link_previews_unsecure".localized() label.text = "vc_share_link_previews_unsecure".localized()
label.textColor = (mode == .attachmentApproval ? Colors.pinIcon : Colors.accent) label.textColor = (mode == .attachmentApproval ? Colors.pinIcon : Colors.accent)
} }
}
default: // If we have no link preview info at this point then assume link previews are disabled
// Format string for file size label in call interstitial view. else {
// Embeds: {{file size as 'N mb' or 'N kb'}}. label.text = "vc_share_link_previews_disabled_explanation".localized()
let fileSize: UInt = attachment.dataLength label.textColor = Colors.text
label.text = String(format: "ATTACHMENT_APPROVAL_FILE_SIZE_FORMAT".localized(), OWSFormat.formatFileSize(UInt(fileSize)))
label.textAlignment = .center label.textAlignment = .center
label.numberOfLines = 0
}
}
// Subtitle for everything else except these types
else if !attachment.isImage && !attachment.isAnimatedImage && !attachment.isVideo {
// Format string for file size label in call interstitial view.
// Embeds: {{file size as 'N mb' or 'N kb'}}.
let fileSize: UInt = attachment.dataLength
label.text = String(format: "ATTACHMENT_APPROVAL_FILE_SIZE_FORMAT".localized(), OWSFormat.formatFileSize(UInt(fileSize)))
label.textAlignment = .center
} }
// Hide the label if it has no content // Hide the label if it has no content
@ -352,7 +344,7 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
private func setupViews() { private func setupViews() {
// Plain text will just be put in the 'message' input so do nothing // Plain text will just be put in the 'message' input so do nothing
guard attachment.fileType != .text && attachment.fileType != .oversizeText else { return } guard !attachment.isText && !attachment.isOversizeText else { return }
// Setup the view hierarchy // Setup the view hierarchy
addSubview(stackView) addSubview(stackView)
@ -370,95 +362,90 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
imageView.addSubview(fileTypeImageView) imageView.addSubview(fileTypeImageView)
// Type-specific configurations // Type-specific configurations
switch attachment.fileType { if attachment.isAnimatedImage {
case .animatedImage: animatedImageView.isHidden = false animatedImageView.isHidden = false
case .image: imageView.isHidden = false }
else if attachment.isImage {
case .video: imageView.isHidden = false
// Note: The 'attachmentApproval' mode provides it's own play button to keep }
// it at the proper scale when zooming else if attachment.isVideo {
imageView.isHidden = false // Note: The 'attachmentApproval' mode provides it's own play button to keep
videoPlayButton.isHidden = (mode == .attachmentApproval) // it at the proper scale when zooming
imageView.isHidden = false
case .audio: videoPlayButton.isHidden = (mode == .attachmentApproval)
// Hide the 'audioPlayPauseButton' if the 'audioPlayer' failed to get created }
imageView.isHidden = false else if attachment.isAudio {
audioPlayPauseButton.isHidden = (audioPlayer == nil) // Hide the 'audioPlayPauseButton' if the 'audioPlayer' failed to get created
setAudioIconToPlay() imageView.isHidden = false
setAudioProgress(0, duration: (audioPlayer?.duration ?? 0)) audioPlayPauseButton.isHidden = (audioPlayer == nil)
setAudioIconToPlay()
fileTypeImageView.image = UIImage(named: "table_ic_notification_sound")? setAudioProgress(0, duration: (audioPlayer?.duration ?? 0))
.withRenderingMode(.alwaysTemplate)
fileTypeImageView.tintColor = Colors.text fileTypeImageView.image = UIImage(named: "table_ic_notification_sound")?
fileTypeImageView.isHidden = false .withRenderingMode(.alwaysTemplate)
fileTypeImageView.tintColor = Colors.text
// Note: There is an annoying bug where the MediaMessageView will fill the screen if the fileTypeImageView.isHidden = false
// 'audioPlayPauseButton' is added anywhere within the view hierarchy causing issues with
// the min scale on 'image' and 'animatedImage' file types (assume it's actually any UIButton) // Note: There is an annoying bug where the MediaMessageView will fill the screen if the
addSubview(audioPlayPauseButton) // 'audioPlayPauseButton' is added anywhere within the view hierarchy causing issues with
// the min scale on 'image' and 'animatedImage' file types (assume it's actually any UIButton)
case .url: addSubview(audioPlayPauseButton)
imageView.isHidden = false }
imageView.alpha = 0 // Not 'isHidden' because we want it to take up space in the UIStackView else if attachment.isUrl {
loadingView.isHidden = false imageView.isHidden = false
imageView.alpha = 0 // Not 'isHidden' because we want it to take up space in the UIStackView
if let linkPreviewUrl: String = linkPreviewInfo?.url { loadingView.isHidden = false
// Don't want to change the axis until we have a URL to start loading, otherwise the
// error message will be broken if let linkPreviewUrl: String = linkPreviewInfo?.url {
stackView.axis = .horizontal // Don't want to change the axis until we have a URL to start loading, otherwise the
// error message will be broken
loadLinkPreview(linkPreviewURL: linkPreviewUrl) stackView.axis = .horizontal
}
default: imageView.isHidden = false loadLinkPreview(linkPreviewURL: linkPreviewUrl)
}
}
else {
imageView.isHidden = false
} }
} }
private func setupLayout() { private func setupLayout() {
// Plain text will just be put in the 'message' input so do nothing // Plain text will just be put in the 'message' input so do nothing
guard attachment.fileType != .text && attachment.fileType != .oversizeText else { return } guard !attachment.isText && !attachment.isOversizeText else { return }
// Sizing calculations // Sizing calculations
let clampedRatio: CGFloat = { let clampedRatio: CGFloat = {
switch attachment.fileType { if attachment.isUrl {
case .url: return 1 return 1
case .image, .video, .audio, .unknown:
let imageSize: CGSize = (imageView.image?.size ?? CGSize(width: 1, height: 1))
let aspectRatio: CGFloat = (imageSize.width / imageSize.height)
return CGFloatClamp(aspectRatio, 0.05, 95.0)
case .animatedImage:
let imageSize: CGSize = (animatedImageView.image?.size ?? CGSize(width: 1, height: 1))
let aspectRatio: CGFloat = (imageSize.width / imageSize.height)
return CGFloatClamp(aspectRatio, 0.05, 95.0)
default: return 0
} }
if attachment.isAnimatedImage {
let imageSize: CGSize = (animatedImageView.image?.size ?? CGSize(width: 1, height: 1))
let aspectRatio: CGFloat = (imageSize.width / imageSize.height)
return CGFloatClamp(aspectRatio, 0.05, 95.0)
}
// All other types should maintain the ratio of the image in the 'imageView'
let imageSize: CGSize = (imageView.image?.size ?? CGSize(width: 1, height: 1))
let aspectRatio: CGFloat = (imageSize.width / imageSize.height)
return CGFloatClamp(aspectRatio, 0.05, 95.0)
}() }()
let maybeImageSize: CGFloat? = { let maybeImageSize: CGFloat? = {
switch attachment.fileType { if attachment.isImage || attachment.isVideo {
case .image, .video: if validImage != nil { return nil }
if validImage != nil { return nil }
// If we don't have a valid image then use the 'generic' case
// If we don't have a valid image then use the 'generic' case }
break else if attachment.isAnimatedImage {
if validAnimatedImage != nil { return nil }
case .animatedImage:
if validAnimatedImage != nil { return nil } // If we don't have a valid image then use the 'generic' case
}
// If we don't have a valid image then use the 'generic' case else if attachment.isUrl {
break return 80
case .url: return 80
// Use the 'generic' case for these
case .audio, .unknown: break
default: return nil
} }
// Generic file size // Generic file size
@ -531,7 +518,7 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
]) ])
// No inset for the text for URLs but there is for all other layouts // No inset for the text for URLs but there is for all other layouts
if (attachment.fileType != .url) { if !attachment.isUrl {
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
titleLabel.widthAnchor.constraint(equalTo: stackView.widthAnchor, constant: -(32 * 2)), titleLabel.widthAnchor.constraint(equalTo: stackView.widthAnchor, constant: -(32 * 2)),
subtitleLabel.widthAnchor.constraint(equalTo: stackView.widthAnchor, constant: -(32 * 2)) subtitleLabel.widthAnchor.constraint(equalTo: stackView.widthAnchor, constant: -(32 * 2))
@ -541,7 +528,7 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
// Note: There is an annoying bug where the MediaMessageView will fill the screen if the // Note: There is an annoying bug where the MediaMessageView will fill the screen if the
// 'audioPlayPauseButton' is added anywhere within the view hierarchy causing issues with // 'audioPlayPauseButton' is added anywhere within the view hierarchy causing issues with
// the min scale on 'image' and 'animatedImage' file types (assume it's actually any UIButton) // the min scale on 'image' and 'animatedImage' file types (assume it's actually any UIButton)
if attachment.fileType == .audio { if attachment.isAudio {
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
audioPlayPauseButton.centerXAnchor.constraint(equalTo: imageView.centerXAnchor), audioPlayPauseButton.centerXAnchor.constraint(equalTo: imageView.centerXAnchor),
audioPlayPauseButton.centerYAnchor.constraint(equalTo: imageView.centerYAnchor), audioPlayPauseButton.centerYAnchor.constraint(equalTo: imageView.centerYAnchor),

Loading…
Cancel
Save