Merge pull request #1058 from j-f1/video-play-button

IOS-119 Video attachment adjustments
This commit is contained in:
Nathan Mattes 2023-06-13 14:46:06 +02:00 committed by GitHub
commit 8b69ff3acd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 48 deletions

View File

@ -1,17 +1,23 @@
//
// MediaBadgesContainer.swift
// InlineMediaOverlayContainer.swift
//
// Created by Jed Fox on 2022-12-20.
//
import SwiftUI
struct MediaBadgesContainer: View {
struct InlineMediaOverlayContainer: View {
var altDescription: String?
var isGIF = false
var mediaType: MediaType = .image
var showDuration = false
var mediaDuration: TimeInterval?
enum MediaType {
case image
case gif
case video
}
@State private var showingAlt = false
@State private var space = AnyHashable(UUID())
@ -35,7 +41,7 @@ struct MediaBadgesContainer: View {
.fixedSize(horizontal: false, vertical: true)
}
}
if isGIF {
if mediaType == .gif {
MediaBadge("GIF")
}
if showDuration {
@ -52,6 +58,20 @@ struct MediaBadgesContainer: View {
}
.padding(.horizontal, 16)
.padding(.vertical, 8)
.overlay {
if mediaType == .video {
Image(systemName: "play.circle.fill")
.font(.system(size: 54))
.foregroundColor(.white)
.shadow(color: .black.opacity(0.5), radius: 32, x: 0, y: 0)
.background(alignment: .center) {
Circle()
.fill(.ultraThinMaterial)
.frame(width: 40, height: 40)
.colorScheme(.light)
}
}
}
.onChange(of: altDescription) { _ in
showingAlt = false
}
@ -60,7 +80,7 @@ struct MediaBadgesContainer: View {
struct MediaAltTextOverlay_Previews: PreviewProvider {
static var previews: some View {
MediaBadgesContainer(altDescription: "Hello, world!")
InlineMediaOverlayContainer(altDescription: "Hello, world!")
.frame(height: 300)
.background(Color.gray)
.previewLayout(.sizeThatFits)

View File

@ -51,23 +51,8 @@ public final class MediaView: UIView {
}()
private var playerLooper: AVPlayerLooper?
private(set) lazy var playbackImageView: UIView = {
let wrapper = UIView()
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.image = UIImage(systemName: "play.circle.fill")
imageView.tintColor = Asset.Colors.Label.primary.color
wrapper.addSubview(imageView)
imageView.pinToParent(padding: .init(top: 8, left: 8, bottom: 8, right: 8))
wrapper.backgroundColor = Asset.Theme.Mastodon.systemBackground.color.withAlphaComponent(0.8)
wrapper.applyCornerRadius(radius: 8)
return wrapper
}()
let badgeViewController: UIHostingController<MediaBadgesContainer> = {
let vc = UIHostingController(rootView: MediaBadgesContainer())
let overlayViewController: UIHostingController<InlineMediaOverlayContainer> = {
let vc = UIHostingController(rootView: InlineMediaOverlayContainer())
vc.view.backgroundColor = .clear
return vc
}()
@ -112,14 +97,17 @@ extension MediaView {
switch configuration.info {
case .image(let info):
layoutImage()
overlayViewController.rootView.mediaType = .image
bindImage(configuration: configuration, info: info)
accessibilityHint = L10n.Common.Controls.Status.Media.expandImageHint
case .gif(let info):
layoutGIF()
overlayViewController.rootView.mediaType = .gif
bindGIF(configuration: configuration, info: info)
accessibilityHint = L10n.Common.Controls.Status.Media.expandGifHint
case .video(let info):
layoutVideo()
overlayViewController.rootView.mediaType = .video
bindVideo(configuration: configuration, info: info)
accessibilityHint = L10n.Common.Controls.Status.Media.expandVideoHint
}
@ -167,8 +155,8 @@ extension MediaView {
}
private func bindGIF(configuration: Configuration, info: Configuration.VideoInfo) {
badgeViewController.rootView.mediaDuration = info.durationMS.map { Double($0) / 1000 }
badgeViewController.rootView.showDuration = false
overlayViewController.rootView.mediaDuration = info.durationMS.map { Double($0) / 1000 }
overlayViewController.rootView.showDuration = false
guard let player = setupGIFPlayer(info: info) else { return }
setupPlayerLooper(player: player)
@ -178,27 +166,16 @@ extension MediaView {
// auto play for GIF
player.play()
badgeViewController.rootView.isGIF = true
bindAlt(configuration: configuration, altDescription: info.altDescription)
}
private func layoutVideo() {
layoutImage()
playbackImageView.translatesAutoresizingMaskIntoConstraints = false
container.addSubview(playbackImageView)
NSLayoutConstraint.activate([
playbackImageView.centerXAnchor.constraint(equalTo: container.centerXAnchor),
playbackImageView.centerYAnchor.constraint(equalTo: container.centerYAnchor),
playbackImageView.widthAnchor.constraint(equalToConstant: 88).priority(.required - 1),
playbackImageView.heightAnchor.constraint(equalToConstant: 88).priority(.required - 1),
])
}
private func bindVideo(configuration: Configuration, info: Configuration.VideoInfo) {
badgeViewController.rootView.mediaDuration = info.durationMS.map { Double($0) / 1000 }
badgeViewController.rootView.showDuration = true
overlayViewController.rootView.mediaDuration = info.durationMS.map { Double($0) / 1000 }
overlayViewController.rootView.showDuration = true
let imageInfo = Configuration.ImageInfo(
aspectRadio: info.aspectRadio,
@ -219,7 +196,7 @@ extension MediaView {
accessibilityLabel = altDescription
}
badgeViewController.rootView.altDescription = altDescription
overlayViewController.rootView.altDescription = altDescription
}
private func layoutBlurhash() {
@ -251,9 +228,9 @@ extension MediaView {
}
private func layoutAlt() {
badgeViewController.view.translatesAutoresizingMaskIntoConstraints = false
container.addSubview(badgeViewController.view)
badgeViewController.view.pinToParent()
overlayViewController.view.translatesAutoresizingMaskIntoConstraints = false
container.addSubview(overlayViewController.view)
overlayViewController.view.pinToParent()
}
public func prepareForReuse() {
@ -277,8 +254,6 @@ extension MediaView {
playerViewController.player = nil
playerLooper = nil
playbackImageView.removeFromSuperview()
// blurhash
blurhashImageView.removeFromSuperview()
blurhashImageView.removeConstraints(blurhashImageView.constraints)
@ -288,10 +263,9 @@ extension MediaView {
container.removeFromSuperview()
container.removeConstraints(container.constraints)
badgeViewController.rootView.altDescription = nil
badgeViewController.rootView.isGIF = false
badgeViewController.rootView.showDuration = false
badgeViewController.rootView.mediaDuration = nil
overlayViewController.rootView.altDescription = nil
overlayViewController.rootView.showDuration = false
overlayViewController.rootView.mediaDuration = nil
// reset configuration
configuration = nil