fix: make blurhash display before video thumbnail ready
This commit is contained in:
parent
a1b553a05d
commit
f2795c035a
@ -27,7 +27,7 @@ public final class Attachment: NSManagedObject {
|
||||
@NSManaged public private(set) var updatedAt: Date
|
||||
@NSManaged public private(set) var index: NSNumber
|
||||
|
||||
// many-to-one relastionship
|
||||
// many-to-one relationship
|
||||
@NSManaged public private(set) var status: Status?
|
||||
|
||||
}
|
||||
|
@ -375,7 +375,7 @@ extension StatusSection {
|
||||
return containerFrame.width
|
||||
}()
|
||||
let scale: CGFloat = 1.3
|
||||
return CGSize(width: maxWidth, height: maxWidth * scale)
|
||||
return CGSize(width: maxWidth, height: floor(maxWidth * scale))
|
||||
}()
|
||||
|
||||
if let videoAttachment = mediaAttachments.filter({ $0.type == .gifv || $0.type == .video }).first,
|
||||
@ -415,6 +415,28 @@ extension StatusSection {
|
||||
}
|
||||
playerContainerView.isHidden = false
|
||||
|
||||
// set blurhash overlay
|
||||
playerContainerView.isReadyForDisplay
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak playerContainerView] isReadyForDisplay in
|
||||
guard let playerContainerView = playerContainerView else { return }
|
||||
playerContainerView.blurhashOverlayImageView.alpha = isReadyForDisplay ? 0 : 1
|
||||
}
|
||||
.store(in: &cell.disposeBag)
|
||||
|
||||
if let blurhash = videoAttachment.blurhash,
|
||||
let url = URL(string: videoAttachment.url) {
|
||||
AppContext.shared.blurhashImageCacheService.image(
|
||||
blurhash: blurhash,
|
||||
size: playerContainerView.playerViewController.view.frame.size,
|
||||
url: url
|
||||
)
|
||||
.sink { image in
|
||||
playerContainerView.blurhashOverlayImageView.image = image
|
||||
}
|
||||
.store(in: &cell.disposeBag)
|
||||
}
|
||||
|
||||
} else {
|
||||
cell.statusView.playerContainerView.playerViewController.player?.pause()
|
||||
cell.statusView.playerContainerView.playerViewController.player = nil
|
||||
|
@ -8,6 +8,7 @@
|
||||
import os.log
|
||||
import AVKit
|
||||
import UIKit
|
||||
import Combine
|
||||
|
||||
protocol PlayerContainerViewDelegate: AnyObject {
|
||||
func playerContainerView(_ playerContainerView: PlayerContainerView, contentWarningOverlayViewDidPressed contentWarningOverlayView: ContentWarningOverlayView)
|
||||
@ -28,10 +29,14 @@ final class PlayerContainerView: UIView {
|
||||
|
||||
let playerViewController = AVPlayerViewController()
|
||||
|
||||
let blurhashOverlayImageView = UIImageView()
|
||||
let mediaTypeIndicatorView = MediaTypeIndicatorView()
|
||||
|
||||
weak var delegate: PlayerContainerViewDelegate?
|
||||
|
||||
private var isReadyForDisplayObservation: NSKeyValueObservation?
|
||||
let isReadyForDisplay = CurrentValueSubject<Bool, Never>(false)
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
_init()
|
||||
@ -64,6 +69,15 @@ extension PlayerContainerView {
|
||||
playerViewController.view.layer.cornerRadius = PlayerContainerView.cornerRadius
|
||||
playerViewController.view.layer.cornerCurve = .continuous
|
||||
|
||||
blurhashOverlayImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
playerViewController.contentOverlayView!.addSubview(blurhashOverlayImageView)
|
||||
NSLayoutConstraint.activate([
|
||||
blurhashOverlayImageView.topAnchor.constraint(equalTo: playerViewController.contentOverlayView!.topAnchor),
|
||||
blurhashOverlayImageView.leadingAnchor.constraint(equalTo: playerViewController.contentOverlayView!.leadingAnchor),
|
||||
blurhashOverlayImageView.trailingAnchor.constraint(equalTo: playerViewController.contentOverlayView!.trailingAnchor),
|
||||
blurhashOverlayImageView.bottomAnchor.constraint(equalTo: playerViewController.contentOverlayView!.bottomAnchor),
|
||||
])
|
||||
|
||||
// mediaType
|
||||
mediaTypeIndicatorView.translatesAutoresizingMaskIntoConstraints = false
|
||||
playerViewController.contentOverlayView!.addSubview(mediaTypeIndicatorView)
|
||||
@ -74,6 +88,12 @@ extension PlayerContainerView {
|
||||
mediaTypeIndicatorView.widthAnchor.constraint(equalToConstant: MediaTypeIndicatorView.indicatorViewSize.width).priority(.required - 1),
|
||||
])
|
||||
|
||||
isReadyForDisplayObservation = playerViewController.observe(\.isReadyForDisplay, options: [.initial, .new]) { [weak self] playerViewController, _ in
|
||||
guard let self = self else { return }
|
||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: isReadyForDisplay: %s", (#file as NSString).lastPathComponent, #line, #function, playerViewController.isReadyForDisplay.description)
|
||||
self.isReadyForDisplay.value = playerViewController.isReadyForDisplay
|
||||
}
|
||||
|
||||
contentWarningOverlayView.delegate = self
|
||||
}
|
||||
}
|
||||
@ -94,6 +114,8 @@ extension PlayerContainerView {
|
||||
playerViewController.view.removeFromSuperview()
|
||||
playerViewController.removeFromParent()
|
||||
|
||||
blurhashOverlayImageView.image = nil
|
||||
|
||||
container.subviews.forEach { subview in
|
||||
subview.removeFromSuperview()
|
||||
}
|
||||
@ -113,7 +135,7 @@ extension PlayerContainerView {
|
||||
let rect = AVMakeRect(
|
||||
aspectRatio: aspectRatio,
|
||||
insideRect: CGRect(origin: .zero, size: maxSize)
|
||||
)
|
||||
).integral
|
||||
|
||||
parent?.addChild(playerViewController)
|
||||
playerViewController.view.translatesAutoresizingMaskIntoConstraints = false
|
||||
@ -124,11 +146,13 @@ extension PlayerContainerView {
|
||||
playerViewController.view.leadingAnchor.constraint(equalTo: touchBlockingView.leadingAnchor),
|
||||
playerViewController.view.trailingAnchor.constraint(equalTo: touchBlockingView.trailingAnchor),
|
||||
playerViewController.view.bottomAnchor.constraint(equalTo: touchBlockingView.bottomAnchor),
|
||||
touchBlockingView.widthAnchor.constraint(equalToConstant: floor(rect.width)).priority(.required - 1),
|
||||
touchBlockingView.widthAnchor.constraint(equalToConstant: rect.width).priority(.required - 1),
|
||||
])
|
||||
containerHeightLayoutConstraint.constant = floor(rect.height)
|
||||
containerHeightLayoutConstraint.constant = rect.height
|
||||
containerHeightLayoutConstraint.isActive = true
|
||||
|
||||
playerViewController.view.frame.size = rect.size
|
||||
|
||||
contentWarningOverlayView.removeFromSuperview()
|
||||
contentWarningOverlayView.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(contentWarningOverlayView)
|
||||
|
Loading…
x
Reference in New Issue
Block a user