Merge branch 'charlesmchen/attachmentProgressVsSendFailures' into release/5.3.3
This commit is contained in:
commit
084e996e61
@ -68,9 +68,8 @@ public class CVComponentBodyMedia: CVComponentBase, CVComponent {
|
||||
let albumView = componentView.albumView
|
||||
albumView.configure(mediaCache: self.mediaCache,
|
||||
items: self.items,
|
||||
isOutgoing: self.isOutgoing,
|
||||
interaction: self.interaction,
|
||||
isBorderless: self.isBorderless,
|
||||
isFromLinkedDevice: self.isFromLinkedDevice,
|
||||
cellMeasurement: cellMeasurement,
|
||||
conversationStyle: conversationStyle)
|
||||
|
||||
|
||||
@ -177,26 +177,31 @@ public class CVComponentGenericAttachment: CVComponentBase, CVComponent {
|
||||
|
||||
private func tryToBuildDownloadView() -> UIView? {
|
||||
|
||||
guard let attachmentPointer = self.attachmentPointer else {
|
||||
let direction: CVAttachmentProgressView.Direction
|
||||
switch CVAttachmentProgressView.progressType(forAttachment: attachment,
|
||||
interaction: interaction) {
|
||||
case .none:
|
||||
return nil
|
||||
}
|
||||
|
||||
switch attachmentPointer.pointerType {
|
||||
case .uploading:
|
||||
// We currently only show progress for downloads here.
|
||||
return nil
|
||||
case .pendingDownload(let attachmentPointer):
|
||||
direction = .download(attachmentPointer: attachmentPointer)
|
||||
case .downloading(let attachmentPointer):
|
||||
direction = .download(attachmentPointer: attachmentPointer)
|
||||
case .restoring:
|
||||
// TODO: Show "restoring" indicator and possibly progress.
|
||||
// TODO: We could easily show progress for restores.
|
||||
owsFailDebug("Restoring progress type.")
|
||||
return nil
|
||||
case .unknown, .incoming:
|
||||
break
|
||||
@unknown default:
|
||||
owsFailDebug("Invalid value.")
|
||||
case .unknown:
|
||||
owsFailDebug("Unknown progress type.")
|
||||
return nil
|
||||
}
|
||||
|
||||
let downloadViewSize = min(iconSize.width, iconSize.height)
|
||||
let progressView = CVAttachmentProgressView(direction: .download(attachmentPointer: attachmentPointer),
|
||||
style: .withoutCircle(diameter: downloadViewSize),
|
||||
conversationStyle: conversationStyle)
|
||||
return progressView
|
||||
return CVAttachmentProgressView(direction: direction,
|
||||
style: .withoutCircle(diameter: downloadViewSize),
|
||||
conversationStyle: conversationStyle)
|
||||
}
|
||||
|
||||
private let hSpacing: CGFloat = 8
|
||||
|
||||
@ -70,13 +70,28 @@ public class CVComponentSticker: CVComponentBase, CVComponent {
|
||||
containerView.addArrangedSubview(mediaView)
|
||||
componentView.layoutConstraints.append(contentsOf: mediaView.autoSetDimensions(to: .square(stickerSize)))
|
||||
|
||||
if isOutgoing, !attachmentStream.isUploaded, !isFromLinkedDevice {
|
||||
switch CVAttachmentProgressView.progressType(forAttachment: attachmentStream,
|
||||
interaction: interaction) {
|
||||
case .none:
|
||||
break
|
||||
case .uploading:
|
||||
let progressView = CVAttachmentProgressView(direction: .upload(attachmentStream: attachmentStream),
|
||||
style: .withCircle,
|
||||
conversationStyle: conversationStyle)
|
||||
containerView.addSubview(progressView)
|
||||
progressView.autoAlignAxis(.horizontal, toSameAxisOf: mediaView)
|
||||
progressView.autoAlignAxis(.vertical, toSameAxisOf: mediaView)
|
||||
case .pendingDownload:
|
||||
break
|
||||
case .downloading:
|
||||
break
|
||||
case .restoring:
|
||||
// TODO: We could easily show progress for restores.
|
||||
owsFailDebug("Restoring progress type.")
|
||||
break
|
||||
case .unknown:
|
||||
owsFailDebug("Unknown progress type.")
|
||||
break
|
||||
}
|
||||
} else if let attachmentPointer = self.attachmentPointer {
|
||||
let placeholderView = UIView()
|
||||
|
||||
@ -451,4 +451,52 @@ public class CVAttachmentProgressView: UIView {
|
||||
stateView.state = .uploadUnknownProgress
|
||||
}
|
||||
}
|
||||
|
||||
public enum ProgressType {
|
||||
case none
|
||||
case uploading(attachmentStream: TSAttachmentStream)
|
||||
case pendingDownload(attachmentPointer: TSAttachmentPointer)
|
||||
case downloading(attachmentPointer: TSAttachmentPointer)
|
||||
case restoring(attachmentPointer: TSAttachmentPointer)
|
||||
case unknown
|
||||
}
|
||||
|
||||
public static func progressType(forAttachment attachment: TSAttachment,
|
||||
interaction: TSInteraction) -> ProgressType {
|
||||
|
||||
if let attachmentStream = attachment as? TSAttachmentStream {
|
||||
if let outgoingMessage = interaction as? TSOutgoingMessage {
|
||||
let hasSendFailed = outgoingMessage.messageState == .failed
|
||||
let isFromLinkedDevice = outgoingMessage.isFromLinkedDevice
|
||||
guard !attachmentStream.isUploaded,
|
||||
!isFromLinkedDevice,
|
||||
!hasSendFailed else {
|
||||
return .none
|
||||
}
|
||||
return .uploading(attachmentStream: attachmentStream)
|
||||
} else if interaction is TSIncomingMessage {
|
||||
return .none
|
||||
} else {
|
||||
owsFailDebug("Unexpected interaction: \(type(of: interaction))")
|
||||
return .unknown
|
||||
}
|
||||
} else if let attachmentPointer = attachment as? TSAttachmentPointer {
|
||||
guard attachmentPointer.pointerType == .incoming else {
|
||||
return .restoring(attachmentPointer: attachmentPointer)
|
||||
}
|
||||
switch attachmentPointer.state {
|
||||
case .pendingMessageRequest, .pendingManualDownload:
|
||||
return .pendingDownload(attachmentPointer: attachmentPointer)
|
||||
case .failed, .enqueued, .downloading:
|
||||
return .downloading(attachmentPointer: attachmentPointer)
|
||||
@unknown default:
|
||||
owsFailDebug("Invalid value.")
|
||||
return .unknown
|
||||
}
|
||||
|
||||
} else {
|
||||
owsFailDebug("Unexpected attachment: \(type(of: attachment))")
|
||||
return .unknown
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,9 +26,8 @@ public class CVMediaAlbumView: UIStackView {
|
||||
|
||||
public func configure(mediaCache: CVMediaCache,
|
||||
items: [CVMediaAlbumItem],
|
||||
isOutgoing: Bool,
|
||||
interaction: TSInteraction,
|
||||
isBorderless: Bool,
|
||||
isFromLinkedDevice: Bool,
|
||||
cellMeasurement: CVCellMeasurement,
|
||||
conversationStyle: ConversationStyle) {
|
||||
|
||||
@ -41,10 +40,9 @@ public class CVMediaAlbumView: UIStackView {
|
||||
self.itemViews = CVMediaAlbumView.itemsToDisplay(forItems: items).map {
|
||||
CVMediaView(mediaCache: mediaCache,
|
||||
attachment: $0.attachment,
|
||||
isOutgoing: isOutgoing,
|
||||
interaction: interaction,
|
||||
maxMessageWidth: maxMessageWidth,
|
||||
isBorderless: isBorderless,
|
||||
isFromLinkedDevice: isFromLinkedDevice,
|
||||
conversationStyle: conversationStyle)
|
||||
}
|
||||
self.isBorderless = isBorderless
|
||||
|
||||
@ -16,11 +16,10 @@ public class CVMediaView: UIView {
|
||||
|
||||
private let mediaCache: CVMediaCache
|
||||
public let attachment: TSAttachment
|
||||
private let interaction: TSInteraction
|
||||
private let conversationStyle: ConversationStyle
|
||||
private let isOutgoing: Bool
|
||||
private let maxMessageWidth: CGFloat
|
||||
private let isBorderless: Bool
|
||||
private let isFromLinkedDevice: Bool
|
||||
|
||||
private var reusableMediaView: ReusableMediaView?
|
||||
|
||||
@ -28,17 +27,15 @@ public class CVMediaView: UIView {
|
||||
|
||||
public required init(mediaCache: CVMediaCache,
|
||||
attachment: TSAttachment,
|
||||
isOutgoing: Bool,
|
||||
interaction: TSInteraction,
|
||||
maxMessageWidth: CGFloat,
|
||||
isBorderless: Bool,
|
||||
isFromLinkedDevice: Bool,
|
||||
conversationStyle: ConversationStyle) {
|
||||
self.mediaCache = mediaCache
|
||||
self.attachment = attachment
|
||||
self.isOutgoing = isOutgoing
|
||||
self.interaction = interaction
|
||||
self.maxMessageWidth = maxMessageWidth
|
||||
self.isBorderless = isBorderless
|
||||
self.isFromLinkedDevice = isFromLinkedDevice
|
||||
self.conversationStyle = conversationStyle
|
||||
|
||||
super.init(frame: .zero)
|
||||
@ -77,49 +74,40 @@ public class CVMediaView: UIView {
|
||||
private func configureForUndownloadedMedia() {
|
||||
tryToConfigureForBlurHash(attachment: attachment)
|
||||
|
||||
guard let attachmentPointer = attachment as? TSAttachmentPointer else {
|
||||
owsFailDebug("Attachment has unexpected type.")
|
||||
configure(forError: .invalid)
|
||||
return
|
||||
}
|
||||
guard attachmentPointer.pointerType == .incoming else {
|
||||
// TODO: Show "restoring" indicator and possibly progress.
|
||||
configure(forError: .missing)
|
||||
return
|
||||
}
|
||||
switch attachmentPointer.state {
|
||||
case .pendingMessageRequest, .pendingManualDownload:
|
||||
_ = addProgressIfNecessary()
|
||||
}
|
||||
|
||||
private func addProgressIfNecessary() -> Bool {
|
||||
|
||||
let direction: CVAttachmentProgressView.Direction
|
||||
switch CVAttachmentProgressView.progressType(forAttachment: attachment,
|
||||
interaction: interaction) {
|
||||
case .none:
|
||||
return false
|
||||
case .uploading(let attachmentStream):
|
||||
direction = .upload(attachmentStream: attachmentStream)
|
||||
case .pendingDownload:
|
||||
// We don't need to add a download indicator for pending
|
||||
// attachments; CVComponentBodyMedia will add a download
|
||||
// button if any media in the gallery is pending.
|
||||
return
|
||||
case .failed, .enqueued, .downloading:
|
||||
break
|
||||
@unknown default:
|
||||
owsFailDebug("Invalid value.")
|
||||
}
|
||||
return false
|
||||
case .downloading(let attachmentPointer):
|
||||
backgroundColor = (Theme.isDarkThemeEnabled ? .ows_gray90 : .ows_gray05)
|
||||
|
||||
backgroundColor = (Theme.isDarkThemeEnabled ? .ows_gray90 : .ows_gray05)
|
||||
let progressView = CVAttachmentProgressView(direction: .download(attachmentPointer: attachmentPointer),
|
||||
style: .withCircle,
|
||||
conversationStyle: conversationStyle)
|
||||
self.addSubview(progressView)
|
||||
progressView.autoCenterInSuperview()
|
||||
}
|
||||
|
||||
private func addUploadProgressIfNecessary(_ subview: UIView) -> Bool {
|
||||
guard let attachmentStream = attachment as? TSAttachmentStream else {
|
||||
direction = .download(attachmentPointer: attachmentPointer)
|
||||
case .restoring:
|
||||
// TODO: We could easily show progress for restores.
|
||||
owsFailDebug("Restoring progress type.")
|
||||
return false
|
||||
case .unknown:
|
||||
owsFailDebug("Unknown progress type.")
|
||||
return false
|
||||
}
|
||||
guard isOutgoing,
|
||||
!attachmentStream.isUploaded,
|
||||
!isFromLinkedDevice else {
|
||||
return false
|
||||
}
|
||||
let progressView = CVAttachmentProgressView(direction: .upload(attachmentStream: attachmentStream),
|
||||
|
||||
let progressView = CVAttachmentProgressView(direction: direction,
|
||||
style: .withCircle,
|
||||
conversationStyle: conversationStyle)
|
||||
self.addSubview(progressView)
|
||||
addSubview(progressView)
|
||||
progressView.autoCenterInSuperview()
|
||||
return true
|
||||
}
|
||||
@ -145,7 +133,7 @@ public class CVMediaView: UIView {
|
||||
}
|
||||
mediaView.backgroundColor = isBorderless ? .clear : Theme.washColor
|
||||
|
||||
if !addUploadProgressIfNecessary(mediaView) {
|
||||
if !addProgressIfNecessary() {
|
||||
if reusableMediaView.isVideo {
|
||||
let videoPlayButton = Self.buildVideoPlayButton()
|
||||
addSubview(videoPlayButton)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user