Addressed PR changes
Added NVActivityIndicatorView to the SessionShareExtension. Removed the SignalAttachmentType.
This commit is contained in:
parent
a7661da41a
commit
2fedba4cea
1
Podfile
1
Podfile
|
@ -22,6 +22,7 @@ target 'SessionShareExtension' do
|
|||
pod 'CryptoSwift', :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 'NVActivityIndicatorView', :inhibit_warnings => true
|
||||
pod 'PromiseKit', :inhibit_warnings => true
|
||||
pod 'PureLayout', '~> 3.1.8', :inhibit_warnings => true
|
||||
pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true
|
||||
|
|
11
Podfile.lock
11
Podfile.lock
|
@ -29,6 +29,7 @@ PODS:
|
|||
- NVActivityIndicatorView (5.0.1):
|
||||
- NVActivityIndicatorView/Base (= 5.0.1)
|
||||
- NVActivityIndicatorView/Base (5.0.1)
|
||||
- OpenSSL-Universal (1.1.1200)
|
||||
- PromiseKit (6.13.1):
|
||||
- PromiseKit/CorePromise (= 6.13.1)
|
||||
- PromiseKit/Foundation (= 6.13.1)
|
||||
|
@ -43,7 +44,7 @@ PODS:
|
|||
- SAMKeychain (1.5.3)
|
||||
- SignalCoreKit (1.0.0):
|
||||
- CocoaLumberjack
|
||||
- GRKOpenSSLFramework
|
||||
- OpenSSL-Universal
|
||||
- Sodium (0.8.0)
|
||||
- SQLCipher (4.4.0):
|
||||
- SQLCipher/standard (= 4.4.0)
|
||||
|
@ -147,6 +148,7 @@ SPEC REPOS:
|
|||
- GRKOpenSSLFramework
|
||||
- HKDFKit
|
||||
- NVActivityIndicatorView
|
||||
- OpenSSL-Universal
|
||||
- PromiseKit
|
||||
- PureLayout
|
||||
- Reachability
|
||||
|
@ -196,11 +198,12 @@ SPEC CHECKSUMS:
|
|||
HKDFKit: c058305d6f64b84f28c50bd7aa89574625bcb62a
|
||||
Mantle: 2fa750afa478cd625a94230fbf1c13462f29395b
|
||||
NVActivityIndicatorView: 738e843cb8924e9e4fc3e559d0728031624bf860
|
||||
OpenSSL-Universal: 3b8c0d6268fbd5d3ac44f97338e2fd16a73d9dbf
|
||||
PromiseKit: 28fda91c973cc377875d8c0ea4f973013c05b6db
|
||||
PureLayout: a4afb3d79dd958564ce33d22c89f407280d8e6a8
|
||||
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
|
||||
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
|
||||
SignalCoreKit: 4562b2bbd9830077439ca003f952a798457d4ea5
|
||||
SignalCoreKit: 1fbd8732163ef76de16cd1107d1fa3684b607e5d
|
||||
Sodium: 63c0ca312a932e6da481689537d4b35568841bdc
|
||||
SQLCipher: e434ed542b24f38ea7b36468a13f9765e1b5c072
|
||||
SwiftProtobuf: 241400280f912735c1e1b9fe675fdd2c6c4d42e2
|
||||
|
@ -208,6 +211,6 @@ SPEC CHECKSUMS:
|
|||
YYImage: 6db68da66f20d9f169ceb94dfb9947c3867b9665
|
||||
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
|
||||
}
|
||||
|
||||
@objc
|
||||
public enum SignalAttachmentType: Int {
|
||||
case text
|
||||
case oversizeText
|
||||
case image
|
||||
case animatedImage
|
||||
case video
|
||||
case audio
|
||||
case url
|
||||
case unknown
|
||||
}
|
||||
|
||||
extension String {
|
||||
public var filenameWithoutExtension: String {
|
||||
return (self as NSString).deletingPathExtension
|
||||
|
@ -446,19 +434,6 @@ public class SignalAttachment: NSObject {
|
|||
private class var mediaUTISet: Set<String> {
|
||||
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
|
||||
public var isImage: Bool {
|
||||
|
|
|
@ -44,37 +44,36 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
|
|||
}
|
||||
|
||||
private lazy var validImage: UIImage? = {
|
||||
switch attachment.fileType {
|
||||
case .image:
|
||||
guard
|
||||
attachment.isValidImage,
|
||||
let image: UIImage = attachment.image(),
|
||||
image.size.width > 0,
|
||||
image.size.height > 0
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return image
|
||||
|
||||
case .video:
|
||||
guard
|
||||
attachment.isValidVideo,
|
||||
let image: UIImage = attachment.videoPreview(),
|
||||
image.size.width > 0,
|
||||
image.size.height > 0
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return image
|
||||
if attachment.isImage {
|
||||
guard
|
||||
attachment.isValidImage,
|
||||
let image: UIImage = attachment.image(),
|
||||
image.size.width > 0,
|
||||
image.size.height > 0
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
default: return nil
|
||||
return image
|
||||
}
|
||||
else if attachment.isVideo {
|
||||
guard
|
||||
attachment.isValidVideo,
|
||||
let image: UIImage = attachment.videoPreview(),
|
||||
image.size.width > 0,
|
||||
image.size.height > 0
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return image
|
||||
}
|
||||
|
||||
return nil
|
||||
}()
|
||||
private lazy var validAnimatedImage: YYImage? = {
|
||||
guard
|
||||
attachment.fileType == .animatedImage,
|
||||
attachment.isAnimatedImage,
|
||||
attachment.isValidImage,
|
||||
let dataUrl: URL = attachment.dataUrl,
|
||||
let image: YYImage = YYImage(contentsOfFile: dataUrl.path),
|
||||
|
@ -153,22 +152,19 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
|
|||
view.isHidden = true
|
||||
|
||||
// Override the image to the correct one
|
||||
switch attachment.fileType {
|
||||
case .image, .video:
|
||||
if let validImage: UIImage = validImage {
|
||||
view.layer.minificationFilter = .trilinear
|
||||
view.layer.magnificationFilter = .trilinear
|
||||
view.image = validImage
|
||||
}
|
||||
|
||||
case .url:
|
||||
view.clipsToBounds = true
|
||||
view.image = UIImage(named: "Link")?.withTint(Colors.text)
|
||||
view.contentMode = .center
|
||||
view.backgroundColor = (isDarkMode ? .black : UIColor.black.withAlphaComponent(0.06))
|
||||
view.layer.cornerRadius = 8
|
||||
|
||||
default: break
|
||||
if attachment.isImage || attachment.isVideo {
|
||||
if let validImage: UIImage = validImage {
|
||||
view.layer.minificationFilter = .trilinear
|
||||
view.layer.magnificationFilter = .trilinear
|
||||
view.image = validImage
|
||||
}
|
||||
}
|
||||
else if attachment.isUrl {
|
||||
view.clipsToBounds = true
|
||||
view.image = UIImage(named: "Link")?.withTint(Colors.text)
|
||||
view.contentMode = .center
|
||||
view.backgroundColor = (isDarkMode ? .black : UIColor.black.withAlphaComponent(0.06))
|
||||
view.layer.cornerRadius = 8
|
||||
}
|
||||
|
||||
return view
|
||||
|
@ -225,7 +221,7 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
|
|||
let stackView: UIStackView = UIStackView()
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
stackView.axis = .vertical
|
||||
stackView.alignment = (attachment.fileType == .url ? .leading : .center)
|
||||
stackView.alignment = (attachment.isUrl ? .leading : .center)
|
||||
stackView.distribution = .fill
|
||||
|
||||
switch mode {
|
||||
|
@ -257,35 +253,33 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
|
|||
}
|
||||
|
||||
// Content
|
||||
switch attachment.fileType {
|
||||
case .image, .animatedImage, .video: break // No title for these
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
if attachment.isUrl {
|
||||
// If we have no link preview info at this point then assume link previews are disabled
|
||||
if let linkPreviewURL: String = linkPreviewInfo?.url {
|
||||
label.font = .boldSystemFont(ofSize: Values.smallFontSize)
|
||||
label.text = linkPreviewURL
|
||||
label.textAlignment = .left
|
||||
label.lineBreakMode = .byTruncatingTail
|
||||
label.numberOfLines = 2
|
||||
|
||||
default:
|
||||
if let fileName: String = attachment.sourceFilename?.trimmingCharacters(in: .whitespacesAndNewlines), fileName.count > 0 {
|
||||
label.text = fileName
|
||||
}
|
||||
else if let fileExtension: String = attachment.fileExtension {
|
||||
label.text = String(
|
||||
format: "ATTACHMENT_APPROVAL_FILE_EXTENSION_FORMAT".localized(),
|
||||
fileExtension.uppercased()
|
||||
)
|
||||
}
|
||||
|
||||
label.textAlignment = .center
|
||||
label.lineBreakMode = .byTruncatingMiddle
|
||||
}
|
||||
else {
|
||||
label.text = "vc_share_link_previews_disabled_title".localized()
|
||||
}
|
||||
}
|
||||
// Title for everything except these types
|
||||
else if !attachment.isImage && !attachment.isAnimatedImage && !attachment.isVideo {
|
||||
if let fileName: String = attachment.sourceFilename?.trimmingCharacters(in: .whitespacesAndNewlines), fileName.count > 0 {
|
||||
label.text = fileName
|
||||
}
|
||||
else if let fileExtension: String = attachment.fileExtension {
|
||||
label.text = String(
|
||||
format: "ATTACHMENT_APPROVAL_FILE_EXTENSION_FORMAT".localized(),
|
||||
fileExtension.uppercased()
|
||||
)
|
||||
}
|
||||
|
||||
label.textAlignment = .center
|
||||
label.lineBreakMode = .byTruncatingMiddle
|
||||
}
|
||||
|
||||
// Hide the label if it has no content
|
||||
|
@ -314,32 +308,30 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
|
|||
}
|
||||
|
||||
// Content
|
||||
switch attachment.fileType {
|
||||
case .image, .animatedImage, .video: break // No size for these
|
||||
|
||||
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 attachment.isUrl {
|
||||
// We only load Link Previews for HTTPS urls so append an explanation for not
|
||||
if let linkPreviewURL: String = linkPreviewInfo?.url {
|
||||
if let targetUrl: URL = URL(string: linkPreviewURL), targetUrl.scheme?.lowercased() != "https" {
|
||||
label.font = UIFont.ows_regularFont(withSize: Values.verySmallFontSize)
|
||||
label.text = "vc_share_link_previews_unsecure".localized()
|
||||
label.textColor = (mode == .attachmentApproval ? Colors.pinIcon : Colors.accent)
|
||||
}
|
||||
|
||||
default:
|
||||
// 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)))
|
||||
}
|
||||
// If we have no link preview info at this point then assume link previews are disabled
|
||||
else {
|
||||
label.text = "vc_share_link_previews_disabled_explanation".localized()
|
||||
label.textColor = Colors.text
|
||||
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
|
||||
|
@ -352,7 +344,7 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
|
|||
|
||||
private func setupViews() {
|
||||
// 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
|
||||
addSubview(stackView)
|
||||
|
@ -370,95 +362,90 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
|
|||
imageView.addSubview(fileTypeImageView)
|
||||
|
||||
// Type-specific configurations
|
||||
switch attachment.fileType {
|
||||
case .animatedImage: animatedImageView.isHidden = false
|
||||
case .image: imageView.isHidden = false
|
||||
if attachment.isAnimatedImage {
|
||||
animatedImageView.isHidden = false
|
||||
}
|
||||
else if attachment.isImage {
|
||||
imageView.isHidden = false
|
||||
}
|
||||
else if attachment.isVideo {
|
||||
// Note: The 'attachmentApproval' mode provides it's own play button to keep
|
||||
// it at the proper scale when zooming
|
||||
imageView.isHidden = false
|
||||
videoPlayButton.isHidden = (mode == .attachmentApproval)
|
||||
}
|
||||
else if attachment.isAudio {
|
||||
// Hide the 'audioPlayPauseButton' if the 'audioPlayer' failed to get created
|
||||
imageView.isHidden = false
|
||||
audioPlayPauseButton.isHidden = (audioPlayer == nil)
|
||||
setAudioIconToPlay()
|
||||
setAudioProgress(0, duration: (audioPlayer?.duration ?? 0))
|
||||
|
||||
fileTypeImageView.image = UIImage(named: "table_ic_notification_sound")?
|
||||
.withRenderingMode(.alwaysTemplate)
|
||||
fileTypeImageView.tintColor = Colors.text
|
||||
fileTypeImageView.isHidden = false
|
||||
|
||||
// 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
|
||||
// the min scale on 'image' and 'animatedImage' file types (assume it's actually any UIButton)
|
||||
addSubview(audioPlayPauseButton)
|
||||
}
|
||||
else if attachment.isUrl {
|
||||
imageView.isHidden = false
|
||||
imageView.alpha = 0 // Not 'isHidden' because we want it to take up space in the UIStackView
|
||||
loadingView.isHidden = false
|
||||
|
||||
if let linkPreviewUrl: String = linkPreviewInfo?.url {
|
||||
// Don't want to change the axis until we have a URL to start loading, otherwise the
|
||||
// error message will be broken
|
||||
stackView.axis = .horizontal
|
||||
|
||||
case .video:
|
||||
// Note: The 'attachmentApproval' mode provides it's own play button to keep
|
||||
// it at the proper scale when zooming
|
||||
imageView.isHidden = false
|
||||
videoPlayButton.isHidden = (mode == .attachmentApproval)
|
||||
|
||||
case .audio:
|
||||
// Hide the 'audioPlayPauseButton' if the 'audioPlayer' failed to get created
|
||||
imageView.isHidden = false
|
||||
audioPlayPauseButton.isHidden = (audioPlayer == nil)
|
||||
setAudioIconToPlay()
|
||||
setAudioProgress(0, duration: (audioPlayer?.duration ?? 0))
|
||||
|
||||
fileTypeImageView.image = UIImage(named: "table_ic_notification_sound")?
|
||||
.withRenderingMode(.alwaysTemplate)
|
||||
fileTypeImageView.tintColor = Colors.text
|
||||
fileTypeImageView.isHidden = false
|
||||
|
||||
// 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
|
||||
// the min scale on 'image' and 'animatedImage' file types (assume it's actually any UIButton)
|
||||
addSubview(audioPlayPauseButton)
|
||||
|
||||
case .url:
|
||||
imageView.isHidden = false
|
||||
imageView.alpha = 0 // Not 'isHidden' because we want it to take up space in the UIStackView
|
||||
loadingView.isHidden = false
|
||||
|
||||
if let linkPreviewUrl: String = linkPreviewInfo?.url {
|
||||
// Don't want to change the axis until we have a URL to start loading, otherwise the
|
||||
// error message will be broken
|
||||
stackView.axis = .horizontal
|
||||
|
||||
loadLinkPreview(linkPreviewURL: linkPreviewUrl)
|
||||
}
|
||||
|
||||
default: imageView.isHidden = false
|
||||
loadLinkPreview(linkPreviewURL: linkPreviewUrl)
|
||||
}
|
||||
}
|
||||
else {
|
||||
imageView.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
private func setupLayout() {
|
||||
// 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
|
||||
let clampedRatio: CGFloat = {
|
||||
switch attachment.fileType {
|
||||
case .url: 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.isUrl {
|
||||
return 1
|
||||
}
|
||||
|
||||
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? = {
|
||||
switch attachment.fileType {
|
||||
case .image, .video:
|
||||
if validImage != nil { return nil }
|
||||
|
||||
// If we don't have a valid image then use the 'generic' case
|
||||
break
|
||||
|
||||
case .animatedImage:
|
||||
if validAnimatedImage != nil { return nil }
|
||||
|
||||
// If we don't have a valid image then use the 'generic' case
|
||||
break
|
||||
|
||||
case .url: return 80
|
||||
|
||||
// Use the 'generic' case for these
|
||||
case .audio, .unknown: break
|
||||
|
||||
default: return nil
|
||||
if attachment.isImage || attachment.isVideo {
|
||||
if validImage != nil { return nil }
|
||||
|
||||
// If we don't have a valid image then use the 'generic' case
|
||||
}
|
||||
else if attachment.isAnimatedImage {
|
||||
if validAnimatedImage != nil { return nil }
|
||||
|
||||
// If we don't have a valid image then use the 'generic' case
|
||||
}
|
||||
else if attachment.isUrl {
|
||||
return 80
|
||||
}
|
||||
|
||||
// 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
|
||||
if (attachment.fileType != .url) {
|
||||
if !attachment.isUrl {
|
||||
NSLayoutConstraint.activate([
|
||||
titleLabel.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
|
||||
// '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)
|
||||
if attachment.fileType == .audio {
|
||||
if attachment.isAudio {
|
||||
NSLayoutConstraint.activate([
|
||||
audioPlayPauseButton.centerXAnchor.constraint(equalTo: imageView.centerXAnchor),
|
||||
audioPlayPauseButton.centerYAnchor.constraint(equalTo: imageView.centerYAnchor),
|
||||
|
|
Loading…
Reference in New Issue