119 lines
3.3 KiB
Swift
119 lines
3.3 KiB
Swift
//
|
|
// LargeImageContentView.swift
|
|
// Tusker
|
|
//
|
|
// Created by Shadowfacts on 6/17/20.
|
|
// Copyright © 2020 Shadowfacts. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import Gifu
|
|
import Pachyderm
|
|
import AVFoundation
|
|
|
|
protocol LargeImageContentView: UIView {
|
|
var animationImage: UIImage? { get }
|
|
var animationGifData: Data? { get }
|
|
var activityItemsForSharing: [Any] { get }
|
|
func grayscaleStateChanged()
|
|
}
|
|
|
|
class LargeImageImageContentView: UIImageView, GIFAnimatable, LargeImageContentView {
|
|
lazy var animator: Animator? = {
|
|
return Animator(withDelegate: self)
|
|
}()
|
|
|
|
var animationImage: UIImage? { image! }
|
|
let animationGifData: Data?
|
|
|
|
var activityItemsForSharing: [Any] {
|
|
[image!]
|
|
}
|
|
|
|
private var sourceData: Data?
|
|
|
|
convenience init(sourceData data: Data, isGif: Bool) {
|
|
self.init(image: UIImage(data: data)!, gifData: isGif ? data : nil)
|
|
|
|
self.sourceData = data
|
|
}
|
|
|
|
init(image: UIImage, gifData: Data?) {
|
|
self.animationGifData = gifData
|
|
|
|
super.init(image: image)
|
|
|
|
contentMode = .scaleAspectFit
|
|
|
|
if let data = gifData {
|
|
self.animate(withGIFData: data)
|
|
}
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override public func display(_ layer: CALayer) {
|
|
super.display(layer)
|
|
|
|
updateImageIfNeeded()
|
|
}
|
|
|
|
func grayscaleStateChanged() {
|
|
guard let data = sourceData else {
|
|
return
|
|
}
|
|
|
|
let image: UIImage?
|
|
if Preferences.shared.grayscaleImages {
|
|
image = ImageGrayscalifier.convert(url: nil, data: data)
|
|
} else {
|
|
image = UIImage(data: data)
|
|
}
|
|
|
|
if let image = image {
|
|
self.image = image
|
|
}
|
|
}
|
|
}
|
|
|
|
class LargeImageGifvContentView: GifvAttachmentView, LargeImageContentView {
|
|
private(set) var animationImage: UIImage?
|
|
var animationGifData: Data? { nil }
|
|
var activityItemsForSharing: [Any] {
|
|
// todo: what should we share for gifvs?
|
|
// some SO posts indicate that just sharing a URL to the video should work, but that may need to be a local URL?
|
|
[]
|
|
}
|
|
|
|
private let asset: AVURLAsset
|
|
|
|
// The content view needs to supply an intrinsicContentSize for the LargeImageViewController to handle layout/scrolling/zooming correctly
|
|
override var intrinsicContentSize: CGSize {
|
|
// This is a really sucky workaround for the fact that in the content view, we don't have access to the size of the underlying video.
|
|
// There's probably some way of getting this from the AVPlayer/AVAsset directly
|
|
animationImage?.size ?? CGSize(width: UIView.noIntrinsicMetric, height: UIView.noIntrinsicMetric)
|
|
}
|
|
|
|
init(attachment: Attachment, source: UIImageView) {
|
|
precondition(attachment.kind == .gifv)
|
|
|
|
self.asset = AVURLAsset(url: attachment.url)
|
|
|
|
super.init(asset: asset, gravity: .resizeAspect)
|
|
|
|
self.animationImage = source.image
|
|
|
|
self.player.play()
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
func grayscaleStateChanged() {
|
|
// no-op, GifvAttachmentView observes the grayscale state itself
|
|
}
|
|
}
|