From 81a1028f20043ef543d10c5ce5e1a200c649e217 Mon Sep 17 00:00:00 2001 From: CMK Date: Mon, 19 Apr 2021 18:33:11 +0800 Subject: [PATCH] feat: pause video playback when set reveal state to false --- Mastodon/Diffiable/Item/Item.swift | 2 +- .../Diffiable/Section/StatusSection.swift | 19 +++++++++---------- ...Provider+StatusTableViewCellDelegate.swift | 5 ++--- .../StatusProvider/StatusProviderFacade.swift | 6 ++++++ .../Container/MosaicImageViewContainer.swift | 2 ++ .../View/Container/PlayerContainerView.swift | 1 + .../Content/ContentWarningOverlayView.swift | 14 +++++++++++++- .../TableviewCell/StatusTableViewCell.swift | 4 ++++ 8 files changed, 38 insertions(+), 15 deletions(-) diff --git a/Mastodon/Diffiable/Item/Item.swift b/Mastodon/Diffiable/Item/Item.swift index cb01ccdc..e169be66 100644 --- a/Mastodon/Diffiable/Item/Item.swift +++ b/Mastodon/Diffiable/Item/Item.swift @@ -39,7 +39,7 @@ extension Item { var isSeparatorLineHidden: Bool let isImageLoaded = CurrentValueSubject(false) - let isMediaRevealing = CurrentValueSubject(false) + let isRevealing = CurrentValueSubject(false) init(isSeparatorLineHidden: Bool = false) { self.isSeparatorLineHidden = isSeparatorLineHidden diff --git a/Mastodon/Diffiable/Section/StatusSection.swift b/Mastodon/Diffiable/Section/StatusSection.swift index 816f852e..a432bf06 100644 --- a/Mastodon/Diffiable/Section/StatusSection.swift +++ b/Mastodon/Diffiable/Section/StatusSection.swift @@ -235,7 +235,7 @@ extension StatusSection { } Publishers.CombineLatest( statusItemAttribute.isImageLoaded, - statusItemAttribute.isMediaRevealing + statusItemAttribute.isRevealing ) .receive(on: DispatchQueue.main) .sink { isImageLoaded, isMediaRevealing in @@ -430,15 +430,16 @@ extension StatusSection { statusView.revealContentWarningButton.isHidden = false statusView.contentWarningOverlayView.isHidden = false statusView.statusMosaicImageViewContainer.contentWarningOverlayView.isHidden = true + statusView.playerContainerView.contentWarningOverlayView.isHidden = true if let revealedAt = status.revealedAt, revealedAt > appStartUpTimestamp { statusView.updateRevealContentWarningButton(isRevealing: true) statusView.updateContentWarningDisplay(isHidden: true, animated: animated) - attribute.isMediaRevealing.value = true + attribute.isRevealing.value = true } else { statusView.updateRevealContentWarningButton(isRevealing: false) statusView.updateContentWarningDisplay(isHidden: false, animated: animated) - attribute.isMediaRevealing.value = false + attribute.isRevealing.value = false } case .media(let isSensitive): if !isSensitive, documentStore.defaultRevealStatusDict[status.id] == nil { @@ -460,17 +461,15 @@ extension StatusSection { return false }() - attribute.isMediaRevealing.value = needsReveal + attribute.isRevealing.value = needsReveal if needsReveal { statusView.updateRevealContentWarningButton(isRevealing: true) - statusView.statusMosaicImageViewContainer.contentWarningOverlayView.blurVisualEffectView.effect = nil - statusView.statusMosaicImageViewContainer.contentWarningOverlayView.vibrancyVisualEffectView.alpha = 0.0 - statusView.statusMosaicImageViewContainer.isUserInteractionEnabled = false + statusView.statusMosaicImageViewContainer.contentWarningOverlayView.update(isRevealing: true, style: .visualEffectView) + statusView.playerContainerView.contentWarningOverlayView.update(isRevealing: true, style: .visualEffectView) } else { statusView.updateRevealContentWarningButton(isRevealing: false) - statusView.statusMosaicImageViewContainer.contentWarningOverlayView.blurVisualEffectView.effect = ContentWarningOverlayView.blurVisualEffect - statusView.statusMosaicImageViewContainer.contentWarningOverlayView.vibrancyVisualEffectView.alpha = 1.0 - statusView.statusMosaicImageViewContainer.isUserInteractionEnabled = true + statusView.statusMosaicImageViewContainer.contentWarningOverlayView.update(isRevealing: false, style: .visualEffectView) + statusView.playerContainerView.contentWarningOverlayView.update(isRevealing: false, style: .visualEffectView) } } if animated { diff --git a/Mastodon/Protocol/StatusProvider/StatusProvider+StatusTableViewCellDelegate.swift b/Mastodon/Protocol/StatusProvider/StatusProvider+StatusTableViewCellDelegate.swift index 8d968777..198f0a4a 100644 --- a/Mastodon/Protocol/StatusProvider/StatusProvider+StatusTableViewCellDelegate.swift +++ b/Mastodon/Protocol/StatusProvider/StatusProvider+StatusTableViewCellDelegate.swift @@ -63,12 +63,11 @@ extension StatusTableViewCellDelegate where Self: StatusProvider { } func statusTableViewCell(_ cell: StatusTableViewCell, mosaicImageViewContainer: MosaicImageViewContainer, contentWarningOverlayViewDidPressed contentWarningOverlayView: ContentWarningOverlayView) { - statusTableViewCell(cell, contentWarningOverlayViewDidPressed: contentWarningOverlayView) + StatusProviderFacade.responseToStatusContentWarningRevealAction(provider: self, cell: cell) } func statusTableViewCell(_ cell: StatusTableViewCell, playerContainerView: PlayerContainerView, contentWarningOverlayViewDidPressed contentWarningOverlayView: ContentWarningOverlayView) { - contentWarningOverlayView.isUserInteractionEnabled = false - statusTableViewCell(cell, contentWarningOverlayViewDidPressed: contentWarningOverlayView) + StatusProviderFacade.responseToStatusContentWarningRevealAction(provider: self, cell: cell) } func statusTableViewCell(_ cell: StatusTableViewCell, contentWarningOverlayViewDidPressed contentWarningOverlayView: ContentWarningOverlayView) { diff --git a/Mastodon/Protocol/StatusProvider/StatusProviderFacade.swift b/Mastodon/Protocol/StatusProvider/StatusProviderFacade.swift index 17d2fbe4..75efcd36 100644 --- a/Mastodon/Protocol/StatusProvider/StatusProviderFacade.swift +++ b/Mastodon/Protocol/StatusProvider/StatusProviderFacade.swift @@ -449,6 +449,12 @@ extension StatusProviderFacade { provider.context.documentStore.defaultRevealStatusDict[status.id] = false status.update(isReveal: !isRevealing) status.reblog?.update(isReveal: !isRevealing) + + // pause video playback if isRevealing before toggle + if isRevealing, let attachment = (status.reblog ?? status).mediaAttachments?.first, + let playerViewModel = provider.context.videoPlaybackService.dequeueVideoPlayerViewModel(for: attachment), playerViewModel.videoKind == .video { + playerViewModel.pause() + } } .map { result in return status diff --git a/Mastodon/Scene/Share/View/Container/MosaicImageViewContainer.swift b/Mastodon/Scene/Share/View/Container/MosaicImageViewContainer.swift index 641050bc..54e25ed8 100644 --- a/Mastodon/Scene/Share/View/Container/MosaicImageViewContainer.swift +++ b/Mastodon/Scene/Share/View/Container/MosaicImageViewContainer.swift @@ -150,6 +150,7 @@ extension MosaicImageViewContainer { blurhashOverlayImageView.bottomAnchor.constraint(equalTo: imageView.bottomAnchor), ]) + contentWarningOverlayView.translatesAutoresizingMaskIntoConstraints = false addSubview(contentWarningOverlayView) NSLayoutConstraint.activate([ contentWarningOverlayView.topAnchor.constraint(equalTo: imageView.topAnchor), @@ -281,6 +282,7 @@ extension MosaicImageViewContainer { ]) } + contentWarningOverlayView.translatesAutoresizingMaskIntoConstraints = false addSubview(contentWarningOverlayView) NSLayoutConstraint.activate([ contentWarningOverlayView.topAnchor.constraint(equalTo: container.topAnchor), diff --git a/Mastodon/Scene/Share/View/Container/PlayerContainerView.swift b/Mastodon/Scene/Share/View/Container/PlayerContainerView.swift index 9c59a7eb..a6fd4406 100644 --- a/Mastodon/Scene/Share/View/Container/PlayerContainerView.swift +++ b/Mastodon/Scene/Share/View/Container/PlayerContainerView.swift @@ -71,6 +71,7 @@ extension PlayerContainerView { mediaTypeIndicotorView.widthAnchor.constraint(equalToConstant: MediaTypeIndicotorView.indicatorViewSize.width).priority(.required - 1), ]) + contentWarningOverlayView.translatesAutoresizingMaskIntoConstraints = false addSubview(contentWarningOverlayView) NSLayoutConstraint.activate([ contentWarningOverlayView.topAnchor.constraint(equalTo: topAnchor), diff --git a/Mastodon/Scene/Share/View/Content/ContentWarningOverlayView.swift b/Mastodon/Scene/Share/View/Content/ContentWarningOverlayView.swift index 37c3c774..a695e1c1 100644 --- a/Mastodon/Scene/Share/View/Content/ContentWarningOverlayView.swift +++ b/Mastodon/Scene/Share/View/Content/ContentWarningOverlayView.swift @@ -70,7 +70,7 @@ class ContentWarningOverlayView: UIView { extension ContentWarningOverlayView { private func _init() { backgroundColor = .clear - translatesAutoresizingMaskIntoConstraints = false + isUserInteractionEnabled = true // visual effect style // add blur visual effect view in the setup method @@ -169,6 +169,18 @@ extension ContentWarningOverlayView { } } + func update(isRevealing: Bool, style: Style) { + switch style { + case .visualEffectView: + blurVisualEffectView.effect = isRevealing ? nil : ContentWarningOverlayView.blurVisualEffect + vibrancyVisualEffectView.alpha = isRevealing ? 0 : 1 + isUserInteractionEnabled = !isRevealing + case .blurContentImageView: + assertionFailure("not handle here") + break + } + } + } extension ContentWarningOverlayView { diff --git a/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell.swift b/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell.swift index d219dadd..7184b767 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell.swift @@ -73,8 +73,10 @@ final class StatusTableViewCell: UITableViewCell { super.prepareForReuse() selectionStyle = .default statusView.updateContentWarningDisplay(isHidden: true, animated: false) + statusView.statusMosaicImageViewContainer.contentWarningOverlayView.isUserInteractionEnabled = true statusView.pollTableView.dataSource = nil statusView.playerContainerView.reset() + statusView.playerContainerView.contentWarningOverlayView.isUserInteractionEnabled = true statusView.playerContainerView.isHidden = true threadMetaView.isHidden = true disposeBag.removeAll() @@ -94,6 +96,8 @@ final class StatusTableViewCell: UITableViewCell { override func layoutSubviews() { super.layoutSubviews() + // precondition: app is active + guard UIApplication.shared.applicationState == .active else { return } DispatchQueue.main.async { self.statusView.drawContentWarningImageView() }