mastodon-ios/MastodonSDK/Sources/MastodonUI/View/Content/InlineMediaOverlayContainer...

89 lines
2.9 KiB
Swift

//
// InlineMediaOverlayContainer.swift
//
// Created by Jed Fox on 2022-12-20.
//
import SwiftUI
struct InlineMediaOverlayContainer: View {
var altDescription: String?
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())
// Date.ComponentsFormatStyle does not allow force-enabling minutes unit
static let formatter: DateComponentsFormatter = {
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.minute, .second]
formatter.unitsStyle = .positional
formatter.zeroFormattingBehavior = []
formatter.formattingContext = .standalone
return formatter
}()
var body: some View {
GeometryReader { geom in
HStack(alignment: .bottom, spacing: 2) {
if let altDescription {
ExpandableMediaBadge("ALT", isExpanded: $showingAlt, in: (geom.size, space)) {
Text(altDescription)
.frame(maxHeight: geom.size.height - 16)
.fixedSize(horizontal: false, vertical: true)
}
}
if mediaType == .gif {
MediaBadge("GIF")
}
if showDuration {
if let mediaDuration, let format = Self.formatter.string(from: mediaDuration) {
MediaBadge(format)
.monospacedDigit()
} else {
MediaBadge("--:--")
}
}
}
.frame(width: geom.size.width, height: geom.size.height, alignment: .bottomLeading)
.coordinateSpace(name: space)
}
.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
}
}
}
struct MediaAltTextOverlay_Previews: PreviewProvider {
static var previews: some View {
InlineMediaOverlayContainer(altDescription: "Hello, world!")
.frame(height: 300)
.background(Color.gray)
.previewLayout(.sizeThatFits)
}
}