Restore blur to cover content warned GIFs

Also, do not create a player view until actually needed (lazy var caused one to be created during prepareForReuse(), just to be able to call removeFromSuperview() on it).

Fixes  #1377 [BUG] Content warning for gifs doesn't blur consistently
This commit is contained in:
shannon 2024-12-16 11:43:24 -05:00
parent e4214f78a5
commit d5e8300066
3 changed files with 35 additions and 18 deletions

View File

@ -180,7 +180,7 @@ extension MediaView.Configuration {
}
extension MediaView {
public static func configuration(status: MastodonStatus) -> [MediaView.Configuration] {
public static func configuration(status: MastodonStatus, contentDisplayMode: StatusView.ContentDisplayMode) -> [MediaView.Configuration] {
func videoInfo(from attachment: MastodonAttachment) -> MediaView.Configuration.VideoInfo {
MediaView.Configuration.VideoInfo(
aspectRadio: attachment.size,
@ -234,6 +234,7 @@ extension MediaView {
} // end switch
}()
configuration.isReveal = !contentDisplayMode.shouldConcealMedia
configuration.load()
return configuration
@ -244,7 +245,7 @@ extension MediaView {
}
extension MediaView {
public static func configuration(status: Mastodon.Entity.StatusEdit) -> [MediaView.Configuration] {
public static func configuration(status: Mastodon.Entity.StatusEdit, contentDisplayMode: StatusView.ContentDisplayMode) -> [MediaView.Configuration] {
func aspectRatio(from attachment: Mastodon.Entity.Attachment) -> CGSize? {
if let width = attachment.meta?.original?.width, let height = attachment.meta?.original?.height {
return CGSize(width: width, height: height)
@ -317,7 +318,7 @@ extension MediaView {
}()
configuration?.load()
configuration?.isReveal = true
configuration?.isReveal = !contentDisplayMode.shouldConcealMedia
return configuration
}

View File

@ -43,15 +43,17 @@ public final class MediaView: UIView {
return imageView
}()
private(set) lazy var playerViewController: AVPlayerViewController = {
private(set) var playerViewController: AVPlayerViewController?
private var playerLooper: AVPlayerLooper?
private func createPlayerViewController() -> AVPlayerViewController {
let playerViewController = AVPlayerViewController()
playerViewController.view.layer.masksToBounds = true
playerViewController.view.isUserInteractionEnabled = false
playerViewController.videoGravity = .resizeAspectFill
playerViewController.updatesNowPlayingInfoCenter = false
return playerViewController
}()
private var playerLooper: AVPlayerLooper?
}
let overlayViewController: UIHostingController<InlineMediaOverlayContainer> = {
let vc = UIHostingController(rootView: InlineMediaOverlayContainer())
@ -152,6 +154,10 @@ extension MediaView {
private func layoutGIF() {
// use view controller as View here
if playerViewController == nil {
playerViewController = createPlayerViewController()
}
guard let playerViewController else { return }
playerViewController.view.translatesAutoresizingMaskIntoConstraints = false
container.addSubview(playerViewController.view)
playerViewController.view.pinToParent()
@ -165,11 +171,21 @@ extension MediaView {
guard let player = setupGIFPlayer(info: info) else { return }
setupPlayerLooper(player: player)
if playerViewController == nil {
playerViewController = createPlayerViewController()
}
guard let playerViewController else { return }
playerViewController.player = player
playerViewController.showsPlaybackControls = false
// auto play for GIF
player.play()
if configuration.isReveal {
blurhashImageView.alpha = 0
player.play()
} else {
blurhashImageView.alpha = 1
}
bindAlt(configuration: configuration, altDescription: info.altDescription)
}
@ -241,12 +257,12 @@ extension MediaView {
imageView.image = nil
// reset player
playerViewController.view.removeFromSuperview()
playerViewController.contentOverlayView.flatMap { view in
playerViewController?.view.removeFromSuperview()
playerViewController?.contentOverlayView.flatMap { view in
view.removeConstraints(view.constraints)
}
playerViewController.player?.pause()
playerViewController.player = nil
playerViewController?.player?.pause()
playerViewController?.player = nil
playerLooper = nil
// blurhash

View File

@ -49,12 +49,12 @@ extension StatusView {
configureAuthor(author: author)
configureTimestamp(timestamp: (status.reblog ?? status).entity.createdAt)
configureApplicationName(status.entity.application?.name)
configureMedia(status: status)
configureMedia(status: status, contentDisplayMode: contentDisplayMode)
configurePollHistory(statusEdit: statusEdit)
configureCard(status: status)
configureToolbar(status: status)
configureContent(statusEdit: statusEdit, status: status)
configureMedia(status: statusEdit)
configureMedia(status: statusEdit, contentDisplayMode: contentDisplayMode)
actionToolbarAdaptiveMarginContainerView.isHidden = true
authorView.menuButton.isHidden = true
headerAdaptiveMarginContainerView.isHidden = true
@ -72,7 +72,7 @@ extension StatusView {
configureTimestamp(timestamp: timestamp)
configureApplicationName(status.entity.application?.name)
configureContent(status: status)
configureMedia(status: status)
configureMedia(status: status, contentDisplayMode: contentDisplayMode)
configurePoll(status: status)
configureCard(status: status)
configureToolbar(status: status)
@ -451,14 +451,14 @@ extension StatusView {
viewModel.visibility = status.entity.mastodonVisibility
}
private func configureMedia(status: MastodonStatus) {
private func configureMedia(status: MastodonStatus, contentDisplayMode: ContentDisplayMode) {
let status = status.reblog ?? status
let configurations = MediaView.configuration(status: status)
let configurations = MediaView.configuration(status: status, contentDisplayMode: contentDisplayMode)
viewModel.mediaViewConfigurations = configurations
}
private func configureMedia(status: Mastodon.Entity.StatusEdit) {
let configurations = MediaView.configuration(status: status)
private func configureMedia(status: Mastodon.Entity.StatusEdit, contentDisplayMode: ContentDisplayMode) {
let configurations = MediaView.configuration(status: status, contentDisplayMode: contentDisplayMode)
viewModel.mediaViewConfigurations = configurations
}