145 lines
4.8 KiB
Swift
145 lines
4.8 KiB
Swift
//
|
|
// ImageGalleryContentViewController.swift
|
|
// Tusker
|
|
//
|
|
// Created by Shadowfacts on 3/17/24.
|
|
// Copyright © 2024 Shadowfacts. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import GalleryVC
|
|
import Pachyderm
|
|
import TuskerComponents
|
|
@preconcurrency import VisionKit
|
|
|
|
class ImageGalleryContentViewController: UIViewController, GalleryContentViewController {
|
|
let url: URL
|
|
let caption: String?
|
|
let originalData: Data?
|
|
let image: UIImage
|
|
let gifController: GIFController?
|
|
|
|
private var imageView: GIFImageView!
|
|
|
|
@available(iOS 16.0, macCatalyst 17.0, *)
|
|
private static let analyzer = ImageAnalyzer()
|
|
private var _analysisInteraction: AnyObject?
|
|
@available(iOS 16.0, macCatalyst 17.0, *)
|
|
private var analysisInteraction: ImageAnalysisInteraction? { _analysisInteraction as? ImageAnalysisInteraction }
|
|
|
|
private var isGrayscale = false
|
|
|
|
init(url: URL, caption: String?, originalData: Data?, image: UIImage, gifController: GIFController?) {
|
|
self.url = url
|
|
self.caption = caption
|
|
self.originalData = originalData
|
|
self.image = image
|
|
self.gifController = gifController
|
|
|
|
super.init(nibName: nil, bundle: nil)
|
|
|
|
preferredContentSize = image.size
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
isGrayscale = Preferences.shared.grayscaleImages
|
|
let maybeGrayscaleImage = if isGrayscale {
|
|
ImageGrayscalifier.convert(url: url, image: image) ?? image
|
|
} else {
|
|
image
|
|
}
|
|
|
|
imageView = GIFImageView(image: maybeGrayscaleImage)
|
|
imageView.translatesAutoresizingMaskIntoConstraints = false
|
|
imageView.contentMode = .scaleAspectFill
|
|
imageView.isUserInteractionEnabled = true
|
|
view.addSubview(imageView)
|
|
NSLayoutConstraint.activate([
|
|
imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
|
imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
|
imageView.topAnchor.constraint(equalTo: view.topAnchor),
|
|
imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
|
|
])
|
|
|
|
if let gifController {
|
|
gifController.attach(to: imageView)
|
|
}
|
|
|
|
if gifController == nil,
|
|
#available(iOS 16.0, macCatalyst 17.0, *) {
|
|
let interaction = ImageAnalysisInteraction(self)
|
|
self._analysisInteraction = interaction
|
|
interaction.preferredInteractionTypes = .automatic
|
|
imageView.addInteraction(interaction)
|
|
Task {
|
|
do {
|
|
let result = try await ImageGalleryContentViewController.analyzer.analyze(image, configuration: ImageAnalyzer.Configuration([.text, .machineReadableCode]))
|
|
interaction.analysis = result
|
|
} catch {
|
|
// if analysis fails, we just don't show anything
|
|
}
|
|
}
|
|
}
|
|
|
|
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
|
|
}
|
|
|
|
override func viewWillAppear(_ animated: Bool) {
|
|
super.viewWillAppear(animated)
|
|
|
|
if let gifController {
|
|
gifController.startAnimating()
|
|
}
|
|
}
|
|
|
|
@objc private func preferencesChanged() {
|
|
if isGrayscale != Preferences.shared.grayscaleImages {
|
|
isGrayscale = Preferences.shared.grayscaleImages
|
|
let image = if isGrayscale {
|
|
ImageGrayscalifier.convert(url: url, image: image)
|
|
} else {
|
|
image
|
|
}
|
|
if let image {
|
|
imageView.image = image
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: GalleryContentViewController
|
|
|
|
var container: (any GalleryVC.GalleryContentViewControllerContainer)?
|
|
|
|
var contentSize: CGSize {
|
|
image.size
|
|
}
|
|
|
|
var activityItemsForSharing: [Any] {
|
|
if let data = originalData ?? image.pngData() {
|
|
return [ImageActivityItemSource(data: data, url: url, image: image)]
|
|
} else {
|
|
return []
|
|
}
|
|
}
|
|
|
|
func setControlsVisible(_ visible: Bool, animated: Bool) {
|
|
if #available(iOS 16.0, macCatalyst 17.0, *),
|
|
let analysisInteraction {
|
|
analysisInteraction.setSupplementaryInterfaceHidden(!visible, animated: animated)
|
|
}
|
|
}
|
|
}
|
|
|
|
@available(iOS 16.0, macCatalyst 17.0, *)
|
|
extension ImageGalleryContentViewController: ImageAnalysisInteractionDelegate {
|
|
func interaction(_ interaction: ImageAnalysisInteraction, shouldBeginAt point: CGPoint, for interactionType: ImageAnalysisInteraction.InteractionTypes) -> Bool {
|
|
return container?.galleryControlsVisible ?? true
|
|
}
|
|
}
|